@frak-labs/core-sdk 1.0.2 → 1.1.0-beta.53162c2d
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -1
- package/cdn/bundle.js +1 -14
- package/dist/actions-BVbAHcBk.cjs +1 -0
- package/dist/actions-dH5NFCj1.js +1 -0
- package/dist/actions.cjs +1 -1
- package/dist/actions.d.cts +2 -2
- package/dist/actions.d.ts +2 -2
- package/dist/actions.js +1 -1
- package/dist/bundle.cjs +1 -1
- package/dist/bundle.d.cts +4 -4
- package/dist/bundle.d.ts +4 -4
- package/dist/bundle.js +1 -1
- package/dist/frakContext-CTKalP6g.js +1 -0
- package/dist/frakContext-_b-_uwgd.cjs +1 -0
- package/dist/{index-DzVPSUQq.d.ts → index-5JycXTk0.d.cts} +248 -352
- package/dist/{index-quaxtKRh.d.ts → index-BD1gOEIo.d.ts} +1 -1
- package/dist/{index-BsBbSMxk.d.cts → index-C2xfJCUg.d.cts} +1 -1
- package/dist/{index-s1vE3jLz.d.cts → index-RNzVfwrP.d.ts} +248 -352
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1 -1
- package/dist/{openSso-DyUQew2K.d.ts → openSso-CtDyvXLM.d.ts} +19 -20
- package/dist/{openSso-rQhLhPbq.d.cts → openSso-DIBN_iiz.d.cts} +18 -19
- package/dist/src-CDfF2FOa.cjs +1 -0
- package/dist/src-DFiac-zk.js +1 -0
- package/package.json +4 -4
- package/src/actions/ensureIdentity.ts +3 -3
- package/src/actions/openSso.ts +13 -6
- package/src/actions/referral/processReferral.test.ts +38 -22
- package/src/actions/referral/processReferral.ts +6 -4
- package/src/actions/referral/referralInteraction.test.ts +7 -7
- package/src/actions/referral/referralInteraction.ts +1 -1
- package/src/actions/sendInteraction.ts +1 -1
- package/src/actions/trackPurchaseStatus.test.ts +4 -4
- package/src/actions/trackPurchaseStatus.ts +3 -3
- package/src/actions/wrapper/siweAuthenticate.test.ts +1 -5
- package/src/actions/wrapper/siweAuthenticate.ts +25 -1
- package/src/clients/createIFrameFrakClient.ts +5 -21
- package/src/clients/index.ts +0 -1
- package/src/clients/transports/iframeLifecycleManager.test.ts +10 -10
- package/src/clients/transports/iframeLifecycleManager.ts +3 -3
- package/src/config/index.ts +3 -0
- package/src/{utils → config}/sdkConfigStore.ts +1 -1
- package/src/{utils/constants.test.ts → constants.test.ts} +1 -6
- package/src/constants.ts +15 -0
- package/src/context/address.ts +76 -0
- package/src/{utils/FrakContext.test.ts → context/frakContext.test.ts} +4 -2
- package/src/{utils/FrakContext.ts → context/frakContext.ts} +4 -4
- package/src/{utils → context}/frakContextV2Codec.test.ts +1 -1
- package/src/{utils → context}/frakContextV2Codec.ts +6 -6
- package/src/context/index.ts +6 -0
- package/src/index.ts +17 -22
- package/src/stubs/rrweb.ts +8 -4
- package/src/types/client.ts +0 -3
- package/src/types/config.ts +11 -0
- package/src/types/index.ts +1 -0
- package/src/types/rpc/sso.ts +6 -2
- package/src/utils/{deepLinkWithFallback.ts → browser/deepLinkWithFallback.ts} +10 -5
- package/src/utils/{inAppBrowser.ts → browser/inAppBrowser.ts} +13 -0
- package/src/utils/browser/index.ts +13 -0
- package/src/utils/{formatAmount.test.ts → format/formatAmount.test.ts} +1 -1
- package/src/utils/{formatAmount.ts → format/formatAmount.ts} +1 -1
- package/src/utils/{getCurrencyAmountKey.test.ts → format/getCurrencyAmountKey.test.ts} +2 -2
- package/src/utils/{getCurrencyAmountKey.ts → format/getCurrencyAmountKey.ts} +1 -1
- package/src/utils/{getSupportedCurrency.test.ts → format/getSupportedCurrency.test.ts} +2 -2
- package/src/utils/{getSupportedCurrency.ts → format/getSupportedCurrency.ts} +2 -2
- package/src/utils/{getSupportedLocale.test.ts → format/getSupportedLocale.test.ts} +3 -3
- package/src/utils/{getSupportedLocale.ts → format/getSupportedLocale.ts} +2 -2
- package/src/utils/format/index.ts +4 -0
- package/src/utils/{iframeHelper.test.ts → iframe/iframeHelper.test.ts} +3 -3
- package/src/utils/{iframeHelper.ts → iframe/iframeHelper.ts} +3 -3
- package/src/utils/iframe/index.ts +6 -0
- package/src/utils/index.ts +31 -24
- package/src/utils/sso/index.ts +6 -0
- package/src/utils/{sso.ts → sso/sso.ts} +2 -2
- package/dist/actions-DihYM-OG.js +0 -1
- package/dist/actions-cYbmqewX.cjs +0 -1
- package/dist/sdkConfigStore-BXzz5PlK.js +0 -1
- package/dist/sdkConfigStore-DDL_fjYX.cjs +0 -1
- package/dist/src-CfxklqLh.cjs +0 -13
- package/dist/src-VDUSvqqt.js +0 -13
- package/src/clients/DebugInfo.test.ts +0 -418
- package/src/clients/DebugInfo.ts +0 -182
- package/src/utils/computeLegacyProductId.ts +0 -11
- package/src/utils/constants.ts +0 -9
- /package/src/{utils → clients}/ssoUrlListener.test.ts +0 -0
- /package/src/{utils → clients}/ssoUrlListener.ts +0 -0
- /package/src/{utils → config}/backendUrl.test.ts +0 -0
- /package/src/{utils → config}/backendUrl.ts +0 -0
- /package/src/{utils → config}/clientId.test.ts +0 -0
- /package/src/{utils → config}/clientId.ts +0 -0
- /package/src/{utils → config}/sdkConfigStore.test.ts +0 -0
- /package/src/{utils → context}/mergeAttribution.test.ts +0 -0
- /package/src/{utils → context}/mergeAttribution.ts +0 -0
- /package/src/utils/{deepLinkWithFallback.test.ts → browser/deepLinkWithFallback.test.ts} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./frakContext-_b-_uwgd.cjs`),t=require(`./src-CDfF2FOa.cjs`);exports.DEEP_LINK_SCHEME=t.h,exports.FrakContextManager=e.t,exports.base64urlDecode=e.d,exports.base64urlEncode=e.f,exports.baseIframeProps=t.f,exports.clearAllCache=e.h,exports.compressJsonToB64=e.u,exports.createIFrameFrakClient=t.d,exports.decompressJsonFromB64=t.o,exports.findIframeInOpener=t.p,exports.formatAmount=t.i,exports.generateSsoUrl=e.l,exports.getBackendUrl=e.m,exports.getClientId=e._,exports.getCurrencyAmountKey=t.r,exports.getSupportedCurrency=t.a,exports.isIOS=t.s,exports.isInAppBrowser=t.c,exports.isMobile=t.l,exports.mergeAttribution=t.t,exports.redirectToExternalBrowser=t.u,exports.sdkConfigStore=e.p,exports.setupClient=t.n,exports.ssoPopupFeatures=e.s,exports.ssoPopupName=e.c,exports.trackEvent=e.a,exports.triggerDeepLinkWithFallback=t.m,exports.withCache=e.g;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { $ as
|
|
2
|
-
import { A as getClientId,
|
|
3
|
-
export { AppSpecificSsoMetadata, AttributionDefaults, AttributionParams, ClientLifecycleEvent, CompressedData, CompressedSsoData, Currency, DEEP_LINK_SCHEME,
|
|
1
|
+
import { $ as SdkResolvedConfig, A as ModalRpcStepsResultType, B as OpenSsoReturnType, C as LoggedInEmbeddedView, D as DisplayModalParamsType, E as SharingPageProduct, F as SiweAuthenticateModalStepType, G as FinalModalStepType, H as PrepareSsoReturnType, I as SiweAuthenticateReturnType, J as IFrameLifecycleEvent, K as ModalStepMetadata, L as SiweAuthenticationParams, M as SendTransactionModalStepType, N as SendTransactionReturnType, O as ModalRpcMetadata, P as SendTransactionTxType, Q as ResolvedSdkConfig, R as LoginModalStepType, S as EmbeddedViewActionSharing, T as DisplaySharingPageResultType, U as SsoMetadata, V as PrepareSsoParamsType, W as FinalActionType, X as MerchantConfigResponse, Y as ClientLifecycleEvent, Z as ResolvedPlacement, _ as SendInteractionParamsType, a as FrakContextV1, at as LocalizedI18nConfig, b as LoggedOutEmbeddedView, c as FrakLifecycleEvent, ct as TrackArrivalParams, d as WalletStatusReturnType, et as Currency, f as UserReferralStatusType, g as TokenAmountType, h as RewardTier, i as FrakContext, it as ListenerPreloadOption, j as ModalStepTypes, k as ModalRpcStepsInput, l as IFrameTransport, lt as TrackArrivalResult, m as GetMerchantInformationReturnType, n as ssoPopupFeatures, nt as I18nConfig, o as FrakContextV2, ot as AttributionDefaults, p as EstimatedReward, q as InteractionTypeKey, r as ssoPopupName, rt as Language, s as FrakClient, st as AttributionParams, tt as FrakWalletSdkConfig, u as IFrameRpcSchema, ut as UtmParams, v as DisplayEmbeddedWalletParamsType, w as DisplaySharingPageParamsType, x as EmbeddedViewActionReferred, y as DisplayEmbeddedWalletResultType, z as OpenSsoParamsType } from "./openSso-DIBN_iiz.cjs";
|
|
2
|
+
import { A as getClientId, C as SdkEventMap, D as FrakContextManager, E as mergeAttribution, F as HashProtectedData, I as KeyProvider, M as setupClient, N as createIFrameFrakClient, O as DEEP_LINK_SCHEME, P as CompressedData, S as trackEvent, T as MergeAttributionInput, _ as isInAppBrowser, a as baseIframeProps, b as DeepLinkFallbackOptions, c as getCurrencyAmountKey, d as compressJsonToB64, f as base64urlDecode, g as isIOS, h as withCache, i as generateSsoUrl, j as getBackendUrl, k as sdkConfigStore, l as formatAmount, m as clearAllCache, n as CompressedSsoData, o as findIframeInOpener, p as base64urlEncode, r as FullSsoParams, s as getSupportedCurrency, t as AppSpecificSsoMetadata, u as decompressJsonFromB64, v as isMobile, w as SdkHandshakeFailureReason, x as triggerDeepLinkWithFallback, y as redirectToExternalBrowser } from "./index-5JycXTk0.cjs";
|
|
3
|
+
export { AppSpecificSsoMetadata, AttributionDefaults, AttributionParams, ClientLifecycleEvent, CompressedData, CompressedSsoData, Currency, DEEP_LINK_SCHEME, 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, ListenerPreloadOption, 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, createIFrameFrakClient, decompressJsonFromB64, findIframeInOpener, formatAmount, generateSsoUrl, getBackendUrl, getClientId, getCurrencyAmountKey, getSupportedCurrency, isIOS, isInAppBrowser, isMobile, mergeAttribution, redirectToExternalBrowser, sdkConfigStore, setupClient, ssoPopupFeatures, ssoPopupName, trackEvent, triggerDeepLinkWithFallback, withCache };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { $ as
|
|
2
|
-
import { A as getClientId,
|
|
3
|
-
export { AppSpecificSsoMetadata, AttributionDefaults, AttributionParams, ClientLifecycleEvent, CompressedData, CompressedSsoData, Currency, DEEP_LINK_SCHEME,
|
|
1
|
+
import { $ as SdkResolvedConfig, A as ModalRpcStepsResultType, B as OpenSsoReturnType, C as LoggedInEmbeddedView, D as DisplayModalParamsType, E as SharingPageProduct, F as SiweAuthenticateModalStepType, G as FinalModalStepType, H as PrepareSsoReturnType, I as SiweAuthenticateReturnType, J as IFrameLifecycleEvent, K as ModalStepMetadata, L as SiweAuthenticationParams, M as SendTransactionModalStepType, N as SendTransactionReturnType, O as ModalRpcMetadata, P as SendTransactionTxType, Q as ResolvedSdkConfig, R as LoginModalStepType, S as EmbeddedViewActionSharing, T as DisplaySharingPageResultType, U as SsoMetadata, V as PrepareSsoParamsType, W as FinalActionType, X as MerchantConfigResponse, Y as ClientLifecycleEvent, Z as ResolvedPlacement, _ as SendInteractionParamsType, a as FrakContextV1, at as LocalizedI18nConfig, b as LoggedOutEmbeddedView, c as FrakLifecycleEvent, ct as TrackArrivalParams, d as WalletStatusReturnType, et as Currency, f as UserReferralStatusType, g as TokenAmountType, h as RewardTier, i as FrakContext, it as ListenerPreloadOption, j as ModalStepTypes, k as ModalRpcStepsInput, l as IFrameTransport, lt as TrackArrivalResult, m as GetMerchantInformationReturnType, n as ssoPopupFeatures, nt as I18nConfig, o as FrakContextV2, ot as AttributionDefaults, p as EstimatedReward, q as InteractionTypeKey, r as ssoPopupName, rt as Language, s as FrakClient, st as AttributionParams, tt as FrakWalletSdkConfig, u as IFrameRpcSchema, ut as UtmParams, v as DisplayEmbeddedWalletParamsType, w as DisplaySharingPageParamsType, x as EmbeddedViewActionReferred, y as DisplayEmbeddedWalletResultType, z as OpenSsoParamsType } from "./openSso-CtDyvXLM.js";
|
|
2
|
+
import { A as getClientId, C as SdkEventMap, D as FrakContextManager, E as mergeAttribution, F as HashProtectedData, I as KeyProvider, M as setupClient, N as createIFrameFrakClient, O as DEEP_LINK_SCHEME, P as CompressedData, S as trackEvent, T as MergeAttributionInput, _ as isInAppBrowser, a as baseIframeProps, b as DeepLinkFallbackOptions, c as getCurrencyAmountKey, d as compressJsonToB64, f as base64urlDecode, g as isIOS, h as withCache, i as generateSsoUrl, j as getBackendUrl, k as sdkConfigStore, l as formatAmount, m as clearAllCache, n as CompressedSsoData, o as findIframeInOpener, p as base64urlEncode, r as FullSsoParams, s as getSupportedCurrency, t as AppSpecificSsoMetadata, u as decompressJsonFromB64, v as isMobile, w as SdkHandshakeFailureReason, x as triggerDeepLinkWithFallback, y as redirectToExternalBrowser } from "./index-RNzVfwrP.js";
|
|
3
|
+
export { AppSpecificSsoMetadata, AttributionDefaults, AttributionParams, ClientLifecycleEvent, CompressedData, CompressedSsoData, Currency, DEEP_LINK_SCHEME, 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, ListenerPreloadOption, 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, createIFrameFrakClient, decompressJsonFromB64, findIframeInOpener, formatAmount, generateSsoUrl, getBackendUrl, getClientId, getCurrencyAmountKey, getSupportedCurrency, isIOS, isInAppBrowser, isMobile, mergeAttribution, redirectToExternalBrowser, sdkConfigStore, setupClient, ssoPopupFeatures, ssoPopupName, trackEvent, triggerDeepLinkWithFallback, withCache };
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{_ as e,a as t,c as n,d as r,f as i,g as a,h as o,
|
|
1
|
+
import{_ as e,a as t,c as n,d as r,f as i,g as a,h as o,l as s,m as c,p as l,s as u,t as d,u as f}from"./frakContext-CTKalP6g.js";import{a as p,c as m,d as h,f as g,h as _,i as v,l as y,m as b,n as x,o as S,p as C,r as w,s as T,t as E,u as D}from"./src-DFiac-zk.js";export{_ as DEEP_LINK_SCHEME,d as FrakContextManager,r as base64urlDecode,i as base64urlEncode,g as baseIframeProps,o as clearAllCache,f as compressJsonToB64,h as createIFrameFrakClient,S as decompressJsonFromB64,C as findIframeInOpener,v as formatAmount,s as generateSsoUrl,c as getBackendUrl,e as getClientId,w as getCurrencyAmountKey,p as getSupportedCurrency,T as isIOS,m as isInAppBrowser,y as isMobile,E as mergeAttribution,D as redirectToExternalBrowser,l as sdkConfigStore,x as setupClient,u as ssoPopupFeatures,n as ssoPopupName,t as trackEvent,b as triggerDeepLinkWithFallback,a as withCache};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Address, Hex } from "viem";
|
|
2
1
|
import { LifecycleMessage, RpcClient } from "@frak-labs/frame-connector";
|
|
3
2
|
import { OpenPanel } from "@openpanel/web";
|
|
3
|
+
import { Address, Hex } from "viem";
|
|
4
4
|
import { SiweMessage } from "viem/siwe";
|
|
5
5
|
|
|
6
6
|
//#region src/types/tracking.d.ts
|
|
@@ -144,6 +144,11 @@ type FrakWalletSdkConfig = {
|
|
|
144
144
|
* excluded — it is per-content/per-product, never a merchant-wide default.
|
|
145
145
|
*/
|
|
146
146
|
attribution?: AttributionDefaults;
|
|
147
|
+
/**
|
|
148
|
+
* Preload specific UI views inside the listener iframe for better UX.
|
|
149
|
+
* Default: ["sharing"]
|
|
150
|
+
*/
|
|
151
|
+
preload?: ListenerPreloadOption[];
|
|
147
152
|
};
|
|
148
153
|
/**
|
|
149
154
|
* Custom i18n configuration for the modal
|
|
@@ -179,6 +184,11 @@ type FrakWalletSdkConfig = {
|
|
|
179
184
|
* @category Config
|
|
180
185
|
*/
|
|
181
186
|
type I18nConfig = Record<Language, LocalizedI18nConfig> | LocalizedI18nConfig;
|
|
187
|
+
/**
|
|
188
|
+
* Options for preloading the listener UI
|
|
189
|
+
* @category Config
|
|
190
|
+
*/
|
|
191
|
+
type ListenerPreloadOption = "modal" | "sharing";
|
|
182
192
|
/**
|
|
183
193
|
* A localized i18n config (inline objects only — URL-based i18n removed)
|
|
184
194
|
* @category Config
|
|
@@ -514,8 +524,12 @@ type PrepareSsoParamsType = {
|
|
|
514
524
|
*/
|
|
515
525
|
redirectUrl?: string;
|
|
516
526
|
/**
|
|
517
|
-
* If the SSO should directly exit after completion
|
|
518
|
-
*
|
|
527
|
+
* If the SSO should directly exit (close the popup) after completion.
|
|
528
|
+
*
|
|
529
|
+
* Defaults to `true` when `redirectUrl` is omitted, `false` otherwise.
|
|
530
|
+
* The default is applied by {@link @frak-labs/core-sdk!actions.openSso | `openSso()`}
|
|
531
|
+
* before the SSO URL is generated and by the wallet SSO route as a fallback
|
|
532
|
+
* for older SDK callers.
|
|
519
533
|
*/
|
|
520
534
|
directExit?: boolean;
|
|
521
535
|
/**
|
|
@@ -1272,9 +1286,6 @@ type FrakLifecycleEvent = IFrameLifecycleEvent | ClientLifecycleEvent;
|
|
|
1272
1286
|
*/
|
|
1273
1287
|
type FrakClient = {
|
|
1274
1288
|
config: FrakWalletSdkConfig;
|
|
1275
|
-
debugInfo: {
|
|
1276
|
-
formatDebugInfo: (error: Error | unknown | string) => string;
|
|
1277
|
-
};
|
|
1278
1289
|
openPanel?: OpenPanel;
|
|
1279
1290
|
} & IFrameTransport;
|
|
1280
1291
|
//#endregion
|
|
@@ -1318,18 +1329,6 @@ type FrakContextV2 = {
|
|
|
1318
1329
|
* @ignore
|
|
1319
1330
|
*/
|
|
1320
1331
|
type FrakContext = FrakContextV1 | FrakContextV2;
|
|
1321
|
-
/**
|
|
1322
|
-
* Type guard: check if a context is V1 (legacy wallet address).
|
|
1323
|
-
* @param ctx - The Frak context to check
|
|
1324
|
-
* @returns True if the context is a V1 context
|
|
1325
|
-
*/
|
|
1326
|
-
declare function isV1Context(ctx: FrakContext): ctx is FrakContextV1;
|
|
1327
|
-
/**
|
|
1328
|
-
* Type guard: check if a context is V2 (anonymous clientId-based).
|
|
1329
|
-
* @param ctx - The Frak context to check
|
|
1330
|
-
* @returns True if the context is a V2 context
|
|
1331
|
-
*/
|
|
1332
|
-
declare function isV2Context(ctx: FrakContext): ctx is FrakContextV2;
|
|
1333
1332
|
//#endregion
|
|
1334
1333
|
//#region src/actions/openSso.d.ts
|
|
1335
1334
|
declare const ssoPopupFeatures = "menubar=no,status=no,scrollbars=no,fullscreen=no,width=500, height=800";
|
|
@@ -1387,6 +1386,6 @@ declare const ssoPopupName = "frak-sso";
|
|
|
1387
1386
|
* ```
|
|
1388
1387
|
* :::
|
|
1389
1388
|
*/
|
|
1390
|
-
declare function openSso(client: FrakClient,
|
|
1389
|
+
declare function openSso(client: FrakClient, inputArgs: OpenSsoParamsType): Promise<OpenSsoReturnType>;
|
|
1391
1390
|
//#endregion
|
|
1392
|
-
export {
|
|
1391
|
+
export { SdkResolvedConfig as $, ModalRpcStepsResultType as A, OpenSsoReturnType as B, LoggedInEmbeddedView as C, DisplayModalParamsType as D, SharingPageProduct as E, SiweAuthenticateModalStepType as F, FinalModalStepType as G, PrepareSsoReturnType as H, SiweAuthenticateReturnType as I, IFrameLifecycleEvent as J, ModalStepMetadata as K, SiweAuthenticationParams as L, SendTransactionModalStepType as M, SendTransactionReturnType as N, ModalRpcMetadata as O, SendTransactionTxType as P, ResolvedSdkConfig as Q, LoginModalStepType as R, EmbeddedViewActionSharing as S, DisplaySharingPageResultType as T, SsoMetadata as U, PrepareSsoParamsType as V, FinalActionType as W, MerchantConfigResponse as X, ClientLifecycleEvent as Y, ResolvedPlacement as Z, SendInteractionParamsType as _, FrakContextV1 as a, LocalizedI18nConfig as at, LoggedOutEmbeddedView as b, FrakLifecycleEvent as c, TrackArrivalParams as ct, WalletStatusReturnType as d, Currency as et, UserReferralStatusType as f, TokenAmountType as g, RewardTier as h, FrakContext as i, ListenerPreloadOption as it, ModalStepTypes as j, ModalRpcStepsInput as k, IFrameTransport as l, TrackArrivalResult as lt, GetMerchantInformationReturnType as m, ssoPopupFeatures as n, I18nConfig as nt, FrakContextV2 as o, AttributionDefaults as ot, EstimatedReward as p, InteractionTypeKey as q, ssoPopupName as r, Language as rt, FrakClient as s, AttributionParams as st, openSso as t, FrakWalletSdkConfig as tt, IFrameRpcSchema as u, UtmParams as ut, DisplayEmbeddedWalletParamsType as v, DisplaySharingPageParamsType as w, EmbeddedViewActionReferred as x, DisplayEmbeddedWalletResultType as y, OpenSsoParamsType as z };
|
|
@@ -144,6 +144,11 @@ type FrakWalletSdkConfig = {
|
|
|
144
144
|
* excluded — it is per-content/per-product, never a merchant-wide default.
|
|
145
145
|
*/
|
|
146
146
|
attribution?: AttributionDefaults;
|
|
147
|
+
/**
|
|
148
|
+
* Preload specific UI views inside the listener iframe for better UX.
|
|
149
|
+
* Default: ["sharing"]
|
|
150
|
+
*/
|
|
151
|
+
preload?: ListenerPreloadOption[];
|
|
147
152
|
};
|
|
148
153
|
/**
|
|
149
154
|
* Custom i18n configuration for the modal
|
|
@@ -179,6 +184,11 @@ type FrakWalletSdkConfig = {
|
|
|
179
184
|
* @category Config
|
|
180
185
|
*/
|
|
181
186
|
type I18nConfig = Record<Language, LocalizedI18nConfig> | LocalizedI18nConfig;
|
|
187
|
+
/**
|
|
188
|
+
* Options for preloading the listener UI
|
|
189
|
+
* @category Config
|
|
190
|
+
*/
|
|
191
|
+
type ListenerPreloadOption = "modal" | "sharing";
|
|
182
192
|
/**
|
|
183
193
|
* A localized i18n config (inline objects only — URL-based i18n removed)
|
|
184
194
|
* @category Config
|
|
@@ -514,8 +524,12 @@ type PrepareSsoParamsType = {
|
|
|
514
524
|
*/
|
|
515
525
|
redirectUrl?: string;
|
|
516
526
|
/**
|
|
517
|
-
* If the SSO should directly exit after completion
|
|
518
|
-
*
|
|
527
|
+
* If the SSO should directly exit (close the popup) after completion.
|
|
528
|
+
*
|
|
529
|
+
* Defaults to `true` when `redirectUrl` is omitted, `false` otherwise.
|
|
530
|
+
* The default is applied by {@link @frak-labs/core-sdk!actions.openSso | `openSso()`}
|
|
531
|
+
* before the SSO URL is generated and by the wallet SSO route as a fallback
|
|
532
|
+
* for older SDK callers.
|
|
519
533
|
*/
|
|
520
534
|
directExit?: boolean;
|
|
521
535
|
/**
|
|
@@ -1272,9 +1286,6 @@ type FrakLifecycleEvent = IFrameLifecycleEvent | ClientLifecycleEvent;
|
|
|
1272
1286
|
*/
|
|
1273
1287
|
type FrakClient = {
|
|
1274
1288
|
config: FrakWalletSdkConfig;
|
|
1275
|
-
debugInfo: {
|
|
1276
|
-
formatDebugInfo: (error: Error | unknown | string) => string;
|
|
1277
|
-
};
|
|
1278
1289
|
openPanel?: OpenPanel;
|
|
1279
1290
|
} & IFrameTransport;
|
|
1280
1291
|
//#endregion
|
|
@@ -1318,18 +1329,6 @@ type FrakContextV2 = {
|
|
|
1318
1329
|
* @ignore
|
|
1319
1330
|
*/
|
|
1320
1331
|
type FrakContext = FrakContextV1 | FrakContextV2;
|
|
1321
|
-
/**
|
|
1322
|
-
* Type guard: check if a context is V1 (legacy wallet address).
|
|
1323
|
-
* @param ctx - The Frak context to check
|
|
1324
|
-
* @returns True if the context is a V1 context
|
|
1325
|
-
*/
|
|
1326
|
-
declare function isV1Context(ctx: FrakContext): ctx is FrakContextV1;
|
|
1327
|
-
/**
|
|
1328
|
-
* Type guard: check if a context is V2 (anonymous clientId-based).
|
|
1329
|
-
* @param ctx - The Frak context to check
|
|
1330
|
-
* @returns True if the context is a V2 context
|
|
1331
|
-
*/
|
|
1332
|
-
declare function isV2Context(ctx: FrakContext): ctx is FrakContextV2;
|
|
1333
1332
|
//#endregion
|
|
1334
1333
|
//#region src/actions/openSso.d.ts
|
|
1335
1334
|
declare const ssoPopupFeatures = "menubar=no,status=no,scrollbars=no,fullscreen=no,width=500, height=800";
|
|
@@ -1387,6 +1386,6 @@ declare const ssoPopupName = "frak-sso";
|
|
|
1387
1386
|
* ```
|
|
1388
1387
|
* :::
|
|
1389
1388
|
*/
|
|
1390
|
-
declare function openSso(client: FrakClient,
|
|
1389
|
+
declare function openSso(client: FrakClient, inputArgs: OpenSsoParamsType): Promise<OpenSsoReturnType>;
|
|
1391
1390
|
//#endregion
|
|
1392
|
-
export {
|
|
1391
|
+
export { SdkResolvedConfig as $, ModalRpcStepsResultType as A, OpenSsoReturnType as B, LoggedInEmbeddedView as C, DisplayModalParamsType as D, SharingPageProduct as E, SiweAuthenticateModalStepType as F, FinalModalStepType as G, PrepareSsoReturnType as H, SiweAuthenticateReturnType as I, IFrameLifecycleEvent as J, ModalStepMetadata as K, SiweAuthenticationParams as L, SendTransactionModalStepType as M, SendTransactionReturnType as N, ModalRpcMetadata as O, SendTransactionTxType as P, ResolvedSdkConfig as Q, LoginModalStepType as R, EmbeddedViewActionSharing as S, DisplaySharingPageResultType as T, SsoMetadata as U, PrepareSsoParamsType as V, FinalActionType as W, MerchantConfigResponse as X, ClientLifecycleEvent as Y, ResolvedPlacement as Z, SendInteractionParamsType as _, FrakContextV1 as a, LocalizedI18nConfig as at, LoggedOutEmbeddedView as b, FrakLifecycleEvent as c, TrackArrivalParams as ct, WalletStatusReturnType as d, Currency as et, UserReferralStatusType as f, TokenAmountType as g, RewardTier as h, FrakContext as i, ListenerPreloadOption as it, ModalStepTypes as j, ModalRpcStepsInput as k, IFrameTransport as l, TrackArrivalResult as lt, GetMerchantInformationReturnType as m, ssoPopupFeatures as n, I18nConfig as nt, FrakContextV2 as o, AttributionDefaults as ot, EstimatedReward as p, InteractionTypeKey as q, ssoPopupName as r, Language as rt, FrakClient as s, AttributionParams as st, openSso as t, FrakWalletSdkConfig as tt, IFrameRpcSchema as u, UtmParams as ut, DisplayEmbeddedWalletParamsType as v, DisplaySharingPageParamsType as w, EmbeddedViewActionReferred as x, DisplayEmbeddedWalletResultType as y, OpenSsoParamsType as z };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=require(`./frakContext-_b-_uwgd.cjs`);let t=require(`@frak-labs/frame-connector`),n=require(`@openpanel/web`);const r=`nexus-wallet-backup`,i=`frakwallet://`;function a(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`))}function o(){let e=navigator.userAgent;return/Android/i.test(e)&&/Chrome\/\d+/i.test(e)}const s=i.replace(`://`,``);function c(e){return`intent://${e.slice(13)}#Intent;scheme=${s};end`}function l(e,t){let n=t?.timeout??2500,r=!1,i=()=>{document.hidden&&(r=!0)};document.addEventListener(`visibilitychange`,i);let a=o()&&u(e)?c(e):e;window.location.href=a,setTimeout(()=>{document.removeEventListener(`visibilitychange`,i),r||t?.onFallback?.()},n)}function u(e){return e.startsWith(i)}const d={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 f({walletBaseUrl:t,config:n}){let r=document.querySelector(`#frak-wallet`);r&&r.remove();let i=document.createElement(`iframe`);i.id=d.id,i.name=d.name,i.allow=d.allow,i.style.zIndex=d.style.zIndex.toString(),p({iframe:i,isVisible:!1});let a=n?.walletUrl??t??`https://wallet.frak.id`,o=e._();return h(a),h(e.m(a)),i.src=`${a}/listener?clientId=${encodeURIComponent(o)}`,new Promise(e=>{i.addEventListener(`load`,()=>e(i)),document.body.appendChild(i)})}function p({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 m(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 h(e){if(!(typeof document>`u`))try{let t=new URL(e).origin,n=`link[rel="preconnect"][data-frak-preconnect="${t}"]`;if(document.head.querySelector(n))return;let r=document.createElement(`link`);r.rel=`preconnect`,r.href=t,r.crossOrigin=``,r.dataset.frakPreconnect=t,document.head.appendChild(r)}catch{}}const g=(()=>{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 _(e){e?localStorage.setItem(r,e):localStorage.removeItem(r)}function v(e,t){try{let n=new URL(e);if(!n.searchParams.has(`u`))return e;let r=x(window.location.href,t);return n.searchParams.delete(`u`),n.searchParams.append(`u`,r),n.toString()}catch{return e}}function y(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 b(e){return e.includes(`/common/social`)}function x(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 S(e,t,n,r,i){if(i){let e=v(t,r);window.open(e,`_blank`);return}if(u(t)){let i=v(t,r);l(i,{onFallback:()=>{e.contentWindow?.postMessage({clientLifecycle:`deep-link-failed`,data:{originalUrl:i}},n)}})}else if(g&&b(t))y(r);else{let e=v(t,r);window.location.href=e}}function C({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`:_(o.backup);break;case`remove-backup`:localStorage.removeItem(r);break;case`show`:case`hide`:p({iframe:e,isVisible:a===`show`});break;case`redirect`:S(e,o.baseRedirectUrl,n,o.mergeToken,o.openInNewTab);break}},isConnected:i.promise}}function w({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.p.setCacheScope(c,s),e.p.reset();let l=e.p.isCacheFresh?void 0:e.p.resolve(r.domain,r.walletUrl,s),u=C({iframe:i,targetOrigin:a}),d=new t.Deferred,f=Date.now();if(!i.contentWindow)throw new t.FrakRpcError(t.RpcErrorCodes.configError,`The iframe does not have a content window`);let p=(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}}],lifecycleHandlers:{iframeLifecycle:(e,t)=>{u.handleEvent(e)}}}),m=T(p,u),h=async()=>{m(),p.cleanup(),i.remove(),e.h(),e.p.clearCache(),e.p.reset()},g;{console.log(`[Frak SDK] Initializing OpenPanel`),g=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.1.0`,userAnonymousClientId:e._()}),!0)}),g.setGlobalProperties({sdkVersion:`1.1.0`,userAnonymousClientId:e._()}),g.init(),g.track(`sdk_initialized`,{sdkVersion:`1.1.0`});let t=!1,r=setTimeout(()=>{t||(t=!0,g?.track(`sdk_iframe_handshake_failed`,{reason:`timeout`}))},3e4);u.isConnected.then(()=>{t||(t=!0,clearTimeout(r),g?.track(`sdk_iframe_connected`,{handshake_duration_ms:Date.now()-f}))}).catch(()=>{t||(t=!0,clearTimeout(r),g?.track(`sdk_iframe_handshake_failed`,{reason:`unknown`}))})}let _=E({config:r,rpcClient:p,lifecycleManager:u,configPromise:l,contextSent:d,openPanel:g}).then(()=>{}).catch(e=>{throw d.reject(e),e});return{config:r,waitForConnection:u.isConnected,waitForSetup:_,request:p.request,listenerRequest:p.listen,destroy:h,openPanel:g}}function T(e,t){let n,r,i=()=>e.sendLifecycle({clientLifecycle:`heartbeat`});async function a(){i(),n=setInterval(i,250),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 E({config:t,rpcClient:n,lifecycleManager:i,configPromise:o,contextSent:s,openPanel:c}){await i.isConnected,a(n,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.p.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=t=>{let r=f?void 0:u;f=!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._();if(c){let e=c.global??{};c.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.p.isResolved&&(p(e.p.getConfig()),s.resolve()),o&&(d(await o),p(e.p.getConfig()),s.resolve());async function m(){let e=t.customizations?.css;e&&n.sendLifecycle({clientLifecycle:`modal-css`,data:{cssLink:e}})}async function h(){let e=t.customizations?.i18n;e&&n.sendLifecycle({clientLifecycle:`modal-i18n`,data:{i18n:e}})}async function g(){if(typeof window>`u`)return;let e=window.localStorage.getItem(r);e&&n.sendLifecycle({clientLifecycle:`restore-backup`,data:{backup:e}})}(await Promise.allSettled([m(),h(),g()])).some(e=>e.status===`rejected`)&&c?.track(`sdk_iframe_handshake_failed`,{reason:`asset_push`})}function D(){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 O=D();function k(){return typeof navigator>`u`?!1:O?!0:/Android|webOS|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)}function A(){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 j=A();function M(e){O&&e.startsWith(`https://`)?window.location.href=`x-safari-https://${e.slice(8)}`:O&&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 N(n){return(0,t.jsonDecode)(e.d(n))}const P={eur:`fr-FR`,usd:`en-US`,gbp:`en-GB`};function F(e){return e&&e in P?e:`eur`}function I(e){return e?P[e]??P.eur:P.eur}function L(e,t){let n=I(t),r=F(t);return e.toLocaleString(n,{style:`currency`,currency:r,minimumFractionDigits:0,maximumFractionDigits:2})}function R(e){return e?`${e}Amount`:`eurAmount`}async function z({config:e}){let t=B(e),n=await f({config:t});if(!n){console.error(`Failed to create iframe`);return}let r=w({config:t,iframe:n});if(await r.waitForSetup,!await r.waitForConnection){console.error(`Failed to connect to client`);return}return r}function B(e){let t=F(e.metadata?.currency);return{...e,metadata:{...e.metadata,currency:t}}}function V({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}Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return F}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return j}}),Object.defineProperty(exports,`d`,{enumerable:!0,get:function(){return w}}),Object.defineProperty(exports,`f`,{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,`h`,{enumerable:!0,get:function(){return i}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return L}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return k}}),Object.defineProperty(exports,`m`,{enumerable:!0,get:function(){return l}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return z}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return N}}),Object.defineProperty(exports,`p`,{enumerable:!0,get:function(){return m}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return R}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return O}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return V}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return M}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as e,d as t,h as n,m as r,p as i}from"./frakContext-CTKalP6g.js";import{Deferred as a,FrakRpcError as o,RpcErrorCodes as s,createRpcClient as c,jsonDecode as l}from"@frak-labs/frame-connector";import{OpenPanel as u}from"@openpanel/web";const d=`nexus-wallet-backup`,f=`frakwallet://`;function p(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`))}function m(){let e=navigator.userAgent;return/Android/i.test(e)&&/Chrome\/\d+/i.test(e)}const h=f.replace(`://`,``);function g(e){return`intent://${e.slice(13)}#Intent;scheme=${h};end`}function _(e,t){let n=t?.timeout??2500,r=!1,i=()=>{document.hidden&&(r=!0)};document.addEventListener(`visibilitychange`,i);let a=m()&&v(e)?g(e):e;window.location.href=a,setTimeout(()=>{document.removeEventListener(`visibilitychange`,i),r||t?.onFallback?.()},n)}function v(e){return e.startsWith(f)}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:t,config:n}){let i=document.querySelector(`#frak-wallet`);i&&i.remove();let a=document.createElement(`iframe`);a.id=y.id,a.name=y.name,a.allow=y.allow,a.style.zIndex=y.style.zIndex.toString(),x({iframe:a,isVisible:!1});let o=n?.walletUrl??t??`https://wallet.frak.id`,s=e();return C(o),C(r(o)),a.src=`${o}/listener?clientId=${encodeURIComponent(s)}`,new Promise(e=>{a.addEventListener(`load`,()=>e(a)),document.body.appendChild(a)})}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(e){if(!(typeof document>`u`))try{let t=new URL(e).origin,n=`link[rel="preconnect"][data-frak-preconnect="${t}"]`;if(document.head.querySelector(n))return;let r=document.createElement(`link`);r.rel=`preconnect`,r.href=t,r.crossOrigin=``,r.dataset.frakPreconnect=t,document.head.appendChild(r)}catch{}}const w=(()=>{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 T(e){e?localStorage.setItem(d,e):localStorage.removeItem(d)}function E(e,t){try{let n=new URL(e);if(!n.searchParams.has(`u`))return e;let r=k(window.location.href,t);return n.searchParams.delete(`u`),n.searchParams.append(`u`,r),n.toString()}catch{return e}}function D(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 O(e){return e.includes(`/common/social`)}function k(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 A(e,t,n,r,i){if(i){let e=E(t,r);window.open(e,`_blank`);return}if(v(t)){let i=E(t,r);_(i,{onFallback:()=>{e.contentWindow?.postMessage({clientLifecycle:`deep-link-failed`,data:{originalUrl:i}},n)}})}else if(w&&O(t))D(r);else{let e=E(t,r);window.location.href=e}}function j({iframe:e,targetOrigin:t}){let n=new a;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`:T(a.backup);break;case`remove-backup`:localStorage.removeItem(d);break;case`show`:case`hide`:x({iframe:e,isVisible:i===`show`});break;case`redirect`:A(e,a.baseRedirectUrl,t,a.mergeToken,a.openInNewTab);break}},isConnected:n.promise}}function M({config:t,iframe:r}){let l=t?.walletUrl??`https://wallet.frak.id`,d=typeof navigator<`u`?navigator.language?.split(`-`)[0]:void 0,f=t.metadata.lang??(d===`en`||d===`fr`?d:void 0),p=t.domain??(typeof window<`u`?window.location.hostname:``);i.setCacheScope(p,f),i.reset();let m=i.isCacheFresh?void 0:i.resolve(t.domain,t.walletUrl,f),h=j({iframe:r,targetOrigin:l}),g=new a,_=Date.now();if(!r.contentWindow)throw new o(s.configError,`The iframe does not have a content window`);let v=c({emittingTransport:r.contentWindow,listeningTransport:window,targetOrigin:l,middleware:[{async onRequest(e,t){if(!await h.isConnected)throw new o(s.clientNotConnected,`The iframe provider isn't connected yet`);return await g.promise,t}}],lifecycleHandlers:{iframeLifecycle:(e,t)=>{h.handleEvent(e)}}}),y=N(v,h),b=async()=>{y(),v.cleanup(),r.remove(),n(),i.clearCache(),i.reset()},x;{console.log(`[Frak SDK] Initializing OpenPanel`),x=new u({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.1.0`,userAnonymousClientId:e()}),!0)}),x.setGlobalProperties({sdkVersion:`1.1.0`,userAnonymousClientId:e()}),x.init(),x.track(`sdk_initialized`,{sdkVersion:`1.1.0`});let t=!1,n=setTimeout(()=>{t||(t=!0,x?.track(`sdk_iframe_handshake_failed`,{reason:`timeout`}))},3e4);h.isConnected.then(()=>{t||(t=!0,clearTimeout(n),x?.track(`sdk_iframe_connected`,{handshake_duration_ms:Date.now()-_}))}).catch(()=>{t||(t=!0,clearTimeout(n),x?.track(`sdk_iframe_handshake_failed`,{reason:`unknown`}))})}let S=P({config:t,rpcClient:v,lifecycleManager:h,configPromise:m,contextSent:g,openPanel:x}).then(()=>{}).catch(e=>{throw g.reject(e),e});return{config:t,waitForConnection:h.isConnected,waitForSetup:S,request:v.request,listenerRequest:v.listen,destroy:b,openPanel:x}}function N(e,t){let n,r,i=()=>e.sendLifecycle({clientLifecycle:`heartbeat`});async function a(){i(),n=setInterval(i,250),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 P({config:t,rpcClient:n,lifecycleManager:r,configPromise:a,contextSent:o,openPanel:s}){await r.isConnected,p(n,r.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=e=>{let n=e?.merchantId??t.metadata.merchantId??``,r=e?.domain??``,a=e?.allowedDomains??[],o=e?.sdkConfig,s=o?.attribution||t.attribution?{...t.attribution,...o?.attribution}:void 0;i.setConfig(o?{isResolved:!0,merchantId:n,domain:r,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:n,domain:r,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,m=t=>{let r=f?void 0:l;f=!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();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}}})};i.isResolved&&(m(i.getConfig()),o.resolve()),a&&(u(await a),m(i.getConfig()),o.resolve());async function h(){let e=t.customizations?.css;e&&n.sendLifecycle({clientLifecycle:`modal-css`,data:{cssLink:e}})}async function g(){let e=t.customizations?.i18n;e&&n.sendLifecycle({clientLifecycle:`modal-i18n`,data:{i18n:e}})}async function _(){if(typeof window>`u`)return;let e=window.localStorage.getItem(d);e&&n.sendLifecycle({clientLifecycle:`restore-backup`,data:{backup:e}})}(await Promise.allSettled([h(),g(),_()])).some(e=>e.status===`rejected`)&&s?.track(`sdk_iframe_handshake_failed`,{reason:`asset_push`})}function F(){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 I=F();function L(){return typeof navigator>`u`?!1:I?!0:/Android|webOS|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)}function R(){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 z=R();function B(e){I&&e.startsWith(`https://`)?window.location.href=`x-safari-https://${e.slice(8)}`:I&&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 V(e){return l(t(e))}const H={eur:`fr-FR`,usd:`en-US`,gbp:`en-GB`};function U(e){return e&&e in H?e:`eur`}function W(e){return e?H[e]??H.eur:H.eur}function G(e,t){let n=W(t),r=U(t);return e.toLocaleString(n,{style:`currency`,currency:r,minimumFractionDigits:0,maximumFractionDigits:2})}function K(e){return e?`${e}Amount`:`eurAmount`}async function q({config:e}){let t=J(e),n=await b({config:t});if(!n){console.error(`Failed to create iframe`);return}let r=M({config:t,iframe:n});if(await r.waitForSetup,!await r.waitForConnection){console.error(`Failed to connect to client`);return}return r}function J(e){let t=U(e.metadata?.currency);return{...e,metadata:{...e.metadata,currency:t}}}function Y({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}export{U as a,z as c,M as d,y as f,f as h,G as i,L as l,_ as m,q as n,V as o,S as p,K as r,I as s,Y as t,B as u};
|
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"url": "https://twitter.com/QNivelais"
|
|
12
12
|
}
|
|
13
13
|
],
|
|
14
|
-
"version": "1.0.
|
|
14
|
+
"version": "1.1.0-beta.53162c2d",
|
|
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,8 +91,8 @@
|
|
|
91
91
|
"viem": "^2.x"
|
|
92
92
|
},
|
|
93
93
|
"dependencies": {
|
|
94
|
-
"@frak-labs/frame-connector": "0.2.0",
|
|
95
|
-
"@openpanel/web": "^1.
|
|
94
|
+
"@frak-labs/frame-connector": "0.2.0-beta.53162c2d",
|
|
95
|
+
"@openpanel/web": "^1.4.1"
|
|
96
96
|
},
|
|
97
97
|
"devDependencies": {
|
|
98
98
|
"@arethetypeswrong/cli": "^0.18.2",
|
|
@@ -103,7 +103,7 @@
|
|
|
103
103
|
"@vitest/coverage-v8": "^4.1.4",
|
|
104
104
|
"@vitest/ui": "^4.1.4",
|
|
105
105
|
"jsdom": "^29.0.0",
|
|
106
|
-
"tsdown": "^0.
|
|
106
|
+
"tsdown": "^0.22.0",
|
|
107
107
|
"typescript": "^6.0.2",
|
|
108
108
|
"viem": "^2.47.16",
|
|
109
109
|
"vitest": "^4.1.4"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { getBackendUrl } from "../
|
|
2
|
-
import { getClientId } from "../
|
|
3
|
-
import { sdkConfigStore } from "../
|
|
1
|
+
import { getBackendUrl } from "../config/backendUrl";
|
|
2
|
+
import { getClientId } from "../config/clientId";
|
|
3
|
+
import { sdkConfigStore } from "../config/sdkConfigStore";
|
|
4
4
|
|
|
5
5
|
const ENSURE_STORAGE_PREFIX = "frak-identity-ensured-";
|
|
6
6
|
|
package/src/actions/openSso.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
+
import { getClientId } from "../config/clientId";
|
|
2
|
+
import { sdkConfigStore } from "../config/sdkConfigStore";
|
|
1
3
|
import type {
|
|
2
4
|
FrakClient,
|
|
3
5
|
OpenSsoParamsType,
|
|
4
6
|
OpenSsoReturnType,
|
|
5
7
|
} from "../types";
|
|
6
|
-
import {
|
|
7
|
-
import { computeLegacyProductId } from "../utils/computeLegacyProductId";
|
|
8
|
-
import { generateSsoUrl } from "../utils/sso";
|
|
8
|
+
import { generateSsoUrl } from "../utils/sso/sso";
|
|
9
9
|
|
|
10
10
|
// SSO popup configuration
|
|
11
11
|
export const ssoPopupFeatures =
|
|
@@ -67,13 +67,20 @@ export const ssoPopupName = "frak-sso";
|
|
|
67
67
|
*/
|
|
68
68
|
export async function openSso(
|
|
69
69
|
client: FrakClient,
|
|
70
|
-
|
|
70
|
+
inputArgs: OpenSsoParamsType
|
|
71
71
|
): Promise<OpenSsoReturnType> {
|
|
72
72
|
const { metadata, customizations, walletUrl } = client.config;
|
|
73
73
|
|
|
74
|
+
// Apply default: when no redirectUrl is provided we want the SSO popup
|
|
75
|
+
// to close itself after completion. Without this default the popup
|
|
76
|
+
// sticks on the success screen and the "Redirect now" button is a no-op.
|
|
77
|
+
const args: OpenSsoParamsType = {
|
|
78
|
+
...inputArgs,
|
|
79
|
+
directExit: inputArgs.directExit ?? !inputArgs.redirectUrl,
|
|
80
|
+
};
|
|
81
|
+
|
|
74
82
|
// Check if redirect mode (default to true if redirectUrl present)
|
|
75
83
|
const isRedirectMode = args.openInSameWindow ?? !!args.redirectUrl;
|
|
76
|
-
|
|
77
84
|
if (isRedirectMode) {
|
|
78
85
|
// Redirect flow: Wallet generates URL and triggers redirect via lifecycle event
|
|
79
86
|
// This must happen on wallet side because only the iframe can trigger the redirect
|
|
@@ -92,7 +99,7 @@ export async function openSso(
|
|
|
92
99
|
generateSsoUrl(
|
|
93
100
|
walletUrl ?? "https://wallet.frak.id",
|
|
94
101
|
args,
|
|
95
|
-
|
|
102
|
+
(await sdkConfigStore.resolveMerchantId()) ?? "",
|
|
96
103
|
metadata.name,
|
|
97
104
|
getClientId(),
|
|
98
105
|
customizations?.css
|
|
@@ -19,15 +19,20 @@ vi.mock("../sendInteraction", () => ({
|
|
|
19
19
|
sendInteraction: vi.fn().mockResolvedValue(undefined),
|
|
20
20
|
}));
|
|
21
21
|
|
|
22
|
-
vi.mock("../../
|
|
22
|
+
vi.mock("../../context", () => ({
|
|
23
23
|
FrakContextManager: {
|
|
24
24
|
replaceUrl: vi.fn(),
|
|
25
25
|
},
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
}));
|
|
27
|
+
|
|
28
|
+
vi.mock("../../config/clientId", () => ({
|
|
28
29
|
getClientId: vi.fn().mockReturnValue("test-client-id"),
|
|
29
30
|
}));
|
|
30
31
|
|
|
32
|
+
vi.mock("../../utils", () => ({
|
|
33
|
+
trackEvent: vi.fn(),
|
|
34
|
+
}));
|
|
35
|
+
|
|
31
36
|
describe("processReferral", () => {
|
|
32
37
|
let mockClient: FrakClient;
|
|
33
38
|
let mockAddress: Address;
|
|
@@ -116,8 +121,10 @@ describe("processReferral", () => {
|
|
|
116
121
|
});
|
|
117
122
|
|
|
118
123
|
it("should return 'self-referral' when v2 context has same clientId as current user", async () => {
|
|
119
|
-
const
|
|
120
|
-
vi.mocked(
|
|
124
|
+
const clientIdMod = await import("../../config/clientId");
|
|
125
|
+
vi.mocked(clientIdMod.getClientId).mockReturnValue(
|
|
126
|
+
"referrer-client-id"
|
|
127
|
+
);
|
|
121
128
|
|
|
122
129
|
const v2SelfReferralContext: FrakContextV2 = {
|
|
123
130
|
v: 2,
|
|
@@ -132,7 +139,9 @@ describe("processReferral", () => {
|
|
|
132
139
|
});
|
|
133
140
|
|
|
134
141
|
expect(result).toBe("self-referral");
|
|
135
|
-
vi.mocked(
|
|
142
|
+
vi.mocked(clientIdMod.getClientId).mockReturnValue(
|
|
143
|
+
"test-client-id"
|
|
144
|
+
);
|
|
136
145
|
});
|
|
137
146
|
|
|
138
147
|
it("should successfully process v2 referral with wallet only (no clientId)", async () => {
|
|
@@ -180,9 +189,11 @@ describe("processReferral", () => {
|
|
|
180
189
|
});
|
|
181
190
|
|
|
182
191
|
it("should prefer wallet over clientId for self-referral when both are present", async () => {
|
|
183
|
-
const
|
|
192
|
+
const clientIdMod = await import("../../config/clientId");
|
|
184
193
|
// clientId does NOT match current user, but wallet does → still self-referral
|
|
185
|
-
vi.mocked(
|
|
194
|
+
vi.mocked(clientIdMod.getClientId).mockReturnValue(
|
|
195
|
+
"some-other-client"
|
|
196
|
+
);
|
|
186
197
|
|
|
187
198
|
const v2Hybrid: FrakContextV2 = {
|
|
188
199
|
v: 2,
|
|
@@ -198,7 +209,9 @@ describe("processReferral", () => {
|
|
|
198
209
|
});
|
|
199
210
|
|
|
200
211
|
expect(result).toBe("self-referral");
|
|
201
|
-
vi.mocked(
|
|
212
|
+
vi.mocked(clientIdMod.getClientId).mockReturnValue(
|
|
213
|
+
"test-client-id"
|
|
214
|
+
);
|
|
202
215
|
});
|
|
203
216
|
});
|
|
204
217
|
|
|
@@ -240,7 +253,8 @@ describe("processReferral", () => {
|
|
|
240
253
|
});
|
|
241
254
|
|
|
242
255
|
it("should update URL context when alwaysAppendUrl is true", async () => {
|
|
243
|
-
const
|
|
256
|
+
const clientIdMod = await import("../../config/clientId");
|
|
257
|
+
const contextMod = await import("../../context");
|
|
244
258
|
|
|
245
259
|
const v2Context: FrakContextV2 = {
|
|
246
260
|
v: 2,
|
|
@@ -257,9 +271,9 @@ describe("processReferral", () => {
|
|
|
257
271
|
},
|
|
258
272
|
});
|
|
259
273
|
|
|
260
|
-
expect(
|
|
274
|
+
expect(clientIdMod.getClientId()).toBe("test-client-id");
|
|
261
275
|
|
|
262
|
-
expect(
|
|
276
|
+
expect(contextMod.FrakContextManager.replaceUrl).toHaveBeenCalledWith({
|
|
263
277
|
url: window.location.href,
|
|
264
278
|
context: expect.objectContaining({
|
|
265
279
|
v: 2,
|
|
@@ -271,7 +285,7 @@ describe("processReferral", () => {
|
|
|
271
285
|
});
|
|
272
286
|
|
|
273
287
|
it("should remove URL context when alwaysAppendUrl is false", async () => {
|
|
274
|
-
const
|
|
288
|
+
const contextMod = await import("../../context");
|
|
275
289
|
|
|
276
290
|
const v2Context: FrakContextV2 = {
|
|
277
291
|
v: 2,
|
|
@@ -288,15 +302,16 @@ describe("processReferral", () => {
|
|
|
288
302
|
},
|
|
289
303
|
});
|
|
290
304
|
|
|
291
|
-
expect(
|
|
305
|
+
expect(contextMod.FrakContextManager.replaceUrl).toHaveBeenCalledWith({
|
|
292
306
|
url: window.location.href,
|
|
293
307
|
context: null,
|
|
294
308
|
});
|
|
295
309
|
});
|
|
296
310
|
|
|
297
311
|
it("should emit wallet in replacement context when alwaysAppendUrl is true and user is connected", async () => {
|
|
298
|
-
const
|
|
299
|
-
|
|
312
|
+
const clientIdMod = await import("../../config/clientId");
|
|
313
|
+
const contextMod = await import("../../context");
|
|
314
|
+
vi.mocked(clientIdMod.getClientId).mockReturnValue(null as never);
|
|
300
315
|
|
|
301
316
|
const v2Context: FrakContextV2 = {
|
|
302
317
|
v: 2,
|
|
@@ -312,7 +327,7 @@ describe("processReferral", () => {
|
|
|
312
327
|
});
|
|
313
328
|
|
|
314
329
|
// clientId is null, but wallet is available — should still emit {w, m}
|
|
315
|
-
expect(
|
|
330
|
+
expect(contextMod.FrakContextManager.replaceUrl).toHaveBeenCalledWith({
|
|
316
331
|
url: window.location.href,
|
|
317
332
|
context: expect.objectContaining({
|
|
318
333
|
v: 2,
|
|
@@ -321,12 +336,13 @@ describe("processReferral", () => {
|
|
|
321
336
|
}),
|
|
322
337
|
});
|
|
323
338
|
|
|
324
|
-
vi.mocked(
|
|
339
|
+
vi.mocked(clientIdMod.getClientId).mockReturnValue("test-client-id");
|
|
325
340
|
});
|
|
326
341
|
|
|
327
342
|
it("should return null replacement context when both clientId and wallet are missing", async () => {
|
|
328
|
-
const
|
|
329
|
-
|
|
343
|
+
const clientIdMod = await import("../../config/clientId");
|
|
344
|
+
const contextMod = await import("../../context");
|
|
345
|
+
vi.mocked(clientIdMod.getClientId).mockReturnValue(null as never);
|
|
330
346
|
|
|
331
347
|
const v2Context: FrakContextV2 = {
|
|
332
348
|
v: 2,
|
|
@@ -341,11 +357,11 @@ describe("processReferral", () => {
|
|
|
341
357
|
options: { alwaysAppendUrl: true },
|
|
342
358
|
});
|
|
343
359
|
|
|
344
|
-
expect(
|
|
360
|
+
expect(contextMod.FrakContextManager.replaceUrl).toHaveBeenCalledWith({
|
|
345
361
|
url: window.location.href,
|
|
346
362
|
context: null,
|
|
347
363
|
});
|
|
348
364
|
|
|
349
|
-
vi.mocked(
|
|
365
|
+
vi.mocked(clientIdMod.getClientId).mockReturnValue("test-client-id");
|
|
350
366
|
});
|
|
351
367
|
});
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getClientId } from "../../config/clientId";
|
|
2
|
+
import { FrakContextManager } from "../../context";
|
|
3
|
+
import { areAddressesEqual } from "../../context/address";
|
|
2
4
|
import type {
|
|
3
5
|
FrakClient,
|
|
4
6
|
FrakContext,
|
|
@@ -6,7 +8,7 @@ import type {
|
|
|
6
8
|
WalletStatusReturnType,
|
|
7
9
|
} from "../../types";
|
|
8
10
|
import { isV1Context, isV2Context } from "../../types";
|
|
9
|
-
import {
|
|
11
|
+
import { trackEvent } from "../../utils";
|
|
10
12
|
import { sendInteraction } from "../sendInteraction";
|
|
11
13
|
|
|
12
14
|
/**
|
|
@@ -113,7 +115,7 @@ function isSelfReferral(
|
|
|
113
115
|
if (isV2Context(frakContext)) {
|
|
114
116
|
// Wallet match takes precedence — it's the strongest signal we have.
|
|
115
117
|
if (frakContext.w && walletStatus?.wallet) {
|
|
116
|
-
return
|
|
118
|
+
return areAddressesEqual(frakContext.w, walletStatus.wallet);
|
|
117
119
|
}
|
|
118
120
|
if (frakContext.c) {
|
|
119
121
|
return getClientId() === frakContext.c;
|
|
@@ -121,7 +123,7 @@ function isSelfReferral(
|
|
|
121
123
|
return false;
|
|
122
124
|
}
|
|
123
125
|
if (isV1Context(frakContext) && walletStatus?.wallet) {
|
|
124
|
-
return
|
|
126
|
+
return areAddressesEqual(frakContext.r, walletStatus.wallet);
|
|
125
127
|
}
|
|
126
128
|
return false;
|
|
127
129
|
}
|