@frak-labs/core-sdk 0.2.0 → 0.2.1

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 (43) hide show
  1. package/cdn/bundle.js +3 -3
  2. package/dist/actions.cjs +1 -1
  3. package/dist/actions.d.cts +2 -2
  4. package/dist/actions.d.ts +2 -2
  5. package/dist/actions.js +1 -1
  6. package/dist/bundle.cjs +1 -1
  7. package/dist/bundle.d.cts +4 -4
  8. package/dist/bundle.d.ts +4 -4
  9. package/dist/bundle.js +1 -1
  10. package/dist/{computeLegacyProductId-Raks6FXg.d.cts → computeLegacyProductId-CCAZvLa5.d.cts} +45 -46
  11. package/dist/{computeLegacyProductId-BkyJ4rEY.d.ts → computeLegacyProductId-b5cUWdAm.d.ts} +45 -46
  12. package/dist/index.cjs +1 -1
  13. package/dist/index.d.cts +3 -3
  14. package/dist/index.d.ts +3 -3
  15. package/dist/index.js +1 -1
  16. package/dist/{openSso-BCJGchIb.d.cts → openSso-B0g7-807.d.cts} +40 -7
  17. package/dist/{openSso-DG-_9CED.d.ts → openSso-CMzwvaCa.d.ts} +40 -7
  18. package/dist/setupClient-BduY6Sym.cjs +13 -0
  19. package/dist/setupClient-ftmdQ-I8.js +13 -0
  20. package/dist/siweAuthenticate-BWmI2_TN.cjs +1 -0
  21. package/dist/{siweAuthenticate-Btem4QHs.d.ts → siweAuthenticate-CVigMOxz.d.cts} +28 -32
  22. package/dist/{siweAuthenticate-BH7Dn7nZ.d.cts → siweAuthenticate-CnCZ7mok.d.ts} +28 -32
  23. package/dist/siweAuthenticate-zczqxm0a.js +1 -0
  24. package/dist/trackEvent-CeLFVzZn.js +1 -0
  25. package/dist/trackEvent-Ew5r5zfI.cjs +1 -0
  26. package/package.json +1 -1
  27. package/src/actions/referral/processReferral.test.ts +109 -125
  28. package/src/actions/referral/processReferral.ts +134 -180
  29. package/src/actions/referral/referralInteraction.test.ts +3 -5
  30. package/src/actions/referral/referralInteraction.ts +2 -7
  31. package/src/index.ts +3 -0
  32. package/src/types/context.ts +48 -6
  33. package/src/types/index.ts +2 -1
  34. package/src/types/rpc/interaction.ts +5 -0
  35. package/src/types/tracking.ts +5 -34
  36. package/src/utils/FrakContext.test.ts +270 -186
  37. package/src/utils/FrakContext.ts +78 -56
  38. package/dist/setupClient-CQrMDGyZ.js +0 -13
  39. package/dist/setupClient-Ccv3XxwL.cjs +0 -13
  40. package/dist/siweAuthenticate-BJHbtty4.js +0 -1
  41. package/dist/siweAuthenticate-Cwj3HP0m.cjs +0 -1
  42. package/dist/trackEvent-M2RLTQ2p.js +0 -1
  43. package/dist/trackEvent-T_R9ER2S.cjs +0 -1
@@ -1,20 +1,39 @@
1
- import { type Address, bytesToHex, hexToBytes } from "viem";
2
- import type { FrakContext } from "../types";
1
+ import { type Address, bytesToHex, hexToBytes, isAddress } from "viem";
2
+ import type { FrakContext, FrakContextV1, FrakContextV2 } from "../types";
3
+ import { isV2Context } from "../types";
3
4
  import { base64urlDecode, base64urlEncode } from "./compression/b64";
5
+ import { compressJsonToB64 } from "./compression/compress";
6
+ import { decompressJsonFromB64 } from "./compression/decompress";
4
7
 
5
8
  /**
6
- * The context key
9
+ * URL parameter key for the Frak referral context
7
10
  */
8
11
  const contextKey = "fCtx";
9
12
 
10
13
  /**
11
- * Compress the current Frak context
12
- * @param context - The context to be compressed
13
- * @returns A compressed string containing the Frak context
14
+ * Compress a Frak context into a URL-safe string.
15
+ *
16
+ * - V2 contexts are serialized as compressed JSON (base64url).
17
+ * - V1 contexts encode the wallet address as raw bytes (base64url).
18
+ *
19
+ * @param context - The context to compress (V1 or V2)
20
+ * @returns A compressed base64url string, or undefined on failure
14
21
  */
15
- function compress(context?: Partial<FrakContext>): string | undefined {
16
- if (!context?.r) return;
22
+ function compress(context?: FrakContextV1 | FrakContextV2): string | undefined {
23
+ if (!context) return;
17
24
  try {
25
+ if (isV2Context(context)) {
26
+ // Runtime validation: all V2 fields must be present and truthy
27
+ if (!context.c || !context.m || !context.t) return undefined;
28
+ return compressJsonToB64({
29
+ v: 2,
30
+ c: context.c,
31
+ m: context.m,
32
+ t: context.t,
33
+ });
34
+ }
35
+
36
+ // V1 legacy: compress wallet address as raw bytes
18
37
  const bytes = hexToBytes(context.r);
19
38
  return base64urlEncode(bytes);
20
39
  } catch (e) {
@@ -24,15 +43,31 @@ function compress(context?: Partial<FrakContext>): string | undefined {
24
43
  }
25
44
 
26
45
  /**
27
- * Decompress the given Frak context
28
- * @param context - The raw context to be decompressed into a `FrakContext`
29
- * @returns The decompressed Frak context, or undefined if it fails
46
+ * Decompress a base64url string back into a Frak context.
47
+ *
48
+ * Attempts V2 JSON decompression first, then falls back to V1 raw bytes.
49
+ *
50
+ * @param context - The compressed context string
51
+ * @returns The decompressed FrakContext, or undefined on failure
30
52
  */
31
53
  function decompress(context?: string): FrakContext | undefined {
32
54
  if (!context || context.length === 0) return;
33
55
  try {
56
+ // Try V2 JSON first — V2 payloads are longer than V1's 20-byte address
57
+ const json = decompressJsonFromB64<FrakContextV2>(context);
58
+ if (json && typeof json === "object" && json.v === 2) {
59
+ if (json.c && json.m && json.t) {
60
+ return { v: 2, c: json.c, m: json.m, t: json.t };
61
+ }
62
+ return undefined;
63
+ }
64
+
65
+ // Fall back to V1: raw 20-byte address
34
66
  const bytes = base64urlDecode(context);
35
- return { r: bytesToHex(bytes, { size: 20 }) as Address };
67
+ const hex = bytesToHex(bytes, { size: 20 }) as Address;
68
+ if (isAddress(hex)) {
69
+ return { r: hex };
70
+ }
36
71
  } catch (e) {
37
72
  console.error("Error decompressing Frak context", { e, context });
38
73
  }
@@ -40,113 +75,100 @@ function decompress(context?: string): FrakContext | undefined {
40
75
  }
41
76
 
42
77
  /**
43
- * Parse the current URL into a Frak Context
78
+ * Parse a URL to extract the Frak referral context from the `fCtx` query parameter.
79
+ *
44
80
  * @param args
45
- * @param args.url - The url to parse
46
- * @returns The parsed Frak context
81
+ * @param args.url - The URL to parse
82
+ * @returns The parsed FrakContext, or null if absent
47
83
  */
48
- function parse({ url }: { url: string }) {
84
+ function parse({ url }: { url: string }): FrakContext | null | undefined {
49
85
  if (!url) return null;
50
86
 
51
- // Check if the url contain the frak context key
52
87
  const urlObj = new URL(url);
53
88
  const frakContext = urlObj.searchParams.get(contextKey);
54
89
  if (!frakContext) return null;
55
90
 
56
- // Decompress and return it
57
91
  return decompress(frakContext);
58
92
  }
59
93
 
60
94
  /**
61
- * Populate the current url with the given Frak context
95
+ * Add or replace the `fCtx` query parameter in a URL with the given context.
96
+ *
62
97
  * @param args
63
- * @param args.url - The url to update
64
- * @param args.context - The context to update
65
- * @returns The new url with the Frak context
98
+ * @param args.url - The URL to update
99
+ * @param args.context - The context to embed (V1 or V2)
100
+ * @returns The updated URL string, or null on failure
66
101
  */
67
102
  function update({
68
103
  url,
69
104
  context,
70
105
  }: {
71
106
  url?: string;
72
- context: Partial<FrakContext>;
73
- }) {
107
+ context: FrakContextV1 | FrakContextV2;
108
+ }): string | null {
74
109
  if (!url) return null;
75
110
 
76
- // Parse the current context
77
- const currentContext = parse({ url });
78
-
79
- // Merge the current context with the new context
80
- const mergedContext = currentContext
81
- ? { ...currentContext, ...context }
82
- : context;
83
-
84
- // If we don't have a referrer, early exit
85
- if (!mergedContext.r) return null;
86
-
87
- // Compress it
88
- const compressedContext = compress(mergedContext);
111
+ const compressedContext = compress(context);
89
112
  if (!compressedContext) return null;
90
113
 
91
- // Build the new url and return it
92
114
  const urlObj = new URL(url);
93
115
  urlObj.searchParams.set(contextKey, compressedContext);
94
116
  return urlObj.toString();
95
117
  }
96
118
 
97
119
  /**
98
- * Remove Frak context from current url
99
- * @param url - The url to update
100
- * @returns The new url without the Frak context
120
+ * Remove the `fCtx` query parameter from a URL.
121
+ *
122
+ * @param url - The URL to strip the context from
123
+ * @returns The cleaned URL string
101
124
  */
102
- function remove(url: string) {
125
+ function remove(url: string): string {
103
126
  const urlObj = new URL(url);
104
127
  urlObj.searchParams.delete(contextKey);
105
128
  return urlObj.toString();
106
129
  }
107
130
 
108
131
  /**
109
- * Replace the current url with the given Frak context
132
+ * Replace the current browser URL with an updated Frak context.
133
+ *
134
+ * - If `context` is non-null, embeds it via {@link update}.
135
+ * - If `context` is null, strips the context via {@link remove}.
136
+ *
110
137
  * @param args
111
- * @param args.url - The url to update
112
- * @param args.context - The context to update
138
+ * @param args.url - Base URL (defaults to `window.location.href`)
139
+ * @param args.context - Context to set, or null to remove
113
140
  */
114
141
  function replaceUrl({
115
142
  url: baseUrl,
116
143
  context,
117
144
  }: {
118
145
  url?: string;
119
- context: Partial<FrakContext> | null;
146
+ context: FrakContextV1 | FrakContextV2 | null;
120
147
  }) {
121
- // If no window here early exit
122
148
  if (!window.location?.href || typeof window === "undefined") {
123
149
  console.error("No window found, can't update context");
124
150
  return;
125
151
  }
126
152
 
127
- // If no url, try to use the current one
128
153
  const url = baseUrl ?? window.location.href;
129
154
 
130
- // Get our new url with the frak context
131
155
  let newUrl: string | null;
132
156
  if (context !== null) {
133
- newUrl = update({
134
- url,
135
- context,
136
- });
157
+ newUrl = update({ url, context });
137
158
  } else {
138
159
  newUrl = remove(url);
139
160
  }
140
161
 
141
- // If no new url, early exit
142
162
  if (!newUrl) return;
143
163
 
144
- // Update the url
145
164
  window.history.replaceState(null, "", newUrl.toString());
146
165
  }
147
166
 
148
167
  /**
149
- * Export our frak context
168
+ * Manager for Frak referral context in URLs.
169
+ *
170
+ * Handles compression, decompression, URL parsing, and browser history updates
171
+ * for both V1 (wallet address) and V2 (anonymous clientId) referral contexts.
150
172
  */
151
173
  export const FrakContextManager = {
152
174
  compress,
@@ -1,13 +0,0 @@
1
- import{f as e,h as t}from"./trackEvent-M2RLTQ2p.js";import{Deferred as n,FrakRpcError as r,RpcErrorCodes as i,createRpcClient as a,jsonDecode as o}from"@frak-labs/frame-connector";import{OpenPanel as s}from"@openpanel/web";function c(t){return o(e(t))}const l=`nexus-wallet-backup`,u=`frakwallet://`;function d(){let e=navigator.userAgent;return/Android/i.test(e)&&/Chrome\/\d+/i.test(e)}function f(e){return`intent://${e.slice(13)}#Intent;scheme=frakwallet;end`}function p(e,t){let n=t?.timeout??2500,r=!1,i=()=>{document.hidden&&(r=!0)};document.addEventListener(`visibilitychange`,i);let a=d()&&m(e)?f(e):e;window.location.href=a,setTimeout(()=>{document.removeEventListener(`visibilitychange`,i),r||t?.onFallback?.()},n)}function m(e){return e.startsWith(u)}const h={eur:`fr-FR`,usd:`en-US`,gbp:`en-GB`};function g(e){return e&&e in h?e:`eur`}function _(e){return e?h[e]??h.eur:h.eur}function v(e,t){let n=_(t),r=g(t);return e.toLocaleString(n,{style:`currency`,currency:r,minimumFractionDigits:0,maximumFractionDigits:2})}function y(e){return e?`${e}Amount`:`eurAmount`}const b={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 x({walletBaseUrl:e,config:n}){let r=document.querySelector(`#frak-wallet`);r&&r.remove();let i=document.createElement(`iframe`);i.id=b.id,i.name=b.name,i.allow=b.allow,i.style.zIndex=b.style.zIndex.toString(),S({iframe:i,isVisible:!1});let a=n?.walletUrl??e??`https://wallet.frak.id`,o=t();return i.src=`${a}/listener?clientId=${encodeURIComponent(o)}`,new Promise(e=>{i.addEventListener(`load`,()=>e(i)),document.body.appendChild(i)})}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 C(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 w(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 T=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(),n=this.getNavigatorInfo(),i=`Unknown`;return e instanceof r?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: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: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 E=(()=>{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 D(e){e?localStorage.setItem(l,e):localStorage.removeItem(l)}function O(e,n,r,i){let a=new URL(window.location.href),o=a.searchParams.get(`fmt`)??void 0;e.contentWindow?.postMessage({clientLifecycle:`handshake-response`,data:{token:n,currentUrl:window.location.href,pendingMergeToken:o,configDomain:i,clientId:t()}},r),o&&(a.searchParams.delete(`fmt`),window.history.replaceState({},``,a.toString()))}function k(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 A(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 j(e){return e.includes(`/common/social`)}function M(e,t,n,r){if(m(t)){let i=k(t,r);p(i,{onFallback:()=>{e.contentWindow?.postMessage({clientLifecycle:`deep-link-failed`,data:{originalUrl:i}},n)}})}else if(E&&j(t))A(r);else{let e=k(t,r);window.location.href=e}}function N({iframe:e,targetOrigin:t,configDomain:r}){let i=new n;return{handleEvent:async n=>{if(!(`iframeLifecycle`in n))return;let{iframeLifecycle:a,data:o}=n;switch(a){case`connected`:i.resolve(!0);break;case`do-backup`:D(o.backup);break;case`remove-backup`:localStorage.removeItem(l);break;case`show`:case`hide`:S({iframe:e,isVisible:a===`show`});break;case`handshake`:O(e,o.token,t,r);break;case`redirect`:M(e,o.baseRedirectUrl,t,o.mergeToken);break}},isConnected:i.promise}}function P({config:e,iframe:n}){let o=e?.walletUrl??`https://wallet.frak.id`,c=N({iframe:n,targetOrigin:o,configDomain:e.domain}),l=new T(e,n);if(!n.contentWindow)throw new r(i.configError,`The iframe does not have a content window`);let u=a({emittingTransport:n.contentWindow,listeningTransport:window,targetOrigin:o,middleware:[{async onRequest(e,t){if(!await c.isConnected)throw new r(i.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=F(u,c),f=async()=>{d(),u.cleanup(),n.remove()},p;console.log(`[Frak SDK] Initializing OpenPanel`),p=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:n})=>(e!==`track`||!n?.properties||`sdkVersion`in n.properties||(n.properties={...n.properties,sdkVersion:`0.2.0`,userAnonymousClientId:t()}),!0)}),p.setGlobalProperties({sdkVersion:`0.2.0`,userAnonymousClientId:t()}),p.init();let m=I({config:e,rpcClient:u,lifecycleManager:c}).then(()=>l.updateSetupStatus(!0));return{config:e,debugInfo:l,waitForConnection:c.isConnected,waitForSetup:m,request:u.request,listenerRequest:u.listen,destroy:f,openPanel:p}}function F(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 I({config:e,rpcClient:t,lifecycleManager:n}){await n.isConnected,w(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(l);if(!e)return;let n={clientLifecycle:`restore-backup`,data:{backup:e}};t.sendLifecycle(n)}await Promise.allSettled([r(),i(),a()])}async function L({config:e}){let t=R(e),n=await x({config:t});if(!n){console.error(`Failed to create iframe`);return}let r=P({config:t,iframe:n});if(await r.waitForSetup,!await r.waitForConnection){console.error(`Failed to connect to client`);return}return r}function R(e){let t=g(e.metadata?.currency);return{...e,metadata:{...e.metadata,currency:t}}}export{c as _,x as a,v as c,h as d,d as f,u as g,p as h,b as i,_ as l,f as m,P as n,C as o,m as p,T as r,y as s,L as t,g as u};
@@ -1,13 +0,0 @@
1
- const e=require(`./trackEvent-T_R9ER2S.cjs`);let t=require(`@frak-labs/frame-connector`),n=require(`@openpanel/web`);function r(n){return(0,t.jsonDecode)(e.f(n))}const i=`nexus-wallet-backup`,a=`frakwallet://`;function o(){let e=navigator.userAgent;return/Android/i.test(e)&&/Chrome\/\d+/i.test(e)}function s(e){return`intent://${e.slice(13)}#Intent;scheme=frakwallet;end`}function c(e,t){let n=t?.timeout??2500,r=!1,i=()=>{document.hidden&&(r=!0)};document.addEventListener(`visibilitychange`,i);let a=o()&&l(e)?s(e):e;window.location.href=a,setTimeout(()=>{document.removeEventListener(`visibilitychange`,i),r||t?.onFallback?.()},n)}function l(e){return e.startsWith(a)}const u={eur:`fr-FR`,usd:`en-US`,gbp:`en-GB`};function d(e){return e&&e in u?e:`eur`}function f(e){return e?u[e]??u.eur:u.eur}function p(e,t){let n=f(t),r=d(t);return e.toLocaleString(n,{style:`currency`,currency:r,minimumFractionDigits:0,maximumFractionDigits:2})}function m(e){return e?`${e}Amount`:`eurAmount`}const h={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 g({walletBaseUrl:t,config:n}){let r=document.querySelector(`#frak-wallet`);r&&r.remove();let i=document.createElement(`iframe`);i.id=h.id,i.name=h.name,i.allow=h.allow,i.style.zIndex=h.style.zIndex.toString(),_({iframe:i,isVisible:!1});let a=n?.walletUrl??t??`https://wallet.frak.id`,o=e.h();return i.src=`${a}/listener?clientId=${encodeURIComponent(o)}`,new Promise(e=>{i.addEventListener(`load`,()=>e(i)),document.body.appendChild(i)})}function _({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 v(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 y(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 b=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 x=(()=>{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 S(e){e?localStorage.setItem(i,e):localStorage.removeItem(i)}function C(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.h()}},r),o&&(a.searchParams.delete(`fmt`),window.history.replaceState({},``,a.toString()))}function w(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 T(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 E(e){return e.includes(`/common/social`)}function D(e,t,n,r){if(l(t)){let i=w(t,r);c(i,{onFallback:()=>{e.contentWindow?.postMessage({clientLifecycle:`deep-link-failed`,data:{originalUrl:i}},n)}})}else if(x&&E(t))T(r);else{let e=w(t,r);window.location.href=e}}function O({iframe:e,targetOrigin:n,configDomain:r}){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`:S(s.backup);break;case`remove-backup`:localStorage.removeItem(i);break;case`show`:case`hide`:_({iframe:e,isVisible:o===`show`});break;case`handshake`:C(e,s.token,n,r);break;case`redirect`:D(e,s.baseRedirectUrl,n,s.mergeToken);break}},isConnected:a.promise}}function k({config:r,iframe:i}){let a=r?.walletUrl??`https://wallet.frak.id`,o=O({iframe:i,targetOrigin:a,configDomain:r.domain}),s=new b(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=A(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:`f305d11d-b93b-487c-80d4-92deb7903e98`,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.h()}),!0)}),d.setGlobalProperties({sdkVersion:`0.2.0`,userAnonymousClientId:e.h()}),d.init();let f=j({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 A(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 j({config:e,rpcClient:t,lifecycleManager:n}){await n.isConnected,y(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 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(i);if(!e)return;let n={clientLifecycle:`restore-backup`,data:{backup:e}};t.sendLifecycle(n)}await Promise.allSettled([r(),a(),o()])}async function M({config:e}){let t=N(e),n=await g({config:t});if(!n){console.error(`Failed to create iframe`);return}let r=k({config:t,iframe:n});if(await r.waitForSetup,!await r.waitForConnection){console.error(`Failed to connect to client`);return}return r}function N(e){let t=d(e.metadata?.currency);return{...e,metadata:{...e.metadata,currency:t}}}Object.defineProperty(exports,`_`,{enumerable:!0,get:function(){return r}}),Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return g}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return p}}),Object.defineProperty(exports,`d`,{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,`f`,{enumerable:!0,get:function(){return o}}),Object.defineProperty(exports,`g`,{enumerable:!0,get:function(){return a}}),Object.defineProperty(exports,`h`,{enumerable:!0,get:function(){return c}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return h}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return f}}),Object.defineProperty(exports,`m`,{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return k}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return v}}),Object.defineProperty(exports,`p`,{enumerable:!0,get:function(){return l}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return b}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return m}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return M}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return d}});
@@ -1 +0,0 @@
1
- import{a as e,h as t,o as n,r,t as i}from"./trackEvent-M2RLTQ2p.js";import{isAddressEqual as a}from"viem";import{Deferred as o,FrakRpcError as s,RpcErrorCodes as c}from"@frak-labs/frame-connector";import{generateSiweNonce as l}from"viem/siwe";async function u(e,t){return await e.request({method:`frak_displayEmbeddedWallet`,params:[t,e.config.metadata]})}async function d(e,{steps:t,metadata:n}){return await e.request({method:`frak_displayModal`,params:[t,n,e.config.metadata]})}async function f(e){if(typeof window>`u`)return;let i=t();if(!i)return;let a=await r();if(!a)return;let o=`frak-identity-ensured-${a}`;if(!window.sessionStorage.getItem(o))try{let t=n();(await fetch(`${t}/user/identity/ensure`,{method:`POST`,headers:{Accept:`application/json`,"Content-Type":`application/json`,"x-wallet-sdk-auth":e,"x-frak-client-id":i},body:JSON.stringify({merchantId:a})})).ok&&window.sessionStorage.setItem(o,`1`)}catch{}}async function p(e){return await e.request({method:`frak_getMerchantInformation`})}async function m(e,t){let{metadata:n,customizations:r}=e.config;return await e.request({method:`frak_prepareSso`,params:[t,n.name,r?.css]})}async function h(e,n){try{await e.request({method:`frak_sendInteraction`,params:[n,{clientId:t()}]})}catch{console.warn(`[Frak SDK] Failed to send interaction:`,n.type)}}async function g(t,{walletStatus:n,frakContext:r,modalConfig:a,options:o}){if(!r?.r)return`no-referrer`;i(t,`user_referred_started`,{properties:{referrer:r?.r,walletStatus:n?.key}}),h(t,{type:`arrival`,referrerWallet:r.r,landingUrl:typeof window<`u`?window.location.href:void 0});let c=!1;async function l(){if(!c)return c=!0,v(t,{modalConfig:{...a,loggedIn:{action:{key:`referred`}}},walletStatus:n})}try{let{status:a,currentWallet:s}=await _({initialWalletStatus:n,getFreshWalletStatus:l,frakContext:r});return e.replaceUrl({url:window.location?.href,context:o?.alwaysAppendUrl?{r:s}:null}),i(t,`user_referred_completed`,{properties:{status:a,referrer:r?.r,wallet:s}}),a}catch(a){return console.log(`Error processing referral`,{error:a}),i(t,`user_referred_error`,{properties:{referrer:r?.r,error:a instanceof s?`[${a.code}] ${a.name} - ${a.message}`:a instanceof Error?a.message:`undefined`}}),e.replaceUrl({url:window.location?.href,context:o?.alwaysAppendUrl?{r:n?.wallet}:null}),y(a)}}async function _({initialWalletStatus:e,getFreshWalletStatus:t,frakContext:n}){let r=e?.wallet;return r||=await t(),r&&a(n.r,r)?{status:`self-referral`,currentWallet:r}:{status:`success`,currentWallet:r}}async function v(e,{modalConfig:t,walletStatus:n}){return n?.key===`connected`?n.wallet??void 0:(await u(e,t??{}))?.wallet??void 0}function y(e){if(e instanceof s)switch(e.code){case c.walletNotConnected:return`no-wallet`;default:return`error`}return`error`}async function b(t,{modalConfig:n,options:r}={}){let i=e.parse({url:window.location.href}),a=await S(t);try{return await g(t,{walletStatus:a,frakContext:i,modalConfig:n,options:r})}catch(e){console.warn(`Error processing referral`,{error:e})}}async function x(e){if(typeof window>`u`){console.warn(`[Frak] No window found, can't track purchase`);return}let i=window.sessionStorage.getItem(`frak-wallet-interaction-token`),a=t();if(!i&&!a){console.warn(`[Frak] No identity found, skipping purchase check`);return}let o=window.sessionStorage.getItem(`frak-merchant-id`),s=e.merchantId??o??await r();if(!s){console.warn(`[Frak] No merchant id found, skipping purchase check`);return}let c={Accept:`application/json`,"Content-Type":`application/json`};i&&(c[`x-wallet-sdk-auth`]=i),a&&(c[`x-frak-client-id`]=a);let l=n();await fetch(`${l}/user/track/purchase`,{method:`POST`,headers:c,body:JSON.stringify({customerId:e.customerId,orderId:e.orderId,token:e.token,merchantId:s})})}function S(e,t){if(!t)return e.request({method:`frak_listenToWalletStatus`}).then(t=>(C(e,t),t));let n=new o,r=!1;return e.listenerRequest({method:`frak_listenToWalletStatus`},i=>{C(e,i),t(i),r||=(n.resolve(i),!0)}),n.promise}function C(e,t){typeof window>`u`||(e.openPanel?.setGlobalProperties({wallet:t.wallet??null}),t.interactionToken?(window.sessionStorage.setItem(`frak-wallet-interaction-token`,t.interactionToken),f(t.interactionToken)):window.sessionStorage.removeItem(`frak-wallet-interaction-token`))}function w(e,{metadata:t,login:n}){return T(e,{steps:{login:n??{}},metadata:t})}function T(e,t){function n(n){return T(e,{...t,steps:{...t.steps,sendTransaction:n}})}function r(n){return T(e,{...t,steps:{...t.steps,final:{...n,action:{key:`reward`}}}})}function i(n,r){return T(e,{...t,steps:{...t.steps,final:{...r,action:{key:`sharing`,options:n}}}})}async function a(n){return n&&(t.metadata=n(t.metadata??{})),await d(e,t)}return{params:t,sendTx:n,reward:r,sharing:i,display:a}}async function E(e,{tx:t,metadata:n}){return(await d(e,{metadata:n,steps:{login:{},sendTransaction:{tx:t}}})).sendTransaction}async function D(e,{siwe:t,metadata:n}){let r=e.config?.domain??window.location.host,i=t?.statement??`I confirm that I want to use my Frak wallet on: ${e.config.metadata.name}`;return(await d(e,{metadata:n,steps:{login:{},siweAuthenticate:{siwe:{...t,statement:i,nonce:t?.nonce??l(),uri:t?.uri??`https://${r}`,version:t?.version??`1`,domain:r}}}})).siweAuthenticate}export{x as a,h as c,f as d,d as f,S as i,m as l,E as n,b as o,u as p,w as r,g as s,D as t,p as u};
@@ -1 +0,0 @@
1
- const e=require(`./trackEvent-T_R9ER2S.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.h();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.o();(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.h()}]})}catch{console.warn(`[Frak SDK] Failed to send interaction:`,n.type)}}async function u(t,{walletStatus:r,frakContext:i,modalConfig:a,options:o}){if(!i?.r)return`no-referrer`;e.t(t,`user_referred_started`,{properties:{referrer:i?.r,walletStatus:r?.key}}),l(t,{type:`arrival`,referrerWallet:i.r,landingUrl:typeof window<`u`?window.location.href:void 0});let s=!1;async function c(){if(!s)return s=!0,f(t,{modalConfig:{...a,loggedIn:{action:{key:`referred`}}},walletStatus:r})}try{let{status:n,currentWallet:a}=await d({initialWalletStatus:r,getFreshWalletStatus:c,frakContext:i});return e.a.replaceUrl({url:window.location?.href,context:o?.alwaysAppendUrl?{r:a}:null}),e.t(t,`user_referred_completed`,{properties:{status:n,referrer:i?.r,wallet:a}}),n}catch(a){return console.log(`Error processing referral`,{error:a}),e.t(t,`user_referred_error`,{properties:{referrer:i?.r,error:a instanceof n.FrakRpcError?`[${a.code}] ${a.name} - ${a.message}`:a instanceof Error?a.message:`undefined`}}),e.a.replaceUrl({url:window.location?.href,context:o?.alwaysAppendUrl?{r:r?.wallet}:null}),p(a)}}async function d({initialWalletStatus:e,getFreshWalletStatus:n,frakContext:r}){let i=e?.wallet;return i||=await n(),i&&(0,t.isAddressEqual)(r.r,i)?{status:`self-referral`,currentWallet:i}:{status:`success`,currentWallet:i}}async function f(e,{modalConfig:t,walletStatus:n}){return n?.key===`connected`?n.wallet??void 0:(await i(e,t??{}))?.wallet??void 0}function p(e){if(e instanceof n.FrakRpcError)switch(e.code){case n.RpcErrorCodes.walletNotConnected:return`no-wallet`;default:return`error`}return`error`}async function m(t,{modalConfig:n,options:r}={}){let i=e.a.parse({url:window.location.href}),a=await g(t);try{return await u(t,{walletStatus:a,frakContext:i,modalConfig:n,options:r})}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.h();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.o();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 u}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return x}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return s}});
@@ -1 +0,0 @@
1
- import{bytesToHex as e,hexToBytes as t,keccak256 as n,toHex as r}from"viem";import{jsonEncode as i}from"@frak-labs/frame-connector";const a=`frak-client-id`;function o(){return typeof crypto<`u`&&crypto.randomUUID?crypto.randomUUID():`xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx`.replace(/[xy]/g,e=>{let t=Math.random()*16|0;return(e===`x`?t:t&3|8).toString(16)})}function s(){if(typeof window>`u`||!window.localStorage)return console.warn(`[Frak SDK] No Window / localStorage available to save the clientId`),o();let e=localStorage.getItem(a);return e||(e=o(),localStorage.setItem(a,e)),e}function c({domain:e}={}){return n(r((e??window.location.host).replace(`www.`,``)))}function l(e){return btoa(Array.from(e,e=>String.fromCharCode(e)).join(``)).replace(/\+/g,`-`).replace(/\//g,`_`).replace(/=+$/,``)}function u(e){let t=e.length%4;return Uint8Array.from(atob(e.replace(/-/g,`+`).replace(/_/g,`/`).padEnd(e.length+(t===0?0:4-t),`=`)),e=>e.charCodeAt(0))}function d(e){return l(i(e))}function f(e,t,n,r,i,a){let o=d(p({redirectUrl:t.redirectUrl,directExit:t.directExit,lang:t.lang,merchantId:n,metadata:{name:r,css:a,logoUrl:t.metadata?.logoUrl,homepageLink:t.metadata?.homepageLink},clientId:i})),s=new URL(e);return s.pathname=`/sso`,s.searchParams.set(`p`,o),s.toString()}function p(e){return{r:e.redirectUrl,cId:e.clientId,d:e.directExit,l:e.lang,m:e.merchantId,md:{n:e.metadata?.name,css:e.metadata?.css,l:e.metadata?.logoUrl,h:e.metadata?.homepageLink}}}const m=`menubar=no,status=no,scrollbars=no,fullscreen=no,width=500, height=800`,h=`frak-sso`;async function g(e,t){let{metadata:n,customizations:r,walletUrl:i}=e.config;if(t.openInSameWindow??!!t.redirectUrl)return await e.request({method:`frak_openSso`,params:[t,n.name,r?.css]});let a=t.ssoPopupUrl??f(i??`https://wallet.frak.id`,t,c(),n.name,s(),r?.css),o=window.open(a,h,m);if(!o)throw Error(`Popup was blocked. Please allow popups for this site.`);return o.focus(),await e.request({method:`frak_openSso`,params:[t,n.name,r?.css]})??{}}const _=`https://backend.frak.id`;function v(e){return e.includes(`localhost:3000`)||e.includes(`localhost:3010`)}function y(e){return v(e)?`http://localhost:3030`:e.includes(`wallet-dev.frak.id`)||e.includes(`wallet.gcp-dev.frak.id`)?`https://backend.gcp-dev.frak.id`:_}function b(e){if(e)return y(e);if(typeof window<`u`){let e=window.FrakSetup?.client?.config?.walletUrl;if(e)return y(e)}return _}const x=`fCtx`;function S(e){if(e?.r)try{return l(t(e.r))}catch(t){console.error(`Error compressing Frak context`,{e:t,context:e})}}function C(t){if(!(!t||t.length===0))try{return{r:e(u(t),{size:20})}}catch(e){console.error(`Error decompressing Frak context`,{e,context:t})}}function w({url:e}){if(!e)return null;let t=new URL(e).searchParams.get(x);return t?C(t):null}function T({url:e,context:t}){if(!e)return null;let n=w({url:e}),r=n?{...n,...t}:t;if(!r.r)return null;let i=S(r);if(!i)return null;let a=new URL(e);return a.searchParams.set(x,i),a.toString()}function E(e){let t=new URL(e);return t.searchParams.delete(x),t.toString()}function D({url:e,context:t}){if(!window.location?.href||typeof window>`u`){console.error(`No window found, can't update context`);return}let n=e??window.location.href,r;r=t===null?E(n):T({url:n,context:t}),r&&window.history.replaceState(null,``,r.toString())}const O={compress:S,decompress:C,parse:w,update:T,remove:E,replaceUrl:D},k=`frak-merchant-id`;let A,j;async function M(e,t){if(A)return A;if(typeof window<`u`){let e=window.sessionStorage.getItem(k);if(e)return A=e,e}if(j)return j;j=N(e,t);let n=await j;return j=void 0,n}async function N(e,t){let n=e??(typeof window<`u`?window.location.hostname:``);if(n)try{let e=b(t),r=await fetch(`${e}/user/merchant/resolve?domain=${encodeURIComponent(n)}`);if(!r.ok){console.warn(`[Frak SDK] Merchant lookup failed for domain ${n}: ${r.status}`);return}let i=await r.json();return A=i.merchantId,typeof window<`u`&&window.sessionStorage.setItem(k,i.merchantId),A}catch(e){console.warn(`[Frak SDK] Failed to fetch merchantId:`,e);return}}function P(){A=void 0,j=void 0,typeof window<`u`&&window.sessionStorage.removeItem(k)}async function F(e,t){return e.metadata?.merchantId?e.metadata.merchantId:M(void 0,t)}function I(e,t,n={}){if(!e){console.debug(`[Frak] No client provided, skipping event tracking`);return}try{e.openPanel?.track(t,n)}catch(e){console.debug(`[Frak] Failed to track event:`,t,e)}}export{O as a,m as c,d,u as f,s as h,F as i,h as l,c as m,P as n,b as o,l as p,M as r,g as s,I as t,f as u};
@@ -1 +0,0 @@
1
- let e=require(`viem`),t=require(`@frak-labs/frame-connector`);const n=`frak-client-id`;function r(){return typeof crypto<`u`&&crypto.randomUUID?crypto.randomUUID():`xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx`.replace(/[xy]/g,e=>{let t=Math.random()*16|0;return(e===`x`?t:t&3|8).toString(16)})}function i(){if(typeof window>`u`||!window.localStorage)return console.warn(`[Frak SDK] No Window / localStorage available to save the clientId`),r();let e=localStorage.getItem(n);return e||(e=r(),localStorage.setItem(n,e)),e}function a({domain:t}={}){return(0,e.keccak256)((0,e.toHex)((t??window.location.host).replace(`www.`,``)))}function o(e){return btoa(Array.from(e,e=>String.fromCharCode(e)).join(``)).replace(/\+/g,`-`).replace(/\//g,`_`).replace(/=+$/,``)}function s(e){let t=e.length%4;return Uint8Array.from(atob(e.replace(/-/g,`+`).replace(/_/g,`/`).padEnd(e.length+(t===0?0:4-t),`=`)),e=>e.charCodeAt(0))}function c(e){return o((0,t.jsonEncode)(e))}function l(e,t,n,r,i,a){let o=c(u({redirectUrl:t.redirectUrl,directExit:t.directExit,lang:t.lang,merchantId:n,metadata:{name:r,css:a,logoUrl:t.metadata?.logoUrl,homepageLink:t.metadata?.homepageLink},clientId:i})),s=new URL(e);return s.pathname=`/sso`,s.searchParams.set(`p`,o),s.toString()}function u(e){return{r:e.redirectUrl,cId:e.clientId,d:e.directExit,l:e.lang,m:e.merchantId,md:{n:e.metadata?.name,css:e.metadata?.css,l:e.metadata?.logoUrl,h:e.metadata?.homepageLink}}}const d=`menubar=no,status=no,scrollbars=no,fullscreen=no,width=500, height=800`,f=`frak-sso`;async function p(e,t){let{metadata:n,customizations:r,walletUrl:o}=e.config;if(t.openInSameWindow??!!t.redirectUrl)return await e.request({method:`frak_openSso`,params:[t,n.name,r?.css]});let s=t.ssoPopupUrl??l(o??`https://wallet.frak.id`,t,a(),n.name,i(),r?.css),c=window.open(s,f,d);if(!c)throw Error(`Popup was blocked. Please allow popups for this site.`);return c.focus(),await e.request({method:`frak_openSso`,params:[t,n.name,r?.css]})??{}}const m=`https://backend.frak.id`;function h(e){return e.includes(`localhost:3000`)||e.includes(`localhost:3010`)}function g(e){return h(e)?`http://localhost:3030`:e.includes(`wallet-dev.frak.id`)||e.includes(`wallet.gcp-dev.frak.id`)?`https://backend.gcp-dev.frak.id`:m}function _(e){if(e)return g(e);if(typeof window<`u`){let e=window.FrakSetup?.client?.config?.walletUrl;if(e)return g(e)}return m}const v=`fCtx`;function y(t){if(t?.r)try{return o((0,e.hexToBytes)(t.r))}catch(e){console.error(`Error compressing Frak context`,{e,context:t})}}function b(t){if(!(!t||t.length===0))try{return{r:(0,e.bytesToHex)(s(t),{size:20})}}catch(e){console.error(`Error decompressing Frak context`,{e,context:t})}}function x({url:e}){if(!e)return null;let t=new URL(e).searchParams.get(v);return t?b(t):null}function S({url:e,context:t}){if(!e)return null;let n=x({url:e}),r=n?{...n,...t}:t;if(!r.r)return null;let i=y(r);if(!i)return null;let a=new URL(e);return a.searchParams.set(v,i),a.toString()}function C(e){let t=new URL(e);return t.searchParams.delete(v),t.toString()}function w({url:e,context:t}){if(!window.location?.href||typeof window>`u`){console.error(`No window found, can't update context`);return}let n=e??window.location.href,r;r=t===null?C(n):S({url:n,context:t}),r&&window.history.replaceState(null,``,r.toString())}const T={compress:y,decompress:b,parse:x,update:S,remove:C,replaceUrl:w},E=`frak-merchant-id`;let D,O;async function k(e,t){if(D)return D;if(typeof window<`u`){let e=window.sessionStorage.getItem(E);if(e)return D=e,e}if(O)return O;O=A(e,t);let n=await O;return O=void 0,n}async function A(e,t){let n=e??(typeof window<`u`?window.location.hostname:``);if(n)try{let e=_(t),r=await fetch(`${e}/user/merchant/resolve?domain=${encodeURIComponent(n)}`);if(!r.ok){console.warn(`[Frak SDK] Merchant lookup failed for domain ${n}: ${r.status}`);return}let i=await r.json();return D=i.merchantId,typeof window<`u`&&window.sessionStorage.setItem(E,i.merchantId),D}catch(e){console.warn(`[Frak SDK] Failed to fetch merchantId:`,e);return}}function j(){D=void 0,O=void 0,typeof window<`u`&&window.sessionStorage.removeItem(E)}async function M(e,t){return e.metadata?.merchantId?e.metadata.merchantId:k(void 0,t)}function N(e,t,n={}){if(!e){console.debug(`[Frak] No client provided, skipping event tracking`);return}try{e.openPanel?.track(t,n)}catch(e){console.debug(`[Frak] Failed to track event:`,t,e)}}Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return T}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,`d`,{enumerable:!0,get:function(){return c}}),Object.defineProperty(exports,`f`,{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,`h`,{enumerable:!0,get:function(){return i}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return M}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return f}}),Object.defineProperty(exports,`m`,{enumerable:!0,get:function(){return a}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return j}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return _}}),Object.defineProperty(exports,`p`,{enumerable:!0,get:function(){return o}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return k}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return p}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return N}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return l}});