@frak-labs/core-sdk 1.0.2-beta.9985efe7 → 1.0.2-beta.9d4f564a
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/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 +16 -22
- package/src/stubs/rrweb.ts +8 -4
- package/src/types/client.ts +0 -3
- 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/cdn/bundle.js +0 -14
- package/dist/actions-DihYM-OG.js +0 -1
- package/dist/actions-cYbmqewX.cjs +0 -1
- package/dist/actions.cjs +0 -1
- package/dist/actions.d.cts +0 -3
- package/dist/actions.d.ts +0 -3
- package/dist/actions.js +0 -1
- package/dist/bundle.cjs +0 -1
- package/dist/bundle.d.cts +0 -4
- package/dist/bundle.d.ts +0 -4
- package/dist/bundle.js +0 -1
- package/dist/index-BsBbSMxk.d.cts +0 -646
- package/dist/index-DzVPSUQq.d.ts +0 -716
- package/dist/index-quaxtKRh.d.ts +0 -646
- package/dist/index-s1vE3jLz.d.cts +0 -716
- package/dist/index.cjs +0 -1
- package/dist/index.d.cts +0 -3
- package/dist/index.d.ts +0 -3
- package/dist/index.js +0 -1
- package/dist/openSso-DyUQew2K.d.ts +0 -1392
- package/dist/openSso-rQhLhPbq.d.cts +0 -1392
- package/dist/sdkConfigStore-BXzz5PlK.js +0 -1
- package/dist/sdkConfigStore-DDL_fjYX.cjs +0 -1
- package/dist/src-BfqUdz3x.js +0 -13
- package/dist/src-x06nhpns.cjs +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
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { Address } from "viem";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Address utilities — minimal, dependency-free replacements for the subset of
|
|
5
|
+
* `viem` helpers we used to import. Keeping these in-house lets the SDK ship
|
|
6
|
+
* without pulling viem's checksum/keccak/error chain into the bundle.
|
|
7
|
+
*
|
|
8
|
+
* Scope is intentionally narrow:
|
|
9
|
+
* - `isAddress`: shape-only validation (no EIP-55 checksum)
|
|
10
|
+
* - `areAddressesEqual`: case-insensitive equality
|
|
11
|
+
* - `addressToBytes` / `bytesToAddress`: fixed 20-byte conversion
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/** Matches a 0x-prefixed 40-char hex string regardless of case. */
|
|
15
|
+
const ADDRESS_REGEX = /^0x[a-fA-F0-9]{40}$/;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Check whether a value is a syntactically valid Ethereum address.
|
|
19
|
+
*
|
|
20
|
+
* This intentionally skips EIP-55 checksum validation: the SDK never produces
|
|
21
|
+
* checksum-cased payloads, and downstream consumers (wallet, indexer) treat
|
|
22
|
+
* addresses case-insensitively. Avoiding the checksum path drops keccak256 +
|
|
23
|
+
* @noble/hashes from the bundle.
|
|
24
|
+
*/
|
|
25
|
+
export function isAddress(value: unknown): value is Address {
|
|
26
|
+
return typeof value === "string" && ADDRESS_REGEX.test(value);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Case-insensitive equality check for two Ethereum addresses.
|
|
31
|
+
*
|
|
32
|
+
* Both inputs are assumed to be syntactically valid addresses; callers that
|
|
33
|
+
* receive untrusted input should validate via {@link isAddress} first.
|
|
34
|
+
*/
|
|
35
|
+
export function areAddressesEqual(a: Address, b: Address): boolean {
|
|
36
|
+
return a.toLowerCase() === b.toLowerCase();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Decode a 20-byte Ethereum address into a fixed-size Uint8Array(20).
|
|
41
|
+
*
|
|
42
|
+
* Throws when the input is not exactly `0x` + 40 hex chars — callers wrap
|
|
43
|
+
* the call in try/catch (see {@link FrakContextManager.compress}) so any
|
|
44
|
+
* malformed input degrades to a graceful undefined return.
|
|
45
|
+
*/
|
|
46
|
+
export function addressToBytes(address: Address): Uint8Array {
|
|
47
|
+
const bytes = new Uint8Array(20);
|
|
48
|
+
for (let i = 0; i < 20; i++) {
|
|
49
|
+
const byte = Number.parseInt(
|
|
50
|
+
address.substring(2 + i * 2, 4 + i * 2),
|
|
51
|
+
16
|
|
52
|
+
);
|
|
53
|
+
if (Number.isNaN(byte)) {
|
|
54
|
+
throw new Error(`Invalid address: ${address}`);
|
|
55
|
+
}
|
|
56
|
+
bytes[i] = byte;
|
|
57
|
+
}
|
|
58
|
+
return bytes;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** Lookup table avoids `padStart` overhead in the hot encode loop. */
|
|
62
|
+
const HEX_BYTE = /*#__PURE__*/ Array.from({ length: 256 }, (_, i) =>
|
|
63
|
+
i.toString(16).padStart(2, "0")
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Encode a 20-byte Uint8Array (or a 20-byte subarray view) into a lowercase
|
|
68
|
+
* hex Ethereum address. The caller MUST guarantee `bytes.length === 20`.
|
|
69
|
+
*/
|
|
70
|
+
export function bytesToAddress(bytes: Uint8Array): Address {
|
|
71
|
+
let out = "0x";
|
|
72
|
+
for (let i = 0; i < 20; i++) {
|
|
73
|
+
out += HEX_BYTE[bytes[i]];
|
|
74
|
+
}
|
|
75
|
+
return out as Address;
|
|
76
|
+
}
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
vi,
|
|
10
10
|
} from "../../tests/vitest-fixtures";
|
|
11
11
|
import type { FrakContextV1, FrakContextV2 } from "../types";
|
|
12
|
-
import { FrakContextManager } from "./
|
|
12
|
+
import { FrakContextManager } from "./frakContext";
|
|
13
13
|
|
|
14
14
|
describe("FrakContextManager", () => {
|
|
15
15
|
let consoleErrorSpy: any;
|
|
@@ -144,7 +144,9 @@ describe("FrakContextManager", () => {
|
|
|
144
144
|
const { encodeFrakContextV2 } = await import(
|
|
145
145
|
"./frakContextV2Codec"
|
|
146
146
|
);
|
|
147
|
-
const { base64urlEncode } = await import(
|
|
147
|
+
const { base64urlEncode } = await import(
|
|
148
|
+
"../utils/compression/b64"
|
|
149
|
+
);
|
|
148
150
|
const encoded = encodeFrakContextV2(v2Context);
|
|
149
151
|
expect(encoded).toBeDefined();
|
|
150
152
|
const tampered = new Uint8Array(encoded as Uint8Array);
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { type Address, bytesToHex, hexToBytes, isAddress } from "viem";
|
|
2
1
|
import type {
|
|
3
2
|
AttributionParams,
|
|
4
3
|
FrakContext,
|
|
@@ -6,7 +5,8 @@ import type {
|
|
|
6
5
|
FrakContextV2,
|
|
7
6
|
} from "../types";
|
|
8
7
|
import { isV2Context } from "../types";
|
|
9
|
-
import { base64urlDecode, base64urlEncode } from "
|
|
8
|
+
import { base64urlDecode, base64urlEncode } from "../utils/compression/b64";
|
|
9
|
+
import { addressToBytes, bytesToAddress, isAddress } from "./address";
|
|
10
10
|
import { decodeFrakContextV2, encodeFrakContextV2 } from "./frakContextV2Codec";
|
|
11
11
|
|
|
12
12
|
/**
|
|
@@ -34,7 +34,7 @@ function compress(context?: FrakContextV1 | FrakContextV2): string | undefined {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
// V1 legacy: compress wallet address as raw bytes
|
|
37
|
-
const bytes =
|
|
37
|
+
const bytes = addressToBytes(context.r);
|
|
38
38
|
return base64urlEncode(bytes);
|
|
39
39
|
} catch (e) {
|
|
40
40
|
console.error("Error compressing Frak context", { e, context });
|
|
@@ -64,7 +64,7 @@ function decompress(context?: string): FrakContext | undefined {
|
|
|
64
64
|
return undefined;
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
const hex =
|
|
67
|
+
const hex = bytesToAddress(bytes);
|
|
68
68
|
if (isAddress(hex)) {
|
|
69
69
|
return { r: hex };
|
|
70
70
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Address } from "viem";
|
|
2
2
|
import { describe, expect, it } from "../../tests/vitest-fixtures";
|
|
3
3
|
import type { FrakContextV2 } from "../types";
|
|
4
|
-
import { base64urlEncode } from "
|
|
4
|
+
import { base64urlEncode } from "../utils/compression/b64";
|
|
5
5
|
import {
|
|
6
6
|
decodeFrakContextV2,
|
|
7
7
|
encodeFrakContextV2,
|
|
@@ -28,8 +28,9 @@
|
|
|
28
28
|
*
|
|
29
29
|
* @ignore
|
|
30
30
|
*/
|
|
31
|
-
import {
|
|
31
|
+
import type { Address } from "viem";
|
|
32
32
|
import type { FrakContextV2 } from "../types";
|
|
33
|
+
import { addressToBytes, bytesToAddress, isAddress } from "./address";
|
|
33
34
|
|
|
34
35
|
const VERSION_V2 = 0x02;
|
|
35
36
|
const VERSION_MASK = 0x0f;
|
|
@@ -111,7 +112,7 @@ export function encodeFrakContextV2(ctx: FrakContextV2): Uint8Array | null {
|
|
|
111
112
|
}
|
|
112
113
|
|
|
113
114
|
if (hasW) {
|
|
114
|
-
buf.set(
|
|
115
|
+
buf.set(addressToBytes(ctx.w as Address), offset);
|
|
115
116
|
offset += ADDRESS_BYTES;
|
|
116
117
|
}
|
|
117
118
|
|
|
@@ -165,10 +166,9 @@ export function decodeFrakContextV2(buf: Uint8Array): FrakContextV2 | null {
|
|
|
165
166
|
}
|
|
166
167
|
|
|
167
168
|
if (hasW) {
|
|
168
|
-
const walletHex =
|
|
169
|
-
buf.subarray(offset, offset + ADDRESS_BYTES)
|
|
170
|
-
|
|
171
|
-
) as Address;
|
|
169
|
+
const walletHex = bytesToAddress(
|
|
170
|
+
buf.subarray(offset, offset + ADDRESS_BYTES)
|
|
171
|
+
);
|
|
172
172
|
if (!isAddress(walletHex)) return null;
|
|
173
173
|
out.w = walletHex;
|
|
174
174
|
offset += ADDRESS_BYTES;
|
package/src/index.ts
CHANGED
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
// Clients
|
|
2
2
|
|
|
3
3
|
export { ssoPopupFeatures, ssoPopupName } from "./actions/openSso";
|
|
4
|
+
export { createIFrameFrakClient, setupClient } from "./clients";
|
|
5
|
+
// Config (reactive merchant config + identity)
|
|
4
6
|
export {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
} from "./
|
|
9
|
-
|
|
7
|
+
getBackendUrl,
|
|
8
|
+
getClientId,
|
|
9
|
+
sdkConfigStore,
|
|
10
|
+
} from "./config";
|
|
11
|
+
// Constants
|
|
12
|
+
export { DEEP_LINK_SCHEME } from "./constants";
|
|
10
13
|
export type { InteractionTypeKey } from "./constants/interactionTypes";
|
|
11
|
-
|
|
12
|
-
|
|
14
|
+
// Context (FrakContext URL codec + attribution merge)
|
|
15
|
+
export {
|
|
16
|
+
FrakContextManager,
|
|
17
|
+
type MergeAttributionInput,
|
|
18
|
+
mergeAttribution,
|
|
19
|
+
} from "./context";
|
|
13
20
|
// Types
|
|
14
21
|
export type {
|
|
15
22
|
AttributionDefaults,
|
|
@@ -87,7 +94,7 @@ export type {
|
|
|
87
94
|
UtmParams,
|
|
88
95
|
WalletStatusReturnType,
|
|
89
96
|
} from "./types";
|
|
90
|
-
|
|
97
|
+
|
|
91
98
|
// Utils
|
|
92
99
|
export {
|
|
93
100
|
type AppSpecificSsoMetadata,
|
|
@@ -97,30 +104,18 @@ export {
|
|
|
97
104
|
type CompressedSsoData,
|
|
98
105
|
clearAllCache,
|
|
99
106
|
compressJsonToB64,
|
|
100
|
-
createIframe,
|
|
101
|
-
DEEP_LINK_SCHEME,
|
|
102
107
|
type DeepLinkFallbackOptions,
|
|
103
108
|
decompressJsonFromB64,
|
|
104
|
-
FrakContextManager,
|
|
105
109
|
type FullSsoParams,
|
|
106
110
|
findIframeInOpener,
|
|
107
111
|
formatAmount,
|
|
108
112
|
generateSsoUrl,
|
|
109
|
-
getBackendUrl,
|
|
110
|
-
getCache,
|
|
111
|
-
getClientId,
|
|
112
113
|
getCurrencyAmountKey,
|
|
113
114
|
getSupportedCurrency,
|
|
114
|
-
getSupportedLocale,
|
|
115
|
-
isChromiumAndroid,
|
|
116
|
-
isFrakDeepLink,
|
|
117
115
|
isInAppBrowser,
|
|
118
116
|
isIOS,
|
|
119
|
-
|
|
120
|
-
mergeAttribution,
|
|
117
|
+
isMobile,
|
|
121
118
|
redirectToExternalBrowser,
|
|
122
|
-
sdkConfigStore,
|
|
123
|
-
toAndroidIntentUrl,
|
|
124
119
|
trackEvent,
|
|
125
120
|
triggerDeepLinkWithFallback,
|
|
126
121
|
withCache,
|
|
@@ -129,4 +124,3 @@ export type {
|
|
|
129
124
|
SdkEventMap,
|
|
130
125
|
SdkHandshakeFailureReason,
|
|
131
126
|
} from "./utils/analytics";
|
|
132
|
-
export { computeLegacyProductId } from "./utils/computeLegacyProductId";
|
package/src/stubs/rrweb.ts
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Stub for rrweb. The
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
2
|
+
* Stub for rrweb. The IIFE/CDN bundles inline every dependency
|
|
3
|
+
* (alwaysBundle catch-all), which would also pull in rrweb via the dynamic
|
|
4
|
+
* `replay` chunk loaded by @openpanel/web. Session replay is disabled in our
|
|
5
|
+
* SDK, so we alias rrweb to a noop record() to keep the CDN bundle small.
|
|
6
|
+
*
|
|
7
|
+
* The NPM ESM/CJS builds don't need this alias: @openpanel/web 1.4.1+ loads
|
|
8
|
+
* rrweb through a dynamic `import("./replay-…")`, so consumers' bundlers can
|
|
9
|
+
* tree-shake / code-split it on their own.
|
|
6
10
|
*/
|
|
7
11
|
export function record() {
|
|
8
12
|
return () => {};
|
package/src/types/client.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DEEP_LINK_SCHEME } from "
|
|
1
|
+
import { DEEP_LINK_SCHEME } from "../../constants";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Options for deep link with fallback
|
|
@@ -24,7 +24,7 @@ export function isChromiumAndroid(): boolean {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
|
-
* Convert a
|
|
27
|
+
* Convert a Frak deep link to an Android intent:// URL.
|
|
28
28
|
*
|
|
29
29
|
* Intent URLs let Chromium browsers open the app directly without
|
|
30
30
|
* showing the "Continue to app?" confirmation bar.
|
|
@@ -35,12 +35,17 @@ export function isChromiumAndroid(): boolean {
|
|
|
35
35
|
* Without `package`, Chrome simply does nothing when the app is
|
|
36
36
|
* missing, allowing the fallback mechanism to fire correctly.
|
|
37
37
|
*
|
|
38
|
-
*
|
|
38
|
+
* The scheme is derived from `DEEP_LINK_SCHEME` so the dev variant
|
|
39
|
+
* (`frakwallet-dev://`) routes to the dev app shell, not prod.
|
|
40
|
+
*
|
|
41
|
+
* Format: intent://path#Intent;scheme=<scheme>;end
|
|
39
42
|
*/
|
|
43
|
+
const DEEP_LINK_SCHEME_NAME = DEEP_LINK_SCHEME.replace("://", "");
|
|
44
|
+
|
|
40
45
|
export function toAndroidIntentUrl(deepLink: string): string {
|
|
41
|
-
// Extract everything after "frakwallet://"
|
|
46
|
+
// Extract everything after the scheme (e.g. "frakwallet://" or "frakwallet-dev://")
|
|
42
47
|
const path = deepLink.slice(DEEP_LINK_SCHEME.length);
|
|
43
|
-
return `intent://${path}#Intent;scheme
|
|
48
|
+
return `intent://${path}#Intent;scheme=${DEEP_LINK_SCHEME_NAME};end`;
|
|
44
49
|
}
|
|
45
50
|
|
|
46
51
|
/**
|
|
@@ -16,6 +16,19 @@ function checkIsIOS(): boolean {
|
|
|
16
16
|
*/
|
|
17
17
|
export const isIOS: boolean = checkIsIOS();
|
|
18
18
|
|
|
19
|
+
/**
|
|
20
|
+
* Check if the current device is a mobile device (iOS, iPadOS, Android,
|
|
21
|
+
* webOS, BlackBerry, IEMobile, Opera Mini). Reuses {@link isIOS} so the
|
|
22
|
+
* iPadOS-13+ Macintosh heuristic stays in one place.
|
|
23
|
+
*/
|
|
24
|
+
export function isMobile(): boolean {
|
|
25
|
+
if (typeof navigator === "undefined") return false;
|
|
26
|
+
if (isIOS) return true;
|
|
27
|
+
return /Android|webOS|BlackBerry|IEMobile|Opera Mini/i.test(
|
|
28
|
+
navigator.userAgent
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
19
32
|
/**
|
|
20
33
|
* Check if the current browser is a social media in-app browser
|
|
21
34
|
* (Instagram, Facebook WebView).
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export {
|
|
2
|
+
type DeepLinkFallbackOptions,
|
|
3
|
+
isChromiumAndroid,
|
|
4
|
+
isFrakDeepLink,
|
|
5
|
+
toAndroidIntentUrl,
|
|
6
|
+
triggerDeepLinkWithFallback,
|
|
7
|
+
} from "./deepLinkWithFallback";
|
|
8
|
+
export {
|
|
9
|
+
isInAppBrowser,
|
|
10
|
+
isIOS,
|
|
11
|
+
isMobile,
|
|
12
|
+
redirectToExternalBrowser,
|
|
13
|
+
} from "./inAppBrowser";
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Tests currency formatting with proper locale support
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { describe, expect, it } from "
|
|
6
|
+
import { describe, expect, it } from "../../../tests/vitest-fixtures";
|
|
7
7
|
import { formatAmount } from "./formatAmount";
|
|
8
8
|
|
|
9
9
|
describe("formatAmount", () => {
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
* Tests currency amount key generation
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { describe, expect, it } from "
|
|
7
|
-
import type { Currency } from "
|
|
6
|
+
import { describe, expect, it } from "../../../tests/vitest-fixtures";
|
|
7
|
+
import type { Currency } from "../../types";
|
|
8
8
|
import { getCurrencyAmountKey } from "./getCurrencyAmountKey";
|
|
9
9
|
|
|
10
10
|
describe("getCurrencyAmountKey", () => {
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
* Tests currency validation and fallback behavior
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { describe, expect, it } from "
|
|
7
|
-
import type { Currency } from "
|
|
6
|
+
import { describe, expect, it } from "../../../tests/vitest-fixtures";
|
|
7
|
+
import type { Currency } from "../../types";
|
|
8
8
|
import { getSupportedCurrency } from "./getSupportedCurrency";
|
|
9
9
|
|
|
10
10
|
describe("getSupportedCurrency", () => {
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
* Tests locale resolution from currency
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { describe, expect, it } from "
|
|
7
|
-
import { locales } from "
|
|
8
|
-
import type { Currency } from "
|
|
6
|
+
import { describe, expect, it } from "../../../tests/vitest-fixtures";
|
|
7
|
+
import { locales } from "../../constants/locales";
|
|
8
|
+
import type { Currency } from "../../types";
|
|
9
9
|
import { getSupportedLocale } from "./getSupportedLocale";
|
|
10
10
|
|
|
11
11
|
describe("getSupportedLocale", () => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type LocalesKey, locales } from "
|
|
2
|
-
import type { Currency } from "
|
|
1
|
+
import { type LocalesKey, locales } from "../../constants/locales";
|
|
2
|
+
import type { Currency } from "../../types";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Get the supported locale for a given currency
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { vi } from "vitest";
|
|
2
2
|
|
|
3
|
-
vi.mock("
|
|
3
|
+
vi.mock("../../config/clientId", () => ({
|
|
4
4
|
getClientId: vi.fn(() => "mock-client-id-for-test"),
|
|
5
5
|
}));
|
|
6
6
|
|
|
@@ -15,8 +15,8 @@ import {
|
|
|
15
15
|
describe,
|
|
16
16
|
expect,
|
|
17
17
|
it,
|
|
18
|
-
} from "
|
|
19
|
-
import type { FrakWalletSdkConfig } from "
|
|
18
|
+
} from "../../../tests/vitest-fixtures";
|
|
19
|
+
import type { FrakWalletSdkConfig } from "../../types";
|
|
20
20
|
import {
|
|
21
21
|
baseIframeProps,
|
|
22
22
|
changeIframeVisibility,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { getBackendUrl } from "../../config/backendUrl";
|
|
2
|
+
import { getClientId } from "../../config/clientId";
|
|
3
|
+
import type { FrakWalletSdkConfig } from "../../types";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Base props for the iframe
|
package/src/utils/index.ts
CHANGED
|
@@ -1,42 +1,49 @@
|
|
|
1
|
+
// Generic, framework-agnostic utilities. Stateful concerns (config store,
|
|
2
|
+
// client identifiers) live in `src/config/`; URL/binary codecs for the
|
|
3
|
+
// referral context live in `src/context/`; SSO URL listener belongs to the
|
|
4
|
+
// iframe client lifecycle in `src/clients/`. Keep this surface narrow.
|
|
1
5
|
export { Deferred } from "@frak-labs/frame-connector";
|
|
6
|
+
|
|
7
|
+
// Analytics
|
|
2
8
|
export { trackEvent } from "./analytics";
|
|
3
|
-
|
|
4
|
-
export { clearAllCache, getCache, withCache } from "./cache";
|
|
5
|
-
export { getClientId } from "./clientId";
|
|
6
|
-
export { base64urlDecode, base64urlEncode } from "./compression/b64";
|
|
7
|
-
export { compressJsonToB64 } from "./compression/compress";
|
|
8
|
-
export { decompressJsonFromB64 } from "./compression/decompress";
|
|
9
|
-
export { DEEP_LINK_SCHEME } from "./constants";
|
|
9
|
+
// Browser / deep linking
|
|
10
10
|
export {
|
|
11
11
|
type DeepLinkFallbackOptions,
|
|
12
12
|
isChromiumAndroid,
|
|
13
13
|
isFrakDeepLink,
|
|
14
14
|
toAndroidIntentUrl,
|
|
15
15
|
triggerDeepLinkWithFallback,
|
|
16
|
-
} from "./deepLinkWithFallback";
|
|
17
|
-
export { FrakContextManager } from "./FrakContext";
|
|
18
|
-
export { formatAmount } from "./formatAmount";
|
|
19
|
-
export { getCurrencyAmountKey } from "./getCurrencyAmountKey";
|
|
20
|
-
export { getSupportedCurrency } from "./getSupportedCurrency";
|
|
21
|
-
export { getSupportedLocale } from "./getSupportedLocale";
|
|
22
|
-
export {
|
|
23
|
-
baseIframeProps,
|
|
24
|
-
createIframe,
|
|
25
|
-
findIframeInOpener,
|
|
26
|
-
} from "./iframeHelper";
|
|
16
|
+
} from "./browser/deepLinkWithFallback";
|
|
27
17
|
export {
|
|
28
18
|
isInAppBrowser,
|
|
29
19
|
isIOS,
|
|
20
|
+
isMobile,
|
|
30
21
|
redirectToExternalBrowser,
|
|
31
|
-
} from "./inAppBrowser";
|
|
22
|
+
} from "./browser/inAppBrowser";
|
|
23
|
+
// Cache
|
|
24
|
+
export { clearAllCache, getCache, withCache } from "./cache";
|
|
25
|
+
// Compression / encoding
|
|
26
|
+
export { base64urlDecode, base64urlEncode } from "./compression/b64";
|
|
27
|
+
export { compressJsonToB64 } from "./compression/compress";
|
|
28
|
+
export { decompressJsonFromB64 } from "./compression/decompress";
|
|
29
|
+
|
|
30
|
+
// Formatting / i18n
|
|
31
|
+
export { formatAmount } from "./format/formatAmount";
|
|
32
|
+
export { getCurrencyAmountKey } from "./format/getCurrencyAmountKey";
|
|
33
|
+
export { getSupportedCurrency } from "./format/getSupportedCurrency";
|
|
34
|
+
export { getSupportedLocale } from "./format/getSupportedLocale";
|
|
35
|
+
|
|
36
|
+
// Iframe DOM helpers
|
|
32
37
|
export {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
38
|
+
baseIframeProps,
|
|
39
|
+
createIframe,
|
|
40
|
+
findIframeInOpener,
|
|
41
|
+
} from "./iframe/iframeHelper";
|
|
42
|
+
|
|
43
|
+
// SSO URL builder
|
|
37
44
|
export {
|
|
38
45
|
type AppSpecificSsoMetadata,
|
|
39
46
|
type CompressedSsoData,
|
|
40
47
|
type FullSsoParams,
|
|
41
48
|
generateSsoUrl,
|
|
42
|
-
} from "./sso";
|
|
49
|
+
} from "./sso/sso";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Hex } from "viem";
|
|
2
|
-
import type { PrepareSsoParamsType, SsoMetadata } from "
|
|
3
|
-
import { compressJsonToB64 } from "
|
|
2
|
+
import type { PrepareSsoParamsType, SsoMetadata } from "../../types";
|
|
3
|
+
import { compressJsonToB64 } from "../compression/compress";
|
|
4
4
|
|
|
5
5
|
export type AppSpecificSsoMetadata = SsoMetadata & {
|
|
6
6
|
name?: string;
|