@frak-labs/core-sdk 0.2.1-beta.b38eef2e → 0.2.1-beta.c7fe645d
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 +1 -2
- package/cdn/bundle.js +55 -3
- package/dist/actions.cjs +1 -1
- package/dist/actions.d.cts +3 -3
- package/dist/actions.d.ts +3 -3
- 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/{computeLegacyProductId-CCAZvLa5.d.cts → computeLegacyProductId-C35yITjX.d.ts} +91 -37
- package/dist/{computeLegacyProductId-b5cUWdAm.d.ts → computeLegacyProductId-mG4x5Cq0.d.cts} +91 -37
- 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-B0g7-807.d.cts → openSso-7e-OKMhg.d.ts} +266 -46
- package/dist/{openSso-CMzwvaCa.d.ts → openSso-BebjXCq0.d.cts} +266 -46
- package/dist/setupClient-CUYyoXtI.js +13 -0
- package/dist/setupClient-LgwHIFJc.cjs +13 -0
- package/dist/{siweAuthenticate-CnCZ7mok.d.ts → siweAuthenticate-BQEMZRg3.d.cts} +102 -8
- package/dist/siweAuthenticate-CWcVvP-G.cjs +1 -0
- package/dist/{siweAuthenticate-CVigMOxz.d.cts → siweAuthenticate-CdLD-9W2.d.ts} +102 -8
- package/dist/siweAuthenticate-DQfdb5UQ.js +1 -0
- package/dist/trackEvent-Ce1XlsIE.js +1 -0
- package/dist/trackEvent-CvbJTTqA.cjs +1 -0
- package/package.json +8 -8
- package/src/actions/displayEmbeddedWallet.ts +6 -2
- package/src/actions/displayModal.ts +6 -2
- package/src/actions/displaySharingPage.ts +49 -0
- package/src/actions/ensureIdentity.ts +2 -2
- package/src/actions/getMerchantInformation.test.ts +13 -1
- package/src/actions/getMerchantInformation.ts +20 -5
- package/src/actions/getUserReferralStatus.ts +42 -0
- package/src/actions/index.ts +7 -1
- package/src/actions/referral/setupReferral.test.ts +79 -0
- package/src/actions/referral/setupReferral.ts +32 -0
- package/src/actions/trackPurchaseStatus.test.ts +32 -20
- package/src/actions/trackPurchaseStatus.ts +3 -5
- package/src/actions/wrapper/modalBuilder.test.ts +4 -2
- package/src/actions/wrapper/modalBuilder.ts +6 -8
- package/src/clients/createIFrameFrakClient.ts +150 -27
- package/src/clients/transports/iframeLifecycleManager.test.ts +14 -94
- package/src/clients/transports/iframeLifecycleManager.ts +15 -48
- package/src/index.ts +17 -4
- package/src/types/config.ts +10 -3
- package/src/types/index.ts +13 -1
- package/src/types/lifecycle/client.ts +22 -27
- package/src/types/lifecycle/iframe.ts +7 -8
- package/src/types/resolvedConfig.ts +123 -0
- package/src/types/rpc/displaySharingPage.ts +77 -0
- package/src/types/rpc/interaction.ts +4 -0
- package/src/types/rpc/userReferralStatus.ts +20 -0
- package/src/types/rpc.ts +42 -5
- package/src/utils/backendUrl.test.ts +2 -2
- package/src/utils/backendUrl.ts +1 -1
- package/src/utils/cache/index.ts +7 -0
- package/src/utils/cache/lruMap.test.ts +55 -0
- package/src/utils/cache/lruMap.ts +38 -0
- package/src/utils/cache/withCache.test.ts +162 -0
- package/src/utils/cache/withCache.ts +105 -0
- package/src/utils/inAppBrowser.ts +60 -0
- package/src/utils/index.ts +6 -4
- package/src/utils/sdkConfigStore.test.ts +405 -0
- package/src/utils/sdkConfigStore.ts +263 -0
- package/src/utils/sso.ts +3 -7
- package/dist/setupClient-CqTHGvVa.cjs +0 -13
- package/dist/setupClient-DTyvAPgh.js +0 -13
- package/dist/siweAuthenticate-BWmI2_TN.cjs +0 -1
- package/dist/siweAuthenticate-zczqxm0a.js +0 -1
- package/dist/trackEvent-CeLFVzZn.js +0 -1
- package/dist/trackEvent-Ew5r5zfI.cjs +0 -1
- package/src/utils/merchantId.test.ts +0 -653
- package/src/utils/merchantId.ts +0 -143
|
@@ -102,7 +102,7 @@ describe("createIFrameLifecycleManager", () => {
|
|
|
102
102
|
iframeLifecycle: "connected" as const,
|
|
103
103
|
};
|
|
104
104
|
|
|
105
|
-
|
|
105
|
+
manager.handleEvent(event);
|
|
106
106
|
|
|
107
107
|
await expect(manager.isConnected).resolves.toBe(true);
|
|
108
108
|
});
|
|
@@ -126,7 +126,7 @@ describe("createIFrameLifecycleManager", () => {
|
|
|
126
126
|
data: { backup },
|
|
127
127
|
};
|
|
128
128
|
|
|
129
|
-
|
|
129
|
+
manager.handleEvent(event);
|
|
130
130
|
|
|
131
131
|
expect(localStorage.getItem("frak-backup-key")).toBe(backup);
|
|
132
132
|
});
|
|
@@ -150,7 +150,7 @@ describe("createIFrameLifecycleManager", () => {
|
|
|
150
150
|
data: {},
|
|
151
151
|
};
|
|
152
152
|
|
|
153
|
-
|
|
153
|
+
manager.handleEvent(event);
|
|
154
154
|
|
|
155
155
|
expect(localStorage.getItem("frak-backup-key")).toBeNull();
|
|
156
156
|
});
|
|
@@ -173,7 +173,7 @@ describe("createIFrameLifecycleManager", () => {
|
|
|
173
173
|
iframeLifecycle: "remove-backup" as const,
|
|
174
174
|
};
|
|
175
175
|
|
|
176
|
-
|
|
176
|
+
manager.handleEvent(event);
|
|
177
177
|
|
|
178
178
|
expect(localStorage.getItem("frak-backup-key")).toBeNull();
|
|
179
179
|
});
|
|
@@ -198,7 +198,7 @@ describe("createIFrameLifecycleManager", () => {
|
|
|
198
198
|
iframeLifecycle: "show" as const,
|
|
199
199
|
};
|
|
200
200
|
|
|
201
|
-
|
|
201
|
+
manager.handleEvent(event);
|
|
202
202
|
|
|
203
203
|
expect(changeIframeVisibility).toHaveBeenCalledWith({
|
|
204
204
|
iframe: mockIframe,
|
|
@@ -224,7 +224,7 @@ describe("createIFrameLifecycleManager", () => {
|
|
|
224
224
|
iframeLifecycle: "hide" as const,
|
|
225
225
|
};
|
|
226
226
|
|
|
227
|
-
|
|
227
|
+
manager.handleEvent(event);
|
|
228
228
|
|
|
229
229
|
expect(changeIframeVisibility).toHaveBeenCalledWith({
|
|
230
230
|
iframe: mockIframe,
|
|
@@ -233,86 +233,6 @@ describe("createIFrameLifecycleManager", () => {
|
|
|
233
233
|
});
|
|
234
234
|
});
|
|
235
235
|
|
|
236
|
-
describe("handshake event", () => {
|
|
237
|
-
test("should post handshake-response with token to iframe origin", async () => {
|
|
238
|
-
const { createIFrameLifecycleManager } = await import(
|
|
239
|
-
"./iframeLifecycleManager"
|
|
240
|
-
);
|
|
241
|
-
|
|
242
|
-
const mockPostMessage = vi.fn();
|
|
243
|
-
const mockIframe = {
|
|
244
|
-
src: "https://wallet.frak.id/listener",
|
|
245
|
-
contentWindow: {
|
|
246
|
-
postMessage: mockPostMessage,
|
|
247
|
-
},
|
|
248
|
-
} as any;
|
|
249
|
-
|
|
250
|
-
const manager = createIFrameLifecycleManager({
|
|
251
|
-
iframe: mockIframe,
|
|
252
|
-
targetOrigin: WALLET_ORIGIN,
|
|
253
|
-
});
|
|
254
|
-
|
|
255
|
-
const event = {
|
|
256
|
-
iframeLifecycle: "handshake" as const,
|
|
257
|
-
data: { token: "handshake-token-123" },
|
|
258
|
-
};
|
|
259
|
-
|
|
260
|
-
await manager.handleEvent(event);
|
|
261
|
-
|
|
262
|
-
expect(mockPostMessage).toHaveBeenCalledWith(
|
|
263
|
-
{
|
|
264
|
-
clientLifecycle: "handshake-response",
|
|
265
|
-
data: {
|
|
266
|
-
token: "handshake-token-123",
|
|
267
|
-
currentUrl: "https://test.com",
|
|
268
|
-
clientId: "mock-client-id",
|
|
269
|
-
},
|
|
270
|
-
},
|
|
271
|
-
"https://wallet.frak.id"
|
|
272
|
-
);
|
|
273
|
-
});
|
|
274
|
-
|
|
275
|
-
test("should include current URL in handshake response", async () => {
|
|
276
|
-
const { createIFrameLifecycleManager } = await import(
|
|
277
|
-
"./iframeLifecycleManager"
|
|
278
|
-
);
|
|
279
|
-
|
|
280
|
-
Object.defineProperty(window, "location", {
|
|
281
|
-
value: { href: "https://example.com/page?param=value" },
|
|
282
|
-
writable: true,
|
|
283
|
-
});
|
|
284
|
-
|
|
285
|
-
const mockPostMessage = vi.fn();
|
|
286
|
-
const mockIframe = {
|
|
287
|
-
src: "https://wallet.frak.id/listener",
|
|
288
|
-
contentWindow: {
|
|
289
|
-
postMessage: mockPostMessage,
|
|
290
|
-
},
|
|
291
|
-
} as any;
|
|
292
|
-
|
|
293
|
-
const manager = createIFrameLifecycleManager({
|
|
294
|
-
iframe: mockIframe,
|
|
295
|
-
targetOrigin: WALLET_ORIGIN,
|
|
296
|
-
});
|
|
297
|
-
|
|
298
|
-
const event = {
|
|
299
|
-
iframeLifecycle: "handshake" as const,
|
|
300
|
-
data: { token: "token" },
|
|
301
|
-
};
|
|
302
|
-
|
|
303
|
-
await manager.handleEvent(event);
|
|
304
|
-
|
|
305
|
-
expect(mockPostMessage).toHaveBeenCalledWith(
|
|
306
|
-
expect.objectContaining({
|
|
307
|
-
data: expect.objectContaining({
|
|
308
|
-
currentUrl: "https://example.com/page?param=value",
|
|
309
|
-
}),
|
|
310
|
-
}),
|
|
311
|
-
"https://wallet.frak.id"
|
|
312
|
-
);
|
|
313
|
-
});
|
|
314
|
-
});
|
|
315
|
-
|
|
316
236
|
describe("redirect event", () => {
|
|
317
237
|
test("should redirect with appended current URL for HTTP URLs", async () => {
|
|
318
238
|
const { createIFrameLifecycleManager } = await import(
|
|
@@ -339,7 +259,7 @@ describe("createIFrameLifecycleManager", () => {
|
|
|
339
259
|
},
|
|
340
260
|
};
|
|
341
261
|
|
|
342
|
-
|
|
262
|
+
manager.handleEvent(event);
|
|
343
263
|
|
|
344
264
|
expect(window.location.href).toBe(
|
|
345
265
|
"https://redirect.com/?u=https%3A%2F%2Foriginal.com"
|
|
@@ -371,7 +291,7 @@ describe("createIFrameLifecycleManager", () => {
|
|
|
371
291
|
},
|
|
372
292
|
};
|
|
373
293
|
|
|
374
|
-
|
|
294
|
+
manager.handleEvent(event);
|
|
375
295
|
|
|
376
296
|
expect(window.location.href).toBe("https://redirect.com/path");
|
|
377
297
|
});
|
|
@@ -405,7 +325,7 @@ describe("createIFrameLifecycleManager", () => {
|
|
|
405
325
|
},
|
|
406
326
|
};
|
|
407
327
|
|
|
408
|
-
|
|
328
|
+
manager.handleEvent(event);
|
|
409
329
|
|
|
410
330
|
expect(triggerDeepLinkWithFallback).toHaveBeenCalledWith(
|
|
411
331
|
"frakwallet://wallet",
|
|
@@ -450,7 +370,7 @@ describe("createIFrameLifecycleManager", () => {
|
|
|
450
370
|
},
|
|
451
371
|
};
|
|
452
372
|
|
|
453
|
-
|
|
373
|
+
manager.handleEvent(event);
|
|
454
374
|
|
|
455
375
|
// Extract the onFallback callback from the mock call
|
|
456
376
|
const callArgs = (triggerDeepLinkWithFallback as any).mock.calls[0];
|
|
@@ -499,7 +419,7 @@ describe("createIFrameLifecycleManager", () => {
|
|
|
499
419
|
},
|
|
500
420
|
};
|
|
501
421
|
|
|
502
|
-
|
|
422
|
+
manager.handleEvent(event);
|
|
503
423
|
|
|
504
424
|
// Should NOT call fallback detection
|
|
505
425
|
expect(triggerDeepLinkWithFallback).not.toHaveBeenCalled();
|
|
@@ -525,7 +445,7 @@ describe("createIFrameLifecycleManager", () => {
|
|
|
525
445
|
} as any;
|
|
526
446
|
|
|
527
447
|
// Should not throw
|
|
528
|
-
|
|
448
|
+
expect(manager.handleEvent(event)).toBeUndefined();
|
|
529
449
|
});
|
|
530
450
|
|
|
531
451
|
test("should only process events with iframeLifecycle", async () => {
|
|
@@ -543,13 +463,13 @@ describe("createIFrameLifecycleManager", () => {
|
|
|
543
463
|
});
|
|
544
464
|
|
|
545
465
|
// Event without iframeLifecycle
|
|
546
|
-
|
|
466
|
+
manager.handleEvent({ randomEvent: "show" } as any);
|
|
547
467
|
|
|
548
468
|
// changeIframeVisibility should not be called
|
|
549
469
|
expect(changeIframeVisibility).not.toHaveBeenCalled();
|
|
550
470
|
|
|
551
471
|
// Event with iframeLifecycle
|
|
552
|
-
|
|
472
|
+
manager.handleEvent({ iframeLifecycle: "show" as const });
|
|
553
473
|
|
|
554
474
|
// Now it should be called
|
|
555
475
|
expect(changeIframeVisibility).toHaveBeenCalled();
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Deferred } from "@frak-labs/frame-connector";
|
|
2
2
|
import type { FrakLifecycleEvent } from "../../types";
|
|
3
|
-
import { getClientId } from "../../utils/clientId";
|
|
4
3
|
import { BACKUP_KEY } from "../../utils/constants";
|
|
5
4
|
import {
|
|
6
5
|
isFrakDeepLink,
|
|
@@ -33,7 +32,7 @@ const isIOSInAppBrowser = (() => {
|
|
|
33
32
|
/** @ignore */
|
|
34
33
|
export type IframeLifecycleManager = {
|
|
35
34
|
isConnected: Promise<boolean>;
|
|
36
|
-
handleEvent: (messageEvent: FrakLifecycleEvent) =>
|
|
35
|
+
handleEvent: (messageEvent: FrakLifecycleEvent) => void;
|
|
37
36
|
};
|
|
38
37
|
|
|
39
38
|
/**
|
|
@@ -47,42 +46,6 @@ function handleBackup(backup: string | undefined): void {
|
|
|
47
46
|
}
|
|
48
47
|
}
|
|
49
48
|
|
|
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
49
|
/**
|
|
87
50
|
* Compute final redirect URL with parameter substitution
|
|
88
51
|
*/
|
|
@@ -137,8 +100,18 @@ function handleRedirect(
|
|
|
137
100
|
iframe: HTMLIFrameElement,
|
|
138
101
|
baseRedirectUrl: string,
|
|
139
102
|
targetOrigin: string,
|
|
140
|
-
mergeToken?: string
|
|
103
|
+
mergeToken?: string,
|
|
104
|
+
openInNewTab?: boolean
|
|
141
105
|
): void {
|
|
106
|
+
// If requested, open in a new tab instead of navigating the current page.
|
|
107
|
+
// This preserves the merchant page while triggering universal links.
|
|
108
|
+
// Requires the iframe postMessage to include user activation delegation.
|
|
109
|
+
if (openInNewTab) {
|
|
110
|
+
const finalUrl = computeRedirectUrl(baseRedirectUrl, mergeToken);
|
|
111
|
+
window.open(finalUrl, "_blank");
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
142
115
|
if (isFrakDeepLink(baseRedirectUrl)) {
|
|
143
116
|
const finalUrl = computeRedirectUrl(baseRedirectUrl, mergeToken);
|
|
144
117
|
triggerDeepLinkWithFallback(finalUrl, {
|
|
@@ -167,23 +140,20 @@ function handleRedirect(
|
|
|
167
140
|
* @param args
|
|
168
141
|
* @param args.iframe - The iframe element used for wallet communication
|
|
169
142
|
* @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
143
|
* @ignore
|
|
172
144
|
*/
|
|
173
145
|
export function createIFrameLifecycleManager({
|
|
174
146
|
iframe,
|
|
175
147
|
targetOrigin,
|
|
176
|
-
configDomain,
|
|
177
148
|
}: {
|
|
178
149
|
iframe: HTMLIFrameElement;
|
|
179
150
|
targetOrigin: string;
|
|
180
|
-
configDomain?: string;
|
|
181
151
|
}): IframeLifecycleManager {
|
|
182
152
|
// Create the isConnected listener
|
|
183
153
|
const isConnectedDeferred = new Deferred<boolean>();
|
|
184
154
|
|
|
185
155
|
// Build the handler itself
|
|
186
|
-
const handler =
|
|
156
|
+
const handler = (messageEvent: FrakLifecycleEvent) => {
|
|
187
157
|
if (!("iframeLifecycle" in messageEvent)) return;
|
|
188
158
|
|
|
189
159
|
const { iframeLifecycle: event, data } = messageEvent;
|
|
@@ -206,17 +176,14 @@ export function createIFrameLifecycleManager({
|
|
|
206
176
|
case "hide":
|
|
207
177
|
changeIframeVisibility({ iframe, isVisible: event === "show" });
|
|
208
178
|
break;
|
|
209
|
-
// Handshake handling
|
|
210
|
-
case "handshake":
|
|
211
|
-
handleHandshake(iframe, data.token, targetOrigin, configDomain);
|
|
212
|
-
break;
|
|
213
179
|
// Redirect handling
|
|
214
180
|
case "redirect":
|
|
215
181
|
handleRedirect(
|
|
216
182
|
iframe,
|
|
217
183
|
data.baseRedirectUrl,
|
|
218
184
|
targetOrigin,
|
|
219
|
-
data.mergeToken
|
|
185
|
+
data.mergeToken,
|
|
186
|
+
data.openInNewTab
|
|
220
187
|
);
|
|
221
188
|
break;
|
|
222
189
|
}
|
package/src/index.ts
CHANGED
|
@@ -19,6 +19,9 @@ export type {
|
|
|
19
19
|
DisplayEmbeddedWalletParamsType,
|
|
20
20
|
DisplayEmbeddedWalletResultType,
|
|
21
21
|
DisplayModalParamsType,
|
|
22
|
+
// RPC Sharing page
|
|
23
|
+
DisplaySharingPageParamsType,
|
|
24
|
+
DisplaySharingPageResultType,
|
|
22
25
|
EmbeddedViewActionReferred,
|
|
23
26
|
EmbeddedViewActionSharing,
|
|
24
27
|
EstimatedReward,
|
|
@@ -47,6 +50,7 @@ export type {
|
|
|
47
50
|
LoggedInEmbeddedView,
|
|
48
51
|
LoggedOutEmbeddedView,
|
|
49
52
|
LoginModalStepType,
|
|
53
|
+
MerchantConfigResponse,
|
|
50
54
|
ModalRpcMetadata,
|
|
51
55
|
ModalRpcStepsInput,
|
|
52
56
|
ModalRpcStepsResultType,
|
|
@@ -58,12 +62,16 @@ export type {
|
|
|
58
62
|
OpenSsoReturnType,
|
|
59
63
|
PrepareSsoParamsType,
|
|
60
64
|
PrepareSsoReturnType,
|
|
65
|
+
ResolvedPlacement,
|
|
66
|
+
ResolvedSdkConfig,
|
|
61
67
|
RewardTier,
|
|
68
|
+
SdkResolvedConfig,
|
|
62
69
|
// RPC Interaction
|
|
63
70
|
SendInteractionParamsType,
|
|
64
71
|
SendTransactionModalStepType,
|
|
65
72
|
SendTransactionReturnType,
|
|
66
73
|
SendTransactionTxType,
|
|
74
|
+
SharingPageProduct,
|
|
67
75
|
SiweAuthenticateModalStepType,
|
|
68
76
|
SiweAuthenticateReturnType,
|
|
69
77
|
SiweAuthenticationParams,
|
|
@@ -72,8 +80,9 @@ export type {
|
|
|
72
80
|
// Tracking
|
|
73
81
|
TrackArrivalParams,
|
|
74
82
|
TrackArrivalResult,
|
|
75
|
-
UtmParams,
|
|
76
83
|
// Rpc
|
|
84
|
+
UserReferralStatusType,
|
|
85
|
+
UtmParams,
|
|
77
86
|
WalletStatusReturnType,
|
|
78
87
|
} from "./types";
|
|
79
88
|
export { isV1Context, isV2Context } from "./types";
|
|
@@ -84,7 +93,7 @@ export {
|
|
|
84
93
|
base64urlEncode,
|
|
85
94
|
baseIframeProps,
|
|
86
95
|
type CompressedSsoData,
|
|
87
|
-
|
|
96
|
+
clearAllCache,
|
|
88
97
|
compressJsonToB64,
|
|
89
98
|
createIframe,
|
|
90
99
|
DEEP_LINK_SCHEME,
|
|
@@ -93,20 +102,24 @@ export {
|
|
|
93
102
|
FrakContextManager,
|
|
94
103
|
type FrakEvent,
|
|
95
104
|
type FullSsoParams,
|
|
96
|
-
fetchMerchantId,
|
|
97
105
|
findIframeInOpener,
|
|
98
106
|
formatAmount,
|
|
99
107
|
generateSsoUrl,
|
|
100
108
|
getBackendUrl,
|
|
109
|
+
getCache,
|
|
101
110
|
getClientId,
|
|
102
111
|
getCurrencyAmountKey,
|
|
103
112
|
getSupportedCurrency,
|
|
104
113
|
getSupportedLocale,
|
|
105
114
|
isChromiumAndroid,
|
|
106
115
|
isFrakDeepLink,
|
|
107
|
-
|
|
116
|
+
isInAppBrowser,
|
|
117
|
+
isIOS,
|
|
118
|
+
redirectToExternalBrowser,
|
|
119
|
+
sdkConfigStore,
|
|
108
120
|
toAndroidIntentUrl,
|
|
109
121
|
trackEvent,
|
|
110
122
|
triggerDeepLinkWithFallback,
|
|
123
|
+
withCache,
|
|
111
124
|
} from "./utils";
|
|
112
125
|
export { computeLegacyProductId } from "./utils/computeLegacyProductId";
|
package/src/types/config.ts
CHANGED
|
@@ -27,7 +27,7 @@ export type FrakWalletSdkConfig = {
|
|
|
27
27
|
/**
|
|
28
28
|
* Your application name (will be displayed in a few modals and in SSO)
|
|
29
29
|
*/
|
|
30
|
-
name
|
|
30
|
+
name?: string;
|
|
31
31
|
/**
|
|
32
32
|
* Your merchant ID from the Frak dashboard (UUID format)
|
|
33
33
|
* Used for referral tracking and analytics
|
|
@@ -71,6 +71,13 @@ export type FrakWalletSdkConfig = {
|
|
|
71
71
|
* @defaultValue window.location.host
|
|
72
72
|
*/
|
|
73
73
|
domain?: string;
|
|
74
|
+
/**
|
|
75
|
+
* Wait for backend config before rendering components.
|
|
76
|
+
* When true (default), components show a spinner until backend config is resolved.
|
|
77
|
+
* When false, components render immediately with SDK static config / HTML attributes.
|
|
78
|
+
* @defaultValue true
|
|
79
|
+
*/
|
|
80
|
+
waitForBackendConfig?: boolean;
|
|
74
81
|
};
|
|
75
82
|
|
|
76
83
|
/**
|
|
@@ -111,7 +118,7 @@ export type I18nConfig =
|
|
|
111
118
|
| LocalizedI18nConfig;
|
|
112
119
|
|
|
113
120
|
/**
|
|
114
|
-
* A localized i18n config
|
|
121
|
+
* A localized i18n config (inline objects only — URL-based i18n removed)
|
|
115
122
|
* @category Config
|
|
116
123
|
*/
|
|
117
|
-
export type LocalizedI18nConfig =
|
|
124
|
+
export type LocalizedI18nConfig = { [key: string]: string };
|
package/src/types/index.ts
CHANGED
|
@@ -17,11 +17,16 @@ export type {
|
|
|
17
17
|
// Utils
|
|
18
18
|
export type { FrakContext, FrakContextV1, FrakContextV2 } from "./context";
|
|
19
19
|
export { isV1Context, isV2Context } from "./context";
|
|
20
|
-
|
|
21
20
|
export type {
|
|
22
21
|
ClientLifecycleEvent,
|
|
23
22
|
IFrameLifecycleEvent,
|
|
24
23
|
} from "./lifecycle";
|
|
24
|
+
export type {
|
|
25
|
+
MerchantConfigResponse,
|
|
26
|
+
ResolvedPlacement,
|
|
27
|
+
ResolvedSdkConfig,
|
|
28
|
+
SdkResolvedConfig,
|
|
29
|
+
} from "./resolvedConfig";
|
|
25
30
|
export type { IFrameRpcSchema } from "./rpc";
|
|
26
31
|
// Modal related
|
|
27
32
|
export type {
|
|
@@ -31,6 +36,12 @@ export type {
|
|
|
31
36
|
ModalRpcStepsResultType,
|
|
32
37
|
ModalStepTypes,
|
|
33
38
|
} from "./rpc/displayModal";
|
|
39
|
+
// Sharing page related
|
|
40
|
+
export type {
|
|
41
|
+
DisplaySharingPageParamsType,
|
|
42
|
+
DisplaySharingPageResultType,
|
|
43
|
+
SharingPageProduct,
|
|
44
|
+
} from "./rpc/displaySharingPage";
|
|
34
45
|
export type {
|
|
35
46
|
DisplayEmbeddedWalletParamsType,
|
|
36
47
|
DisplayEmbeddedWalletResultType,
|
|
@@ -65,6 +76,7 @@ export type {
|
|
|
65
76
|
PrepareSsoReturnType,
|
|
66
77
|
SsoMetadata,
|
|
67
78
|
} from "./rpc/sso";
|
|
79
|
+
export type { UserReferralStatusType } from "./rpc/userReferralStatus";
|
|
68
80
|
export type { WalletStatusReturnType } from "./rpc/walletStatus";
|
|
69
81
|
// Tracking
|
|
70
82
|
export type {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { I18nConfig } from "../config";
|
|
2
|
+
import type { ResolvedSdkConfig } from "../resolvedConfig";
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Event related to the iframe lifecycle
|
|
@@ -9,9 +10,9 @@ export type ClientLifecycleEvent =
|
|
|
9
10
|
| CustomI18nEvent
|
|
10
11
|
| RestoreBackupEvent
|
|
11
12
|
| HearbeatEvent
|
|
12
|
-
| HandshakeResponse
|
|
13
13
|
| SsoRedirectCompleteEvent
|
|
14
|
-
| DeepLinkFailedEvent
|
|
14
|
+
| DeepLinkFailedEvent
|
|
15
|
+
| ResolvedConfigEvent;
|
|
15
16
|
|
|
16
17
|
type CustomCssEvent = {
|
|
17
18
|
clientLifecycle: "modal-css";
|
|
@@ -33,31 +34,6 @@ type HearbeatEvent = {
|
|
|
33
34
|
data?: never;
|
|
34
35
|
};
|
|
35
36
|
|
|
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
37
|
type SsoRedirectCompleteEvent = {
|
|
62
38
|
clientLifecycle: "sso-redirect-complete";
|
|
63
39
|
data: { compressed: string };
|
|
@@ -67,3 +43,22 @@ type DeepLinkFailedEvent = {
|
|
|
67
43
|
clientLifecycle: "deep-link-failed";
|
|
68
44
|
data: { originalUrl: string };
|
|
69
45
|
};
|
|
46
|
+
|
|
47
|
+
type ResolvedConfigEvent = {
|
|
48
|
+
clientLifecycle: "resolved-config";
|
|
49
|
+
data: {
|
|
50
|
+
merchantId: string;
|
|
51
|
+
/** The domain the backend resolved this config for */
|
|
52
|
+
domain: string;
|
|
53
|
+
/** All domains registered for this merchant (for domain proof) */
|
|
54
|
+
allowedDomains: string[];
|
|
55
|
+
/** Full URL of the parent page (for interaction tracking) */
|
|
56
|
+
sourceUrl: string;
|
|
57
|
+
/**
|
|
58
|
+
* Pending merge token extracted from URL (?fmt= parameter).
|
|
59
|
+
* When present, listener should execute identity merge in background.
|
|
60
|
+
*/
|
|
61
|
+
pendingMergeToken?: string;
|
|
62
|
+
sdkConfig?: ResolvedSdkConfig;
|
|
63
|
+
};
|
|
64
|
+
};
|
|
@@ -8,7 +8,6 @@ export type IFrameLifecycleEvent =
|
|
|
8
8
|
data?: never;
|
|
9
9
|
}
|
|
10
10
|
| DoBackupEvent
|
|
11
|
-
| HandshakeRequestEvent
|
|
12
11
|
| RedirectRequestEvent;
|
|
13
12
|
|
|
14
13
|
type DoBackupEvent = {
|
|
@@ -16,13 +15,6 @@ type DoBackupEvent = {
|
|
|
16
15
|
data: { backup?: string };
|
|
17
16
|
};
|
|
18
17
|
|
|
19
|
-
type HandshakeRequestEvent = {
|
|
20
|
-
iframeLifecycle: "handshake";
|
|
21
|
-
data: {
|
|
22
|
-
token: string;
|
|
23
|
-
};
|
|
24
|
-
};
|
|
25
|
-
|
|
26
18
|
type RedirectRequestEvent = {
|
|
27
19
|
iframeLifecycle: "redirect";
|
|
28
20
|
data: {
|
|
@@ -37,5 +29,12 @@ type RedirectRequestEvent = {
|
|
|
37
29
|
* Used when redirecting out of social browsers to preserve identity across contexts
|
|
38
30
|
*/
|
|
39
31
|
mergeToken?: string;
|
|
32
|
+
/**
|
|
33
|
+
* When true, open the URL in a new tab via window.open(_blank)
|
|
34
|
+
* instead of navigating the current page.
|
|
35
|
+
* Requires the postMessage to include user activation delegation
|
|
36
|
+
* (includeUserActivation: true) so Safari allows the popup.
|
|
37
|
+
*/
|
|
38
|
+
openInNewTab?: boolean;
|
|
40
39
|
};
|
|
41
40
|
};
|