@frak-labs/core-sdk 0.0.19 → 0.1.0

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/dist/bundle.d.ts CHANGED
@@ -1,8 +1,10 @@
1
1
  import { Address } from 'viem';
2
2
  import { Hex } from 'viem';
3
+ import type { LifecycleMessage } from '@frak-labs/frame-connector';
3
4
  import type { OpenPanel } from '@openpanel/web';
4
- import type { Prettify } from 'viem/chains';
5
- import type { RpcSchema } from 'viem';
5
+ import type { RpcClient } from '@frak-labs/frame-connector';
6
+ import { RpcMessage } from '@frak-labs/frame-connector';
7
+ import { RpcResponse } from '@frak-labs/frame-connector';
6
8
  import type { SiweMessage } from 'viem/siwe';
7
9
 
8
10
  /**
@@ -44,12 +46,7 @@ export declare const baseIframeProps: {
44
46
  * Event related to the iframe lifecycle
45
47
  * @ignore
46
48
  */
47
- export declare type ClientLifecycleEvent = CustomCssEvent | CustomI18nEvent | RestoreBackupEvent | HearbeatEvent | HandshakeResponse;
48
-
49
- /** @ignore */
50
- export declare class ClientNotFound extends FrakRpcError {
51
- constructor();
52
- }
49
+ export declare type ClientLifecycleEvent = CustomCssEvent | CustomI18nEvent | RestoreBackupEvent | HearbeatEvent | HandshakeResponse | SsoRedirectCompleteEvent;
53
50
 
54
51
  /**
55
52
  * Compress the current Frak context
@@ -65,13 +62,6 @@ declare function compress(context?: Partial<FrakContext>): string | undefined;
65
62
  */
66
63
  export declare type CompressedData = Uint8Array;
67
64
 
68
- /**
69
- * Compress json data
70
- * @param data
71
- * @ignore
72
- */
73
- export declare function compressJson(data: unknown): Uint8Array;
74
-
75
65
  /**
76
66
  * Compress json data
77
67
  * @param data
@@ -139,8 +129,8 @@ export declare class DebugInfoGatherer {
139
129
  private lastResponse;
140
130
  private lastRequest;
141
131
  constructor(config?: FrakWalletSdkConfig, iframe?: HTMLIFrameElement);
142
- setLastResponse(event: MessageEvent<IFrameEvent>): void;
143
- setLastRequest(event: IFrameEvent, target: string): void;
132
+ setLastResponse(message: RpcMessage, response: RpcResponse): void;
133
+ setLastRequest(event: RpcMessage): void;
144
134
  updateSetupStatus(status: boolean): void;
145
135
  private base64Encode;
146
136
  /**
@@ -163,20 +153,6 @@ export declare class DebugInfoGatherer {
163
153
  */
164
154
  declare function decompress(context?: string): FrakContext | undefined;
165
155
 
166
- /**
167
- * Decompress the given string
168
- * @param compressedData The params to encode
169
- * @ignore
170
- */
171
- export declare function decompressDataAndCheckHash<T>(compressedData: CompressedData): HashProtectedData<T>;
172
-
173
- /**
174
- * Decompress json data
175
- * @param data
176
- * @ignore
177
- */
178
- export declare function decompressJson<T>(data: Uint8Array): T | null;
179
-
180
156
  /**
181
157
  * Decompress json data
182
158
  * @param data
@@ -184,20 +160,6 @@ export declare function decompressJson<T>(data: Uint8Array): T | null;
184
160
  */
185
161
  export declare function decompressJsonFromB64<T>(data: string): T | null;
186
162
 
187
- /**
188
- * Simple deferred promise wrapper
189
- * @ignore
190
- */
191
- export declare class Deferred<T> {
192
- private readonly _promise;
193
- private _resolve;
194
- private _reject;
195
- constructor();
196
- get promise(): Promise<T>;
197
- resolve: (value: T | PromiseLike<T>) => void;
198
- reject: (reason?: unknown) => void;
199
- }
200
-
201
163
  /**
202
164
  * Function used to display the Frak embedded wallet popup
203
165
  * @param client - The current Frak Client
@@ -433,34 +395,6 @@ export declare type EmbeddedViewActionSharing = {
433
395
 
434
396
  declare type EventProps = Record<string, unknown>;
435
397
 
436
- /**
437
- * Type that extract the possible return type from a RPC Schema
438
- * @ignore
439
- */
440
- declare type ExtractedMethodFromRpc<TRpcSchema extends RpcSchema, TMethod extends ExtractedParametersFromRpc<TRpcSchema>["method"] = ExtractedParametersFromRpc<TRpcSchema>["method"]> = Extract<TRpcSchema[number], {
441
- Method: TMethod;
442
- }>;
443
-
444
- /**
445
- * Type that extract the possible parameters from a RPC Schema
446
- * @ignore
447
- */
448
- export declare type ExtractedParametersFromRpc<TRpcSchema extends RpcSchema> = {
449
- [K in keyof TRpcSchema]: Prettify<{
450
- method: TRpcSchema[K] extends TRpcSchema[number] ? TRpcSchema[K]["Method"] : string;
451
- } & (TRpcSchema[K] extends TRpcSchema[number] ? TRpcSchema[K]["Parameters"] extends undefined ? {
452
- params?: never;
453
- } : {
454
- params: TRpcSchema[K]["Parameters"];
455
- } : never)>;
456
- }[number];
457
-
458
- /**
459
- * Type that extract the possible return type from a RPC Schema
460
- * @ignore
461
- */
462
- export declare type ExtractedReturnTypeFromRpc<TRpcSchema extends RpcSchema, TParameters extends ExtractedParametersFromRpc<TRpcSchema> = ExtractedParametersFromRpc<TRpcSchema>> = ExtractedMethodFromRpc<TRpcSchema, TParameters["method"]>["ReturnType"];
463
-
464
398
  /**
465
399
  * The different types of final actions we can display in the final step
466
400
  * @group Modal Display
@@ -522,7 +456,7 @@ export declare type FrakContext = {
522
456
  };
523
457
 
524
458
  /**
525
- * Export our frak context "class"
459
+ * Export our frak context
526
460
  */
527
461
  export declare const FrakContextManager: {
528
462
  compress: typeof compress;
@@ -536,14 +470,9 @@ export declare const FrakContextManager: {
536
470
  declare type FrakEvent = "share_button_clicked" | "wallet_button_clicked" | "share_modal_error" | "user_referred";
537
471
 
538
472
  /**
539
- * Generic Frak RPC error
540
- * @ignore
473
+ * Represent an iframe event
541
474
  */
542
- export declare class FrakRpcError<T = undefined> extends Error {
543
- code: number;
544
- data?: T | undefined;
545
- constructor(code: number, message: string, data?: T | undefined);
546
- }
475
+ export declare type FrakLifecycleEvent = IFrameLifecycleEvent | ClientLifecycleEvent;
547
476
 
548
477
  /**
549
478
  * Configuration for the Frak Wallet SDK
@@ -710,13 +639,6 @@ declare type HandshakeResponse = {
710
639
  };
711
640
  };
712
641
 
713
- /**
714
- * Compress the given params, and add hash protection to (rapidly) prevent interception modification
715
- * @param data The params to encode
716
- * @ignore
717
- */
718
- export declare function hashAndCompressData<T>(data: T): CompressedData;
719
-
720
642
  /**
721
643
  * The encoded data to send to a client / received by a client
722
644
  * @ignore
@@ -727,6 +649,7 @@ export declare type HashProtectedData<DataType> = Readonly<DataType & {
727
649
 
728
650
  declare type HearbeatEvent = {
729
651
  clientLifecycle: "heartbeat";
652
+ data?: never;
730
653
  };
731
654
 
732
655
  /**
@@ -764,66 +687,63 @@ declare type HearbeatEvent = {
764
687
  */
765
688
  export declare type I18nConfig = Record<Language, LocalizedI18nConfig> | LocalizedI18nConfig;
766
689
 
767
- /**
768
- * Represent an iframe event
769
- */
770
- export declare type IFrameEvent = IFrameRpcEvent | IFrameLifecycleEvent | ClientLifecycleEvent;
771
-
772
690
  /**
773
691
  * Event related to the iframe lifecycle
774
692
  * @ignore
775
693
  */
776
694
  export declare type IFrameLifecycleEvent = {
777
- iframeLifecycle: "connected" | "show" | "hide";
695
+ iframeLifecycle: "connected" | "show" | "hide" | "remove-backup";
778
696
  data?: never;
779
- } | DoBackupEvent | RemoveBackupEvent | HandshakeRequestEvent | RedirectRequestEvent;
780
-
781
- /**
782
- * Represent an iframe rpc event
783
- */
784
- export declare type IFrameRpcEvent = {
785
- id: string;
786
- topic: ExtractedParametersFromRpc<IFrameRpcSchema>["method"];
787
- data: CompressedData;
788
- };
697
+ } | DoBackupEvent | HandshakeRequestEvent | RedirectRequestEvent;
789
698
 
790
699
  /**
791
700
  * RPC interface that's used for the iframe communication
792
701
  *
793
- * Define all the methods available within the iFrame RPC client
702
+ * Define all the methods available within the iFrame RPC client with response type annotations
794
703
  *
795
704
  * @group RPC Schema
796
705
  *
797
706
  * @remarks
798
- * Here is the list of methods available:
707
+ * Each method in the schema now includes a ResponseType field that indicates:
708
+ * - "promise": One-shot request that resolves once
709
+ * - "stream": Streaming request that can emit multiple values
710
+ *
711
+ * ### Methods:
799
712
  *
800
- * ### frak_listenToWalletStatus
713
+ * #### frak_listenToWalletStatus
801
714
  * - Params: None
802
715
  * - Returns: {@link WalletStatusReturnType}
716
+ * - Response Type: stream (emits updates when wallet status changes)
803
717
  *
804
- * ### frak_displayModal
805
- * - Params: [{@link ModalRpcStepsInput}, name: string, metadata?: {@link ModalRpcMetadata}]
718
+ * #### frak_displayModal
719
+ * - Params: [requests: {@link ModalRpcStepsInput}, metadata?: {@link ModalRpcMetadata}, configMetadata: {@link FrakWalletSdkConfig}["metadata"]]
806
720
  * - Returns: {@link ModalRpcStepsResultType}
721
+ * - Response Type: promise (one-shot)
807
722
  *
808
- * ### frak_sendInteraction
723
+ * #### frak_sendInteraction
809
724
  * - Params: [productId: Hex, interaction: {@link PreparedInteraction}, signature?: Hex]
810
725
  * - Returns: {@link SendInteractionReturnType}
726
+ * - Response Type: promise (one-shot)
811
727
  *
812
- * ### frak_sso
813
- * - Params [params: {@link OpenSsoParamsType}, name: string, customCss?: string]
814
- * - Returns: undefined
728
+ * #### frak_sso
729
+ * - Params: [params: {@link OpenSsoParamsType}, name: string, customCss?: string]
730
+ * - Returns: {@link OpenSsoReturnType}
731
+ * - Response Type: promise (one-shot)
815
732
  *
816
- * ### frak_getProductInformation
733
+ * #### frak_getProductInformation
817
734
  * - Params: None
818
735
  * - Returns: {@link GetProductInformationReturnType}
736
+ * - Response Type: promise (one-shot)
819
737
  *
820
- * ### frak_displayEmbeddedWallet
821
- * - Params: [{@link DisplayEmbeddedWalletParamsType}]
738
+ * #### frak_displayEmbeddedWallet
739
+ * - Params: [request: {@link DisplayEmbeddedWalletParamsType}, metadata: {@link FrakWalletSdkConfig}["metadata"]]
822
740
  * - Returns: {@link DisplayEmbeddedWalletResultType}
741
+ * - Response Type: promise (one-shot)
823
742
  */
824
743
  export declare type IFrameRpcSchema = [
825
744
  /**
826
745
  * Method used to listen to the wallet status
746
+ * This is a streaming method that emits updates when wallet status changes
827
747
  */
828
748
  {
829
749
  Method: "frak_listenToWalletStatus";
@@ -832,6 +752,7 @@ export declare type IFrameRpcSchema = [
832
752
  },
833
753
  /**
834
754
  * Method to display a modal with the provided steps
755
+ * This is a one-shot request
835
756
  */
836
757
  {
837
758
  Method: "frak_displayModal";
@@ -844,6 +765,7 @@ export declare type IFrameRpcSchema = [
844
765
  },
845
766
  /**
846
767
  * Method to transmit a user interaction
768
+ * This is a one-shot request
847
769
  */
848
770
  {
849
771
  Method: "frak_sendInteraction";
@@ -856,7 +778,7 @@ export declare type IFrameRpcSchema = [
856
778
  },
857
779
  /**
858
780
  * Method to start a SSO
859
- * todo: Should also support direct tracking via a consumeKey
781
+ * This is a one-shot request
860
782
  */
861
783
  {
862
784
  Method: "frak_sso";
@@ -865,13 +787,14 @@ export declare type IFrameRpcSchema = [
865
787
  name: string,
866
788
  customCss?: string
867
789
  ];
868
- ReturnType: undefined;
790
+ ReturnType: OpenSsoReturnType;
869
791
  },
870
792
  /**
871
793
  * Method to get current product information's
872
794
  * - Is product minted?
873
795
  * - Does it have running campaign?
874
796
  * - Estimated reward on actions
797
+ * This is a one-shot request
875
798
  */
876
799
  {
877
800
  Method: "frak_getProductInformation";
@@ -880,6 +803,7 @@ export declare type IFrameRpcSchema = [
880
803
  },
881
804
  /**
882
805
  * Method to show the embedded wallet, with potential customization
806
+ * This is a one-shot request
883
807
  */
884
808
  {
885
809
  Method: "frak_displayEmbeddedWallet";
@@ -906,11 +830,11 @@ export declare type IFrameTransport = {
906
830
  /**
907
831
  * Function used to perform a single request via the iframe transport
908
832
  */
909
- request: RequestFn<IFrameRpcSchema>;
833
+ request: RpcClient<IFrameRpcSchema, LifecycleMessage>["request"];
910
834
  /**
911
835
  * Function used to listen to a request response via the iframe transport
912
836
  */
913
- listenerRequest: ListenerRequestFn<IFrameRpcSchema>;
837
+ listenerRequest: RpcClient<IFrameRpcSchema, LifecycleMessage>["listen"];
914
838
  /**
915
839
  * Function used to destroy the iframe transport
916
840
  */
@@ -966,12 +890,6 @@ export declare type KeyProvider<DataType> = (value: DataType) => string[];
966
890
  */
967
891
  export declare type Language = "fr" | "en";
968
892
 
969
- /**
970
- * Type used for a listening request
971
- * @inline
972
- */
973
- declare type ListenerRequestFn<TRpcSchema extends RpcSchema> = <TParameters extends ExtractedParametersFromRpc<TRpcSchema> = ExtractedParametersFromRpc<TRpcSchema>, _ReturnType = ExtractedReturnTypeFromRpc<TRpcSchema, TParameters>>(args: TParameters, callback: (result: _ReturnType) => void) => Promise<void>;
974
-
975
893
  /**
976
894
  * Map the currency to the locale
977
895
  */
@@ -1283,9 +1201,18 @@ export declare type OpenInteractionSessionReturnType = {
1283
1201
  * metadata,
1284
1202
  * });
1285
1203
  * ```
1204
+ * ```ts [With tracking]
1205
+ * // Trigger an sso with consumeKey for tracking
1206
+ * const result = await openSso(frakConfig, {
1207
+ * directExit: true,
1208
+ * generateConsumeKey: true,
1209
+ * metadata,
1210
+ * });
1211
+ * console.log(result.consumeKey); // Use this to track SSO status
1212
+ * ```
1286
1213
  * :::
1287
1214
  */
1288
- export declare function openSso(client: FrakClient, args: OpenSsoParamsType): Promise<void>;
1215
+ export declare function openSso(client: FrakClient, args: OpenSsoParamsType): Promise<OpenSsoReturnType>;
1289
1216
 
1290
1217
  /**
1291
1218
  * Params to start a SSO
@@ -1301,6 +1228,11 @@ export declare type OpenSsoParamsType = {
1301
1228
  * @defaultValue true
1302
1229
  */
1303
1230
  directExit?: boolean;
1231
+ /**
1232
+ * If true, opens SSO in same window instead of popup
1233
+ * Defaults to true when redirectUrl is provided, false otherwise
1234
+ */
1235
+ openInSameWindow?: boolean;
1304
1236
  /**
1305
1237
  * Language of the SSO page (optional)
1306
1238
  * It will default to the current user language (or "en" if unsupported language)
@@ -1312,6 +1244,17 @@ export declare type OpenSsoParamsType = {
1312
1244
  metadata: SsoMetadata;
1313
1245
  };
1314
1246
 
1247
+ /**
1248
+ * Response after an SSO has been openned
1249
+ */
1250
+ export declare type OpenSsoReturnType = {
1251
+ /**
1252
+ * Optional wallet address, returned when SSO completes via postMessage
1253
+ * Note: Only present when SSO flow completes (not immediately on open)
1254
+ */
1255
+ wallet?: Hex;
1256
+ };
1257
+
1315
1258
  /**
1316
1259
  * Parse the current URL into a Frak Context
1317
1260
  * @param args
@@ -1497,7 +1440,8 @@ declare type RedirectRequestEvent = {
1497
1440
  iframeLifecycle: "redirect";
1498
1441
  data: {
1499
1442
  /**
1500
- * The base url to redirect to (contain a query param `u`, the client need to suffix the current url to the base url)
1443
+ * The base url to redirect to
1444
+ * If it contain a query param `u`, the client need will suffix the current url to the base url
1501
1445
  */
1502
1446
  baseRedirectUrl: string;
1503
1447
  };
@@ -1567,10 +1511,6 @@ declare type ReferralState = "idle" | "processing" | "success" | "no-wallet" | "
1567
1511
  */
1568
1512
  declare function remove(url: string): string;
1569
1513
 
1570
- declare type RemoveBackupEvent = {
1571
- iframeLifecycle: "remove-backup";
1572
- };
1573
-
1574
1514
  /**
1575
1515
  * Replace the current url with the given Frak context
1576
1516
  * @param args
@@ -1582,12 +1522,6 @@ declare function replaceUrl({ url: baseUrl, context, }: {
1582
1522
  context: Partial<FrakContext> | null;
1583
1523
  }): void;
1584
1524
 
1585
- /**
1586
- * Type used for a one shot request function
1587
- * @inline
1588
- */
1589
- declare type RequestFn<TRpcSchema extends RpcSchema> = <TParameters extends ExtractedParametersFromRpc<TRpcSchema> = ExtractedParametersFromRpc<TRpcSchema>, _ReturnType = ExtractedReturnTypeFromRpc<TRpcSchema, TParameters>>(args: TParameters) => Promise<_ReturnType>;
1590
-
1591
1525
  declare type RestoreBackupEvent = {
1592
1526
  clientLifecycle: "restore-backup";
1593
1527
  data: {
@@ -1621,42 +1555,6 @@ export declare const RetailInteractionEncoder: {
1621
1555
  }): PreparedInteraction;
1622
1556
  };
1623
1557
 
1624
- /**
1625
- * The different Frak RPC error codes
1626
- */
1627
- export declare const RpcErrorCodes: {
1628
- readonly parseError: -32700;
1629
- readonly invalidRequest: -32600;
1630
- readonly methodNotFound: -32601;
1631
- readonly invalidParams: -32602;
1632
- readonly internalError: -32603;
1633
- readonly serverError: -32000;
1634
- readonly clientNotConnected: -32001;
1635
- readonly configError: -32002;
1636
- readonly corruptedResponse: -32003;
1637
- readonly clientAborted: -32004;
1638
- readonly walletNotConnected: -32005;
1639
- readonly serverErrorForInteractionDelegation: -32006;
1640
- };
1641
-
1642
- /**
1643
- * Raw response that we will receive after an rpc request
1644
- * @ignore
1645
- */
1646
- export declare type RpcResponse<TRpcSchema extends RpcSchema, TMethod extends TRpcSchema[number]["Method"] = TRpcSchema[number]["Method"]> = {
1647
- result: Extract<TRpcSchema[number], {
1648
- Method: TMethod;
1649
- }>["ReturnType"];
1650
- error?: never;
1651
- } | {
1652
- result?: never;
1653
- error: {
1654
- code: number;
1655
- message: string;
1656
- data?: unknown;
1657
- };
1658
- };
1659
-
1660
1558
  /**
1661
1559
  * Function used to send an interaction
1662
1560
  * @param client - The current Frak Client
@@ -1892,6 +1790,13 @@ export declare type SsoMetadata = {
1892
1790
  homepageLink?: string;
1893
1791
  };
1894
1792
 
1793
+ declare type SsoRedirectCompleteEvent = {
1794
+ clientLifecycle: "sso-redirect-complete";
1795
+ data: {
1796
+ compressed: string;
1797
+ };
1798
+ };
1799
+
1895
1800
  /**
1896
1801
  * The type for the amount of tokens
1897
1802
  */
@@ -1982,7 +1887,7 @@ export declare type WalletStatusReturnType = WalletConnected | WalletNotConnecte
1982
1887
  * Function used to watch the current frak wallet status
1983
1888
  * @param client - The current Frak Client
1984
1889
  * @param callback - The callback that will receive any wallet status change
1985
- * @returns A rpomise resolving with the initial wallet status
1890
+ * @returns A promise resolving with the initial wallet status
1986
1891
  *
1987
1892
  * @description This function will return the current wallet status, and will listen to any change in the wallet status.
1988
1893
  *
package/dist/bundle.js CHANGED
@@ -1,4 +1,4 @@
1
- import{OpenPanel as e}from"@openpanel/web";import{CborDecoder as t,CborEncoder as n}from"@jsonjoy.com/json-pack/lib/cbor/index.js";import{bytesToHex as r,concatHex as o,encodeAbiParameters as a,hexToBytes as i,isAddressEqual as s,keccak256 as c,pad as l,sha256 as d,toHex as u}from"viem";import{generateSiweNonce as f}from"viem/siwe";class p extends Error{code;data;constructor(e,t,n){super(t),this.code=e,this.data=n}}class h extends p{constructor(e){super(m.internalError,e)}}class w extends p{constructor(){super(m.clientNotConnected,"Client not found")}}let m={parseError:-32700,invalidRequest:-32600,methodNotFound:-32601,invalidParams:-32602,internalError:-32603,serverError:-32e3,clientNotConnected:-32001,configError:-32002,corruptedResponse:-32003,clientAborted:-32004,walletNotConnected:-32005,serverErrorForInteractionDelegation:-32006};class g{_promise;_resolve;_reject;constructor(){this._promise=new Promise((e,t)=>{this._resolve=e,this._reject=t})}get promise(){return this._promise}resolve=e=>{this._resolve?.(e)};reject=e=>{this._reject?.(e)}}function y(e){return btoa(Array.from(e,e=>String.fromCharCode(e)).join("")).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function k(e){let t=e.length%4;return Uint8Array.from(atob(e.replace(/-/g,"+").replace(/_/g,"/").padEnd(e.length+(0===t?0:4-t),"=")),e=>e.charCodeAt(0))}let b=new n;function v(e){let t={...e,validationHash:C(e)};return b.encode(t)}function S(e){return b.encode(e)}function I(e){return y(S(e))}function C(e){return d(b.encode(e))}let E=new t;function R(e){if(!e.length)throw new p(m.corruptedResponse,"Missing compressed data");let t=x(e);if(!t)throw new p(m.corruptedResponse,"Invalid compressed data");if(!t?.validationHash)throw new p(m.corruptedResponse,"Missing validation hash");let{validationHash:n,...r}=t;if(C(r)!==t.validationHash)throw new p(m.corruptedResponse,"Invalid data validation hash");return t}function x(e){try{return E.decode(e)}catch(t){return console.error("Invalid compressed data",{e:t,data:e}),null}}function L(e){return x(k(e))}let F="nexus-wallet-backup";class D{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){this.lastResponse={event:e.data,origin:e.origin,timestamp:Date.now()}}setLastRequest(e,t){this.lastRequest={event:e,target:t,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?+("complete"===this.iframe.contentDocument.readyState):-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(),n=this.getNavigatorInfo(),r="Unknown";return e instanceof p?r=`FrakRpcError: ${e.code} '${e.message}'`:e instanceof Error?r=e.message:"string"==typeof e&&(r=e),{timestamp:new Date().toISOString(),encodedUrl:btoa(window.location.href),encodedConfig:this.config?this.base64Encode(this.config):"no-config",navigatorInfo:n?this.base64Encode(n):"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:r}}static empty(){return new D}formatDebugInfo(e){let t=this.gatherDebugInfo(e);return`
1
+ import{Deferred as e,FrakRpcError as t,RpcErrorCodes as n,compressJson as r,createRpcClient as a,decompressJson as o}from"@frak-labs/frame-connector";import{createClientCompressionMiddleware as i}from"@frak-labs/frame-connector/middleware";import{OpenPanel as s}from"@openpanel/web";import{bytesToHex as c,concatHex as l,encodeAbiParameters as u,hexToBytes as d,isAddressEqual as f,keccak256 as p,pad as m,toHex as w}from"viem";import{generateSiweNonce as h}from"viem/siwe";let g="nexus-wallet-backup";class y{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?+("complete"===this.iframe.contentDocument.readyState):-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(),a="Unknown";return e instanceof t?a=`FrakRpcError: ${e.code} '${e.message}'`:e instanceof Error?a=e.message:"string"==typeof e&&(a=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:a}}static empty(){return new y}formatDebugInfo(e){let t=this.gatherDebugInfo(e);return`
2
2
  Debug Information:
3
3
  -----------------
4
4
  Timestamp: ${t.timestamp}
@@ -10,4 +10,4 @@ import{OpenPanel as e}from"@openpanel/web";import{CborDecoder as t,CborEncoder a
10
10
  Last Response: ${t.lastResponse}
11
11
  Client Status: ${t.clientStatus}
12
12
  Error: ${t.error}
13
- `.trim()}}let T={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 A({walletBaseUrl:e,config:t}){let n=document.querySelector("#frak-wallet");n&&n.remove();let r=document.createElement("iframe");return r.id=T.id,r.name=T.name,r.allow=T.allow,r.style.zIndex=T.style.zIndex.toString(),U({iframe:r,isVisible:!1}),document.body.appendChild(r),new Promise(n=>{r?.addEventListener("load",()=>n(r)),r.src=`${t?.walletUrl??e??"https://wallet.frak.id"}/listener`})}function U({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 P({config:t,iframe:n}){let r,o=function(){let e=new Map;return{createChannel:t=>{let n=Math.random().toString(36).substring(7);return e.set(n,t),n},getRpcResolver:t=>e.get(t),removeChannel:t=>e.delete(t),destroy:()=>e.clear()}}(),a=function({iframe:e}){let t=new g;return{handleEvent:async n=>{switch(n.iframeLifecycle){case"connected":t.resolve(!0);break;case"do-backup":n.data.backup?localStorage.setItem(F,n.data.backup):localStorage.removeItem(F);break;case"remove-backup":localStorage.removeItem(F);break;case"show":case"hide":U({iframe:e,isVisible:"show"===n.iframeLifecycle});break;case"handshake":e.contentWindow?.postMessage({clientLifecycle:"handshake-response",data:{token:n.data.token,currentUrl:window.location.href}},"*");break;case"redirect":window.location.href=`${n.data.baseRedirectUrl}${encodeURIComponent(window.location.href)}`}},isConnected:t.promise}}({iframe:n}),i=new D(t,n),s=function({frakWalletUrl:e,iframe:t,channelManager:n,iframeLifecycleManager:r,debugInfo:o}){if("undefined"==typeof window)throw new p(m.configError,"iframe client should be used in the browser");if(!t.contentWindow)throw new p(m.configError,"The iframe does not have a product window");let a=t.contentWindow;async function i(t){if(!t.origin)return;try{if(new URL(t.origin).origin.toLowerCase()!==new URL(e).origin.toLowerCase())return}catch(e){console.log("Unable to check frak msg origin",e);return}if("object"!=typeof t.data)return;if(o.setLastResponse(t),"iframeLifecycle"in t.data)return void await r.handleEvent(t.data);if("clientLifecycle"in t.data)return void console.error("Client lifecycle event received on the client side, dismissing it");let a=t.data.id,i=n.getRpcResolver(a);i&&i(t.data)}return window.addEventListener("message",i),{sendEvent:function(t){a.postMessage(t,{targetOrigin:e}),o.setLastRequest(t,e)},cleanup:function(){window.removeEventListener("message",i)}}}({frakWalletUrl:t?.walletUrl??"https://wallet.frak.id",iframe:n,channelManager:o,iframeLifecycleManager:a,debugInfo:i}),c=async e=>{if(!await a.isConnected)throw new p(m.clientNotConnected,"The iframe provider isn't connected yet");let t=new g,n=o.createChannel(e=>{let r=R(e.data);r.error?t.reject(new p(r.error.code,r.error.message,r.error?.data)):t.resolve(r.result),o.removeChannel(n)}),r=v(e);return s.sendEvent({id:n,topic:e.method,data:r}),t.promise},l=async(e,t)=>{if(!await a.isConnected)throw new p(m.clientNotConnected,"The iframe provider isn't connected yet");let n=o.createChannel(e=>{let n=R(e.data);if(n.result)t(n.result);else throw new h("No valid result in the response")}),r=v(e);s.sendEvent({id:n,topic:e.method,data:r})},d=function(e,t){let n,r,o=()=>e.sendEvent({clientLifecycle:"heartbeat"});function a(){n&&clearInterval(n),r&&clearTimeout(r)}return async function(){o(),n=setInterval(o,100),r=setTimeout(()=>{a(),console.log("Heartbeat timeout: connection failed")},3e4),await t.isConnected,a()}(),a}(s,a),u=async()=>{d(),o.destroy(),s.cleanup(),n.remove()};console.log("[Frak SDK] Initializing OpenPanel"),(r=new e({apiUrl:"https://op-api.gcp.frak.id",clientId:"f305d11d-b93b-487c-80d4-92deb7903e98",trackScreenViews:!0,trackOutgoingLinks:!0,trackAttributes:!1,filter:({type:e,payload:t})=>!("track"===e&&t?.properties)||("sdkVersion"in t.properties||(t.properties={...t.properties,sdkVersion:"0.0.19"}),!0)})).setGlobalProperties({sdkVersion:"0.0.19"}),r.init();let f=q({config:t,messageHandler:s,lifecycleManager:a}).then(()=>i.updateSetupStatus(!0));return{config:t,debugInfo:i,waitForConnection:a.isConnected,waitForSetup:f,request:c,listenerRequest:l,destroy:u,openPanel:r}}async function q({config:e,messageHandler:t,lifecycleManager:n}){async function r(){let n=e.customizations?.css;n&&t.sendEvent({clientLifecycle:"modal-css",data:{cssLink:n}})}async function o(){let n=e.customizations?.i18n;n&&t.sendEvent({clientLifecycle:"modal-i18n",data:{i18n:n}})}async function a(){if("undefined"==typeof window)return;let e=window.localStorage.getItem(F);e&&t.sendEvent({clientLifecycle:"restore-backup",data:{backup:e}})}await n.isConnected,await Promise.allSettled([r(),o(),a()])}let N={eur:"fr-FR",usd:"en-US",gbp:"en-GB"};function _(e){return e&&e in N?e:"eur"}async function $({config:e}){let t=function(e){let t=_(e.metadata?.currency);return{...e,metadata:{...e.metadata,currency:t}}}(e),n=await A({config:t});if(!n)return void console.error("Failed to create iframe");let r=P({config:t,iframe:n});return(await r.waitForSetup,await r.waitForConnection)?r:void console.error("Failed to connect to client")}let W="fCtx";function j(e){if(e?.r)try{let t=i(e.r);return y(t)}catch(t){console.error("Error compressing Frak context",{e:t,context:e})}}function M(e){if(e&&0!==e.length)try{let t=k(e);return{r:r(t,{size:20})}}catch(t){console.error("Error decompressing Frak context",{e:t,context:e})}}function z({url:e}){if(!e)return null;let t=new URL(e).searchParams.get(W);return t?M(t):null}function O({url:e,context:t}){if(!e)return null;let n=z({url:e}),r=n?{...n,...t}:t;if(!r.r)return null;let o=j(r);if(!o)return null;let a=new URL(e);return a.searchParams.set(W,o),a.toString()}function V(e){let t=new URL(e);return t.searchParams.delete(W),t.toString()}let B={compress:j,decompress:M,parse:z,update:O,remove:V,replaceUrl:function({url:e,context:t}){let n;if(!window.location?.href||"undefined"==typeof window)return void console.error("No window found, can't update context");let r=e??window.location.href;(n=null!==t?O({url:r,context:t}):V(r))&&window.history.replaceState(null,"",n.toString())}};function H(e){return e?N[e]??N.eur:N.eur}function J(e){return e?`${e}Amount`:"eurAmount"}function G(e,t){let n=H(t),r=_(t);return e.toLocaleString(n,{style:"currency",currency:r,minimumFractionDigits:0,maximumFractionDigits:2})}function K(e,t,n={}){if(!e)return void console.debug("[Frak] No client provided, skipping event tracking");try{e.openPanel?.track(t,n)}catch(e){console.debug("[Frak] Failed to track event:",t,e)}}let Q={dapp:1,press:2,webshop:3,retail:4,referral:30,purchase:31},X=Object.entries(Q).reduce((e,[t,n])=>(e[t]=BigInt(1)<<BigInt(n),e),{}),Y={press:{openArticle:"0xc0a24ffb",readArticle:"0xd5bd0fbe"},dapp:{proofVerifiableStorageUpdate:"0x2ab2aeef",callableVerifiableStorageUpdate:"0xa07da986"},webshop:{open:"0xb311798f"},referral:{referred:"0x010cc3b9",createLink:"0xb2c0f17c"},purchase:{started:"0xd87e90c3",completed:"0x8403aeb4",unsafeCompleted:"0x4d5b14e0"},retail:{customerMeeting:"0x74489004"}};function Z(e,t){if(!t)return e.request({method:"frak_listenToWalletStatus"}).then(t=>(ee(e,t),t));let n=new g,r=!1;return e.listenerRequest({method:"frak_listenToWalletStatus"},o=>{ee(e,o),t(o),r||(n.resolve(o),r=!0)}).then(()=>n.promise)}function ee(e,t){"undefined"!=typeof window&&(e.openPanel?.setGlobalProperties({wallet:t.wallet??null}),t.interactionToken?window.sessionStorage.setItem("frak-wallet-interaction-token",t.interactionToken):window.sessionStorage.removeItem("frak-wallet-interaction-token"))}async function et(e,{productId:t,interaction:n,validation:r}){let o=t??function({domain:e}){return c(u((e??window.location.host).replace("www.","")))}(e.config);return await e.request({method:"frak_sendInteraction",params:[o,n,r]})}async function en(e,{steps:t,metadata:n}){return await e.request({method:"frak_displayModal",params:[t,n,e.config.metadata]})}async function er(e,t){return await e.request({method:"frak_displayEmbeddedWallet",params:[t,e.config.metadata]})}async function eo(e,t){let{metadata:n,customizations:r}=e.config;await e.request({method:"frak_sso",params:[t,n.name,r?.css]})}async function ea(e){return await e.request({method:"frak_getProductInformation"})}async function ei(e){if("undefined"==typeof window)return void console.warn("[Frak] No window found, can't track purchase");let t=window.sessionStorage.getItem("frak-wallet-interaction-token");if(!t)return void console.warn("[Frak] No frak session found, skipping purchase check");await fetch("https://backend.frak.id/interactions/listenForPurchase",{method:"POST",headers:{Accept:"application/json","Content-Type":"application/json","x-wallet-sdk-auth":t},body:JSON.stringify(e)})}async function es(e,{siwe:t,metadata:n}){let r=e.config?.domain??window.location.host,o=t?.statement??`I confirm that I want to use my Frak wallet on: ${e.config.metadata.name}`,a={...t,statement:o,nonce:t?.nonce??f(),uri:t?.uri??`https://${r}`,version:t?.version??"1",domain:r};return(await en(e,{metadata:n,steps:{login:{},siweAuthenticate:{siwe:a}}})).siweAuthenticate}async function ec(e,{tx:t,metadata:n}){return(await en(e,{metadata:n,steps:{login:{},sendTransaction:{tx:t}}})).sendTransaction}function el(e,{metadata:t,login:n,openSession:r}){return function e(t,n){async function r(e){return e&&(n.metadata=e(n.metadata??{})),await en(t,n)}return{params:n,sendTx:function(r){return e(t,{...n,steps:{...n.steps,sendTransaction:r}})},reward:function(r){return e(t,{...n,steps:{...n.steps,final:{...r,action:{key:"reward"}}}})},sharing:function(r,o){return e(t,{...n,steps:{...n.steps,final:{...o,action:{key:"sharing",options:r}}}})},display:r}}(e,{steps:{login:n??{},openSession:r??{}},metadata:t})}let ed={createLink:()=>({handlerTypeDenominator:u(Q.referral),interactionData:Y.referral.createLink}),referred({referrer:e}){let t=o([Y.referral.referred,l(e,{size:32})]);return{handlerTypeDenominator:u(Q.referral),interactionData:t}}};async function eu(e,{walletStatus:t,frakContext:n,modalConfig:r,productId:o,options:a}){let i=!1;async function s(){if(!i)return i=!0,ep(e,{modalConfig:{...r,loggedIn:{action:{key:"referred"}}},walletStatus:t})}async function c(t){let n=ed.referred({referrer:t});await Promise.allSettled([et(e,{productId:o,interaction:n}),K(e,"user_referred",{properties:{referrer:t}})])}try{let{status:e,currentWallet:r}=await ef({initialWalletStatus:t,getFreshWalletStatus:s,pushReferralInteraction:c,frakContext:n});return B.replaceUrl({url:window.location?.href,context:a?.alwaysAppendUrl?{r:r}:null}),e}catch(e){return console.log("Error processing referral",{error:e}),B.replaceUrl({url:window.location?.href,context:a?.alwaysAppendUrl?{r:t?.wallet}:null}),function(e){if(e instanceof p)switch(e.code){case m.walletNotConnected:return"no-wallet";case m.serverErrorForInteractionDelegation:return"no-session"}return"error"}(e)}}async function ef({initialWalletStatus:e,getFreshWalletStatus:t,pushReferralInteraction:n,frakContext:r}){let o=e?.wallet;return r?.r?(o||(o=await t()),o&&s(r.r,o))?{status:"self-referral",currentWallet:o}:(e?.interactionSession||(o=await t()),await n(r.r),{status:"success",currentWallet:o}):{status:"no-referrer",currentWallet:o}}async function ep(e,{modalConfig:t,walletStatus:n}){if(!n?.interactionSession){let n=await er(e,t??{});return n?.wallet??void 0}return n.wallet??void 0}async function eh(e,{productId:t,modalConfig:n,options:r}={}){let o=B.parse({url:window.location.href}),a=await Z(e);try{return await eu(e,{walletStatus:a,frakContext:o,modalConfig:n,productId:t,options:r})}catch(e){console.warn("Error processing referral",{error:e})}}let ew={openArticle({articleId:e}){let t=o([Y.press.openArticle,l(e,{size:32})]);return{handlerTypeDenominator:u(Q.press),interactionData:t}},readArticle({articleId:e}){let t=o([Y.press.readArticle,l(e,{size:32})]);return{handlerTypeDenominator:u(Q.press),interactionData:t}}},em={startPurchase({purchaseId:e}){let t=o([Y.purchase.started,l(e,{size:32})]);return{handlerTypeDenominator:u(Q.purchase),interactionData:t}},completedPurchase({purchaseId:e,proof:t}){let n=a([{type:"uint256"},{type:"bytes32[]"}],[BigInt(e),t]),r=o([Y.purchase.completed,n]);return{handlerTypeDenominator:u(Q.purchase),interactionData:r}},unsafeCompletedPurchase({purchaseId:e}){let t=o([Y.purchase.unsafeCompleted,l(e,{size:32})]);return{handlerTypeDenominator:u(Q.purchase),interactionData:t}}},eg={open:()=>({handlerTypeDenominator:u(Q.webshop),interactionData:Y.webshop.open})},ey={customerMeeting({agencyId:e}){let t=o([Y.retail.customerMeeting,l(e,{size:32})]);return{handlerTypeDenominator:u(Q.retail),interactionData:t}}};export{w as ClientNotFound,D as DebugInfoGatherer,g as Deferred,B as FrakContextManager,p as FrakRpcError,ew as PressInteractionEncoder,em as PurchaseInteractionEncoder,ed as ReferralInteractionEncoder,ey as RetailInteractionEncoder,m as RpcErrorCodes,eg as WebShopInteractionEncoder,k as base64urlDecode,y as base64urlEncode,T as baseIframeProps,S as compressJson,I as compressJsonToB64,P as createIFrameFrakClient,A as createIframe,R as decompressDataAndCheckHash,x as decompressJson,L as decompressJsonFromB64,er as displayEmbeddedWallet,en as displayModal,G as formatAmount,J as getCurrencyAmountKey,ea as getProductInformation,_ as getSupportedCurrency,H as getSupportedLocale,v as hashAndCompressData,Y as interactionTypes,N as locales,el as modalBuilder,eo as openSso,eu as processReferral,Q as productTypes,X as productTypesMask,eh as referralInteraction,et as sendInteraction,ec as sendTransaction,$ as setupClient,es as siweAuthenticate,K as trackEvent,ei as trackPurchaseStatus,Z as watchWalletStatus};
13
+ `.trim()}}let k={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 b({walletBaseUrl:e,config:t}){let n=document.querySelector("#frak-wallet");n&&n.remove();let r=document.createElement("iframe");return r.id=k.id,r.name=k.name,r.allow=k.allow,r.style.zIndex=k.style.zIndex.toString(),S({iframe:r,isVisible:!1}),document.body.appendChild(r),new Promise(n=>{r?.addEventListener("load",()=>n(r)),r.src=`${t?.walletUrl??e??"https://wallet.frak.id"}/listener`})}function S({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 I({config:r,iframe:o}){let c,l=r?.walletUrl??"https://wallet.frak.id",u=function({iframe:t}){let n=new e;return{handleEvent:async e=>{if(!("iframeLifecycle"in e))return;let{iframeLifecycle:r,data:a}=e;switch(r){case"connected":n.resolve(!0);break;case"do-backup":a.backup?localStorage.setItem(g,a.backup):localStorage.removeItem(g);break;case"remove-backup":localStorage.removeItem(g);break;case"show":case"hide":S({iframe:t,isVisible:"show"===r});break;case"handshake":t.contentWindow?.postMessage({clientLifecycle:"handshake-response",data:{token:a.token,currentUrl:window.location.href}},"*");break;case"redirect":{let e=new URL(a.baseRedirectUrl);e.searchParams.has("u")?(e.searchParams.delete("u"),e.searchParams.append("u",window.location.href),window.location.href=e.toString()):window.location.href=a.baseRedirectUrl}}},isConnected:n.promise}}({iframe:o}),d=new y(r,o);if(!o.contentWindow)throw new t(n.configError,"The iframe does not have a content window");let f=a({emittingTransport:o.contentWindow,listeningTransport:window,targetOrigin:l,middleware:[{async onRequest(e,r){if(!await u.isConnected)throw new t(n.clientNotConnected,"The iframe provider isn't connected yet");return r}},i(),{onRequest:(e,t)=>(d.setLastRequest(e),t),onResponse:(e,t)=>(d.setLastResponse(e,t),t)}],lifecycleHandlers:{iframeLifecycle:async(e,t)=>{await u.handleEvent(e)}}}),p=function(e,t){let n,r,a=()=>e.sendLifecycle({clientLifecycle:"heartbeat"});function o(){n&&clearInterval(n),r&&clearTimeout(r)}return async function(){a(),n=setInterval(a,1e3),r=setTimeout(()=>{o(),console.log("Heartbeat timeout: connection failed")},3e4),await t.isConnected,o()}(),o}(f,u),m=async()=>{p(),f.cleanup(),o.remove()};console.log("[Frak SDK] Initializing OpenPanel"),(c=new s({apiUrl:"https://op-api.gcp.frak.id",clientId:"f305d11d-b93b-487c-80d4-92deb7903e98",trackScreenViews:!0,trackOutgoingLinks:!0,trackAttributes:!1,filter:({type:e,payload:t})=>!("track"===e&&t?.properties)||("sdkVersion"in t.properties||(t.properties={...t.properties,sdkVersion:"0.1.0"}),!0)})).setGlobalProperties({sdkVersion:"0.1.0"}),c.init();let w=v({config:r,rpcClient:f,lifecycleManager:u}).then(()=>d.updateSetupStatus(!0));return{config:r,debugInfo:d,waitForConnection:u.isConnected,waitForSetup:w,request:f.request,listenerRequest:f.listen,destroy:m,openPanel:c}}async function v({config:e,rpcClient:t,lifecycleManager:n}){async function r(){let n=e.customizations?.css;n&&t.sendLifecycle({clientLifecycle:"modal-css",data:{cssLink:n}})}async function a(){let n=e.customizations?.i18n;n&&t.sendLifecycle({clientLifecycle:"modal-i18n",data:{i18n:n}})}async function o(){if("undefined"==typeof window)return;let e=window.localStorage.getItem(g);e&&t.sendLifecycle({clientLifecycle:"restore-backup",data:{backup:e}})}await n.isConnected,function(e,t){if("undefined"==typeof window)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"))}(t,n.isConnected),await Promise.allSettled([r(),a(),o()])}let R={eur:"fr-FR",usd:"en-US",gbp:"en-GB"};function L(e){return e&&e in R?e:"eur"}async function x({config:e}){let t=function(e){let t=L(e.metadata?.currency);return{...e,metadata:{...e.metadata,currency:t}}}(e),n=await b({config:t});if(!n)return void console.error("Failed to create iframe");let r=I({config:t,iframe:n});return(await r.waitForSetup,await r.waitForConnection)?r:void console.error("Failed to connect to client")}function F(e){return btoa(Array.from(e,e=>String.fromCharCode(e)).join("")).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function C(e){let t=e.length%4;return Uint8Array.from(atob(e.replace(/-/g,"+").replace(/_/g,"/").padEnd(e.length+(0===t?0:4-t),"=")),e=>e.charCodeAt(0))}function T(e){return F(r(e))}function E(e){return o(C(e))}let D="fCtx";function P(e){if(e?.r)try{let t=d(e.r);return F(t)}catch(t){console.error("Error compressing Frak context",{e:t,context:e})}}function U(e){if(e&&0!==e.length)try{let t=C(e);return{r:c(t,{size:20})}}catch(t){console.error("Error decompressing Frak context",{e:t,context:e})}}function q({url:e}){if(!e)return null;let t=new URL(e).searchParams.get(D);return t?U(t):null}function A({url:e,context:t}){if(!e)return null;let n=q({url:e}),r=n?{...n,...t}:t;if(!r.r)return null;let a=P(r);if(!a)return null;let o=new URL(e);return o.searchParams.set(D,a),o.toString()}function $(e){let t=new URL(e);return t.searchParams.delete(D),t.toString()}let O={compress:P,decompress:U,parse:q,update:A,remove:$,replaceUrl:function({url:e,context:t}){let n;if(!window.location?.href||"undefined"==typeof window)return void console.error("No window found, can't update context");let r=e??window.location.href;(n=null!==t?A({url:r,context:t}):$(r))&&window.history.replaceState(null,"",n.toString())}};function W(e){return e?R[e]??R.eur:R.eur}function z(e){return e?`${e}Amount`:"eurAmount"}function N(e,t){let n=W(t),r=L(t);return e.toLocaleString(n,{style:"currency",currency:r,minimumFractionDigits:0,maximumFractionDigits:2})}function _(e,t,n={}){if(!e)return void console.debug("[Frak] No client provided, skipping event tracking");try{e.openPanel?.track(t,n)}catch(e){console.debug("[Frak] Failed to track event:",t,e)}}let M={dapp:1,press:2,webshop:3,retail:4,referral:30,purchase:31},V=Object.entries(M).reduce((e,[t,n])=>(e[t]=BigInt(1)<<BigInt(n),e),{}),B={press:{openArticle:"0xc0a24ffb",readArticle:"0xd5bd0fbe"},dapp:{proofVerifiableStorageUpdate:"0x2ab2aeef",callableVerifiableStorageUpdate:"0xa07da986"},webshop:{open:"0xb311798f"},referral:{referred:"0x010cc3b9",createLink:"0xb2c0f17c"},purchase:{started:"0xd87e90c3",completed:"0x8403aeb4",unsafeCompleted:"0x4d5b14e0"},retail:{customerMeeting:"0x74489004"}};function j(t,n){if(!n)return t.request({method:"frak_listenToWalletStatus"}).then(e=>(G(t,e),e));let r=new e,a=!1;return t.listenerRequest({method:"frak_listenToWalletStatus"},e=>{G(t,e),n(e),a||(r.resolve(e),a=!0)}),r.promise}function G(e,t){"undefined"!=typeof window&&(e.openPanel?.setGlobalProperties({wallet:t.wallet??null}),t.interactionToken?window.sessionStorage.setItem("frak-wallet-interaction-token",t.interactionToken):window.sessionStorage.removeItem("frak-wallet-interaction-token"))}async function J(e,{productId:t,interaction:n,validation:r}){let a=t??function({domain:e}){return p(w((e??window.location.host).replace("www.","")))}(e.config);return await e.request({method:"frak_sendInteraction",params:[a,n,r]})}async function H(e,{steps:t,metadata:n}){return await e.request({method:"frak_displayModal",params:[t,n,e.config.metadata]})}async function K(e,t){return await e.request({method:"frak_displayEmbeddedWallet",params:[t,e.config.metadata]})}async function Q(e,t){let{metadata:n,customizations:r}=e.config;return await e.request({method:"frak_sso",params:[t,n.name,r?.css]})??{}}async function X(e){return await e.request({method:"frak_getProductInformation"})}async function Y(e){if("undefined"==typeof window)return void console.warn("[Frak] No window found, can't track purchase");let t=window.sessionStorage.getItem("frak-wallet-interaction-token");if(!t)return void console.warn("[Frak] No frak session found, skipping purchase check");await fetch("https://backend.frak.id/interactions/listenForPurchase",{method:"POST",headers:{Accept:"application/json","Content-Type":"application/json","x-wallet-sdk-auth":t},body:JSON.stringify(e)})}async function Z(e,{siwe:t,metadata:n}){let r=e.config?.domain??window.location.host,a=t?.statement??`I confirm that I want to use my Frak wallet on: ${e.config.metadata.name}`,o={...t,statement:a,nonce:t?.nonce??h(),uri:t?.uri??`https://${r}`,version:t?.version??"1",domain:r};return(await H(e,{metadata:n,steps:{login:{},siweAuthenticate:{siwe:o}}})).siweAuthenticate}async function ee(e,{tx:t,metadata:n}){return(await H(e,{metadata:n,steps:{login:{},sendTransaction:{tx:t}}})).sendTransaction}function et(e,{metadata:t,login:n,openSession:r}){return function e(t,n){async function r(e){return e&&(n.metadata=e(n.metadata??{})),await H(t,n)}return{params:n,sendTx:function(r){return e(t,{...n,steps:{...n.steps,sendTransaction:r}})},reward:function(r){return e(t,{...n,steps:{...n.steps,final:{...r,action:{key:"reward"}}}})},sharing:function(r,a){return e(t,{...n,steps:{...n.steps,final:{...a,action:{key:"sharing",options:r}}}})},display:r}}(e,{steps:{login:n??{},openSession:r??{}},metadata:t})}let en={createLink:()=>({handlerTypeDenominator:w(M.referral),interactionData:B.referral.createLink}),referred({referrer:e}){let t=l([B.referral.referred,m(e,{size:32})]);return{handlerTypeDenominator:w(M.referral),interactionData:t}}};async function er(e,{walletStatus:r,frakContext:a,modalConfig:o,productId:i,options:s}){let c=!1;async function l(){if(!c)return c=!0,eo(e,{modalConfig:{...o,loggedIn:{action:{key:"referred"}}},walletStatus:r})}async function u(t){let n=en.referred({referrer:t});await Promise.allSettled([J(e,{productId:i,interaction:n}),_(e,"user_referred",{properties:{referrer:t}})])}try{let{status:e,currentWallet:t}=await ea({initialWalletStatus:r,getFreshWalletStatus:l,pushReferralInteraction:u,frakContext:a});return O.replaceUrl({url:window.location?.href,context:s?.alwaysAppendUrl?{r:t}:null}),e}catch(e){return console.log("Error processing referral",{error:e}),O.replaceUrl({url:window.location?.href,context:s?.alwaysAppendUrl?{r:r?.wallet}:null}),function(e){if(e instanceof t)switch(e.code){case n.walletNotConnected:return"no-wallet";case n.serverErrorForInteractionDelegation:return"no-session"}return"error"}(e)}}async function ea({initialWalletStatus:e,getFreshWalletStatus:t,pushReferralInteraction:n,frakContext:r}){let a=e?.wallet;return r?.r?(a||(a=await t()),a&&f(r.r,a))?{status:"self-referral",currentWallet:a}:(e?.interactionSession||(a=await t()),await n(r.r),{status:"success",currentWallet:a}):{status:"no-referrer",currentWallet:a}}async function eo(e,{modalConfig:t,walletStatus:n}){if(!n?.interactionSession){let n=await K(e,t??{});return n?.wallet??void 0}return n.wallet??void 0}async function ei(e,{productId:t,modalConfig:n,options:r}={}){let a=O.parse({url:window.location.href}),o=await j(e);try{return await er(e,{walletStatus:o,frakContext:a,modalConfig:n,productId:t,options:r})}catch(e){console.warn("Error processing referral",{error:e})}}let es={openArticle({articleId:e}){let t=l([B.press.openArticle,m(e,{size:32})]);return{handlerTypeDenominator:w(M.press),interactionData:t}},readArticle({articleId:e}){let t=l([B.press.readArticle,m(e,{size:32})]);return{handlerTypeDenominator:w(M.press),interactionData:t}}},ec={startPurchase({purchaseId:e}){let t=l([B.purchase.started,m(e,{size:32})]);return{handlerTypeDenominator:w(M.purchase),interactionData:t}},completedPurchase({purchaseId:e,proof:t}){let n=u([{type:"uint256"},{type:"bytes32[]"}],[BigInt(e),t]),r=l([B.purchase.completed,n]);return{handlerTypeDenominator:w(M.purchase),interactionData:r}},unsafeCompletedPurchase({purchaseId:e}){let t=l([B.purchase.unsafeCompleted,m(e,{size:32})]);return{handlerTypeDenominator:w(M.purchase),interactionData:t}}},el={open:()=>({handlerTypeDenominator:w(M.webshop),interactionData:B.webshop.open})},eu={customerMeeting({agencyId:e}){let t=l([B.retail.customerMeeting,m(e,{size:32})]);return{handlerTypeDenominator:w(M.retail),interactionData:t}}};export{y as DebugInfoGatherer,O as FrakContextManager,es as PressInteractionEncoder,ec as PurchaseInteractionEncoder,en as ReferralInteractionEncoder,eu as RetailInteractionEncoder,el as WebShopInteractionEncoder,C as base64urlDecode,F as base64urlEncode,k as baseIframeProps,T as compressJsonToB64,I as createIFrameFrakClient,b as createIframe,E as decompressJsonFromB64,K as displayEmbeddedWallet,H as displayModal,N as formatAmount,z as getCurrencyAmountKey,X as getProductInformation,L as getSupportedCurrency,W as getSupportedLocale,B as interactionTypes,R as locales,et as modalBuilder,Q as openSso,er as processReferral,M as productTypes,V as productTypesMask,ei as referralInteraction,J as sendInteraction,ee as sendTransaction,x as setupClient,Z as siweAuthenticate,_ as trackEvent,Y as trackPurchaseStatus,j as watchWalletStatus};