@frak-labs/core-sdk 0.1.0 → 0.1.1-beta.1e44255d

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/README.md +58 -0
  2. package/cdn/bundle.js +3 -8
  3. package/dist/actions.cjs +1 -1
  4. package/dist/actions.d.cts +3 -1400
  5. package/dist/actions.d.ts +3 -1400
  6. package/dist/actions.js +1 -1
  7. package/dist/bundle.cjs +1 -13
  8. package/dist/bundle.d.cts +4 -1927
  9. package/dist/bundle.d.ts +4 -1927
  10. package/dist/bundle.js +1 -13
  11. package/dist/computeLegacyProductId-BkyJ4rEY.d.ts +538 -0
  12. package/dist/computeLegacyProductId-Raks6FXg.d.cts +538 -0
  13. package/dist/index.cjs +1 -13
  14. package/dist/index.d.cts +3 -1269
  15. package/dist/index.d.ts +3 -1269
  16. package/dist/index.js +1 -13
  17. package/dist/openSso-BCJGchIb.d.cts +1022 -0
  18. package/dist/openSso-DG-_9CED.d.ts +1022 -0
  19. package/dist/setupClient-Cfwpu08d.js +13 -0
  20. package/dist/setupClient-Dh8ljuhV.cjs +13 -0
  21. package/dist/siweAuthenticate-BH7Dn7nZ.d.cts +536 -0
  22. package/dist/siweAuthenticate-BJHbtty4.js +1 -0
  23. package/dist/siweAuthenticate-Btem4QHs.d.ts +536 -0
  24. package/dist/siweAuthenticate-Cwj3HP0m.cjs +1 -0
  25. package/dist/trackEvent-M2RLTQ2p.js +1 -0
  26. package/dist/trackEvent-T_R9ER2S.cjs +1 -0
  27. package/package.json +25 -31
  28. package/src/actions/displayEmbeddedWallet.test.ts +194 -0
  29. package/src/actions/displayEmbeddedWallet.ts +21 -0
  30. package/src/actions/displayModal.test.ts +388 -0
  31. package/src/actions/displayModal.ts +120 -0
  32. package/src/actions/ensureIdentity.ts +68 -0
  33. package/src/actions/getMerchantInformation.test.ts +116 -0
  34. package/src/actions/getMerchantInformation.ts +16 -0
  35. package/src/actions/index.ts +30 -0
  36. package/src/actions/openSso.ts +118 -0
  37. package/src/actions/prepareSso.test.ts +223 -0
  38. package/src/actions/prepareSso.ts +48 -0
  39. package/src/actions/referral/processReferral.test.ts +248 -0
  40. package/src/actions/referral/processReferral.ts +232 -0
  41. package/src/actions/referral/referralInteraction.test.ts +147 -0
  42. package/src/actions/referral/referralInteraction.ts +52 -0
  43. package/src/actions/sendInteraction.ts +56 -0
  44. package/src/actions/trackPurchaseStatus.test.ts +500 -0
  45. package/src/actions/trackPurchaseStatus.ts +90 -0
  46. package/src/actions/watchWalletStatus.test.ts +372 -0
  47. package/src/actions/watchWalletStatus.ts +93 -0
  48. package/src/actions/wrapper/modalBuilder.test.ts +239 -0
  49. package/src/actions/wrapper/modalBuilder.ts +203 -0
  50. package/src/actions/wrapper/sendTransaction.test.ts +164 -0
  51. package/src/actions/wrapper/sendTransaction.ts +62 -0
  52. package/src/actions/wrapper/siweAuthenticate.test.ts +290 -0
  53. package/src/actions/wrapper/siweAuthenticate.ts +94 -0
  54. package/src/bundle.ts +2 -0
  55. package/src/clients/DebugInfo.test.ts +418 -0
  56. package/src/clients/DebugInfo.ts +182 -0
  57. package/src/clients/createIFrameFrakClient.ts +292 -0
  58. package/src/clients/index.ts +3 -0
  59. package/src/clients/setupClient.test.ts +343 -0
  60. package/src/clients/setupClient.ts +73 -0
  61. package/src/clients/transports/iframeLifecycleManager.test.ts +558 -0
  62. package/src/clients/transports/iframeLifecycleManager.ts +229 -0
  63. package/src/constants/interactionTypes.ts +15 -0
  64. package/src/constants/locales.ts +14 -0
  65. package/src/index.ts +109 -0
  66. package/src/types/client.ts +14 -0
  67. package/src/types/compression.ts +22 -0
  68. package/src/types/config.ts +117 -0
  69. package/src/types/context.ts +13 -0
  70. package/src/types/index.ts +74 -0
  71. package/src/types/lifecycle/client.ts +69 -0
  72. package/src/types/lifecycle/iframe.ts +41 -0
  73. package/src/types/lifecycle/index.ts +2 -0
  74. package/src/types/rpc/displayModal.ts +82 -0
  75. package/src/types/rpc/embedded/index.ts +68 -0
  76. package/src/types/rpc/embedded/loggedIn.ts +55 -0
  77. package/src/types/rpc/embedded/loggedOut.ts +28 -0
  78. package/src/types/rpc/interaction.ts +30 -0
  79. package/src/types/rpc/merchantInformation.ts +77 -0
  80. package/src/types/rpc/modal/final.ts +46 -0
  81. package/src/types/rpc/modal/generic.ts +46 -0
  82. package/src/types/rpc/modal/index.ts +16 -0
  83. package/src/types/rpc/modal/login.ts +36 -0
  84. package/src/types/rpc/modal/siweAuthenticate.ts +37 -0
  85. package/src/types/rpc/modal/transaction.ts +33 -0
  86. package/src/types/rpc/sso.ts +80 -0
  87. package/src/types/rpc/walletStatus.ts +29 -0
  88. package/src/types/rpc.ts +150 -0
  89. package/src/types/tracking.ts +60 -0
  90. package/src/types/transport.ts +34 -0
  91. package/src/utils/FrakContext.test.ts +407 -0
  92. package/src/utils/FrakContext.ts +158 -0
  93. package/src/utils/backendUrl.test.ts +83 -0
  94. package/src/utils/backendUrl.ts +62 -0
  95. package/src/utils/clientId.test.ts +41 -0
  96. package/src/utils/clientId.ts +43 -0
  97. package/src/utils/compression/b64.test.ts +181 -0
  98. package/src/utils/compression/b64.ts +29 -0
  99. package/src/utils/compression/compress.test.ts +123 -0
  100. package/src/utils/compression/compress.ts +11 -0
  101. package/src/utils/compression/decompress.test.ts +149 -0
  102. package/src/utils/compression/decompress.ts +11 -0
  103. package/src/utils/compression/index.ts +3 -0
  104. package/src/utils/computeLegacyProductId.ts +11 -0
  105. package/src/utils/constants.test.ts +23 -0
  106. package/src/utils/constants.ts +9 -0
  107. package/src/utils/deepLinkWithFallback.test.ts +243 -0
  108. package/src/utils/deepLinkWithFallback.ts +103 -0
  109. package/src/utils/formatAmount.test.ts +113 -0
  110. package/src/utils/formatAmount.ts +24 -0
  111. package/src/utils/getCurrencyAmountKey.test.ts +44 -0
  112. package/src/utils/getCurrencyAmountKey.ts +15 -0
  113. package/src/utils/getSupportedCurrency.test.ts +51 -0
  114. package/src/utils/getSupportedCurrency.ts +14 -0
  115. package/src/utils/getSupportedLocale.test.ts +64 -0
  116. package/src/utils/getSupportedLocale.ts +16 -0
  117. package/src/utils/iframeHelper.test.ts +463 -0
  118. package/src/utils/iframeHelper.ts +150 -0
  119. package/src/utils/index.ts +36 -0
  120. package/src/utils/merchantId.test.ts +653 -0
  121. package/src/utils/merchantId.ts +143 -0
  122. package/src/utils/sso.ts +126 -0
  123. package/src/utils/ssoUrlListener.test.ts +252 -0
  124. package/src/utils/ssoUrlListener.ts +60 -0
  125. package/src/utils/trackEvent.test.ts +180 -0
  126. package/src/utils/trackEvent.ts +41 -0
  127. package/cdn/bundle.js.LICENSE.txt +0 -10
  128. package/dist/interactions.cjs +0 -1
  129. package/dist/interactions.d.cts +0 -182
  130. package/dist/interactions.d.ts +0 -182
  131. package/dist/interactions.js +0 -1
@@ -0,0 +1,229 @@
1
+ import { Deferred } from "@frak-labs/frame-connector";
2
+ import type { FrakLifecycleEvent } from "../../types";
3
+ import { getClientId } from "../../utils/clientId";
4
+ import { BACKUP_KEY } from "../../utils/constants";
5
+ import {
6
+ isFrakDeepLink,
7
+ triggerDeepLinkWithFallback,
8
+ } from "../../utils/deepLinkWithFallback";
9
+ import { changeIframeVisibility } from "../../utils/iframeHelper";
10
+
11
+ /**
12
+ * Detect iOS in-app browsers (Instagram, Facebook) where server-side
13
+ * 302 redirects to custom URL schemes (x-safari-https://) are silently
14
+ * swallowed by WKWebView. Direct window.location.href assignment works.
15
+ */
16
+ const isIOSInAppBrowser = (() => {
17
+ if (typeof navigator === "undefined") return false;
18
+ const ua = navigator.userAgent;
19
+ // Standard iOS or iPadOS 13+ (reports as Macintosh with touch)
20
+ const isIOS =
21
+ /iPhone|iPad|iPod/i.test(ua) ||
22
+ (/Macintosh/i.test(ua) && navigator.maxTouchPoints > 1);
23
+ if (!isIOS) return false;
24
+ const lower = ua.toLowerCase();
25
+ return (
26
+ lower.includes("instagram") ||
27
+ lower.includes("fban") ||
28
+ lower.includes("fbav") ||
29
+ lower.includes("facebook")
30
+ );
31
+ })();
32
+
33
+ /** @ignore */
34
+ export type IframeLifecycleManager = {
35
+ isConnected: Promise<boolean>;
36
+ handleEvent: (messageEvent: FrakLifecycleEvent) => Promise<void>;
37
+ };
38
+
39
+ /**
40
+ * Handle backup storage
41
+ */
42
+ function handleBackup(backup: string | undefined): void {
43
+ if (backup) {
44
+ localStorage.setItem(BACKUP_KEY, backup);
45
+ } else {
46
+ localStorage.removeItem(BACKUP_KEY);
47
+ }
48
+ }
49
+
50
+ /**
51
+ * Handle handshake with iframe — sends client metadata so the listener can resolve the correct merchant
52
+ * @param iframe - The iframe element to post the handshake response to
53
+ * @param token - The handshake token received from the iframe
54
+ * @param targetOrigin - The target origin for postMessage security
55
+ * @param configDomain - Optional override domain for merchant resolution in tunneled/proxied environments
56
+ */
57
+ function handleHandshake(
58
+ iframe: HTMLIFrameElement,
59
+ token: string,
60
+ targetOrigin: string,
61
+ configDomain?: string
62
+ ): void {
63
+ const url = new URL(window.location.href);
64
+ const pendingMergeToken = url.searchParams.get("fmt") ?? undefined;
65
+
66
+ iframe.contentWindow?.postMessage(
67
+ {
68
+ clientLifecycle: "handshake-response",
69
+ data: {
70
+ token,
71
+ currentUrl: window.location.href,
72
+ pendingMergeToken,
73
+ configDomain,
74
+ clientId: getClientId(),
75
+ },
76
+ },
77
+ targetOrigin
78
+ );
79
+
80
+ if (pendingMergeToken) {
81
+ url.searchParams.delete("fmt");
82
+ window.history.replaceState({}, "", url.toString());
83
+ }
84
+ }
85
+
86
+ /**
87
+ * Compute final redirect URL with parameter substitution
88
+ */
89
+ function computeRedirectUrl(
90
+ baseRedirectUrl: string,
91
+ mergeToken?: string
92
+ ): string {
93
+ try {
94
+ const redirectUrl = new URL(baseRedirectUrl);
95
+ if (!redirectUrl.searchParams.has("u")) {
96
+ return baseRedirectUrl;
97
+ }
98
+
99
+ redirectUrl.searchParams.delete("u");
100
+ redirectUrl.searchParams.append("u", window.location.href);
101
+
102
+ if (mergeToken) {
103
+ redirectUrl.searchParams.append("fmt", mergeToken);
104
+ }
105
+
106
+ return redirectUrl.toString();
107
+ } catch {
108
+ return baseRedirectUrl;
109
+ }
110
+ }
111
+
112
+ /**
113
+ * Redirect current page to Safari via x-safari-https:// scheme.
114
+ * Used on iOS in-app browsers where backend 302 → custom scheme fails.
115
+ */
116
+ function redirectToSafari(mergeToken?: string) {
117
+ const url = new URL(window.location.href);
118
+ if (mergeToken) {
119
+ url.searchParams.set("fmt", mergeToken);
120
+ }
121
+ const scheme =
122
+ url.protocol === "http:" ? "x-safari-http" : "x-safari-https";
123
+ window.location.href = `${scheme}://${url.host}${url.pathname}${url.search}${url.hash}`;
124
+ }
125
+
126
+ /**
127
+ * Check if this is a social/in-app-browser escape redirect (contains /common/social)
128
+ */
129
+ function isSocialRedirect(url: string): boolean {
130
+ return url.includes("/common/social");
131
+ }
132
+
133
+ /**
134
+ * Handle redirect with deep link fallback
135
+ */
136
+ function handleRedirect(
137
+ iframe: HTMLIFrameElement,
138
+ baseRedirectUrl: string,
139
+ targetOrigin: string,
140
+ mergeToken?: string
141
+ ): void {
142
+ if (isFrakDeepLink(baseRedirectUrl)) {
143
+ const finalUrl = computeRedirectUrl(baseRedirectUrl, mergeToken);
144
+ triggerDeepLinkWithFallback(finalUrl, {
145
+ onFallback: () => {
146
+ iframe.contentWindow?.postMessage(
147
+ {
148
+ clientLifecycle: "deep-link-failed",
149
+ data: { originalUrl: finalUrl },
150
+ },
151
+ targetOrigin
152
+ );
153
+ },
154
+ });
155
+ } else if (isIOSInAppBrowser && isSocialRedirect(baseRedirectUrl)) {
156
+ // iOS WKWebView silently swallows 302 redirects to custom URL
157
+ // schemes — bypass the server redirect entirely
158
+ redirectToSafari(mergeToken);
159
+ } else {
160
+ const finalUrl = computeRedirectUrl(baseRedirectUrl, mergeToken);
161
+ window.location.href = finalUrl;
162
+ }
163
+ }
164
+
165
+ /**
166
+ * Create a new iframe lifecycle handler
167
+ * @param args
168
+ * @param args.iframe - The iframe element used for wallet communication
169
+ * @param args.targetOrigin - The wallet URL origin for postMessage security
170
+ * @param args.configDomain - Optional domain override forwarded during handshake for tunneled/proxied environments
171
+ * @ignore
172
+ */
173
+ export function createIFrameLifecycleManager({
174
+ iframe,
175
+ targetOrigin,
176
+ configDomain,
177
+ }: {
178
+ iframe: HTMLIFrameElement;
179
+ targetOrigin: string;
180
+ configDomain?: string;
181
+ }): IframeLifecycleManager {
182
+ // Create the isConnected listener
183
+ const isConnectedDeferred = new Deferred<boolean>();
184
+
185
+ // Build the handler itself
186
+ const handler = async (messageEvent: FrakLifecycleEvent) => {
187
+ if (!("iframeLifecycle" in messageEvent)) return;
188
+
189
+ const { iframeLifecycle: event, data } = messageEvent;
190
+
191
+ switch (event) {
192
+ // Resolve the isConnected promise
193
+ case "connected":
194
+ isConnectedDeferred.resolve(true);
195
+ break;
196
+ // Perform a frak backup
197
+ case "do-backup":
198
+ handleBackup(data.backup);
199
+ break;
200
+ // Remove frak backup
201
+ case "remove-backup":
202
+ localStorage.removeItem(BACKUP_KEY);
203
+ break;
204
+ // Change iframe visibility
205
+ case "show":
206
+ case "hide":
207
+ changeIframeVisibility({ iframe, isVisible: event === "show" });
208
+ break;
209
+ // Handshake handling
210
+ case "handshake":
211
+ handleHandshake(iframe, data.token, targetOrigin, configDomain);
212
+ break;
213
+ // Redirect handling
214
+ case "redirect":
215
+ handleRedirect(
216
+ iframe,
217
+ data.baseRedirectUrl,
218
+ targetOrigin,
219
+ data.mergeToken
220
+ );
221
+ break;
222
+ }
223
+ };
224
+
225
+ return {
226
+ handleEvent: handler,
227
+ isConnected: isConnectedDeferred.promise,
228
+ };
229
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * The supported interaction type keys
3
+ *
4
+ * - `referral` - User arrived via a referral link
5
+ * - `create_referral_link` - User created/shared a referral link
6
+ * - `purchase` - User completed a purchase
7
+ * - `custom.${string}` - Custom interaction type defined per campaign
8
+ *
9
+ * @inline
10
+ */
11
+ export type InteractionTypeKey =
12
+ | "referral"
13
+ | "create_referral_link"
14
+ | "purchase"
15
+ | `custom.${string}`;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * The keys for each locales
3
+ * @inline
4
+ */
5
+ export type LocalesKey = keyof typeof locales;
6
+
7
+ /**
8
+ * Map the currency to the locale
9
+ */
10
+ export const locales = {
11
+ eur: "fr-FR",
12
+ usd: "en-US",
13
+ gbp: "en-GB",
14
+ } as const;
package/src/index.ts ADDED
@@ -0,0 +1,109 @@
1
+ // Clients
2
+
3
+ export { ssoPopupFeatures, ssoPopupName } from "./actions/openSso";
4
+ export {
5
+ createIFrameFrakClient,
6
+ DebugInfoGatherer,
7
+ setupClient,
8
+ } from "./clients";
9
+
10
+ export type { InteractionTypeKey } from "./constants/interactionTypes";
11
+ export { type LocalesKey, locales } from "./constants/locales";
12
+
13
+ // Types
14
+ export type {
15
+ ClientLifecycleEvent,
16
+ CompressedData,
17
+ Currency,
18
+ // RPC Embedded wallet
19
+ DisplayEmbeddedWalletParamsType,
20
+ DisplayEmbeddedWalletResultType,
21
+ DisplayModalParamsType,
22
+ EmbeddedViewActionReferred,
23
+ EmbeddedViewActionSharing,
24
+ EstimatedReward,
25
+ FinalActionType,
26
+ FinalModalStepType,
27
+ // Client
28
+ FrakClient,
29
+ // Utils
30
+ FrakContext,
31
+ FrakLifecycleEvent,
32
+ // Config
33
+ FrakWalletSdkConfig,
34
+ GetMerchantInformationReturnType,
35
+ HashProtectedData,
36
+ I18nConfig,
37
+ IFrameLifecycleEvent,
38
+ IFrameRpcSchema,
39
+ // Transport
40
+ IFrameTransport,
41
+ // Compression
42
+ KeyProvider,
43
+ Language,
44
+ LocalizedI18nConfig,
45
+ LoggedInEmbeddedView,
46
+ LoggedOutEmbeddedView,
47
+ LoginModalStepType,
48
+ ModalRpcMetadata,
49
+ ModalRpcStepsInput,
50
+ ModalRpcStepsResultType,
51
+ // RPC Modal types
52
+ ModalStepMetadata,
53
+ // RPC Modal generics
54
+ ModalStepTypes,
55
+ OpenSsoParamsType,
56
+ OpenSsoReturnType,
57
+ PrepareSsoParamsType,
58
+ PrepareSsoReturnType,
59
+ RewardTier,
60
+ // RPC Interaction
61
+ SendInteractionParamsType,
62
+ SendTransactionModalStepType,
63
+ SendTransactionReturnType,
64
+ SendTransactionTxType,
65
+ SiweAuthenticateModalStepType,
66
+ SiweAuthenticateReturnType,
67
+ SiweAuthenticationParams,
68
+ SsoMetadata,
69
+ TokenAmountType,
70
+ // Tracking
71
+ TrackArrivalParams,
72
+ TrackArrivalResult,
73
+ UtmParams,
74
+ // Rpc
75
+ WalletStatusReturnType,
76
+ } from "./types";
77
+ // Utils
78
+ export {
79
+ type AppSpecificSsoMetadata,
80
+ base64urlDecode,
81
+ base64urlEncode,
82
+ baseIframeProps,
83
+ type CompressedSsoData,
84
+ clearMerchantIdCache,
85
+ compressJsonToB64,
86
+ createIframe,
87
+ DEEP_LINK_SCHEME,
88
+ type DeepLinkFallbackOptions,
89
+ decompressJsonFromB64,
90
+ FrakContextManager,
91
+ type FrakEvent,
92
+ type FullSsoParams,
93
+ fetchMerchantId,
94
+ findIframeInOpener,
95
+ formatAmount,
96
+ generateSsoUrl,
97
+ getBackendUrl,
98
+ getClientId,
99
+ getCurrencyAmountKey,
100
+ getSupportedCurrency,
101
+ getSupportedLocale,
102
+ isChromiumAndroid,
103
+ isFrakDeepLink,
104
+ resolveMerchantId,
105
+ toAndroidIntentUrl,
106
+ trackEvent,
107
+ triggerDeepLinkWithFallback,
108
+ } from "./utils";
109
+ export { computeLegacyProductId } from "./utils/computeLegacyProductId";
@@ -0,0 +1,14 @@
1
+ import type { OpenPanel } from "@openpanel/web";
2
+ import type { FrakWalletSdkConfig } from "./config";
3
+ import type { IFrameTransport } from "./transport";
4
+
5
+ /**
6
+ * Representing a Frak client, used to interact with the Frak Wallet
7
+ */
8
+ export type FrakClient = {
9
+ config: FrakWalletSdkConfig;
10
+ debugInfo: {
11
+ formatDebugInfo: (error: Error | unknown | string) => string;
12
+ };
13
+ openPanel?: OpenPanel;
14
+ } & IFrameTransport;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * The received encoded data from a client
3
+ * -> The encoded should contain a HashProtectedData once decoded
4
+ * @ignore
5
+ */
6
+ export type CompressedData = Uint8Array;
7
+
8
+ /**
9
+ * The encoded data to send to a client / received by a client
10
+ * @ignore
11
+ */
12
+ export type HashProtectedData<DataType> = Readonly<
13
+ DataType & {
14
+ validationHash: string;
15
+ }
16
+ >;
17
+
18
+ /**
19
+ * Represent a key provider used for the hashed and secure compression
20
+ * @ignore
21
+ */
22
+ export type KeyProvider<DataType> = (value: DataType) => string[];
@@ -0,0 +1,117 @@
1
+ /**
2
+ * All the currencies available
3
+ * @category Config
4
+ */
5
+ export type Currency = "eur" | "usd" | "gbp";
6
+
7
+ /**
8
+ * All the languages available
9
+ * @category Config
10
+ */
11
+ export type Language = "fr" | "en";
12
+
13
+ /**
14
+ * Configuration for the Frak Wallet SDK
15
+ * @category Config
16
+ */
17
+ export type FrakWalletSdkConfig = {
18
+ /**
19
+ * The Frak wallet url
20
+ * @defaultValue "https://wallet.frak.id"
21
+ */
22
+ walletUrl?: string;
23
+ /**
24
+ * Some metadata about your implementation of the Frak SDK
25
+ */
26
+ metadata: {
27
+ /**
28
+ * Your application name (will be displayed in a few modals and in SSO)
29
+ */
30
+ name: string;
31
+ /**
32
+ * Your merchant ID from the Frak dashboard (UUID format)
33
+ * Used for referral tracking and analytics
34
+ * If not provided, will be auto-fetched from the backend using your domain
35
+ */
36
+ merchantId?: string;
37
+ /**
38
+ * Language to display in the modal
39
+ * If undefined, will default to the browser language
40
+ */
41
+ lang?: Language;
42
+ /**
43
+ * The currency to display in the modal
44
+ * @defaultValue `"eur"`
45
+ */
46
+ currency?: Currency;
47
+ /**
48
+ * The logo URL that will be displayed in a few components
49
+ */
50
+ logoUrl?: string;
51
+ /**
52
+ * The homepage link that could be displayed in a few components
53
+ */
54
+ homepageLink?: string;
55
+ };
56
+ /**
57
+ * Some customization for the modal
58
+ */
59
+ customizations?: {
60
+ /**
61
+ * Custom CSS styles to apply to the modals and components
62
+ */
63
+ css?: `${string}.css`;
64
+ /**
65
+ * Custom i18n configuration for the modal
66
+ */
67
+ i18n?: I18nConfig;
68
+ };
69
+ /**
70
+ * The domain name of your application
71
+ * @defaultValue window.location.host
72
+ */
73
+ domain?: string;
74
+ };
75
+
76
+ /**
77
+ * Custom i18n configuration for the modal
78
+ * See [i18next json format](https://www.i18next.com/misc/json-format#i18next-json-v4)
79
+ *
80
+ * Available variables
81
+ * - `{{ productName }}` : The name of your website (`metadata.name`)
82
+ * - `{{ productOrigin }}` : The origin url of your website
83
+ * - `{{ estimatedReward }}` : The estimated reward for the user (based on the specific `targetInteraction` you can specify, or the max referrer reward if no target interaction is specified)
84
+ *
85
+ * Context of the translation [see i18n context](https://www.i18next.com/translation-function/context)
86
+ * - For modal display, the key of the final action (`sharing`, `reward`, or undefined)
87
+ * - For embedded wallet display, the key of the logged in action (`sharing` or undefined)
88
+ *
89
+ * @example
90
+ * ```ts
91
+ * // Multi language config
92
+ * const multiI18n = {
93
+ * fr: {
94
+ * "sdk.modal.title": "Titre de modal",
95
+ * "sdk.modal.description": "Description de modal, avec {{ estimatedReward }} de gains possible",
96
+ * },
97
+ * en: "https://example.com/en.json"
98
+ * }
99
+ *
100
+ * // Single language config
101
+ * const singleI18n = {
102
+ * "sdk.modal.title": "Modal title",
103
+ * "sdk.modal.description": "Modal description, with {{ estimatedReward }} of gains possible",
104
+ * }
105
+ * ```
106
+ *
107
+ * @category Config
108
+ */
109
+ export type I18nConfig =
110
+ | Record<Language, LocalizedI18nConfig>
111
+ | LocalizedI18nConfig;
112
+
113
+ /**
114
+ * A localized i18n config
115
+ * @category Config
116
+ */
117
+ export type LocalizedI18nConfig = `${string}.css` | { [key: string]: string };
@@ -0,0 +1,13 @@
1
+ import type { Address } from "viem";
2
+
3
+ /**
4
+ * The current Frak Context
5
+ *
6
+ * For now, only contain a referrer address.
7
+ *
8
+ * @ignore
9
+ */
10
+ export type FrakContext = {
11
+ // Referrer address
12
+ r: Address;
13
+ };
@@ -0,0 +1,74 @@
1
+ // Rpc related
2
+
3
+ // Client related
4
+ export type { FrakClient } from "./client";
5
+ export type {
6
+ CompressedData,
7
+ HashProtectedData,
8
+ KeyProvider,
9
+ } from "./compression";
10
+ export type {
11
+ Currency,
12
+ FrakWalletSdkConfig,
13
+ I18nConfig,
14
+ Language,
15
+ LocalizedI18nConfig,
16
+ } from "./config";
17
+ // Utils
18
+ export type { FrakContext } from "./context";
19
+
20
+ export type {
21
+ ClientLifecycleEvent,
22
+ IFrameLifecycleEvent,
23
+ } from "./lifecycle";
24
+ export type { IFrameRpcSchema } from "./rpc";
25
+ // Modal related
26
+ export type {
27
+ DisplayModalParamsType,
28
+ ModalRpcMetadata,
29
+ ModalRpcStepsInput,
30
+ ModalRpcStepsResultType,
31
+ ModalStepTypes,
32
+ } from "./rpc/displayModal";
33
+ export type {
34
+ DisplayEmbeddedWalletParamsType,
35
+ DisplayEmbeddedWalletResultType,
36
+ EmbeddedViewActionReferred,
37
+ EmbeddedViewActionSharing,
38
+ LoggedInEmbeddedView,
39
+ LoggedOutEmbeddedView,
40
+ } from "./rpc/embedded";
41
+ export type { SendInteractionParamsType } from "./rpc/interaction";
42
+ export type {
43
+ EstimatedReward,
44
+ GetMerchantInformationReturnType,
45
+ RewardTier,
46
+ TokenAmountType,
47
+ } from "./rpc/merchantInformation";
48
+ export type {
49
+ FinalActionType,
50
+ FinalModalStepType,
51
+ LoginModalStepType,
52
+ ModalStepMetadata,
53
+ SendTransactionModalStepType,
54
+ SendTransactionReturnType,
55
+ SendTransactionTxType,
56
+ SiweAuthenticateModalStepType,
57
+ SiweAuthenticateReturnType,
58
+ SiweAuthenticationParams,
59
+ } from "./rpc/modal";
60
+ export type {
61
+ OpenSsoParamsType,
62
+ OpenSsoReturnType,
63
+ PrepareSsoParamsType,
64
+ PrepareSsoReturnType,
65
+ SsoMetadata,
66
+ } from "./rpc/sso";
67
+ export type { WalletStatusReturnType } from "./rpc/walletStatus";
68
+ // Tracking
69
+ export type {
70
+ TrackArrivalParams,
71
+ TrackArrivalResult,
72
+ UtmParams,
73
+ } from "./tracking";
74
+ export type { FrakLifecycleEvent, IFrameTransport } from "./transport";
@@ -0,0 +1,69 @@
1
+ import type { I18nConfig } from "../config";
2
+
3
+ /**
4
+ * Event related to the iframe lifecycle
5
+ * @ignore
6
+ */
7
+ export type ClientLifecycleEvent =
8
+ | CustomCssEvent
9
+ | CustomI18nEvent
10
+ | RestoreBackupEvent
11
+ | HearbeatEvent
12
+ | HandshakeResponse
13
+ | SsoRedirectCompleteEvent
14
+ | DeepLinkFailedEvent;
15
+
16
+ type CustomCssEvent = {
17
+ clientLifecycle: "modal-css";
18
+ data: { cssLink: string };
19
+ };
20
+
21
+ type CustomI18nEvent = {
22
+ clientLifecycle: "modal-i18n";
23
+ data: { i18n: I18nConfig };
24
+ };
25
+
26
+ type RestoreBackupEvent = {
27
+ clientLifecycle: "restore-backup";
28
+ data: { backup: string };
29
+ };
30
+
31
+ type HearbeatEvent = {
32
+ clientLifecycle: "heartbeat";
33
+ data?: never;
34
+ };
35
+
36
+ type HandshakeResponse = {
37
+ clientLifecycle: "handshake-response";
38
+ data: {
39
+ token: string;
40
+ currentUrl: string;
41
+ /**
42
+ * Pending merge token extracted from URL (?fmt= parameter)
43
+ * When present, listener should execute identity merge in background
44
+ * URL is cleaned after handshake response is sent
45
+ */
46
+ pendingMergeToken?: string;
47
+ /**
48
+ * Client ID for identity tracking (belt & suspenders fallback)
49
+ * Primary delivery is via iframe URL query param; handshake is backup for SSR
50
+ */
51
+ clientId?: string;
52
+ /**
53
+ * Explicit domain from SDK config (FrakWalletSdkConfig.domain)
54
+ * When present, listener should prefer this over URL-derived domain
55
+ * for merchant resolution (handles proxied/tunneled environments)
56
+ */
57
+ configDomain?: string;
58
+ };
59
+ };
60
+
61
+ type SsoRedirectCompleteEvent = {
62
+ clientLifecycle: "sso-redirect-complete";
63
+ data: { compressed: string };
64
+ };
65
+
66
+ type DeepLinkFailedEvent = {
67
+ clientLifecycle: "deep-link-failed";
68
+ data: { originalUrl: string };
69
+ };