@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.
Files changed (130) hide show
  1. package/README.md +58 -0
  2. package/cdn/bundle.js +14 -0
  3. package/dist/actions.cjs +1 -1
  4. package/dist/actions.d.cts +3 -3
  5. package/dist/actions.d.ts +3 -3
  6. package/dist/actions.js +1 -1
  7. package/dist/bundle.cjs +1 -1
  8. package/dist/bundle.d.cts +4 -6
  9. package/dist/bundle.d.ts +4 -6
  10. package/dist/bundle.js +1 -1
  11. package/dist/computeLegacyProductId-CCAZvLa5.d.cts +537 -0
  12. package/dist/computeLegacyProductId-b5cUWdAm.d.ts +537 -0
  13. package/dist/index.cjs +1 -1
  14. package/dist/index.d.cts +3 -4
  15. package/dist/index.d.ts +3 -4
  16. package/dist/index.js +1 -1
  17. package/dist/{openSso-D--Airj6.d.cts → openSso-B0g7-807.d.cts} +173 -136
  18. package/dist/{openSso-DsKJ4y0j.d.ts → openSso-CMzwvaCa.d.ts} +173 -136
  19. package/dist/setupClient-BICl5fdX.js +13 -0
  20. package/dist/setupClient-nl8Dhh4V.cjs +13 -0
  21. package/dist/siweAuthenticate-BWmI2_TN.cjs +1 -0
  22. package/dist/{index-d8xS4ryI.d.ts → siweAuthenticate-CVigMOxz.d.cts} +113 -92
  23. package/dist/{index-C6FxkWPC.d.cts → siweAuthenticate-CnCZ7mok.d.ts} +113 -92
  24. package/dist/siweAuthenticate-zczqxm0a.js +1 -0
  25. package/dist/trackEvent-CeLFVzZn.js +1 -0
  26. package/dist/trackEvent-Ew5r5zfI.cjs +1 -0
  27. package/package.json +11 -22
  28. package/src/actions/displayEmbeddedWallet.ts +1 -0
  29. package/src/actions/displayModal.test.ts +12 -11
  30. package/src/actions/displayModal.ts +7 -18
  31. package/src/actions/ensureIdentity.ts +68 -0
  32. package/src/actions/{getProductInformation.test.ts → getMerchantInformation.test.ts} +33 -50
  33. package/src/actions/getMerchantInformation.ts +16 -0
  34. package/src/actions/index.ts +3 -2
  35. package/src/actions/openSso.ts +4 -2
  36. package/src/actions/referral/processReferral.test.ts +117 -242
  37. package/src/actions/referral/processReferral.ts +134 -204
  38. package/src/actions/referral/referralInteraction.test.ts +4 -12
  39. package/src/actions/referral/referralInteraction.ts +3 -13
  40. package/src/actions/sendInteraction.ts +46 -22
  41. package/src/actions/trackPurchaseStatus.test.ts +354 -141
  42. package/src/actions/trackPurchaseStatus.ts +48 -11
  43. package/src/actions/watchWalletStatus.ts +2 -3
  44. package/src/actions/wrapper/modalBuilder.test.ts +0 -14
  45. package/src/actions/wrapper/modalBuilder.ts +3 -12
  46. package/src/bundle.ts +0 -1
  47. package/src/clients/createIFrameFrakClient.ts +10 -5
  48. package/src/clients/transports/iframeLifecycleManager.test.ts +163 -4
  49. package/src/clients/transports/iframeLifecycleManager.ts +172 -33
  50. package/src/constants/interactionTypes.ts +12 -41
  51. package/src/index.ts +27 -16
  52. package/src/types/config.ts +6 -0
  53. package/src/types/context.ts +48 -6
  54. package/src/types/index.ts +15 -11
  55. package/src/types/lifecycle/client.ts +24 -1
  56. package/src/types/lifecycle/iframe.ts +6 -0
  57. package/src/types/rpc/displayModal.ts +2 -4
  58. package/src/types/rpc/embedded/index.ts +2 -2
  59. package/src/types/rpc/interaction.ts +31 -39
  60. package/src/types/rpc/merchantInformation.ts +77 -0
  61. package/src/types/rpc/modal/index.ts +0 -4
  62. package/src/types/rpc/modal/login.ts +5 -1
  63. package/src/types/rpc/walletStatus.ts +1 -7
  64. package/src/types/rpc.ts +22 -30
  65. package/src/types/tracking.ts +31 -0
  66. package/src/utils/FrakContext.test.ts +270 -186
  67. package/src/utils/FrakContext.ts +78 -56
  68. package/src/utils/backendUrl.test.ts +83 -0
  69. package/src/utils/backendUrl.ts +62 -0
  70. package/src/utils/clientId.test.ts +41 -0
  71. package/src/utils/clientId.ts +43 -0
  72. package/src/utils/compression/compress.test.ts +1 -1
  73. package/src/utils/compression/compress.ts +2 -2
  74. package/src/utils/compression/decompress.test.ts +8 -4
  75. package/src/utils/compression/decompress.ts +2 -2
  76. package/src/utils/{computeProductId.ts → computeLegacyProductId.ts} +2 -2
  77. package/src/utils/constants.ts +5 -0
  78. package/src/utils/deepLinkWithFallback.test.ts +243 -0
  79. package/src/utils/deepLinkWithFallback.ts +103 -0
  80. package/src/utils/formatAmount.ts +6 -0
  81. package/src/utils/iframeHelper.test.ts +18 -5
  82. package/src/utils/iframeHelper.ts +10 -3
  83. package/src/utils/index.ts +16 -1
  84. package/src/utils/merchantId.test.ts +653 -0
  85. package/src/utils/merchantId.ts +143 -0
  86. package/src/utils/sso.ts +18 -11
  87. package/src/utils/trackEvent.test.ts +23 -5
  88. package/src/utils/trackEvent.ts +13 -0
  89. package/cdn/bundle.iife.js +0 -14
  90. package/dist/actions-B5j-i1p0.cjs +0 -1
  91. package/dist/actions-q090Z0oR.js +0 -1
  92. package/dist/index-7OZ39x1U.d.ts +0 -195
  93. package/dist/index-CRsQWnTs.d.cts +0 -351
  94. package/dist/index-Ck1hudEi.d.ts +0 -351
  95. package/dist/index-zDq-VlKx.d.cts +0 -195
  96. package/dist/interaction-DMJ3ZfaF.d.cts +0 -45
  97. package/dist/interaction-KX1h9a7V.d.ts +0 -45
  98. package/dist/interactions-DnfM3oe0.js +0 -1
  99. package/dist/interactions-EIXhNLf6.cjs +0 -1
  100. package/dist/interactions.cjs +0 -1
  101. package/dist/interactions.d.cts +0 -2
  102. package/dist/interactions.d.ts +0 -2
  103. package/dist/interactions.js +0 -1
  104. package/dist/productTypes-BUkXJKZ7.cjs +0 -1
  105. package/dist/productTypes-CGb1MmBF.js +0 -1
  106. package/dist/src-1LQ4eLq5.js +0 -13
  107. package/dist/src-hW71KjPN.cjs +0 -13
  108. package/dist/trackEvent-CHnYa85W.js +0 -1
  109. package/dist/trackEvent-GuQm_1Nm.cjs +0 -1
  110. package/src/actions/getProductInformation.ts +0 -14
  111. package/src/actions/openSso.test.ts +0 -407
  112. package/src/actions/sendInteraction.test.ts +0 -219
  113. package/src/constants/interactionTypes.test.ts +0 -128
  114. package/src/constants/productTypes.test.ts +0 -130
  115. package/src/constants/productTypes.ts +0 -33
  116. package/src/interactions/index.ts +0 -5
  117. package/src/interactions/pressEncoder.test.ts +0 -215
  118. package/src/interactions/pressEncoder.ts +0 -53
  119. package/src/interactions/purchaseEncoder.test.ts +0 -291
  120. package/src/interactions/purchaseEncoder.ts +0 -99
  121. package/src/interactions/referralEncoder.test.ts +0 -170
  122. package/src/interactions/referralEncoder.ts +0 -47
  123. package/src/interactions/retailEncoder.test.ts +0 -107
  124. package/src/interactions/retailEncoder.ts +0 -37
  125. package/src/interactions/webshopEncoder.test.ts +0 -56
  126. package/src/interactions/webshopEncoder.ts +0 -30
  127. package/src/types/rpc/modal/openSession.ts +0 -25
  128. package/src/types/rpc/productInformation.ts +0 -59
  129. package/src/utils/computeProductId.test.ts +0 -80
  130. 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 final keys for each interaction types (e.g. `openArticle`) -> interaction type
193
- * @inline
194
- */
195
- type InteractionTypesKey = { [K in keyof typeof interactionTypes]: keyof (typeof interactionTypes)[K] }[keyof typeof interactionTypes];
196
- /**
197
- * The keys for each interaction types (e.g. `press.openArticle`) -> category_type.interaction_type
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 FullInteractionTypesKey = { [Category in keyof typeof interactionTypes]: `${Category & string}.${keyof (typeof interactionTypes)[Category] & string}` }[keyof typeof interactionTypes];
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 | OpenInteractionSessionModalStepType | FinalModalStepType;
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?: FullInteractionTypesKey;
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?: FullInteractionTypesKey;
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/constants/productTypes.d.ts
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
- * List of the product types per denominator
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
- declare const productTypes: {
691
- dapp: number;
692
- press: number;
693
- webshop: number;
694
- retail: number;
695
- referral: number;
696
- purchase: number;
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/productInformation.d.ts
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
- * Response of the `frak_getProductInformation` RPC method
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 GetProductInformationReturnType = {
745
+ type GetMerchantInformationReturnType = {
718
746
  /**
719
- * Current product id
747
+ * Current merchant id
720
748
  */
721
- id: Hex;
749
+ id: string;
722
750
  /**
723
751
  * Some metadata
724
752
  */
725
753
  onChainMetadata: {
726
754
  /**
727
- * Name of the product on-chain
755
+ * Name of the merchant on-chain
728
756
  */
729
757
  name: string;
730
758
  /**
731
- * Domain of the product on-chain
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: Address;
752
- campaign: Address;
753
- interactionTypeKey: FullInteractionTypesKey;
754
- referrer: TokenAmountType;
755
- referee: TokenAmountType;
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
- * #### frak_getProductInformation
827
+ * #### frak_getMerchantInformation
825
828
  * - Params: None
826
- * - Returns: {@link GetProductInformationReturnType}
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 product information's
885
- * - Is product minted?
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: "frak_getProductInformation";
885
+ Method: "frak_getMerchantInformation";
892
886
  Parameters?: undefined;
893
- ReturnType: GetProductInformationReturnType;
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
- * The current Frak Context
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
- * For now, only contain a referrer address.
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
- r: Address;
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 { SiweAuthenticateReturnType as A, FinalActionType as B, ModalRpcStepsInput as C, SendTransactionReturnType as D, SendTransactionModalStepType as E, OpenSsoParamsType as F, interactionTypes as G, ModalStepMetadata as H, OpenSsoReturnType as I, Currency as J, IFrameLifecycleEvent as K, PrepareSsoParamsType as L, OpenInteractionSessionModalStepType as M, OpenInteractionSessionReturnType as N, SendTransactionTxType as O, LoginModalStepType as P, LocalizedI18nConfig as Q, PrepareSsoReturnType as R, ModalRpcMetadata as S, ModalStepTypes as T, FullInteractionTypesKey as U, FinalModalStepType as V, InteractionTypesKey as W, I18nConfig as X, FrakWalletSdkConfig as Y, Language as Z, LoggedOutEmbeddedView as _, FrakClient as a, LoggedInEmbeddedView as b, IFrameRpcSchema as c, TokenAmountType as d, ProductTypesKey as f, DisplayEmbeddedWalletResultType as g, DisplayEmbeddedWalletParamsType as h, FrakContext as i, SiweAuthenticationParams as j, SiweAuthenticateModalStepType as k, WalletStatusReturnType as l, productTypesMask as m, ssoPopupFeatures as n, FrakLifecycleEvent as o, productTypes as p, ClientLifecycleEvent as q, ssoPopupName as r, IFrameTransport as s, openSso as t, GetProductInformationReturnType as u, EmbeddedViewActionReferred as v, ModalRpcStepsResultType as w, DisplayModalParamsType as x, EmbeddedViewActionSharing as y, SsoMetadata as z };
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}});