@frak-labs/core-sdk 1.0.2 → 1.1.0-beta.d970d1ee
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-Arjch8ws.cjs +1 -0
- package/dist/actions-CeWbcY36.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-DwNmSqqt.cjs +1 -0
- package/dist/frakContext-Dy77kBoO.js +1 -0
- package/dist/{index-quaxtKRh.d.ts → index-BoQDFjOU.d.ts} +1 -1
- package/dist/{index-DzVPSUQq.d.ts → index-C5EmUmCE.d.cts} +248 -352
- package/dist/{index-BsBbSMxk.d.cts → index-XSvobRVM.d.cts} +1 -1
- package/dist/{index-s1vE3jLz.d.cts → index-YBqvI7U4.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-BqvIHd8A.d.cts} +12 -17
- package/dist/{openSso-rQhLhPbq.d.cts → openSso-mTA1gB4r.d.ts} +12 -17
- package/dist/src-CGTfUgRU.js +1 -0
- package/dist/src-myx7UFlu.cjs +1 -0
- package/package.json +4 -4
- package/src/actions/ensureIdentity.ts +3 -3
- package/src/actions/openSso.ts +4 -4
- 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/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-DwNmSqqt.cjs`),t=require(`./src-myx7UFlu.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-BqvIHd8A.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-C5EmUmCE.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-mTA1gB4r.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-YBqvI7U4.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-Dy77kBoO.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-CGTfUgRU.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 { 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
|
|
@@ -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
|
|
@@ -1272,9 +1282,6 @@ type FrakLifecycleEvent = IFrameLifecycleEvent | ClientLifecycleEvent;
|
|
|
1272
1282
|
*/
|
|
1273
1283
|
type FrakClient = {
|
|
1274
1284
|
config: FrakWalletSdkConfig;
|
|
1275
|
-
debugInfo: {
|
|
1276
|
-
formatDebugInfo: (error: Error | unknown | string) => string;
|
|
1277
|
-
};
|
|
1278
1285
|
openPanel?: OpenPanel;
|
|
1279
1286
|
} & IFrameTransport;
|
|
1280
1287
|
//#endregion
|
|
@@ -1318,18 +1325,6 @@ type FrakContextV2 = {
|
|
|
1318
1325
|
* @ignore
|
|
1319
1326
|
*/
|
|
1320
1327
|
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
1328
|
//#endregion
|
|
1334
1329
|
//#region src/actions/openSso.d.ts
|
|
1335
1330
|
declare const ssoPopupFeatures = "menubar=no,status=no,scrollbars=no,fullscreen=no,width=500, height=800";
|
|
@@ -1389,4 +1384,4 @@ declare const ssoPopupName = "frak-sso";
|
|
|
1389
1384
|
*/
|
|
1390
1385
|
declare function openSso(client: FrakClient, args: OpenSsoParamsType): Promise<OpenSsoReturnType>;
|
|
1391
1386
|
//#endregion
|
|
1392
|
-
export {
|
|
1387
|
+
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 };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { LifecycleMessage, RpcClient } from "@frak-labs/frame-connector";
|
|
1
2
|
import { OpenPanel } from "@openpanel/web";
|
|
2
3
|
import { Address, Hex } from "viem";
|
|
3
|
-
import { LifecycleMessage, RpcClient } from "@frak-labs/frame-connector";
|
|
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
|
|
@@ -1272,9 +1282,6 @@ type FrakLifecycleEvent = IFrameLifecycleEvent | ClientLifecycleEvent;
|
|
|
1272
1282
|
*/
|
|
1273
1283
|
type FrakClient = {
|
|
1274
1284
|
config: FrakWalletSdkConfig;
|
|
1275
|
-
debugInfo: {
|
|
1276
|
-
formatDebugInfo: (error: Error | unknown | string) => string;
|
|
1277
|
-
};
|
|
1278
1285
|
openPanel?: OpenPanel;
|
|
1279
1286
|
} & IFrameTransport;
|
|
1280
1287
|
//#endregion
|
|
@@ -1318,18 +1325,6 @@ type FrakContextV2 = {
|
|
|
1318
1325
|
* @ignore
|
|
1319
1326
|
*/
|
|
1320
1327
|
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
1328
|
//#endregion
|
|
1334
1329
|
//#region src/actions/openSso.d.ts
|
|
1335
1330
|
declare const ssoPopupFeatures = "menubar=no,status=no,scrollbars=no,fullscreen=no,width=500, height=800";
|
|
@@ -1389,4 +1384,4 @@ declare const ssoPopupName = "frak-sso";
|
|
|
1389
1384
|
*/
|
|
1390
1385
|
declare function openSso(client: FrakClient, args: OpenSsoParamsType): Promise<OpenSsoReturnType>;
|
|
1391
1386
|
//#endregion
|
|
1392
|
-
export {
|
|
1387
|
+
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
|
+
import{_ as e,d as t,h as n,m as r,p as i}from"./frakContext-Dy77kBoO.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};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=require(`./frakContext-DwNmSqqt.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}});
|
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.d970d1ee",
|
|
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.d970d1ee",
|
|
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 =
|
|
@@ -92,7 +92,7 @@ export async function openSso(
|
|
|
92
92
|
generateSsoUrl(
|
|
93
93
|
walletUrl ?? "https://wallet.frak.id",
|
|
94
94
|
args,
|
|
95
|
-
|
|
95
|
+
(await sdkConfigStore.resolveMerchantId()) ?? "",
|
|
96
96
|
metadata.name,
|
|
97
97
|
getClientId(),
|
|
98
98
|
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
|
}
|
|
@@ -2,7 +2,7 @@ import type { Hex } from "viem";
|
|
|
2
2
|
import { beforeEach, describe, expect, test, vi } from "vitest";
|
|
3
3
|
import { referralInteraction } from "./referralInteraction";
|
|
4
4
|
|
|
5
|
-
vi.mock("../../
|
|
5
|
+
vi.mock("../../context", () => ({
|
|
6
6
|
FrakContextManager: {
|
|
7
7
|
parse: vi.fn(),
|
|
8
8
|
},
|
|
@@ -30,7 +30,7 @@ describe("referralInteraction", () => {
|
|
|
30
30
|
});
|
|
31
31
|
|
|
32
32
|
test("should parse context from window location", async () => {
|
|
33
|
-
const { FrakContextManager } = await import("../../
|
|
33
|
+
const { FrakContextManager } = await import("../../context");
|
|
34
34
|
const { watchWalletStatus } = await import("../index");
|
|
35
35
|
const { processReferral } = await import("./processReferral");
|
|
36
36
|
|
|
@@ -46,7 +46,7 @@ describe("referralInteraction", () => {
|
|
|
46
46
|
});
|
|
47
47
|
|
|
48
48
|
test("should get current wallet status", async () => {
|
|
49
|
-
const { FrakContextManager } = await import("../../
|
|
49
|
+
const { FrakContextManager } = await import("../../context");
|
|
50
50
|
const { watchWalletStatus } = await import("../index");
|
|
51
51
|
const { processReferral } = await import("./processReferral");
|
|
52
52
|
|
|
@@ -63,7 +63,7 @@ describe("referralInteraction", () => {
|
|
|
63
63
|
});
|
|
64
64
|
|
|
65
65
|
test("should call processReferral with all parameters", async () => {
|
|
66
|
-
const { FrakContextManager } = await import("../../
|
|
66
|
+
const { FrakContextManager } = await import("../../context");
|
|
67
67
|
const { watchWalletStatus } = await import("../index");
|
|
68
68
|
const { processReferral } = await import("./processReferral");
|
|
69
69
|
|
|
@@ -87,7 +87,7 @@ describe("referralInteraction", () => {
|
|
|
87
87
|
});
|
|
88
88
|
|
|
89
89
|
test("should return result from processReferral", async () => {
|
|
90
|
-
const { FrakContextManager } = await import("../../
|
|
90
|
+
const { FrakContextManager } = await import("../../context");
|
|
91
91
|
const { watchWalletStatus } = await import("../index");
|
|
92
92
|
const { processReferral } = await import("./processReferral");
|
|
93
93
|
|
|
@@ -101,7 +101,7 @@ describe("referralInteraction", () => {
|
|
|
101
101
|
});
|
|
102
102
|
|
|
103
103
|
test("should return undefined on error", async () => {
|
|
104
|
-
const { FrakContextManager } = await import("../../
|
|
104
|
+
const { FrakContextManager } = await import("../../context");
|
|
105
105
|
const { watchWalletStatus } = await import("../index");
|
|
106
106
|
const { processReferral } = await import("./processReferral");
|
|
107
107
|
|
|
@@ -124,7 +124,7 @@ describe("referralInteraction", () => {
|
|
|
124
124
|
});
|
|
125
125
|
|
|
126
126
|
test("should work with empty options", async () => {
|
|
127
|
-
const { FrakContextManager } = await import("../../
|
|
127
|
+
const { FrakContextManager } = await import("../../context");
|
|
128
128
|
const { watchWalletStatus } = await import("../index");
|
|
129
129
|
const { processReferral } = await import("./processReferral");
|
|
130
130
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { getClientId } from "../config/clientId";
|
|
1
2
|
import type { FrakClient } from "../types";
|
|
2
3
|
import type { SendInteractionParamsType } from "../types/rpc/interaction";
|
|
3
|
-
import { getClientId } from "../utils/clientId";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Send an interaction to the backend via the listener RPC.
|