@frak-labs/core-sdk 0.1.1 → 0.2.0-beta.7898df5b
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 +58 -0
- package/cdn/bundle.js +14 -0
- 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 -6
- package/dist/bundle.d.ts +4 -6
- package/dist/bundle.js +1 -1
- package/dist/computeLegacyProductId-CCAZvLa5.d.cts +537 -0
- package/dist/computeLegacyProductId-b5cUWdAm.d.ts +537 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +3 -4
- package/dist/index.d.ts +3 -4
- package/dist/index.js +1 -1
- package/dist/{openSso-D--Airj6.d.cts → openSso-B0g7-807.d.cts} +173 -136
- package/dist/{openSso-DsKJ4y0j.d.ts → openSso-CMzwvaCa.d.ts} +173 -136
- package/dist/setupClient-BICl5fdX.js +13 -0
- package/dist/setupClient-nl8Dhh4V.cjs +13 -0
- package/dist/siweAuthenticate-BWmI2_TN.cjs +1 -0
- package/dist/{index-d8xS4ryI.d.ts → siweAuthenticate-CVigMOxz.d.cts} +113 -92
- package/dist/{index-C6FxkWPC.d.cts → siweAuthenticate-CnCZ7mok.d.ts} +113 -92
- package/dist/siweAuthenticate-zczqxm0a.js +1 -0
- package/dist/trackEvent-CeLFVzZn.js +1 -0
- package/dist/trackEvent-Ew5r5zfI.cjs +1 -0
- package/package.json +11 -22
- package/src/actions/displayEmbeddedWallet.ts +1 -0
- package/src/actions/displayModal.test.ts +12 -11
- package/src/actions/displayModal.ts +7 -18
- package/src/actions/ensureIdentity.ts +68 -0
- package/src/actions/{getProductInformation.test.ts → getMerchantInformation.test.ts} +33 -50
- package/src/actions/getMerchantInformation.ts +16 -0
- package/src/actions/index.ts +3 -2
- package/src/actions/openSso.ts +4 -2
- package/src/actions/referral/processReferral.test.ts +117 -242
- package/src/actions/referral/processReferral.ts +134 -204
- package/src/actions/referral/referralInteraction.test.ts +4 -12
- package/src/actions/referral/referralInteraction.ts +3 -13
- package/src/actions/sendInteraction.ts +46 -22
- package/src/actions/trackPurchaseStatus.test.ts +354 -141
- package/src/actions/trackPurchaseStatus.ts +48 -11
- package/src/actions/watchWalletStatus.ts +2 -3
- package/src/actions/wrapper/modalBuilder.test.ts +0 -14
- package/src/actions/wrapper/modalBuilder.ts +3 -12
- package/src/bundle.ts +0 -1
- package/src/clients/createIFrameFrakClient.ts +10 -5
- package/src/clients/transports/iframeLifecycleManager.test.ts +163 -4
- package/src/clients/transports/iframeLifecycleManager.ts +172 -33
- package/src/constants/interactionTypes.ts +12 -41
- package/src/index.ts +27 -16
- package/src/types/config.ts +6 -0
- package/src/types/context.ts +48 -6
- package/src/types/index.ts +15 -11
- package/src/types/lifecycle/client.ts +24 -1
- package/src/types/lifecycle/iframe.ts +6 -0
- package/src/types/rpc/displayModal.ts +2 -4
- package/src/types/rpc/embedded/index.ts +2 -2
- package/src/types/rpc/interaction.ts +31 -39
- package/src/types/rpc/merchantInformation.ts +77 -0
- package/src/types/rpc/modal/index.ts +0 -4
- package/src/types/rpc/modal/login.ts +5 -1
- package/src/types/rpc/walletStatus.ts +1 -7
- package/src/types/rpc.ts +22 -30
- package/src/types/tracking.ts +31 -0
- package/src/utils/FrakContext.test.ts +270 -186
- package/src/utils/FrakContext.ts +78 -56
- package/src/utils/backendUrl.test.ts +83 -0
- package/src/utils/backendUrl.ts +62 -0
- package/src/utils/clientId.test.ts +41 -0
- package/src/utils/clientId.ts +43 -0
- package/src/utils/compression/compress.test.ts +1 -1
- package/src/utils/compression/compress.ts +2 -2
- package/src/utils/compression/decompress.test.ts +8 -4
- package/src/utils/compression/decompress.ts +2 -2
- package/src/utils/{computeProductId.ts → computeLegacyProductId.ts} +2 -2
- package/src/utils/constants.ts +5 -0
- package/src/utils/deepLinkWithFallback.test.ts +243 -0
- package/src/utils/deepLinkWithFallback.ts +103 -0
- package/src/utils/formatAmount.ts +6 -0
- package/src/utils/iframeHelper.test.ts +18 -5
- package/src/utils/iframeHelper.ts +10 -3
- package/src/utils/index.ts +16 -1
- package/src/utils/merchantId.test.ts +653 -0
- package/src/utils/merchantId.ts +143 -0
- package/src/utils/sso.ts +18 -11
- package/src/utils/trackEvent.test.ts +23 -5
- package/src/utils/trackEvent.ts +13 -0
- package/cdn/bundle.iife.js +0 -14
- package/dist/actions-B5j-i1p0.cjs +0 -1
- package/dist/actions-q090Z0oR.js +0 -1
- package/dist/index-7OZ39x1U.d.ts +0 -195
- package/dist/index-CRsQWnTs.d.cts +0 -351
- package/dist/index-Ck1hudEi.d.ts +0 -351
- package/dist/index-zDq-VlKx.d.cts +0 -195
- package/dist/interaction-DMJ3ZfaF.d.cts +0 -45
- package/dist/interaction-KX1h9a7V.d.ts +0 -45
- package/dist/interactions-DnfM3oe0.js +0 -1
- package/dist/interactions-EIXhNLf6.cjs +0 -1
- package/dist/interactions.cjs +0 -1
- package/dist/interactions.d.cts +0 -2
- package/dist/interactions.d.ts +0 -2
- package/dist/interactions.js +0 -1
- package/dist/productTypes-BUkXJKZ7.cjs +0 -1
- package/dist/productTypes-CGb1MmBF.js +0 -1
- package/dist/src-1LQ4eLq5.js +0 -13
- package/dist/src-hW71KjPN.cjs +0 -13
- package/dist/trackEvent-CHnYa85W.js +0 -1
- package/dist/trackEvent-GuQm_1Nm.cjs +0 -1
- package/src/actions/getProductInformation.ts +0 -14
- package/src/actions/openSso.test.ts +0 -407
- package/src/actions/sendInteraction.test.ts +0 -219
- package/src/constants/interactionTypes.test.ts +0 -128
- package/src/constants/productTypes.test.ts +0 -130
- package/src/constants/productTypes.ts +0 -33
- package/src/interactions/index.ts +0 -5
- package/src/interactions/pressEncoder.test.ts +0 -215
- package/src/interactions/pressEncoder.ts +0 -53
- package/src/interactions/purchaseEncoder.test.ts +0 -291
- package/src/interactions/purchaseEncoder.ts +0 -99
- package/src/interactions/referralEncoder.test.ts +0 -170
- package/src/interactions/referralEncoder.ts +0 -47
- package/src/interactions/retailEncoder.test.ts +0 -107
- package/src/interactions/retailEncoder.ts +0 -37
- package/src/interactions/webshopEncoder.test.ts +0 -56
- package/src/interactions/webshopEncoder.ts +0 -30
- package/src/types/rpc/modal/openSession.ts +0 -25
- package/src/types/rpc/productInformation.ts +0 -59
- package/src/utils/computeProductId.test.ts +0 -80
- package/src/utils/sso.test.ts +0 -361
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { r as SendInteractionReturnType, t as PreparedInteraction } from "./interaction-KX1h9a7V.js";
|
|
2
1
|
import { Address, Hex } from "viem";
|
|
3
2
|
import { LifecycleMessage, RpcClient } from "@frak-labs/frame-connector";
|
|
4
3
|
import { OpenPanel } from "@openpanel/web";
|
|
@@ -33,6 +32,12 @@ type FrakWalletSdkConfig = {
|
|
|
33
32
|
* Your application name (will be displayed in a few modals and in SSO)
|
|
34
33
|
*/
|
|
35
34
|
name: string;
|
|
35
|
+
/**
|
|
36
|
+
* Your merchant ID from the Frak dashboard (UUID format)
|
|
37
|
+
* Used for referral tracking and analytics
|
|
38
|
+
* If not provided, will be auto-fetched from the backend using your domain
|
|
39
|
+
*/
|
|
40
|
+
merchantId?: string;
|
|
36
41
|
/**
|
|
37
42
|
* Language to display in the modal
|
|
38
43
|
* If undefined, will default to the browser language
|
|
@@ -118,7 +123,7 @@ type LocalizedI18nConfig = `${string}.css` | {
|
|
|
118
123
|
* Event related to the iframe lifecycle
|
|
119
124
|
* @ignore
|
|
120
125
|
*/
|
|
121
|
-
type ClientLifecycleEvent = CustomCssEvent | CustomI18nEvent | RestoreBackupEvent | HearbeatEvent | HandshakeResponse | SsoRedirectCompleteEvent;
|
|
126
|
+
type ClientLifecycleEvent = CustomCssEvent | CustomI18nEvent | RestoreBackupEvent | HearbeatEvent | HandshakeResponse | SsoRedirectCompleteEvent | DeepLinkFailedEvent;
|
|
122
127
|
type CustomCssEvent = {
|
|
123
128
|
clientLifecycle: "modal-css";
|
|
124
129
|
data: {
|
|
@@ -146,6 +151,23 @@ type HandshakeResponse = {
|
|
|
146
151
|
data: {
|
|
147
152
|
token: string;
|
|
148
153
|
currentUrl: string;
|
|
154
|
+
/**
|
|
155
|
+
* Pending merge token extracted from URL (?fmt= parameter)
|
|
156
|
+
* When present, listener should execute identity merge in background
|
|
157
|
+
* URL is cleaned after handshake response is sent
|
|
158
|
+
*/
|
|
159
|
+
pendingMergeToken?: string;
|
|
160
|
+
/**
|
|
161
|
+
* Client ID for identity tracking (belt & suspenders fallback)
|
|
162
|
+
* Primary delivery is via iframe URL query param; handshake is backup for SSR
|
|
163
|
+
*/
|
|
164
|
+
clientId?: string;
|
|
165
|
+
/**
|
|
166
|
+
* Explicit domain from SDK config (FrakWalletSdkConfig.domain)
|
|
167
|
+
* When present, listener should prefer this over URL-derived domain
|
|
168
|
+
* for merchant resolution (handles proxied/tunneled environments)
|
|
169
|
+
*/
|
|
170
|
+
configDomain?: string;
|
|
149
171
|
};
|
|
150
172
|
};
|
|
151
173
|
type SsoRedirectCompleteEvent = {
|
|
@@ -154,6 +176,12 @@ type SsoRedirectCompleteEvent = {
|
|
|
154
176
|
compressed: string;
|
|
155
177
|
};
|
|
156
178
|
};
|
|
179
|
+
type DeepLinkFailedEvent = {
|
|
180
|
+
clientLifecycle: "deep-link-failed";
|
|
181
|
+
data: {
|
|
182
|
+
originalUrl: string;
|
|
183
|
+
};
|
|
184
|
+
};
|
|
157
185
|
//#endregion
|
|
158
186
|
//#region src/types/lifecycle/iframe.d.ts
|
|
159
187
|
/**
|
|
@@ -184,48 +212,27 @@ type RedirectRequestEvent = {
|
|
|
184
212
|
* If it contain a query param `u`, the client need will suffix the current url to the base url
|
|
185
213
|
*/
|
|
186
214
|
baseRedirectUrl: string;
|
|
215
|
+
/**
|
|
216
|
+
* Optional merge token for anonymous identity merging
|
|
217
|
+
* When provided, appended as ?fmt= query parameter to the final redirect URL
|
|
218
|
+
* Used when redirecting out of social browsers to preserve identity across contexts
|
|
219
|
+
*/
|
|
220
|
+
mergeToken?: string;
|
|
187
221
|
};
|
|
188
222
|
};
|
|
189
223
|
//#endregion
|
|
190
224
|
//#region src/constants/interactionTypes.d.ts
|
|
191
225
|
/**
|
|
192
|
-
* The
|
|
193
|
-
*
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
*
|
|
226
|
+
* The supported interaction type keys
|
|
227
|
+
*
|
|
228
|
+
* - `referral` - User arrived via a referral link
|
|
229
|
+
* - `create_referral_link` - User created/shared a referral link
|
|
230
|
+
* - `purchase` - User completed a purchase
|
|
231
|
+
* - `custom.${string}` - Custom interaction type defined per campaign
|
|
232
|
+
*
|
|
198
233
|
* @inline
|
|
199
234
|
*/
|
|
200
|
-
type
|
|
201
|
-
/**
|
|
202
|
-
* Each interactions types according to the product types
|
|
203
|
-
*/
|
|
204
|
-
declare const interactionTypes: {
|
|
205
|
-
readonly press: {
|
|
206
|
-
readonly openArticle: "0xc0a24ffb";
|
|
207
|
-
readonly readArticle: "0xd5bd0fbe";
|
|
208
|
-
};
|
|
209
|
-
readonly dapp: {
|
|
210
|
-
readonly proofVerifiableStorageUpdate: "0x2ab2aeef";
|
|
211
|
-
readonly callableVerifiableStorageUpdate: "0xa07da986";
|
|
212
|
-
};
|
|
213
|
-
readonly webshop: {
|
|
214
|
-
readonly open: "0xb311798f";
|
|
215
|
-
};
|
|
216
|
-
readonly referral: {
|
|
217
|
-
readonly referred: "0x010cc3b9";
|
|
218
|
-
readonly createLink: "0xb2c0f17c";
|
|
219
|
-
};
|
|
220
|
-
readonly purchase: {
|
|
221
|
-
readonly started: "0xd87e90c3";
|
|
222
|
-
readonly completed: "0x8403aeb4";
|
|
223
|
-
readonly unsafeCompleted: "0x4d5b14e0";
|
|
224
|
-
};
|
|
225
|
-
readonly retail: {
|
|
226
|
-
readonly customerMeeting: "0x74489004";
|
|
227
|
-
};
|
|
228
|
-
};
|
|
235
|
+
type InteractionTypeKey = "referral" | "create_referral_link" | "purchase" | `custom.${string}`;
|
|
229
236
|
//#endregion
|
|
230
237
|
//#region src/types/rpc/modal/generic.d.ts
|
|
231
238
|
/**
|
|
@@ -404,28 +411,12 @@ type LoginWithoutSso = {
|
|
|
404
411
|
*/
|
|
405
412
|
type LoginModalStepType = GenericModalStepType<"login", LoginWithSso | LoginWithoutSso, {
|
|
406
413
|
wallet: Address;
|
|
414
|
+
webauthnProof?: {
|
|
415
|
+
challenge: Hex;
|
|
416
|
+
authenticatorResponse: string;
|
|
417
|
+
};
|
|
407
418
|
}>;
|
|
408
419
|
//#endregion
|
|
409
|
-
//#region src/types/rpc/modal/openSession.d.ts
|
|
410
|
-
/**
|
|
411
|
-
* Return type of the open session modal step
|
|
412
|
-
* @inline
|
|
413
|
-
* @ignore
|
|
414
|
-
*/
|
|
415
|
-
type OpenInteractionSessionReturnType = {
|
|
416
|
-
startTimestamp: number;
|
|
417
|
-
endTimestamp: number;
|
|
418
|
-
};
|
|
419
|
-
/**
|
|
420
|
-
* The open interaction session step for a Modal
|
|
421
|
-
*
|
|
422
|
-
* **Input**: None
|
|
423
|
-
* **Output**: The interactions session period (start and end timestamp)
|
|
424
|
-
*
|
|
425
|
-
* @group Modal Display
|
|
426
|
-
*/
|
|
427
|
-
type OpenInteractionSessionModalStepType = GenericModalStepType<"openSession", object, OpenInteractionSessionReturnType>;
|
|
428
|
-
//#endregion
|
|
429
420
|
//#region src/types/rpc/modal/siweAuthenticate.d.ts
|
|
430
421
|
/**
|
|
431
422
|
* Parameters used send a SIWE rpc request
|
|
@@ -487,7 +478,7 @@ type SendTransactionModalStepType = GenericModalStepType<"sendTransaction", {
|
|
|
487
478
|
* Generic type of steps we will display in the modal to the end user
|
|
488
479
|
* @group Modal Display
|
|
489
480
|
*/
|
|
490
|
-
type ModalStepTypes = LoginModalStepType | SiweAuthenticateModalStepType | SendTransactionModalStepType |
|
|
481
|
+
type ModalStepTypes = LoginModalStepType | SiweAuthenticateModalStepType | SendTransactionModalStepType | FinalModalStepType;
|
|
491
482
|
/**
|
|
492
483
|
* Type for the result of a modal request
|
|
493
484
|
* Just the `returns` type of each `ModalStepTypes`
|
|
@@ -518,7 +509,7 @@ type ModalRpcMetadata = {
|
|
|
518
509
|
title?: string;
|
|
519
510
|
icon?: string;
|
|
520
511
|
};
|
|
521
|
-
targetInteraction?:
|
|
512
|
+
targetInteraction?: InteractionTypeKey;
|
|
522
513
|
/**
|
|
523
514
|
* Some i18n override for the displayed modal (i.e. update the displayed text only for this modal)
|
|
524
515
|
*/
|
|
@@ -658,7 +649,7 @@ type DisplayEmbeddedWalletParamsType = {
|
|
|
658
649
|
/**
|
|
659
650
|
* The target interaction behind this modal
|
|
660
651
|
*/
|
|
661
|
-
targetInteraction?:
|
|
652
|
+
targetInteraction?: InteractionTypeKey;
|
|
662
653
|
/**
|
|
663
654
|
* The position of the component
|
|
664
655
|
*/
|
|
@@ -678,29 +669,37 @@ type DisplayEmbeddedWalletResultType = {
|
|
|
678
669
|
wallet: Address;
|
|
679
670
|
};
|
|
680
671
|
//#endregion
|
|
681
|
-
//#region src/
|
|
682
|
-
/**
|
|
683
|
-
* The keys for each product types
|
|
684
|
-
* @inline
|
|
685
|
-
*/
|
|
686
|
-
type ProductTypesKey = keyof typeof productTypes;
|
|
672
|
+
//#region src/types/rpc/interaction.d.ts
|
|
687
673
|
/**
|
|
688
|
-
*
|
|
674
|
+
* Parameters for sending interactions via RPC
|
|
675
|
+
*
|
|
676
|
+
* Note: merchantId and clientId come from WalletRpcContext
|
|
677
|
+
* and are NOT included in the params - they are resolved by the listener
|
|
678
|
+
*
|
|
679
|
+
* @group RPC Schema
|
|
689
680
|
*/
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
681
|
+
type SendInteractionParamsType = {
|
|
682
|
+
type: "arrival"; /** @deprecated V1 legacy — use referrerClientId for v2 */
|
|
683
|
+
referrerWallet?: Address;
|
|
684
|
+
referrerClientId?: string;
|
|
685
|
+
referrerMerchantId?: string; /** Epoch seconds timestamp from the referral link creation */
|
|
686
|
+
referralTimestamp?: number;
|
|
687
|
+
landingUrl?: string;
|
|
688
|
+
utmSource?: string;
|
|
689
|
+
utmMedium?: string;
|
|
690
|
+
utmCampaign?: string;
|
|
691
|
+
utmTerm?: string;
|
|
692
|
+
utmContent?: string;
|
|
693
|
+
} | {
|
|
694
|
+
type: "sharing";
|
|
695
|
+
} | {
|
|
696
|
+
type: "custom";
|
|
697
|
+
customType: string;
|
|
698
|
+
data?: Record<string, unknown>;
|
|
699
|
+
idempotencyKey?: string;
|
|
697
700
|
};
|
|
698
|
-
/**
|
|
699
|
-
* Bitmask for each product types
|
|
700
|
-
*/
|
|
701
|
-
declare const productTypesMask: Record<ProductTypesKey, bigint>;
|
|
702
701
|
//#endregion
|
|
703
|
-
//#region src/types/rpc/
|
|
702
|
+
//#region src/types/rpc/merchantInformation.d.ts
|
|
704
703
|
/**
|
|
705
704
|
* The type for the amount of tokens
|
|
706
705
|
*/
|
|
@@ -711,48 +710,62 @@ type TokenAmountType = {
|
|
|
711
710
|
gbpAmount: number;
|
|
712
711
|
};
|
|
713
712
|
/**
|
|
714
|
-
*
|
|
713
|
+
* A tier definition for tiered rewards
|
|
714
|
+
*/
|
|
715
|
+
type RewardTier = {
|
|
716
|
+
minValue: number;
|
|
717
|
+
maxValue?: number;
|
|
718
|
+
amount: TokenAmountType;
|
|
719
|
+
};
|
|
720
|
+
/**
|
|
721
|
+
* Estimated reward amount — discriminated union by payout type
|
|
722
|
+
*
|
|
723
|
+
* - `fixed`: A known token amount (with fiat equivalents)
|
|
724
|
+
* - `percentage`: A percent of a purchase field (e.g. 5% of purchase_amount), with optional min/max caps
|
|
725
|
+
* - `tiered`: Amount depends on a field value matching tier brackets
|
|
726
|
+
*/
|
|
727
|
+
type EstimatedReward = {
|
|
728
|
+
payoutType: "fixed";
|
|
729
|
+
amount: TokenAmountType;
|
|
730
|
+
} | {
|
|
731
|
+
payoutType: "percentage";
|
|
732
|
+
percent: number;
|
|
733
|
+
percentOf: string;
|
|
734
|
+
maxAmount?: TokenAmountType;
|
|
735
|
+
minAmount?: TokenAmountType;
|
|
736
|
+
} | {
|
|
737
|
+
payoutType: "tiered";
|
|
738
|
+
tierField: string;
|
|
739
|
+
tiers: RewardTier[];
|
|
740
|
+
};
|
|
741
|
+
/**
|
|
742
|
+
* Response of the `frak_getMerchantInformation` RPC method
|
|
715
743
|
* @group RPC Schema
|
|
716
744
|
*/
|
|
717
|
-
type
|
|
745
|
+
type GetMerchantInformationReturnType = {
|
|
718
746
|
/**
|
|
719
|
-
* Current
|
|
747
|
+
* Current merchant id
|
|
720
748
|
*/
|
|
721
|
-
id:
|
|
749
|
+
id: string;
|
|
722
750
|
/**
|
|
723
751
|
* Some metadata
|
|
724
752
|
*/
|
|
725
753
|
onChainMetadata: {
|
|
726
754
|
/**
|
|
727
|
-
* Name of the
|
|
755
|
+
* Name of the merchant on-chain
|
|
728
756
|
*/
|
|
729
757
|
name: string;
|
|
730
758
|
/**
|
|
731
|
-
* Domain of the
|
|
759
|
+
* Domain of the merchant on-chain
|
|
732
760
|
*/
|
|
733
761
|
domain: string;
|
|
734
|
-
/**
|
|
735
|
-
* The supported product types
|
|
736
|
-
*/
|
|
737
|
-
productTypes: ProductTypesKey[];
|
|
738
762
|
};
|
|
739
|
-
/**
|
|
740
|
-
* The max potential reward for the referrer
|
|
741
|
-
*/
|
|
742
|
-
maxReferrer?: TokenAmountType;
|
|
743
|
-
/**
|
|
744
|
-
* The max potential reward for the referee
|
|
745
|
-
*/
|
|
746
|
-
maxReferee?: TokenAmountType;
|
|
747
|
-
/**
|
|
748
|
-
* List of all the potentials reward arround this product
|
|
749
|
-
*/
|
|
750
763
|
rewards: {
|
|
751
|
-
token
|
|
752
|
-
|
|
753
|
-
interactionTypeKey:
|
|
754
|
-
referrer
|
|
755
|
-
referee
|
|
764
|
+
token?: Address;
|
|
765
|
+
campaignId: string;
|
|
766
|
+
interactionTypeKey: InteractionTypeKey;
|
|
767
|
+
referrer?: EstimatedReward;
|
|
768
|
+
referee?: EstimatedReward;
|
|
756
769
|
}[];
|
|
757
770
|
};
|
|
758
771
|
//#endregion
|
|
@@ -770,10 +783,6 @@ type WalletConnected = {
|
|
|
770
783
|
key: "connected";
|
|
771
784
|
wallet: Address;
|
|
772
785
|
interactionToken?: string;
|
|
773
|
-
interactionSession?: {
|
|
774
|
-
startTimestamp: number;
|
|
775
|
-
endTimestamp: number;
|
|
776
|
-
};
|
|
777
786
|
};
|
|
778
787
|
/**
|
|
779
788
|
* @ignore
|
|
@@ -783,7 +792,6 @@ type WalletNotConnected = {
|
|
|
783
792
|
key: "not-connected";
|
|
784
793
|
wallet?: never;
|
|
785
794
|
interactionToken?: never;
|
|
786
|
-
interactionSession?: never;
|
|
787
795
|
};
|
|
788
796
|
//#endregion
|
|
789
797
|
//#region src/types/rpc.d.ts
|
|
@@ -811,19 +819,14 @@ type WalletNotConnected = {
|
|
|
811
819
|
* - Returns: {@link ModalRpcStepsResultType}
|
|
812
820
|
* - Response Type: promise (one-shot)
|
|
813
821
|
*
|
|
814
|
-
* #### frak_sendInteraction
|
|
815
|
-
* - Params: [productId: Hex, interaction: {@link PreparedInteraction}, signature?: Hex]
|
|
816
|
-
* - Returns: {@link SendInteractionReturnType}
|
|
817
|
-
* - Response Type: promise (one-shot)
|
|
818
|
-
*
|
|
819
822
|
* #### frak_sso
|
|
820
823
|
* - Params: [params: {@link OpenSsoParamsType}, name: string, customCss?: string]
|
|
821
824
|
* - Returns: {@link OpenSsoReturnType}
|
|
822
825
|
* - Response Type: promise (one-shot)
|
|
823
826
|
*
|
|
824
|
-
* ####
|
|
827
|
+
* #### frak_getMerchantInformation
|
|
825
828
|
* - Params: None
|
|
826
|
-
* - Returns: {@link
|
|
829
|
+
* - Returns: {@link GetMerchantInformationReturnType}
|
|
827
830
|
* - Response Type: promise (one-shot)
|
|
828
831
|
*
|
|
829
832
|
* #### frak_displayEmbeddedWallet
|
|
@@ -850,15 +853,6 @@ type IFrameRpcSchema = [
|
|
|
850
853
|
Parameters: [requests: ModalRpcStepsInput, metadata: ModalRpcMetadata | undefined, configMetadata: FrakWalletSdkConfig["metadata"]];
|
|
851
854
|
ReturnType: ModalRpcStepsResultType;
|
|
852
855
|
},
|
|
853
|
-
/**
|
|
854
|
-
* Method to transmit a user interaction
|
|
855
|
-
* This is a one-shot request
|
|
856
|
-
*/
|
|
857
|
-
{
|
|
858
|
-
Method: "frak_sendInteraction";
|
|
859
|
-
Parameters: [productId: Hex, interaction: PreparedInteraction, signature?: Hex];
|
|
860
|
-
ReturnType: SendInteractionReturnType;
|
|
861
|
-
},
|
|
862
856
|
/**
|
|
863
857
|
* Method to prepare SSO (generate URL for popup)
|
|
864
858
|
* Returns the SSO URL that should be opened in a popup
|
|
@@ -881,16 +875,16 @@ type IFrameRpcSchema = [
|
|
|
881
875
|
ReturnType: OpenSsoReturnType;
|
|
882
876
|
},
|
|
883
877
|
/**
|
|
884
|
-
* Method to get current
|
|
885
|
-
* - Is
|
|
878
|
+
* Method to get current merchant information
|
|
879
|
+
* - Is merchant registered?
|
|
886
880
|
* - Does it have running campaign?
|
|
887
881
|
* - Estimated reward on actions
|
|
888
882
|
* This is a one-shot request
|
|
889
883
|
*/
|
|
890
884
|
{
|
|
891
|
-
Method: "
|
|
885
|
+
Method: "frak_getMerchantInformation";
|
|
892
886
|
Parameters?: undefined;
|
|
893
|
-
ReturnType:
|
|
887
|
+
ReturnType: GetMerchantInformationReturnType;
|
|
894
888
|
},
|
|
895
889
|
/**
|
|
896
890
|
* Method to show the embedded wallet, with potential customization
|
|
@@ -900,6 +894,19 @@ type IFrameRpcSchema = [
|
|
|
900
894
|
Method: "frak_displayEmbeddedWallet";
|
|
901
895
|
Parameters: [request: DisplayEmbeddedWalletParamsType, metadata: FrakWalletSdkConfig["metadata"]];
|
|
902
896
|
ReturnType: DisplayEmbeddedWalletResultType;
|
|
897
|
+
},
|
|
898
|
+
/**
|
|
899
|
+
* Method to send interactions (arrival, sharing, custom events)
|
|
900
|
+
* Fire-and-forget method - no return value expected
|
|
901
|
+
* merchantId is resolved from context
|
|
902
|
+
* clientId is passed via metadata as safeguard against handshake race condition
|
|
903
|
+
*/
|
|
904
|
+
{
|
|
905
|
+
Method: "frak_sendInteraction";
|
|
906
|
+
Parameters: [interaction: SendInteractionParamsType, metadata?: {
|
|
907
|
+
clientId?: string;
|
|
908
|
+
}];
|
|
909
|
+
ReturnType: undefined;
|
|
903
910
|
}];
|
|
904
911
|
//#endregion
|
|
905
912
|
//#region src/types/transport.d.ts
|
|
@@ -947,15 +954,45 @@ type FrakClient = {
|
|
|
947
954
|
//#endregion
|
|
948
955
|
//#region src/types/context.d.ts
|
|
949
956
|
/**
|
|
950
|
-
*
|
|
957
|
+
* V1 (legacy) Frak Context — contains only the referrer wallet address.
|
|
958
|
+
* Used for backward compatibility with old sharing links.
|
|
959
|
+
* @ignore
|
|
960
|
+
*/
|
|
961
|
+
type FrakContextV1 = {
|
|
962
|
+
/** Referrer wallet address */r: Address;
|
|
963
|
+
};
|
|
964
|
+
/**
|
|
965
|
+
* V2 Frak Context — anonymous-first referral context.
|
|
966
|
+
* Contains the sharer's clientId, merchantId, and link creation timestamp.
|
|
967
|
+
* @ignore
|
|
968
|
+
*/
|
|
969
|
+
type FrakContextV2 = {
|
|
970
|
+
/** Version discriminator */v: 2; /** Sharer's anonymous clientId (UUID from localStorage) */
|
|
971
|
+
c: string; /** Merchant ID (UUID) */
|
|
972
|
+
m: string; /** Link creation timestamp (epoch seconds) */
|
|
973
|
+
t: number;
|
|
974
|
+
};
|
|
975
|
+
/**
|
|
976
|
+
* The current Frak Context — union of all versions.
|
|
951
977
|
*
|
|
952
|
-
*
|
|
978
|
+
* - No `v` field → V1 (legacy wallet address)
|
|
979
|
+
* - `v: 2` → V2 (anonymous clientId-based)
|
|
953
980
|
*
|
|
954
981
|
* @ignore
|
|
955
982
|
*/
|
|
956
|
-
type FrakContext =
|
|
957
|
-
|
|
958
|
-
|
|
983
|
+
type FrakContext = FrakContextV1 | FrakContextV2;
|
|
984
|
+
/**
|
|
985
|
+
* Type guard: check if a context is V1 (legacy wallet address).
|
|
986
|
+
* @param ctx - The Frak context to check
|
|
987
|
+
* @returns True if the context is a V1 context
|
|
988
|
+
*/
|
|
989
|
+
declare function isV1Context(ctx: FrakContext): ctx is FrakContextV1;
|
|
990
|
+
/**
|
|
991
|
+
* Type guard: check if a context is V2 (anonymous clientId-based).
|
|
992
|
+
* @param ctx - The Frak context to check
|
|
993
|
+
* @returns True if the context is a V2 context
|
|
994
|
+
*/
|
|
995
|
+
declare function isV2Context(ctx: FrakContext): ctx is FrakContextV2;
|
|
959
996
|
//#endregion
|
|
960
997
|
//#region src/actions/openSso.d.ts
|
|
961
998
|
declare const ssoPopupFeatures = "menubar=no,status=no,scrollbars=no,fullscreen=no,width=500, height=800";
|
|
@@ -1015,4 +1052,4 @@ declare const ssoPopupName = "frak-sso";
|
|
|
1015
1052
|
*/
|
|
1016
1053
|
declare function openSso(client: FrakClient, args: OpenSsoParamsType): Promise<OpenSsoReturnType>;
|
|
1017
1054
|
//#endregion
|
|
1018
|
-
export {
|
|
1055
|
+
export { SendTransactionModalStepType as A, PrepareSsoReturnType as B, EmbeddedViewActionSharing as C, ModalRpcStepsInput as D, ModalRpcMetadata as E, SiweAuthenticationParams as F, InteractionTypeKey as G, FinalActionType as H, LoginModalStepType as I, Currency as J, IFrameLifecycleEvent as K, OpenSsoParamsType as L, SendTransactionTxType as M, SiweAuthenticateModalStepType as N, ModalRpcStepsResultType as O, SiweAuthenticateReturnType as P, LocalizedI18nConfig as Q, OpenSsoReturnType as R, EmbeddedViewActionReferred as S, DisplayModalParamsType as T, FinalModalStepType as U, SsoMetadata as V, ModalStepMetadata as W, I18nConfig as X, FrakWalletSdkConfig as Y, Language as Z, TokenAmountType as _, FrakContextV1 as a, DisplayEmbeddedWalletResultType as b, isV2Context as c, IFrameTransport as d, IFrameRpcSchema as f, RewardTier as g, GetMerchantInformationReturnType as h, FrakContext as i, SendTransactionReturnType as j, ModalStepTypes as k, FrakClient as l, EstimatedReward as m, ssoPopupFeatures as n, FrakContextV2 as o, WalletStatusReturnType as p, ClientLifecycleEvent as q, ssoPopupName as r, isV1Context as s, openSso as t, FrakLifecycleEvent as u, SendInteractionParamsType as v, LoggedInEmbeddedView as w, LoggedOutEmbeddedView as x, DisplayEmbeddedWalletParamsType as y, PrepareSsoParamsType as z };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import{v as e}from"./trackEvent-CeLFVzZn.js";import{Deferred as t,FrakRpcError as n,RpcErrorCodes as r,createRpcClient as i}from"@frak-labs/frame-connector";import{OpenPanel as a}from"@openpanel/web";const o=`nexus-wallet-backup`,s=`frakwallet://`;function c(){let e=navigator.userAgent;return/Android/i.test(e)&&/Chrome\/\d+/i.test(e)}function l(e){return`intent://${e.slice(13)}#Intent;scheme=frakwallet;end`}function u(e,t){let n=t?.timeout??2500,r=!1,i=()=>{document.hidden&&(r=!0)};document.addEventListener(`visibilitychange`,i);let a=c()&&d(e)?l(e):e;window.location.href=a,setTimeout(()=>{document.removeEventListener(`visibilitychange`,i),r||t?.onFallback?.()},n)}function d(e){return e.startsWith(s)}const f={eur:`fr-FR`,usd:`en-US`,gbp:`en-GB`};function p(e){return e&&e in f?e:`eur`}function m(e){return e?f[e]??f.eur:f.eur}function h(e,t){let n=m(t),r=p(t);return e.toLocaleString(n,{style:`currency`,currency:r,minimumFractionDigits:0,maximumFractionDigits:2})}function g(e){return e?`${e}Amount`:`eurAmount`}const _={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 v({walletBaseUrl:t,config:n}){let r=document.querySelector(`#frak-wallet`);r&&r.remove();let i=document.createElement(`iframe`);i.id=_.id,i.name=_.name,i.allow=_.allow,i.style.zIndex=_.style.zIndex.toString(),y({iframe:i,isVisible:!1});let a=n?.walletUrl??t??`https://wallet.frak.id`,o=e();return i.src=`${a}/listener?clientId=${encodeURIComponent(o)}`,new Promise(e=>{i.addEventListener(`load`,()=>e(i)),document.body.appendChild(i)})}function y({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 b(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 x(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`))}var S=class e{config;iframe;isSetupDone=!1;lastResponse=null;lastRequest=null;constructor(e,t){this.config=e,this.iframe=t,this.lastRequest=null,this.lastResponse=null}setLastResponse(e,t){this.lastResponse={message:e,response:t,timestamp:Date.now()}}setLastRequest(e){this.lastRequest={event:e,timestamp:Date.now()}}updateSetupStatus(e){this.isSetupDone=e}base64Encode(e){try{return btoa(JSON.stringify(e))}catch(e){return console.warn(`Failed to encode debug data`,e),btoa(`Failed to encode data`)}}getIframeStatus(){return this.iframe?{loading:this.iframe.hasAttribute(`loading`),url:this.iframe.src,readyState:this.iframe.contentDocument?.readyState?this.iframe.contentDocument.readyState===`complete`?1:0:-1,contentWindow:!!this.iframe.contentWindow,isConnected:this.iframe.isConnected}:null}getNavigatorInfo(){return navigator?{userAgent:navigator.userAgent,language:navigator.language,onLine:navigator.onLine,screenWidth:window.screen.width,screenHeight:window.screen.height,pixelRatio:window.devicePixelRatio}:null}gatherDebugInfo(e){let t=this.getIframeStatus(),r=this.getNavigatorInfo(),i=`Unknown`;return e instanceof n?i=`FrakRpcError: ${e.code} '${e.message}'`:e instanceof Error?i=e.message:typeof e==`string`&&(i=e),{timestamp:new Date().toISOString(),encodedUrl:btoa(window.location.href),encodedConfig:this.config?this.base64Encode(this.config):`no-config`,navigatorInfo:r?this.base64Encode(r):`no-navigator`,iframeStatus:t?this.base64Encode(t):`not-iframe`,lastRequest:this.lastRequest?this.base64Encode(this.lastRequest):`No Frak request logged`,lastResponse:this.lastResponse?this.base64Encode(this.lastResponse):`No Frak response logged`,clientStatus:this.isSetupDone?`setup`:`not-setup`,error:i}}static empty(){return new e}formatDebugInfo(e){let t=this.gatherDebugInfo(e);return`
|
|
2
|
+
Debug Information:
|
|
3
|
+
-----------------
|
|
4
|
+
Timestamp: ${t.timestamp}
|
|
5
|
+
URL: ${t.encodedUrl}
|
|
6
|
+
Config: ${t.encodedConfig}
|
|
7
|
+
Navigator Info: ${t.navigatorInfo}
|
|
8
|
+
IFrame Status: ${t.iframeStatus}
|
|
9
|
+
Last Request: ${t.lastRequest}
|
|
10
|
+
Last Response: ${t.lastResponse}
|
|
11
|
+
Client Status: ${t.clientStatus}
|
|
12
|
+
Error: ${t.error}
|
|
13
|
+
`.trim()}};const C=(()=>{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 w(e){e?localStorage.setItem(o,e):localStorage.removeItem(o)}function T(t,n,r,i){let a=new URL(window.location.href),o=a.searchParams.get(`fmt`)??void 0;t.contentWindow?.postMessage({clientLifecycle:`handshake-response`,data:{token:n,currentUrl:window.location.href,pendingMergeToken:o,configDomain:i,clientId:e()}},r),o&&(a.searchParams.delete(`fmt`),window.history.replaceState({},``,a.toString()))}function E(e,t){try{let n=new URL(e);return n.searchParams.has(`u`)?(n.searchParams.delete(`u`),n.searchParams.append(`u`,window.location.href),t&&n.searchParams.append(`fmt`,t),n.toString()):e}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,n,r){if(d(t)){let i=E(t,r);u(i,{onFallback:()=>{e.contentWindow?.postMessage({clientLifecycle:`deep-link-failed`,data:{originalUrl:i}},n)}})}else if(C&&O(t))D(r);else{let e=E(t,r);window.location.href=e}}function A({iframe:e,targetOrigin:n,configDomain:r}){let i=new t;return{handleEvent:async t=>{if(!(`iframeLifecycle`in t))return;let{iframeLifecycle:a,data:s}=t;switch(a){case`connected`:i.resolve(!0);break;case`do-backup`:w(s.backup);break;case`remove-backup`:localStorage.removeItem(o);break;case`show`:case`hide`:y({iframe:e,isVisible:a===`show`});break;case`handshake`:T(e,s.token,n,r);break;case`redirect`:k(e,s.baseRedirectUrl,n,s.mergeToken);break}},isConnected:i.promise}}function j({config:t,iframe:o}){let s=t?.walletUrl??`https://wallet.frak.id`,c=A({iframe:o,targetOrigin:s,configDomain:t.domain}),l=new S(t,o);if(!o.contentWindow)throw new n(r.configError,`The iframe does not have a content window`);let u=i({emittingTransport:o.contentWindow,listeningTransport:window,targetOrigin:s,middleware:[{async onRequest(e,t){if(!await c.isConnected)throw new n(r.clientNotConnected,`The iframe provider isn't connected yet`);return t}},{onRequest(e,t){return l.setLastRequest(e),t},onResponse(e,t){return l.setLastResponse(e,t),t}}],lifecycleHandlers:{iframeLifecycle:async(e,t)=>{await c.handleEvent(e)}}}),d=M(u,c),f=async()=>{d(),u.cleanup(),o.remove()},p;console.log(`[Frak SDK] Initializing OpenPanel`),p=new a({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:`0.2.0`,userAnonymousClientId:e()}),!0)}),p.setGlobalProperties({sdkVersion:`0.2.0`,userAnonymousClientId:e()}),p.init();let m=N({config:t,rpcClient:u,lifecycleManager:c}).then(()=>l.updateSetupStatus(!0));return{config:t,debugInfo:l,waitForConnection:c.isConnected,waitForSetup:m,request:u.request,listenerRequest:u.listen,destroy:f,openPanel:p}}function M(e,t){let n,r,i=()=>e.sendLifecycle({clientLifecycle:`heartbeat`});async function a(){i(),n=setInterval(i,1e3),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 N({config:e,rpcClient:t,lifecycleManager:n}){await n.isConnected,x(t,n.isConnected);async function r(){let n=e.customizations?.css;if(!n)return;let r={clientLifecycle:`modal-css`,data:{cssLink:n}};t.sendLifecycle(r)}async function i(){let n=e.customizations?.i18n;if(!n)return;let r={clientLifecycle:`modal-i18n`,data:{i18n:n}};t.sendLifecycle(r)}async function a(){if(typeof window>`u`)return;let e=window.localStorage.getItem(o);if(!e)return;let n={clientLifecycle:`restore-backup`,data:{backup:e}};t.sendLifecycle(n)}await Promise.allSettled([r(),i(),a()])}async function P({config:e}){let t=F(e),n=await v({config:t});if(!n){console.error(`Failed to create iframe`);return}let r=j({config:t,iframe:n});if(await r.waitForSetup,!await r.waitForConnection){console.error(`Failed to connect to client`);return}return r}function F(e){let t=p(e.metadata?.currency);return{...e,metadata:{...e.metadata,currency:t}}}export{v as a,h as c,f as d,c as f,s as g,u as h,_ as i,m as l,l as m,j as n,b as o,d as p,S as r,g as s,P as t,p as u};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const e=require(`./trackEvent-Ew5r5zfI.cjs`);let t=require(`@frak-labs/frame-connector`),n=require(`@openpanel/web`);const r=`nexus-wallet-backup`,i=`frakwallet://`;function a(){let e=navigator.userAgent;return/Android/i.test(e)&&/Chrome\/\d+/i.test(e)}function o(e){return`intent://${e.slice(13)}#Intent;scheme=frakwallet;end`}function s(e,t){let n=t?.timeout??2500,r=!1,i=()=>{document.hidden&&(r=!0)};document.addEventListener(`visibilitychange`,i);let s=a()&&c(e)?o(e):e;window.location.href=s,setTimeout(()=>{document.removeEventListener(`visibilitychange`,i),r||t?.onFallback?.()},n)}function c(e){return e.startsWith(i)}const l={eur:`fr-FR`,usd:`en-US`,gbp:`en-GB`};function u(e){return e&&e in l?e:`eur`}function d(e){return e?l[e]??l.eur:l.eur}function f(e,t){let n=d(t),r=u(t);return e.toLocaleString(n,{style:`currency`,currency:r,minimumFractionDigits:0,maximumFractionDigits:2})}function p(e){return e?`${e}Amount`:`eurAmount`}const m={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 h({walletBaseUrl:t,config:n}){let r=document.querySelector(`#frak-wallet`);r&&r.remove();let i=document.createElement(`iframe`);i.id=m.id,i.name=m.name,i.allow=m.allow,i.style.zIndex=m.style.zIndex.toString(),g({iframe:i,isVisible:!1});let a=n?.walletUrl??t??`https://wallet.frak.id`,o=e.v();return i.src=`${a}/listener?clientId=${encodeURIComponent(o)}`,new Promise(e=>{i.addEventListener(`load`,()=>e(i)),document.body.appendChild(i)})}function g({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 _(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 v(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`))}var y=class e{config;iframe;isSetupDone=!1;lastResponse=null;lastRequest=null;constructor(e,t){this.config=e,this.iframe=t,this.lastRequest=null,this.lastResponse=null}setLastResponse(e,t){this.lastResponse={message:e,response:t,timestamp:Date.now()}}setLastRequest(e){this.lastRequest={event:e,timestamp:Date.now()}}updateSetupStatus(e){this.isSetupDone=e}base64Encode(e){try{return btoa(JSON.stringify(e))}catch(e){return console.warn(`Failed to encode debug data`,e),btoa(`Failed to encode data`)}}getIframeStatus(){return this.iframe?{loading:this.iframe.hasAttribute(`loading`),url:this.iframe.src,readyState:this.iframe.contentDocument?.readyState?this.iframe.contentDocument.readyState===`complete`?1:0:-1,contentWindow:!!this.iframe.contentWindow,isConnected:this.iframe.isConnected}:null}getNavigatorInfo(){return navigator?{userAgent:navigator.userAgent,language:navigator.language,onLine:navigator.onLine,screenWidth:window.screen.width,screenHeight:window.screen.height,pixelRatio:window.devicePixelRatio}:null}gatherDebugInfo(e){let n=this.getIframeStatus(),r=this.getNavigatorInfo(),i=`Unknown`;return e instanceof t.FrakRpcError?i=`FrakRpcError: ${e.code} '${e.message}'`:e instanceof Error?i=e.message:typeof e==`string`&&(i=e),{timestamp:new Date().toISOString(),encodedUrl:btoa(window.location.href),encodedConfig:this.config?this.base64Encode(this.config):`no-config`,navigatorInfo:r?this.base64Encode(r):`no-navigator`,iframeStatus:n?this.base64Encode(n):`not-iframe`,lastRequest:this.lastRequest?this.base64Encode(this.lastRequest):`No Frak request logged`,lastResponse:this.lastResponse?this.base64Encode(this.lastResponse):`No Frak response logged`,clientStatus:this.isSetupDone?`setup`:`not-setup`,error:i}}static empty(){return new e}formatDebugInfo(e){let t=this.gatherDebugInfo(e);return`
|
|
2
|
+
Debug Information:
|
|
3
|
+
-----------------
|
|
4
|
+
Timestamp: ${t.timestamp}
|
|
5
|
+
URL: ${t.encodedUrl}
|
|
6
|
+
Config: ${t.encodedConfig}
|
|
7
|
+
Navigator Info: ${t.navigatorInfo}
|
|
8
|
+
IFrame Status: ${t.iframeStatus}
|
|
9
|
+
Last Request: ${t.lastRequest}
|
|
10
|
+
Last Response: ${t.lastResponse}
|
|
11
|
+
Client Status: ${t.clientStatus}
|
|
12
|
+
Error: ${t.error}
|
|
13
|
+
`.trim()}};const b=(()=>{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 x(e){e?localStorage.setItem(r,e):localStorage.removeItem(r)}function S(t,n,r,i){let a=new URL(window.location.href),o=a.searchParams.get(`fmt`)??void 0;t.contentWindow?.postMessage({clientLifecycle:`handshake-response`,data:{token:n,currentUrl:window.location.href,pendingMergeToken:o,configDomain:i,clientId:e.v()}},r),o&&(a.searchParams.delete(`fmt`),window.history.replaceState({},``,a.toString()))}function C(e,t){try{let n=new URL(e);return n.searchParams.has(`u`)?(n.searchParams.delete(`u`),n.searchParams.append(`u`,window.location.href),t&&n.searchParams.append(`fmt`,t),n.toString()):e}catch{return e}}function w(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 T(e){return e.includes(`/common/social`)}function E(e,t,n,r){if(c(t)){let i=C(t,r);s(i,{onFallback:()=>{e.contentWindow?.postMessage({clientLifecycle:`deep-link-failed`,data:{originalUrl:i}},n)}})}else if(b&&T(t))w(r);else{let e=C(t,r);window.location.href=e}}function D({iframe:e,targetOrigin:n,configDomain:i}){let a=new t.Deferred;return{handleEvent:async t=>{if(!(`iframeLifecycle`in t))return;let{iframeLifecycle:o,data:s}=t;switch(o){case`connected`:a.resolve(!0);break;case`do-backup`:x(s.backup);break;case`remove-backup`:localStorage.removeItem(r);break;case`show`:case`hide`:g({iframe:e,isVisible:o===`show`});break;case`handshake`:S(e,s.token,n,i);break;case`redirect`:E(e,s.baseRedirectUrl,n,s.mergeToken);break}},isConnected:a.promise}}function O({config:r,iframe:i}){let a=r?.walletUrl??`https://wallet.frak.id`,o=D({iframe:i,targetOrigin:a,configDomain:r.domain}),s=new y(r,i);if(!i.contentWindow)throw new t.FrakRpcError(t.RpcErrorCodes.configError,`The iframe does not have a content window`);let c=(0,t.createRpcClient)({emittingTransport:i.contentWindow,listeningTransport:window,targetOrigin:a,middleware:[{async onRequest(e,n){if(!await o.isConnected)throw new t.FrakRpcError(t.RpcErrorCodes.clientNotConnected,`The iframe provider isn't connected yet`);return n}},{onRequest(e,t){return s.setLastRequest(e),t},onResponse(e,t){return s.setLastResponse(e,t),t}}],lifecycleHandlers:{iframeLifecycle:async(e,t)=>{await o.handleEvent(e)}}}),l=k(c,o),u=async()=>{l(),c.cleanup(),i.remove()},d;console.log(`[Frak SDK] Initializing OpenPanel`),d=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:`0.2.0`,userAnonymousClientId:e.v()}),!0)}),d.setGlobalProperties({sdkVersion:`0.2.0`,userAnonymousClientId:e.v()}),d.init();let f=A({config:r,rpcClient:c,lifecycleManager:o}).then(()=>s.updateSetupStatus(!0));return{config:r,debugInfo:s,waitForConnection:o.isConnected,waitForSetup:f,request:c.request,listenerRequest:c.listen,destroy:u,openPanel:d}}function k(e,t){let n,r,i=()=>e.sendLifecycle({clientLifecycle:`heartbeat`});async function a(){i(),n=setInterval(i,1e3),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 A({config:e,rpcClient:t,lifecycleManager:n}){await n.isConnected,v(t,n.isConnected);async function i(){let n=e.customizations?.css;if(!n)return;let r={clientLifecycle:`modal-css`,data:{cssLink:n}};t.sendLifecycle(r)}async function a(){let n=e.customizations?.i18n;if(!n)return;let r={clientLifecycle:`modal-i18n`,data:{i18n:n}};t.sendLifecycle(r)}async function o(){if(typeof window>`u`)return;let e=window.localStorage.getItem(r);if(!e)return;let n={clientLifecycle:`restore-backup`,data:{backup:e}};t.sendLifecycle(n)}await Promise.allSettled([i(),a(),o()])}async function j({config:e}){let t=M(e),n=await h({config:t});if(!n){console.error(`Failed to create iframe`);return}let r=O({config:t,iframe:n});if(await r.waitForSetup,!await r.waitForConnection){console.error(`Failed to connect to client`);return}return r}function M(e){let t=u(e.metadata?.currency);return{...e,metadata:{...e.metadata,currency:t}}}Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return h}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return f}}),Object.defineProperty(exports,`d`,{enumerable:!0,get:function(){return l}}),Object.defineProperty(exports,`f`,{enumerable:!0,get:function(){return a}}),Object.defineProperty(exports,`g`,{enumerable:!0,get:function(){return i}}),Object.defineProperty(exports,`h`,{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return m}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,`m`,{enumerable:!0,get:function(){return o}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return O}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return _}}),Object.defineProperty(exports,`p`,{enumerable:!0,get:function(){return c}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return y}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return p}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return j}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return u}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=require(`./trackEvent-Ew5r5zfI.cjs`);let t=require(`viem`),n=require(`@frak-labs/frame-connector`),r=require(`viem/siwe`);async function i(e,t){return await e.request({method:`frak_displayEmbeddedWallet`,params:[t,e.config.metadata]})}async function a(e,{steps:t,metadata:n}){return await e.request({method:`frak_displayModal`,params:[t,n,e.config.metadata]})}async function o(t){if(typeof window>`u`)return;let n=e.v();if(!n)return;let r=await e.r();if(!r)return;let i=`frak-identity-ensured-${r}`;if(!window.sessionStorage.getItem(i))try{let a=e.l();(await fetch(`${a}/user/identity/ensure`,{method:`POST`,headers:{Accept:`application/json`,"Content-Type":`application/json`,"x-wallet-sdk-auth":t,"x-frak-client-id":n},body:JSON.stringify({merchantId:r})})).ok&&window.sessionStorage.setItem(i,`1`)}catch{}}async function s(e){return await e.request({method:`frak_getMerchantInformation`})}async function c(e,t){let{metadata:n,customizations:r}=e.config;return await e.request({method:`frak_prepareSso`,params:[t,n.name,r?.css]})}async function l(t,n){try{await t.request({method:`frak_sendInteraction`,params:[n,{clientId:e.v()}]})}catch{console.warn(`[Frak SDK] Failed to send interaction:`,n.type)}}function u(t,n,r){let i=typeof window<`u`?window.location.href:void 0;return e.s(n)?(e.t(t,`user_referred_started`,{properties:{referrerClientId:n.c,walletStatus:r?.key}}),l(t,{type:`arrival`,referrerClientId:n.c,referrerMerchantId:n.m,referralTimestamp:n.t,landingUrl:i}),!0):e.o(n)?(e.t(t,`user_referred_started`,{properties:{referrer:n.r,walletStatus:r?.key}}),l(t,{type:`arrival`,referrerWallet:n.r,landingUrl:i}),!0):!1}function d(t){let n=e.v();return n?{v:2,c:n,m:t,t:Math.floor(Date.now()/1e3)}:null}function f(n,r){return e.s(n)?e.v()===n.c:e.o(n)&&r?.wallet?(0,t.isAddressEqual)(n.r,r.wallet):!1}function p(t,{walletStatus:n,frakContext:r,options:i}){if(!r)return`no-referrer`;if(f(r,n))return`self-referral`;if(!u(t,r,n))return`no-referrer`;let a=e.s(r)?r.m:i?.merchantId,o=i?.alwaysAppendUrl&&a?d(a):null;return e.a.replaceUrl({url:window.location?.href,context:o}),e.t(t,`user_referred_completed`,{properties:{status:`success`}}),`success`}async function m(t,{options:n}={}){let r=e.a.parse({url:window.location.href}),i=await g(t);try{return p(t,{walletStatus:i,frakContext:r,options:n})}catch(e){console.warn(`Error processing referral`,{error:e})}}async function h(t){if(typeof window>`u`){console.warn(`[Frak] No window found, can't track purchase`);return}let n=window.sessionStorage.getItem(`frak-wallet-interaction-token`),r=e.v();if(!n&&!r){console.warn(`[Frak] No identity found, skipping purchase check`);return}let i=window.sessionStorage.getItem(`frak-merchant-id`),a=t.merchantId??i??await e.r();if(!a){console.warn(`[Frak] No merchant id found, skipping purchase check`);return}let o={Accept:`application/json`,"Content-Type":`application/json`};n&&(o[`x-wallet-sdk-auth`]=n),r&&(o[`x-frak-client-id`]=r);let s=e.l();await fetch(`${s}/user/track/purchase`,{method:`POST`,headers:o,body:JSON.stringify({customerId:t.customerId,orderId:t.orderId,token:t.token,merchantId:a})})}function g(e,t){if(!t)return e.request({method:`frak_listenToWalletStatus`}).then(t=>(_(e,t),t));let r=new n.Deferred,i=!1;return e.listenerRequest({method:`frak_listenToWalletStatus`},n=>{_(e,n),t(n),i||=(r.resolve(n),!0)}),r.promise}function _(e,t){typeof window>`u`||(e.openPanel?.setGlobalProperties({wallet:t.wallet??null}),t.interactionToken?(window.sessionStorage.setItem(`frak-wallet-interaction-token`,t.interactionToken),o(t.interactionToken)):window.sessionStorage.removeItem(`frak-wallet-interaction-token`))}function v(e,{metadata:t,login:n}){return y(e,{steps:{login:n??{}},metadata:t})}function y(e,t){function n(n){return y(e,{...t,steps:{...t.steps,sendTransaction:n}})}function r(n){return y(e,{...t,steps:{...t.steps,final:{...n,action:{key:`reward`}}}})}function i(n,r){return y(e,{...t,steps:{...t.steps,final:{...r,action:{key:`sharing`,options:n}}}})}async function o(n){return n&&(t.metadata=n(t.metadata??{})),await a(e,t)}return{params:t,sendTx:n,reward:r,sharing:i,display:o}}async function b(e,{tx:t,metadata:n}){return(await a(e,{metadata:n,steps:{login:{},sendTransaction:{tx:t}}})).sendTransaction}async function x(e,{siwe:t,metadata:n}){let i=e.config?.domain??window.location.host,o=t?.statement??`I confirm that I want to use my Frak wallet on: ${e.config.metadata.name}`;return(await a(e,{metadata:n,steps:{login:{},siweAuthenticate:{siwe:{...t,statement:o,nonce:t?.nonce??(0,r.generateSiweNonce)(),uri:t?.uri??`https://${i}`,version:t?.version??`1`,domain:i}}}})).siweAuthenticate}Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return h}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return l}}),Object.defineProperty(exports,`d`,{enumerable:!0,get:function(){return o}}),Object.defineProperty(exports,`f`,{enumerable:!0,get:function(){return a}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return g}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return c}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return b}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return m}}),Object.defineProperty(exports,`p`,{enumerable:!0,get:function(){return i}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return v}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return p}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return x}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return s}});
|