@frak-labs/core-sdk 1.0.2-beta.64c76510 → 1.0.2-beta.75bb63ae
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -1
- package/package.json +4 -4
- package/src/actions/ensureIdentity.ts +3 -3
- package/src/actions/openSso.ts +4 -4
- package/src/actions/referral/processReferral.test.ts +38 -22
- package/src/actions/referral/processReferral.ts +6 -4
- package/src/actions/referral/referralInteraction.test.ts +7 -7
- package/src/actions/referral/referralInteraction.ts +1 -1
- package/src/actions/sendInteraction.ts +1 -1
- package/src/actions/trackPurchaseStatus.test.ts +4 -4
- package/src/actions/trackPurchaseStatus.ts +3 -3
- package/src/actions/wrapper/siweAuthenticate.test.ts +1 -5
- package/src/actions/wrapper/siweAuthenticate.ts +25 -1
- package/src/clients/createIFrameFrakClient.ts +5 -21
- package/src/clients/index.ts +0 -1
- package/src/clients/transports/iframeLifecycleManager.test.ts +10 -10
- package/src/clients/transports/iframeLifecycleManager.ts +3 -3
- package/src/config/index.ts +3 -0
- package/src/{utils → config}/sdkConfigStore.ts +1 -1
- package/src/{utils/constants.test.ts → constants.test.ts} +1 -6
- package/src/context/address.ts +76 -0
- package/src/{utils/FrakContext.test.ts → context/frakContext.test.ts} +4 -2
- package/src/{utils/FrakContext.ts → context/frakContext.ts} +4 -4
- package/src/{utils → context}/frakContextV2Codec.test.ts +1 -1
- package/src/{utils → context}/frakContextV2Codec.ts +6 -6
- package/src/context/index.ts +6 -0
- package/src/index.ts +17 -22
- package/src/stubs/rrweb.ts +8 -4
- package/src/types/client.ts +0 -3
- package/src/types/config.ts +11 -0
- package/src/types/index.ts +1 -0
- package/src/utils/{deepLinkWithFallback.ts → browser/deepLinkWithFallback.ts} +1 -1
- package/src/utils/{inAppBrowser.ts → browser/inAppBrowser.ts} +13 -0
- package/src/utils/browser/index.ts +13 -0
- package/src/utils/{formatAmount.test.ts → format/formatAmount.test.ts} +1 -1
- package/src/utils/{formatAmount.ts → format/formatAmount.ts} +1 -1
- package/src/utils/{getCurrencyAmountKey.test.ts → format/getCurrencyAmountKey.test.ts} +2 -2
- package/src/utils/{getCurrencyAmountKey.ts → format/getCurrencyAmountKey.ts} +1 -1
- package/src/utils/{getSupportedCurrency.test.ts → format/getSupportedCurrency.test.ts} +2 -2
- package/src/utils/{getSupportedCurrency.ts → format/getSupportedCurrency.ts} +2 -2
- package/src/utils/{getSupportedLocale.test.ts → format/getSupportedLocale.test.ts} +3 -3
- package/src/utils/{getSupportedLocale.ts → format/getSupportedLocale.ts} +2 -2
- package/src/utils/format/index.ts +4 -0
- package/src/utils/{iframeHelper.test.ts → iframe/iframeHelper.test.ts} +3 -3
- package/src/utils/{iframeHelper.ts → iframe/iframeHelper.ts} +3 -3
- package/src/utils/iframe/index.ts +6 -0
- package/src/utils/index.ts +31 -24
- package/src/utils/sso/index.ts +6 -0
- package/src/utils/{sso.ts → sso/sso.ts} +2 -2
- package/cdn/bundle.js +0 -14
- package/dist/actions-DihYM-OG.js +0 -1
- package/dist/actions-cYbmqewX.cjs +0 -1
- package/dist/actions.cjs +0 -1
- package/dist/actions.d.cts +0 -3
- package/dist/actions.d.ts +0 -3
- package/dist/actions.js +0 -1
- package/dist/bundle.cjs +0 -1
- package/dist/bundle.d.cts +0 -4
- package/dist/bundle.d.ts +0 -4
- package/dist/bundle.js +0 -1
- package/dist/index-BhBuaCRl.d.cts +0 -707
- package/dist/index-BsBbSMxk.d.cts +0 -646
- package/dist/index-CeX1Tl7W.d.ts +0 -707
- package/dist/index-quaxtKRh.d.ts +0 -646
- package/dist/index.cjs +0 -1
- package/dist/index.d.cts +0 -3
- package/dist/index.d.ts +0 -3
- package/dist/index.js +0 -1
- package/dist/openSso-DyUQew2K.d.ts +0 -1392
- package/dist/openSso-rQhLhPbq.d.cts +0 -1392
- package/dist/sdkConfigStore-BXzz5PlK.js +0 -1
- package/dist/sdkConfigStore-DDL_fjYX.cjs +0 -1
- package/dist/src-CMaRNkkJ.cjs +0 -13
- package/dist/src-DMFOQMm6.js +0 -13
- package/src/clients/DebugInfo.test.ts +0 -418
- package/src/clients/DebugInfo.ts +0 -182
- package/src/utils/computeLegacyProductId.ts +0 -11
- /package/src/{utils → clients}/ssoUrlListener.test.ts +0 -0
- /package/src/{utils → clients}/ssoUrlListener.ts +0 -0
- /package/src/{utils → config}/backendUrl.test.ts +0 -0
- /package/src/{utils → config}/backendUrl.ts +0 -0
- /package/src/{utils → config}/clientId.test.ts +0 -0
- /package/src/{utils → config}/clientId.ts +0 -0
- /package/src/{utils → config}/sdkConfigStore.test.ts +0 -0
- /package/src/{utils/constants.ts → constants.ts} +0 -0
- /package/src/{utils → context}/mergeAttribution.test.ts +0 -0
- /package/src/{utils → context}/mergeAttribution.ts +0 -0
- /package/src/utils/{deepLinkWithFallback.test.ts → browser/deepLinkWithFallback.test.ts} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{bytesToHex as e,hexToBytes as t,isAddress as n,keccak256 as r,toHex as i}from"viem";import{jsonEncode as a}from"@frak-labs/frame-connector";const o=`frak-client-id`;function s(){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 c(){if(typeof window>`u`||!window.localStorage)return console.warn(`[Frak SDK] No Window / localStorage available to save the clientId`),s();let e=localStorage.getItem(o);return e||(e=s(),localStorage.setItem(o,e)),e}function l({domain:e}={}){return r(i((e??window.location.host).replace(`www.`,``)))}function u(e){return btoa(Array.from(e,e=>String.fromCharCode(e)).join(``)).replace(/\+/g,`-`).replace(/\//g,`_`).replace(/=+$/,``)}function d(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 f(e){return u(a(e))}function p(e,t,n,r,i,a){let o=f(m({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 m(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 h=`menubar=no,status=no,scrollbars=no,fullscreen=no,width=500, height=800`,g=`frak-sso`;async function ee(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??p(i??`https://wallet.frak.id`,t,l(),n.name,c(),r?.css),o=window.open(a,g,h);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]})??{}}function te(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)}}const _=`https://backend.frak.id`;function ne(e){return e.includes(`localhost:3000`)||e.includes(`localhost:3010`)}function v(e){return ne(e)?`https://localhost:3030`:e.includes(`wallet-dev.frak.id`)||e.includes(`wallet.gcp-dev.frak.id`)?`https://backend.gcp-dev.frak.id`:_}function y(e){if(e)return v(e);if(typeof window<`u`){let e=window.FrakSetup?.client?.config?.walletUrl;if(e)return v(e)}return _}var b=class extends Map{maxSize;constructor(e){super(),this.maxSize=e}get(e){let t=super.get(e);return super.has(e)&&(super.delete(e),super.set(e,t)),t}set(e,t){if(super.has(e)&&super.delete(e),super.set(e,t),this.maxSize&&this.size>this.maxSize){let e=super.keys().next().value;e!==void 0&&super.delete(e)}return this}};const x=new b(1024),S=new b(1024),C=3e4,w=new b(1024);async function T(e,{cacheKey:t,cacheTime:n=C}){if(n>0){let e=S.get(t);if(e&&Date.now()-e.created<n)return e.data}let r=w.get(t);if(r&&Date.now()-r<1e3)throw Error(`Cache: ${t} recently failed, backing off`);let i=x.get(t);i||(i=e(),x.set(t,i));try{let e=await i;return S.set(t,{data:e,created:Date.now()}),w.delete(t),e}catch(e){throw w.set(t,Date.now()),e}finally{x.delete(t)}}function E(e){return{clear:()=>{x.delete(e),S.delete(e)},has:(t=C)=>{let n=S.get(e);return n?Date.now()-n.created<t:!1}}}function D(){x.clear(),S.clear(),w.clear()}function re(e){return`r`in e&&!(`v`in e)}function O(e){return`v`in e&&e.v===2}const k=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function A(e){return typeof e==`string`&&k.test(e)}function j(e){let t=e.replace(/-/g,``),n=new Uint8Array(16);for(let e=0;e<16;e++)n[e]=Number.parseInt(t.substring(e*2,e*2+2),16);return n}function M(e){let t=``;for(let n=0;n<16;n++)t+=e[n].toString(16).padStart(2,`0`);return`${t.slice(0,8)}-${t.slice(8,12)}-${t.slice(12,16)}-${t.slice(16,20)}-${t.slice(20,32)}`}function ie(e){if(!A(e.m)||!Number.isInteger(e.t)||e.t<0||e.t>4294967295)return null;let r=typeof e.c==`string`&&e.c.length>0,i=typeof e.w==`string`&&n(e.w);if(!r&&!i||r&&!A(e.c))return null;let a=new Uint8Array(21+(r?16:0)+(i?20:0)),o=new DataView(a.buffer,a.byteOffset,a.byteLength),s=0;return a[s++]=2|(r?16:0)|(i?32:0),a.set(j(e.m),s),s+=16,o.setUint32(s,e.t,!1),s+=4,r&&(a.set(j(e.c),s),s+=16),i&&(a.set(t(e.w),s),s+=20),a}function ae(t){if(t.length<21)return null;let r=t[0];if((r&15)!=2||r&192)return null;let i=(r&16)!=0,a=(r&32)!=0;if(!i&&!a)return null;let o=21+(i?16:0)+(a?20:0);if(t.length!==o)return null;let s=1,c=M(t.subarray(s,s+16));s+=16;let l=new DataView(t.buffer,t.byteOffset,t.byteLength).getUint32(s,!1);s+=4;let u={v:2,m:c,t:l};if(i&&(u.c=M(t.subarray(s,s+16)),s+=16),a){let r=e(t.subarray(s,s+20),{size:20});if(!n(r))return null;u.w=r,s+=20}return u}const N=`fCtx`;function P(e){if(e)try{if(O(e)){let t=ie(e);return t?u(t):void 0}return u(t(e.r))}catch(t){console.error(`Error compressing Frak context`,{e:t,context:e})}}function F(t){if(!(!t||t.length===0))try{let r=d(t);if(r.length!==20)return ae(r)||void 0;let i=e(r,{size:20});if(n(i))return{r:i}}catch(e){console.error(`Error decompressing Frak context`,{e,context:t})}}function I({url:e}){if(!e)return null;let t=new URL(e).searchParams.get(N);return t?F(t):null}const L=`frak`;function oe(e,t){let n=O(e);return{utm_source:t.utmSource??L,utm_medium:t.utmMedium??`referral`,utm_campaign:t.utmCampaign??(n?e.m:void 0),utm_content:t.utmContent,utm_term:t.utmTerm,via:t.via??L,ref:t.ref??(n?e.c:void 0)}}function se(e,t,n){let r=oe(t,n??{});for(let[t,n]of Object.entries(r))n===void 0||n===``||e.searchParams.has(t)||e.searchParams.set(t,n)}function R({url:e,context:t,attribution:n}){if(!e)return null;let r=P(t);if(!r)return null;let i=new URL(e);return i.searchParams.set(N,r),se(i,t,n),i.toString()}function z(e){let t=new URL(e);return t.searchParams.delete(N),t.toString()}function ce({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?z(n):R({url:n,context:t}),r&&window.history.replaceState(null,``,r.toString())}const B={compress:P,decompress:F,parse:I,update:R,remove:z,replaceUrl:ce},V=`__frakSdkConfig`,H=`frak-config-cache`,U=`frak-merchant-id`,W={key:H},G=typeof window<`u`;function K(){return{isResolved:!1,merchantId:``}}let q=null;function J(){if(!G)return null;try{let e=localStorage.getItem(W.key);if(!e)return null;let t=JSON.parse(e);return t.config?.isResolved?(q=t,t):null}catch{return null}}function Y(){return(q??J())?.config}function le(){let e=q??J();return e?Date.now()-e.timestamp<3e4:!1}function ue(e){if(!(!G||!e.isResolved))try{let t={config:e,timestamp:Date.now()};localStorage.setItem(W.key,JSON.stringify(t)),q=t}catch{}}function X(){if(G){q=null;try{localStorage.removeItem(W.key)}catch{}}}function de(){G&&(window[V]||(window[V]=Y()??K()))}de();function Z(){return G?window[V]??K():K()}function Q(e){G&&window.dispatchEvent(new CustomEvent(`frak:config`,{detail:e}))}function fe(e){return e??(G?window.location.hostname:``)}async function pe(e,t,n){try{let r=y(t),i=n?`&lang=${encodeURIComponent(n)}`:``,a=await fetch(`${r}/user/merchant/resolve?domain=${encodeURIComponent(e)}${i}`);if(!a.ok){console.warn(`[Frak SDK] Merchant lookup failed for domain ${e}: ${a.status}`);return}let o=await a.json();if(G)try{sessionStorage.setItem(U,o.merchantId)}catch{}return o}catch(e){console.warn(`[Frak SDK] Failed to fetch merchant config:`,e);return}}const $={getConfig:Z,get isResolved(){return Z().isResolved},get isCacheFresh(){return le()},setCacheScope(e,t){W.key=`${H}:${`${e}:${t??``}`}`,q=null},setConfig(e){if(G&&(window[V]=e),ue(e),Q(e),G&&e.merchantId)try{sessionStorage.setItem(U,e.merchantId)}catch{}},reset(){let e=Y()??K();G&&(window[V]=e),Q(e)},clearCache(){if(X(),D(),G)try{sessionStorage.removeItem(U)}catch{}},resolve(e,t,n){let r=fe(e);return r?T(async()=>{let e=await pe(r,t,n);if(!e)throw Error(`Config resolution returned empty`);return e},{cacheKey:`sdkConfig:${r}:${n??``}`,cacheTime:1/0}).catch(()=>void 0):Promise.resolve(void 0)},getMerchantId(){let e=Z();if(e.isResolved&&e.merchantId)return e.merchantId;if(G)try{return sessionStorage.getItem(U)??void 0}catch{}},async resolveMerchantId(e,t){return $.getMerchantId()||(await $.resolve(e,t))?.merchantId}};export{l as _,D as a,y as c,h as d,g as f,u as g,d as h,O as i,te as l,f as m,B as n,E as o,p,re as r,T as s,$ as t,ee as u,c as v};
|
|
@@ -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 ee(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]})??{}}function p(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)}}const m=`https://backend.frak.id`;function h(e){return e.includes(`localhost:3000`)||e.includes(`localhost:3010`)}function g(e){return h(e)?`https://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}var v=class extends Map{maxSize;constructor(e){super(),this.maxSize=e}get(e){let t=super.get(e);return super.has(e)&&(super.delete(e),super.set(e,t)),t}set(e,t){if(super.has(e)&&super.delete(e),super.set(e,t),this.maxSize&&this.size>this.maxSize){let e=super.keys().next().value;e!==void 0&&super.delete(e)}return this}};const y=new v(1024),b=new v(1024),x=3e4,S=new v(1024);async function C(e,{cacheKey:t,cacheTime:n=x}){if(n>0){let e=b.get(t);if(e&&Date.now()-e.created<n)return e.data}let r=S.get(t);if(r&&Date.now()-r<1e3)throw Error(`Cache: ${t} recently failed, backing off`);let i=y.get(t);i||(i=e(),y.set(t,i));try{let e=await i;return b.set(t,{data:e,created:Date.now()}),S.delete(t),e}catch(e){throw S.set(t,Date.now()),e}finally{y.delete(t)}}function w(e){return{clear:()=>{y.delete(e),b.delete(e)},has:(t=x)=>{let n=b.get(e);return n?Date.now()-n.created<t:!1}}}function T(){y.clear(),b.clear(),S.clear()}function te(e){return`r`in e&&!(`v`in e)}function E(e){return`v`in e&&e.v===2}const D=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function O(e){return typeof e==`string`&&D.test(e)}function k(e){let t=e.replace(/-/g,``),n=new Uint8Array(16);for(let e=0;e<16;e++)n[e]=Number.parseInt(t.substring(e*2,e*2+2),16);return n}function A(e){let t=``;for(let n=0;n<16;n++)t+=e[n].toString(16).padStart(2,`0`);return`${t.slice(0,8)}-${t.slice(8,12)}-${t.slice(12,16)}-${t.slice(16,20)}-${t.slice(20,32)}`}function j(t){if(!O(t.m)||!Number.isInteger(t.t)||t.t<0||t.t>4294967295)return null;let n=typeof t.c==`string`&&t.c.length>0,r=typeof t.w==`string`&&(0,e.isAddress)(t.w);if(!n&&!r||n&&!O(t.c))return null;let i=new Uint8Array(21+(n?16:0)+(r?20:0)),a=new DataView(i.buffer,i.byteOffset,i.byteLength),o=0;return i[o++]=2|(n?16:0)|(r?32:0),i.set(k(t.m),o),o+=16,a.setUint32(o,t.t,!1),o+=4,n&&(i.set(k(t.c),o),o+=16),r&&(i.set((0,e.hexToBytes)(t.w),o),o+=20),i}function ne(t){if(t.length<21)return null;let n=t[0];if((n&15)!=2||n&192)return null;let r=(n&16)!=0,i=(n&32)!=0;if(!r&&!i)return null;let a=21+(r?16:0)+(i?20:0);if(t.length!==a)return null;let o=1,s=A(t.subarray(o,o+16));o+=16;let c=new DataView(t.buffer,t.byteOffset,t.byteLength).getUint32(o,!1);o+=4;let l={v:2,m:s,t:c};if(r&&(l.c=A(t.subarray(o,o+16)),o+=16),i){let n=(0,e.bytesToHex)(t.subarray(o,o+20),{size:20});if(!(0,e.isAddress)(n))return null;l.w=n,o+=20}return l}const M=`fCtx`;function N(t){if(t)try{if(E(t)){let e=j(t);return e?o(e):void 0}return o((0,e.hexToBytes)(t.r))}catch(e){console.error(`Error compressing Frak context`,{e,context:t})}}function P(t){if(!(!t||t.length===0))try{let n=s(t);if(n.length!==20)return ne(n)||void 0;let r=(0,e.bytesToHex)(n,{size:20});if((0,e.isAddress)(r))return{r}}catch(e){console.error(`Error decompressing Frak context`,{e,context:t})}}function F({url:e}){if(!e)return null;let t=new URL(e).searchParams.get(M);return t?P(t):null}const I=`frak`;function L(e,t){let n=E(e);return{utm_source:t.utmSource??I,utm_medium:t.utmMedium??`referral`,utm_campaign:t.utmCampaign??(n?e.m:void 0),utm_content:t.utmContent,utm_term:t.utmTerm,via:t.via??I,ref:t.ref??(n?e.c:void 0)}}function R(e,t,n){let r=L(t,n??{});for(let[t,n]of Object.entries(r))n===void 0||n===``||e.searchParams.has(t)||e.searchParams.set(t,n)}function z({url:e,context:t,attribution:n}){if(!e)return null;let r=N(t);if(!r)return null;let i=new URL(e);return i.searchParams.set(M,r),R(i,t,n),i.toString()}function B(e){let t=new URL(e);return t.searchParams.delete(M),t.toString()}function re({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?B(n):z({url:n,context:t}),r&&window.history.replaceState(null,``,r.toString())}const V={compress:N,decompress:P,parse:F,update:z,remove:B,replaceUrl:re},H=`__frakSdkConfig`,U=`frak-config-cache`,W=`frak-merchant-id`,G={key:U},K=typeof window<`u`;function q(){return{isResolved:!1,merchantId:``}}let J=null;function Y(){if(!K)return null;try{let e=localStorage.getItem(G.key);if(!e)return null;let t=JSON.parse(e);return t.config?.isResolved?(J=t,t):null}catch{return null}}function X(){return(J??Y())?.config}function ie(){let e=J??Y();return e?Date.now()-e.timestamp<3e4:!1}function ae(e){if(!(!K||!e.isResolved))try{let t={config:e,timestamp:Date.now()};localStorage.setItem(G.key,JSON.stringify(t)),J=t}catch{}}function oe(){if(K){J=null;try{localStorage.removeItem(G.key)}catch{}}}function se(){K&&(window[H]||(window[H]=X()??q()))}se();function Z(){return K?window[H]??q():q()}function Q(e){K&&window.dispatchEvent(new CustomEvent(`frak:config`,{detail:e}))}function ce(e){return e??(K?window.location.hostname:``)}async function le(e,t,n){try{let r=_(t),i=n?`&lang=${encodeURIComponent(n)}`:``,a=await fetch(`${r}/user/merchant/resolve?domain=${encodeURIComponent(e)}${i}`);if(!a.ok){console.warn(`[Frak SDK] Merchant lookup failed for domain ${e}: ${a.status}`);return}let o=await a.json();if(K)try{sessionStorage.setItem(W,o.merchantId)}catch{}return o}catch(e){console.warn(`[Frak SDK] Failed to fetch merchant config:`,e);return}}const $={getConfig:Z,get isResolved(){return Z().isResolved},get isCacheFresh(){return ie()},setCacheScope(e,t){G.key=`${U}:${`${e}:${t??``}`}`,J=null},setConfig(e){if(K&&(window[H]=e),ae(e),Q(e),K&&e.merchantId)try{sessionStorage.setItem(W,e.merchantId)}catch{}},reset(){let e=X()??q();K&&(window[H]=e),Q(e)},clearCache(){if(oe(),T(),K)try{sessionStorage.removeItem(W)}catch{}},resolve(e,t,n){let r=ce(e);return r?C(async()=>{let e=await le(r,t,n);if(!e)throw Error(`Config resolution returned empty`);return e},{cacheKey:`sdkConfig:${r}:${n??``}`,cacheTime:1/0}).catch(()=>void 0):Promise.resolve(void 0)},getMerchantId(){let e=Z();if(e.isResolved&&e.merchantId)return e.merchantId;if(K)try{return sessionStorage.getItem(W)??void 0}catch{}},async resolveMerchantId(e,t){return $.getMerchantId()||(await $.resolve(e,t))?.merchantId}};Object.defineProperty(exports,`_`,{enumerable:!0,get:function(){return a}}),Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return T}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return _}}),Object.defineProperty(exports,`d`,{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,`f`,{enumerable:!0,get:function(){return f}}),Object.defineProperty(exports,`g`,{enumerable:!0,get:function(){return o}}),Object.defineProperty(exports,`h`,{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return E}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return p}}),Object.defineProperty(exports,`m`,{enumerable:!0,get:function(){return c}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return V}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return w}}),Object.defineProperty(exports,`p`,{enumerable:!0,get:function(){return l}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return te}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return C}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return $}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return ee}}),Object.defineProperty(exports,`v`,{enumerable:!0,get:function(){return i}});
|
package/dist/src-CMaRNkkJ.cjs
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
const e=require(`./sdkConfigStore-DDL_fjYX.cjs`);let t=require(`@frak-labs/frame-connector`),n=require(`@openpanel/web`);function r(n){return(0,t.jsonDecode)(e.h(n))}const i=`nexus-wallet-backup`,a=`frakwallet://`;function o(){let e=navigator.userAgent;return/Android/i.test(e)&&/Chrome\/\d+/i.test(e)}const s=a.replace(`://`,``);function c(e){return`intent://${e.slice(13)}#Intent;scheme=${s};end`}function l(e,t){let n=t?.timeout??2500,r=!1,i=()=>{document.hidden&&(r=!0)};document.addEventListener(`visibilitychange`,i);let a=o()&&u(e)?c(e):e;window.location.href=a,setTimeout(()=>{document.removeEventListener(`visibilitychange`,i),r||t?.onFallback?.()},n)}function u(e){return e.startsWith(a)}const d={eur:`fr-FR`,usd:`en-US`,gbp:`en-GB`};function f(e){return e&&e in d?e:`eur`}function p(e){return e?d[e]??d.eur:d.eur}function m(e,t){let n=p(t),r=f(t);return e.toLocaleString(n,{style:`currency`,currency:r,minimumFractionDigits:0,maximumFractionDigits:2})}function h(e){return e?`${e}Amount`:`eurAmount`}const g={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 _({walletBaseUrl:t,config:n}){let r=document.querySelector(`#frak-wallet`);r&&r.remove();let i=document.createElement(`iframe`);i.id=g.id,i.name=g.name,i.allow=g.allow,i.style.zIndex=g.style.zIndex.toString(),v({iframe:i,isVisible:!1});let a=n?.walletUrl??t??`https://wallet.frak.id`,o=e.v();return b(a),b(e.c(a)),i.src=`${a}/listener?clientId=${encodeURIComponent(o)}`,new Promise(e=>{i.addEventListener(`load`,()=>e(i)),document.body.appendChild(i)})}function v({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 y(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 b(e){if(!(typeof document>`u`))try{let t=new URL(e).origin,n=`link[rel="preconnect"][data-frak-preconnect="${t}"]`;if(document.head.querySelector(n))return;let r=document.createElement(`link`);r.rel=`preconnect`,r.href=t,r.crossOrigin=``,r.dataset.frakPreconnect=t,document.head.appendChild(r)}catch{}}function x(){if(typeof navigator>`u`)return!1;let e=navigator.userAgent;return!!(/iPhone|iPad|iPod/i.test(e)||/Macintosh/i.test(e)&&navigator.maxTouchPoints>1)}const S=x();function C(){if(typeof navigator>`u`)return!1;let e=navigator.userAgent.toLowerCase();return e.includes(`instagram`)||e.includes(`fban`)||e.includes(`fbav`)||e.includes(`facebook`)}const w=C();function T(e){S&&e.startsWith(`https://`)?window.location.href=`x-safari-https://${e.slice(8)}`:S&&e.startsWith(`http://`)?window.location.href=`x-safari-http://${e.slice(7)}`:window.location.href=`https://backend.frak.id/common/social?u=${encodeURIComponent(e)}`}function E({perCall:e,defaults:t,productUtmContent:n}){if(e===null)return;let r=e!==void 0,i=t!==void 0&&Object.keys(t).length>0;if(!r&&!i&&!(n!==void 0&&n!==``))return;let a={...t,...e??{}},o=n??e?.utmContent;return o!==void 0&&o!==``?a.utmContent=o:delete a.utmContent,a}function D(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 O=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,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 k=(()=>{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 A(e){e?localStorage.setItem(i,e):localStorage.removeItem(i)}function j(e,t){try{let n=new URL(e);if(!n.searchParams.has(`u`))return e;let r=P(window.location.href,t);return n.searchParams.delete(`u`),n.searchParams.append(`u`,r),n.toString()}catch{return e}}function M(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 N(e){return e.includes(`/common/social`)}function P(e,t){if(!t)return e;try{let n=new URL(e);return n.searchParams.set(`fmt`,t),n.toString()}catch{return`${e}${e.includes(`?`)?`&`:`?`}fmt=${encodeURIComponent(t)}`}}function F(e,t,n,r,i){if(i){let e=j(t,r);window.open(e,`_blank`);return}if(u(t)){let i=j(t,r);l(i,{onFallback:()=>{e.contentWindow?.postMessage({clientLifecycle:`deep-link-failed`,data:{originalUrl:i}},n)}})}else if(k&&N(t))M(r);else{let e=j(t,r);window.location.href=e}}function I({iframe:e,targetOrigin:n}){let r=new t.Deferred;return{handleEvent:t=>{if(!(`iframeLifecycle`in t))return;let{iframeLifecycle:a,data:o}=t;switch(a){case`connected`:r.resolve(!0);break;case`do-backup`:A(o.backup);break;case`remove-backup`:localStorage.removeItem(i);break;case`show`:case`hide`:v({iframe:e,isVisible:a===`show`});break;case`redirect`:F(e,o.baseRedirectUrl,n,o.mergeToken,o.openInNewTab);break}},isConnected:r.promise}}function L({config:r,iframe:i}){let a=r?.walletUrl??`https://wallet.frak.id`,o=typeof navigator<`u`?navigator.language?.split(`-`)[0]:void 0,s=r.metadata.lang??(o===`en`||o===`fr`?o:void 0),c=r.domain??(typeof window<`u`?window.location.hostname:``);e.t.setCacheScope(c,s),e.t.reset();let l=e.t.isCacheFresh?void 0:e.t.resolve(r.domain,r.walletUrl,s),u=I({iframe:i,targetOrigin:a}),d=new t.Deferred,f=Date.now(),p=new O(r,i);if(!i.contentWindow)throw new t.FrakRpcError(t.RpcErrorCodes.configError,`The iframe does not have a content window`);let m=(0,t.createRpcClient)({emittingTransport:i.contentWindow,listeningTransport:window,targetOrigin:a,middleware:[{async onRequest(e,n){if(!await u.isConnected)throw new t.FrakRpcError(t.RpcErrorCodes.clientNotConnected,`The iframe provider isn't connected yet`);return await d.promise,n}},{onRequest(e,t){return p.setLastRequest(e),t},onResponse(e,t){return p.setLastResponse(e,t),t}}],lifecycleHandlers:{iframeLifecycle:(e,t)=>{u.handleEvent(e)}}}),h=R(m,u),g=async()=>{h(),m.cleanup(),i.remove(),e.a(),e.t.clearCache(),e.t.reset()},_;{console.log(`[Frak SDK] Initializing OpenPanel`),_=new n.OpenPanel({apiUrl:`https://op-api.gcp.frak.id`,clientId:`6eacc8d7-49ac-4936-95e9-81ef29449570`,trackScreenViews:!0,trackOutgoingLinks:!0,trackAttributes:!1,filter:({type:t,payload:n})=>(t!==`track`||!n?.properties||`sdkVersion`in n.properties||(n.properties={...n.properties,sdkVersion:`1.0.2`,userAnonymousClientId:e.v()}),!0)}),_.setGlobalProperties({sdkVersion:`1.0.2`,userAnonymousClientId:e.v()}),_.init(),_.track(`sdk_initialized`,{sdkVersion:`1.0.2`});let t=!1,r=setTimeout(()=>{t||(t=!0,_?.track(`sdk_iframe_handshake_failed`,{reason:`timeout`}))},3e4);u.isConnected.then(()=>{t||(t=!0,clearTimeout(r),_?.track(`sdk_iframe_connected`,{handshake_duration_ms:Date.now()-f}))}).catch(()=>{t||(t=!0,clearTimeout(r),_?.track(`sdk_iframe_handshake_failed`,{reason:`unknown`}))})}let v=z({config:r,rpcClient:m,lifecycleManager:u,configPromise:l,contextSent:d,openPanel:_}).then(()=>p.updateSetupStatus(!0)).catch(e=>{throw d.reject(e),e});return{config:r,debugInfo:p,waitForConnection:u.isConnected,waitForSetup:v,request:m.request,listenerRequest:m.listen,destroy:g,openPanel:_}}function R(e,t){let n,r,i=()=>e.sendLifecycle({clientLifecycle:`heartbeat`});async function a(){i(),n=setInterval(i,250),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 z({config:t,rpcClient:n,lifecycleManager:r,configPromise:a,contextSent:o,openPanel:s}){await r.isConnected,D(n,r.isConnected);let c=new URL(window.location.href),l=c.searchParams.get(`fmt`)??void 0;l&&(c.searchParams.delete(`fmt`),window.history.replaceState({},``,c.toString()));let u=n=>{let r=n?.merchantId??t.metadata.merchantId??``,i=n?.domain??``,a=n?.allowedDomains??[],o=n?.sdkConfig,s=o?.attribution||t.attribution?{...t.attribution,...o?.attribution}:void 0;e.t.setConfig(o?{isResolved:!0,merchantId:r,domain:i,allowedDomains:a,hasRawSdkConfig:!0,name:o.name??t.metadata.name,logoUrl:o.logoUrl??t.metadata.logoUrl,homepageLink:o.homepageLink??t.metadata.homepageLink,lang:o.lang??t.metadata.lang,currency:o.currency??t.metadata.currency,hidden:o.hidden,css:o.css,translations:o.translations,placements:o.placements,components:o.components,attribution:s}:{isResolved:!0,merchantId:r,domain:i,allowedDomains:a,name:t.metadata.name,logoUrl:t.metadata.logoUrl,homepageLink:t.metadata.homepageLink,lang:t.metadata.lang,currency:t.metadata.currency,attribution:s})},d=!1,f=t=>{let r=d?void 0:l;d=!0;let i=t.hasRawSdkConfig?{name:t.name,logoUrl:t.logoUrl,homepageLink:t.homepageLink,lang:t.lang,currency:t.currency,hidden:t.hidden,css:t.css,translations:t.translations,placements:t.placements,attribution:t.attribution}:t.attribution?{attribution:t.attribution}:void 0,a=e.v();if(s){let e=s.global??{};s.setGlobalProperties({...e,merchantId:t.merchantId,domain:t.domain??``})}n.sendLifecycle({clientLifecycle:`resolved-config`,data:{merchantId:t.merchantId,domain:t.domain??``,allowedDomains:t.allowedDomains??[],sourceUrl:window.location.href,...a&&{sdkAnonymousId:a},...r&&{pendingMergeToken:r},...i&&{sdkConfig:i}}})};e.t.isResolved&&(f(e.t.getConfig()),o.resolve()),a&&(u(await a),f(e.t.getConfig()),o.resolve());async function p(){let e=t.customizations?.css;e&&n.sendLifecycle({clientLifecycle:`modal-css`,data:{cssLink:e}})}async function m(){let e=t.customizations?.i18n;e&&n.sendLifecycle({clientLifecycle:`modal-i18n`,data:{i18n:e}})}async function h(){if(typeof window>`u`)return;let e=window.localStorage.getItem(i);e&&n.sendLifecycle({clientLifecycle:`restore-backup`,data:{backup:e}})}(await Promise.allSettled([p(),m(),h()])).some(e=>e.status===`rejected`)&&s?.track(`sdk_iframe_handshake_failed`,{reason:`asset_push`})}async function B({config:e}){let t=V(e),n=await _({config:t});if(!n){console.error(`Failed to create iframe`);return}let r=L({config:t,iframe:n});if(await r.waitForSetup,!await r.waitForConnection){console.error(`Failed to connect to client`);return}return r}function V(e){let t=f(e.metadata?.currency);return{...e,metadata:{...e.metadata,currency:t}}}Object.defineProperty(exports,`_`,{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return S}}),Object.defineProperty(exports,`b`,{enumerable:!0,get:function(){return a}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return g}}),Object.defineProperty(exports,`d`,{enumerable:!0,get:function(){return h}}),Object.defineProperty(exports,`f`,{enumerable:!0,get:function(){return m}}),Object.defineProperty(exports,`g`,{enumerable:!0,get:function(){return o}}),Object.defineProperty(exports,`h`,{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return E}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return _}}),Object.defineProperty(exports,`m`,{enumerable:!0,get:function(){return f}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return L}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return w}}),Object.defineProperty(exports,`p`,{enumerable:!0,get:function(){return p}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return O}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return T}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return B}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return y}}),Object.defineProperty(exports,`v`,{enumerable:!0,get:function(){return c}}),Object.defineProperty(exports,`x`,{enumerable:!0,get:function(){return r}}),Object.defineProperty(exports,`y`,{enumerable:!0,get:function(){return l}});
|
package/dist/src-DMFOQMm6.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import{a as e,c as t,h as n,t as r,v as i}from"./sdkConfigStore-BXzz5PlK.js";import{Deferred as a,FrakRpcError as o,RpcErrorCodes as s,createRpcClient as c,jsonDecode as l}from"@frak-labs/frame-connector";import{OpenPanel as u}from"@openpanel/web";function d(e){return l(n(e))}const f=`nexus-wallet-backup`,p=`frakwallet://`;function m(){let e=navigator.userAgent;return/Android/i.test(e)&&/Chrome\/\d+/i.test(e)}const h=p.replace(`://`,``);function g(e){return`intent://${e.slice(13)}#Intent;scheme=${h};end`}function _(e,t){let n=t?.timeout??2500,r=!1,i=()=>{document.hidden&&(r=!0)};document.addEventListener(`visibilitychange`,i);let a=m()&&v(e)?g(e):e;window.location.href=a,setTimeout(()=>{document.removeEventListener(`visibilitychange`,i),r||t?.onFallback?.()},n)}function v(e){return e.startsWith(p)}const y={eur:`fr-FR`,usd:`en-US`,gbp:`en-GB`};function b(e){return e&&e in y?e:`eur`}function x(e){return e?y[e]??y.eur:y.eur}function S(e,t){let n=x(t),r=b(t);return e.toLocaleString(n,{style:`currency`,currency:r,minimumFractionDigits:0,maximumFractionDigits:2})}function C(e){return e?`${e}Amount`:`eurAmount`}const w={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 T({walletBaseUrl:e,config:n}){let r=document.querySelector(`#frak-wallet`);r&&r.remove();let a=document.createElement(`iframe`);a.id=w.id,a.name=w.name,a.allow=w.allow,a.style.zIndex=w.style.zIndex.toString(),E({iframe:a,isVisible:!1});let o=n?.walletUrl??e??`https://wallet.frak.id`,s=i();return O(o),O(t(o)),a.src=`${o}/listener?clientId=${encodeURIComponent(s)}`,new Promise(e=>{a.addEventListener(`load`,()=>e(a)),document.body.appendChild(a)})}function E({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 D(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 O(e){if(!(typeof document>`u`))try{let t=new URL(e).origin,n=`link[rel="preconnect"][data-frak-preconnect="${t}"]`;if(document.head.querySelector(n))return;let r=document.createElement(`link`);r.rel=`preconnect`,r.href=t,r.crossOrigin=``,r.dataset.frakPreconnect=t,document.head.appendChild(r)}catch{}}function k(){if(typeof navigator>`u`)return!1;let e=navigator.userAgent;return!!(/iPhone|iPad|iPod/i.test(e)||/Macintosh/i.test(e)&&navigator.maxTouchPoints>1)}const A=k();function j(){if(typeof navigator>`u`)return!1;let e=navigator.userAgent.toLowerCase();return e.includes(`instagram`)||e.includes(`fban`)||e.includes(`fbav`)||e.includes(`facebook`)}const M=j();function N(e){A&&e.startsWith(`https://`)?window.location.href=`x-safari-https://${e.slice(8)}`:A&&e.startsWith(`http://`)?window.location.href=`x-safari-http://${e.slice(7)}`:window.location.href=`https://backend.frak.id/common/social?u=${encodeURIComponent(e)}`}function P({perCall:e,defaults:t,productUtmContent:n}){if(e===null)return;let r=e!==void 0,i=t!==void 0&&Object.keys(t).length>0;if(!r&&!i&&!(n!==void 0&&n!==``))return;let a={...t,...e??{}},o=n??e?.utmContent;return o!==void 0&&o!==``?a.utmContent=o:delete a.utmContent,a}function F(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 I=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,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 o?r=`FrakRpcError: ${e.code} '${e.message}'`:e instanceof Error?r=e.message:typeof e==`string`&&(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 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 L=(()=>{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 R(e){e?localStorage.setItem(f,e):localStorage.removeItem(f)}function z(e,t){try{let n=new URL(e);if(!n.searchParams.has(`u`))return e;let r=H(window.location.href,t);return n.searchParams.delete(`u`),n.searchParams.append(`u`,r),n.toString()}catch{return e}}function B(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 V(e){return e.includes(`/common/social`)}function H(e,t){if(!t)return e;try{let n=new URL(e);return n.searchParams.set(`fmt`,t),n.toString()}catch{return`${e}${e.includes(`?`)?`&`:`?`}fmt=${encodeURIComponent(t)}`}}function U(e,t,n,r,i){if(i){let e=z(t,r);window.open(e,`_blank`);return}if(v(t)){let i=z(t,r);_(i,{onFallback:()=>{e.contentWindow?.postMessage({clientLifecycle:`deep-link-failed`,data:{originalUrl:i}},n)}})}else if(L&&V(t))B(r);else{let e=z(t,r);window.location.href=e}}function W({iframe:e,targetOrigin:t}){let n=new a;return{handleEvent:r=>{if(!(`iframeLifecycle`in r))return;let{iframeLifecycle:i,data:a}=r;switch(i){case`connected`:n.resolve(!0);break;case`do-backup`:R(a.backup);break;case`remove-backup`:localStorage.removeItem(f);break;case`show`:case`hide`:E({iframe:e,isVisible:i===`show`});break;case`redirect`:U(e,a.baseRedirectUrl,t,a.mergeToken,a.openInNewTab);break}},isConnected:n.promise}}function G({config:t,iframe:n}){let l=t?.walletUrl??`https://wallet.frak.id`,d=typeof navigator<`u`?navigator.language?.split(`-`)[0]:void 0,f=t.metadata.lang??(d===`en`||d===`fr`?d:void 0),p=t.domain??(typeof window<`u`?window.location.hostname:``);r.setCacheScope(p,f),r.reset();let m=r.isCacheFresh?void 0:r.resolve(t.domain,t.walletUrl,f),h=W({iframe:n,targetOrigin:l}),g=new a,_=Date.now(),v=new I(t,n);if(!n.contentWindow)throw new o(s.configError,`The iframe does not have a content window`);let y=c({emittingTransport:n.contentWindow,listeningTransport:window,targetOrigin:l,middleware:[{async onRequest(e,t){if(!await h.isConnected)throw new o(s.clientNotConnected,`The iframe provider isn't connected yet`);return await g.promise,t}},{onRequest(e,t){return v.setLastRequest(e),t},onResponse(e,t){return v.setLastResponse(e,t),t}}],lifecycleHandlers:{iframeLifecycle:(e,t)=>{h.handleEvent(e)}}}),b=K(y,h),x=async()=>{b(),y.cleanup(),n.remove(),e(),r.clearCache(),r.reset()},S;{console.log(`[Frak SDK] Initializing OpenPanel`),S=new u({apiUrl:`https://op-api.gcp.frak.id`,clientId:`6eacc8d7-49ac-4936-95e9-81ef29449570`,trackScreenViews:!0,trackOutgoingLinks:!0,trackAttributes:!1,filter:({type:e,payload:t})=>(e!==`track`||!t?.properties||`sdkVersion`in t.properties||(t.properties={...t.properties,sdkVersion:`1.0.2`,userAnonymousClientId:i()}),!0)}),S.setGlobalProperties({sdkVersion:`1.0.2`,userAnonymousClientId:i()}),S.init(),S.track(`sdk_initialized`,{sdkVersion:`1.0.2`});let e=!1,t=setTimeout(()=>{e||(e=!0,S?.track(`sdk_iframe_handshake_failed`,{reason:`timeout`}))},3e4);h.isConnected.then(()=>{e||(e=!0,clearTimeout(t),S?.track(`sdk_iframe_connected`,{handshake_duration_ms:Date.now()-_}))}).catch(()=>{e||(e=!0,clearTimeout(t),S?.track(`sdk_iframe_handshake_failed`,{reason:`unknown`}))})}let C=q({config:t,rpcClient:y,lifecycleManager:h,configPromise:m,contextSent:g,openPanel:S}).then(()=>v.updateSetupStatus(!0)).catch(e=>{throw g.reject(e),e});return{config:t,debugInfo:v,waitForConnection:h.isConnected,waitForSetup:C,request:y.request,listenerRequest:y.listen,destroy:x,openPanel:S}}function K(e,t){let n,r,i=()=>e.sendLifecycle({clientLifecycle:`heartbeat`});async function a(){i(),n=setInterval(i,250),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 q({config:e,rpcClient:t,lifecycleManager:n,configPromise:a,contextSent:o,openPanel:s}){await n.isConnected,F(t,n.isConnected);let c=new URL(window.location.href),l=c.searchParams.get(`fmt`)??void 0;l&&(c.searchParams.delete(`fmt`),window.history.replaceState({},``,c.toString()));let u=t=>{let n=t?.merchantId??e.metadata.merchantId??``,i=t?.domain??``,a=t?.allowedDomains??[],o=t?.sdkConfig,s=o?.attribution||e.attribution?{...e.attribution,...o?.attribution}:void 0;r.setConfig(o?{isResolved:!0,merchantId:n,domain:i,allowedDomains:a,hasRawSdkConfig:!0,name:o.name??e.metadata.name,logoUrl:o.logoUrl??e.metadata.logoUrl,homepageLink:o.homepageLink??e.metadata.homepageLink,lang:o.lang??e.metadata.lang,currency:o.currency??e.metadata.currency,hidden:o.hidden,css:o.css,translations:o.translations,placements:o.placements,components:o.components,attribution:s}:{isResolved:!0,merchantId:n,domain:i,allowedDomains:a,name:e.metadata.name,logoUrl:e.metadata.logoUrl,homepageLink:e.metadata.homepageLink,lang:e.metadata.lang,currency:e.metadata.currency,attribution:s})},d=!1,p=e=>{let n=d?void 0:l;d=!0;let r=e.hasRawSdkConfig?{name:e.name,logoUrl:e.logoUrl,homepageLink:e.homepageLink,lang:e.lang,currency:e.currency,hidden:e.hidden,css:e.css,translations:e.translations,placements:e.placements,attribution:e.attribution}:e.attribution?{attribution:e.attribution}:void 0,a=i();if(s){let t=s.global??{};s.setGlobalProperties({...t,merchantId:e.merchantId,domain:e.domain??``})}t.sendLifecycle({clientLifecycle:`resolved-config`,data:{merchantId:e.merchantId,domain:e.domain??``,allowedDomains:e.allowedDomains??[],sourceUrl:window.location.href,...a&&{sdkAnonymousId:a},...n&&{pendingMergeToken:n},...r&&{sdkConfig:r}}})};r.isResolved&&(p(r.getConfig()),o.resolve()),a&&(u(await a),p(r.getConfig()),o.resolve());async function m(){let n=e.customizations?.css;n&&t.sendLifecycle({clientLifecycle:`modal-css`,data:{cssLink:n}})}async function h(){let n=e.customizations?.i18n;n&&t.sendLifecycle({clientLifecycle:`modal-i18n`,data:{i18n:n}})}async function g(){if(typeof window>`u`)return;let e=window.localStorage.getItem(f);e&&t.sendLifecycle({clientLifecycle:`restore-backup`,data:{backup:e}})}(await Promise.allSettled([m(),h(),g()])).some(e=>e.status===`rejected`)&&s?.track(`sdk_iframe_handshake_failed`,{reason:`asset_push`})}async function J({config:e}){let t=Y(e),n=await T({config:t});if(!n){console.error(`Failed to create iframe`);return}let r=G({config:t,iframe:n});if(await r.waitForSetup,!await r.waitForConnection){console.error(`Failed to connect to client`);return}return r}function Y(e){let t=b(e.metadata?.currency);return{...e,metadata:{...e.metadata,currency:t}}}export{v as _,A as a,p as b,w as c,C as d,S as f,m as g,y as h,P as i,T as l,b as m,G as n,M as o,x as p,I as r,N as s,J as t,D as u,g as v,d as x,_ as y};
|
|
@@ -1,418 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for DebugInfoGatherer class
|
|
3
|
-
* Tests debug information gathering and formatting for error reporting
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { FrakRpcError, RpcErrorCodes } from "@frak-labs/frame-connector";
|
|
7
|
-
import {
|
|
8
|
-
afterEach,
|
|
9
|
-
beforeEach,
|
|
10
|
-
describe,
|
|
11
|
-
expect,
|
|
12
|
-
it,
|
|
13
|
-
vi,
|
|
14
|
-
} from "../../tests/vitest-fixtures";
|
|
15
|
-
import type { FrakWalletSdkConfig } from "../types";
|
|
16
|
-
import { DebugInfoGatherer } from "./DebugInfo";
|
|
17
|
-
|
|
18
|
-
describe("DebugInfoGatherer", () => {
|
|
19
|
-
let mockConfig: FrakWalletSdkConfig;
|
|
20
|
-
let mockIframe: HTMLIFrameElement;
|
|
21
|
-
let consoleWarnSpy: ReturnType<typeof vi.spyOn>;
|
|
22
|
-
|
|
23
|
-
beforeEach(() => {
|
|
24
|
-
// Create mock config
|
|
25
|
-
mockConfig = {
|
|
26
|
-
metadata: {
|
|
27
|
-
name: "Test App",
|
|
28
|
-
},
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
// Create mock iframe
|
|
32
|
-
mockIframe = document.createElement("iframe");
|
|
33
|
-
mockIframe.src = "https://wallet.frak.id";
|
|
34
|
-
mockIframe.setAttribute("loading", "lazy");
|
|
35
|
-
document.body.appendChild(mockIframe);
|
|
36
|
-
|
|
37
|
-
// Mock iframe contentDocument
|
|
38
|
-
Object.defineProperty(mockIframe, "contentDocument", {
|
|
39
|
-
value: {
|
|
40
|
-
readyState: "complete",
|
|
41
|
-
},
|
|
42
|
-
writable: true,
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
// Mock iframe contentWindow
|
|
46
|
-
Object.defineProperty(mockIframe, "contentWindow", {
|
|
47
|
-
value: {},
|
|
48
|
-
writable: true,
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
// Spy on console.warn
|
|
52
|
-
consoleWarnSpy = vi.spyOn(console, "warn").mockImplementation(() => {});
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
afterEach(() => {
|
|
56
|
-
consoleWarnSpy.mockRestore();
|
|
57
|
-
document.body.removeChild(mockIframe);
|
|
58
|
-
vi.clearAllMocks();
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
describe("constructor", () => {
|
|
62
|
-
it("should create instance with config and iframe", () => {
|
|
63
|
-
const gatherer = new DebugInfoGatherer(mockConfig, mockIframe);
|
|
64
|
-
|
|
65
|
-
expect(gatherer).toBeInstanceOf(DebugInfoGatherer);
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
it("should create instance without config and iframe", () => {
|
|
69
|
-
const gatherer = new DebugInfoGatherer();
|
|
70
|
-
|
|
71
|
-
expect(gatherer).toBeInstanceOf(DebugInfoGatherer);
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
it("should initialize with null lastRequest and lastResponse", () => {
|
|
75
|
-
const gatherer = new DebugInfoGatherer(mockConfig, mockIframe);
|
|
76
|
-
|
|
77
|
-
// Access private properties through formatDebugInfo output
|
|
78
|
-
const debugInfo = gatherer.formatDebugInfo("test error");
|
|
79
|
-
expect(debugInfo).toContain("No Frak request logged");
|
|
80
|
-
expect(debugInfo).toContain("No Frak response logged");
|
|
81
|
-
});
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
describe("static empty()", () => {
|
|
85
|
-
it("should create empty instance", () => {
|
|
86
|
-
const gatherer = DebugInfoGatherer.empty();
|
|
87
|
-
|
|
88
|
-
expect(gatherer).toBeInstanceOf(DebugInfoGatherer);
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
it("should create instance without config or iframe", () => {
|
|
92
|
-
const gatherer = DebugInfoGatherer.empty();
|
|
93
|
-
const debugInfo = gatherer.formatDebugInfo("test error");
|
|
94
|
-
|
|
95
|
-
expect(debugInfo).toContain("no-config");
|
|
96
|
-
expect(debugInfo).toContain("not-iframe");
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
describe("setLastRequest", () => {
|
|
101
|
-
it("should set last request with timestamp", () => {
|
|
102
|
-
const gatherer = new DebugInfoGatherer(mockConfig, mockIframe);
|
|
103
|
-
const mockMessage = {
|
|
104
|
-
id: 1,
|
|
105
|
-
method: "test_method",
|
|
106
|
-
params: [],
|
|
107
|
-
} as any;
|
|
108
|
-
|
|
109
|
-
gatherer.setLastRequest(mockMessage);
|
|
110
|
-
|
|
111
|
-
const debugInfo = gatherer.formatDebugInfo("test error");
|
|
112
|
-
expect(debugInfo).toContain("Last Request:");
|
|
113
|
-
expect(debugInfo).not.toContain("No Frak request logged");
|
|
114
|
-
});
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
describe("setLastResponse", () => {
|
|
118
|
-
it("should set last response with timestamp", () => {
|
|
119
|
-
const gatherer = new DebugInfoGatherer(mockConfig, mockIframe);
|
|
120
|
-
const mockMessage = {
|
|
121
|
-
id: 1,
|
|
122
|
-
method: "test_method",
|
|
123
|
-
} as any;
|
|
124
|
-
const mockResponse = {
|
|
125
|
-
id: 1,
|
|
126
|
-
result: "success",
|
|
127
|
-
} as any;
|
|
128
|
-
|
|
129
|
-
gatherer.setLastResponse(mockMessage, mockResponse);
|
|
130
|
-
|
|
131
|
-
const debugInfo = gatherer.formatDebugInfo("test error");
|
|
132
|
-
expect(debugInfo).toContain("Last Response:");
|
|
133
|
-
expect(debugInfo).not.toContain("No Frak response logged");
|
|
134
|
-
});
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
describe("updateSetupStatus", () => {
|
|
138
|
-
it("should update setup status to true", () => {
|
|
139
|
-
const gatherer = new DebugInfoGatherer(mockConfig, mockIframe);
|
|
140
|
-
|
|
141
|
-
gatherer.updateSetupStatus(true);
|
|
142
|
-
|
|
143
|
-
const debugInfo = gatherer.formatDebugInfo("test error");
|
|
144
|
-
expect(debugInfo).toContain("Client Status: setup");
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
it("should update setup status to false", () => {
|
|
148
|
-
const gatherer = new DebugInfoGatherer(mockConfig, mockIframe);
|
|
149
|
-
|
|
150
|
-
gatherer.updateSetupStatus(false);
|
|
151
|
-
|
|
152
|
-
const debugInfo = gatherer.formatDebugInfo("test error");
|
|
153
|
-
expect(debugInfo).toContain("Client Status: not-setup");
|
|
154
|
-
});
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
describe("formatDebugInfo", () => {
|
|
158
|
-
it("should format debug info with all fields", () => {
|
|
159
|
-
const gatherer = new DebugInfoGatherer(mockConfig, mockIframe);
|
|
160
|
-
|
|
161
|
-
const debugInfo = gatherer.formatDebugInfo("test error");
|
|
162
|
-
|
|
163
|
-
expect(debugInfo).toContain("Debug Information:");
|
|
164
|
-
expect(debugInfo).toContain("Timestamp:");
|
|
165
|
-
expect(debugInfo).toContain("URL:");
|
|
166
|
-
expect(debugInfo).toContain("Config:");
|
|
167
|
-
expect(debugInfo).toContain("Navigator Info:");
|
|
168
|
-
expect(debugInfo).toContain("IFrame Status:");
|
|
169
|
-
expect(debugInfo).toContain("Last Request:");
|
|
170
|
-
expect(debugInfo).toContain("Last Response:");
|
|
171
|
-
expect(debugInfo).toContain("Client Status:");
|
|
172
|
-
expect(debugInfo).toContain("Error:");
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
it("should format FrakRpcError correctly", () => {
|
|
176
|
-
const gatherer = new DebugInfoGatherer(mockConfig, mockIframe);
|
|
177
|
-
const error = new FrakRpcError(
|
|
178
|
-
RpcErrorCodes.walletNotConnected,
|
|
179
|
-
"Wallet not connected"
|
|
180
|
-
);
|
|
181
|
-
|
|
182
|
-
const debugInfo = gatherer.formatDebugInfo(error);
|
|
183
|
-
|
|
184
|
-
expect(debugInfo).toContain(
|
|
185
|
-
`FrakRpcError: ${RpcErrorCodes.walletNotConnected} 'Wallet not connected'`
|
|
186
|
-
);
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
it("should format regular Error correctly", () => {
|
|
190
|
-
const gatherer = new DebugInfoGatherer(mockConfig, mockIframe);
|
|
191
|
-
const error = new Error("Network timeout");
|
|
192
|
-
|
|
193
|
-
const debugInfo = gatherer.formatDebugInfo(error);
|
|
194
|
-
|
|
195
|
-
expect(debugInfo).toContain("Network timeout");
|
|
196
|
-
});
|
|
197
|
-
|
|
198
|
-
it("should format string error correctly", () => {
|
|
199
|
-
const gatherer = new DebugInfoGatherer(mockConfig, mockIframe);
|
|
200
|
-
|
|
201
|
-
const debugInfo = gatherer.formatDebugInfo("String error message");
|
|
202
|
-
|
|
203
|
-
expect(debugInfo).toContain("String error message");
|
|
204
|
-
});
|
|
205
|
-
|
|
206
|
-
it("should format unknown error as 'Unknown'", () => {
|
|
207
|
-
const gatherer = new DebugInfoGatherer(mockConfig, mockIframe);
|
|
208
|
-
|
|
209
|
-
const debugInfo = gatherer.formatDebugInfo(null);
|
|
210
|
-
|
|
211
|
-
expect(debugInfo).toContain("Error: Unknown");
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
it("should include encoded URL", () => {
|
|
215
|
-
const gatherer = new DebugInfoGatherer(mockConfig, mockIframe);
|
|
216
|
-
|
|
217
|
-
const debugInfo = gatherer.formatDebugInfo("test error");
|
|
218
|
-
|
|
219
|
-
// URL should be base64 encoded
|
|
220
|
-
expect(debugInfo).toContain("URL:");
|
|
221
|
-
const urlMatch = debugInfo.match(/URL: (.+)/);
|
|
222
|
-
expect(urlMatch).toBeTruthy();
|
|
223
|
-
if (urlMatch) {
|
|
224
|
-
// Should be base64 encoded (alphanumeric + =)
|
|
225
|
-
expect(urlMatch[1]).toMatch(/^[A-Za-z0-9+/=]+$/);
|
|
226
|
-
}
|
|
227
|
-
});
|
|
228
|
-
|
|
229
|
-
it("should include encoded config when config is provided", () => {
|
|
230
|
-
const gatherer = new DebugInfoGatherer(mockConfig, mockIframe);
|
|
231
|
-
|
|
232
|
-
const debugInfo = gatherer.formatDebugInfo("test error");
|
|
233
|
-
|
|
234
|
-
expect(debugInfo).toContain("Config:");
|
|
235
|
-
expect(debugInfo).not.toContain("no-config");
|
|
236
|
-
});
|
|
237
|
-
|
|
238
|
-
it("should show 'no-config' when config is not provided", () => {
|
|
239
|
-
const gatherer = new DebugInfoGatherer(undefined, mockIframe);
|
|
240
|
-
|
|
241
|
-
const debugInfo = gatherer.formatDebugInfo("test error");
|
|
242
|
-
|
|
243
|
-
expect(debugInfo).toContain("Config: no-config");
|
|
244
|
-
});
|
|
245
|
-
|
|
246
|
-
it("should include iframe status when iframe is provided", () => {
|
|
247
|
-
const gatherer = new DebugInfoGatherer(mockConfig, mockIframe);
|
|
248
|
-
|
|
249
|
-
const debugInfo = gatherer.formatDebugInfo("test error");
|
|
250
|
-
|
|
251
|
-
expect(debugInfo).toContain("IFrame Status:");
|
|
252
|
-
expect(debugInfo).not.toContain("not-iframe");
|
|
253
|
-
});
|
|
254
|
-
|
|
255
|
-
it("should show 'not-iframe' when iframe is not provided", () => {
|
|
256
|
-
const gatherer = new DebugInfoGatherer(mockConfig, undefined);
|
|
257
|
-
|
|
258
|
-
const debugInfo = gatherer.formatDebugInfo("test error");
|
|
259
|
-
|
|
260
|
-
expect(debugInfo).toContain("IFrame Status: not-iframe");
|
|
261
|
-
});
|
|
262
|
-
|
|
263
|
-
it("should include navigator info", () => {
|
|
264
|
-
const gatherer = new DebugInfoGatherer(mockConfig, mockIframe);
|
|
265
|
-
|
|
266
|
-
const debugInfo = gatherer.formatDebugInfo("test error");
|
|
267
|
-
|
|
268
|
-
expect(debugInfo).toContain("Navigator Info:");
|
|
269
|
-
expect(debugInfo).not.toContain("no-navigator");
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
it("should handle iframe without contentDocument", () => {
|
|
273
|
-
const iframeWithoutDoc = document.createElement("iframe");
|
|
274
|
-
Object.defineProperty(iframeWithoutDoc, "contentDocument", {
|
|
275
|
-
value: null,
|
|
276
|
-
writable: true,
|
|
277
|
-
});
|
|
278
|
-
Object.defineProperty(iframeWithoutDoc, "contentWindow", {
|
|
279
|
-
value: {},
|
|
280
|
-
writable: true,
|
|
281
|
-
});
|
|
282
|
-
|
|
283
|
-
const gatherer = new DebugInfoGatherer(
|
|
284
|
-
mockConfig,
|
|
285
|
-
iframeWithoutDoc
|
|
286
|
-
);
|
|
287
|
-
|
|
288
|
-
const debugInfo = gatherer.formatDebugInfo("test error");
|
|
289
|
-
|
|
290
|
-
expect(debugInfo).toContain("IFrame Status:");
|
|
291
|
-
});
|
|
292
|
-
|
|
293
|
-
it("should handle iframe with incomplete readyState", () => {
|
|
294
|
-
const iframeIncomplete = document.createElement("iframe");
|
|
295
|
-
Object.defineProperty(iframeIncomplete, "contentDocument", {
|
|
296
|
-
value: {
|
|
297
|
-
readyState: "loading",
|
|
298
|
-
},
|
|
299
|
-
writable: true,
|
|
300
|
-
});
|
|
301
|
-
Object.defineProperty(iframeIncomplete, "contentWindow", {
|
|
302
|
-
value: {},
|
|
303
|
-
writable: true,
|
|
304
|
-
});
|
|
305
|
-
|
|
306
|
-
const gatherer = new DebugInfoGatherer(
|
|
307
|
-
mockConfig,
|
|
308
|
-
iframeIncomplete
|
|
309
|
-
);
|
|
310
|
-
|
|
311
|
-
const debugInfo = gatherer.formatDebugInfo("test error");
|
|
312
|
-
|
|
313
|
-
expect(debugInfo).toContain("IFrame Status:");
|
|
314
|
-
});
|
|
315
|
-
|
|
316
|
-
it("should include last request when set", () => {
|
|
317
|
-
const gatherer = new DebugInfoGatherer(mockConfig, mockIframe);
|
|
318
|
-
const mockMessage = {
|
|
319
|
-
id: 1,
|
|
320
|
-
method: "test_method",
|
|
321
|
-
params: [],
|
|
322
|
-
} as any;
|
|
323
|
-
|
|
324
|
-
gatherer.setLastRequest(mockMessage);
|
|
325
|
-
const debugInfo = gatherer.formatDebugInfo("test error");
|
|
326
|
-
|
|
327
|
-
expect(debugInfo).toContain("Last Request:");
|
|
328
|
-
expect(debugInfo).not.toContain("No Frak request logged");
|
|
329
|
-
});
|
|
330
|
-
|
|
331
|
-
it("should include last response when set", () => {
|
|
332
|
-
const gatherer = new DebugInfoGatherer(mockConfig, mockIframe);
|
|
333
|
-
const mockMessage = {
|
|
334
|
-
id: 1,
|
|
335
|
-
method: "test_method",
|
|
336
|
-
} as any;
|
|
337
|
-
const mockResponse = {
|
|
338
|
-
id: 1,
|
|
339
|
-
result: "success",
|
|
340
|
-
} as any;
|
|
341
|
-
|
|
342
|
-
gatherer.setLastResponse(mockMessage, mockResponse);
|
|
343
|
-
const debugInfo = gatherer.formatDebugInfo("test error");
|
|
344
|
-
|
|
345
|
-
expect(debugInfo).toContain("Last Response:");
|
|
346
|
-
expect(debugInfo).not.toContain("No Frak response logged");
|
|
347
|
-
});
|
|
348
|
-
|
|
349
|
-
it("should show 'No Frak request logged' when no request is set", () => {
|
|
350
|
-
const gatherer = new DebugInfoGatherer(mockConfig, mockIframe);
|
|
351
|
-
|
|
352
|
-
const debugInfo = gatherer.formatDebugInfo("test error");
|
|
353
|
-
|
|
354
|
-
expect(debugInfo).toContain("No Frak request logged");
|
|
355
|
-
});
|
|
356
|
-
|
|
357
|
-
it("should show 'No Frak response logged' when no response is set", () => {
|
|
358
|
-
const gatherer = new DebugInfoGatherer(mockConfig, mockIframe);
|
|
359
|
-
|
|
360
|
-
const debugInfo = gatherer.formatDebugInfo("test error");
|
|
361
|
-
|
|
362
|
-
expect(debugInfo).toContain("No Frak response logged");
|
|
363
|
-
});
|
|
364
|
-
});
|
|
365
|
-
|
|
366
|
-
describe("base64 encoding error handling", () => {
|
|
367
|
-
it("should handle encoding errors gracefully", () => {
|
|
368
|
-
const gatherer = new DebugInfoGatherer(mockConfig, mockIframe);
|
|
369
|
-
|
|
370
|
-
// Create a circular reference that can't be JSON stringified
|
|
371
|
-
const circularObj: any = { prop: "value" };
|
|
372
|
-
circularObj.self = circularObj;
|
|
373
|
-
|
|
374
|
-
// Mock base64Encode to throw an error
|
|
375
|
-
// We can't directly test the private method, but we can test
|
|
376
|
-
// that formatDebugInfo doesn't throw when encoding fails
|
|
377
|
-
// by checking that it still produces output
|
|
378
|
-
|
|
379
|
-
const debugInfo = gatherer.formatDebugInfo("test error");
|
|
380
|
-
|
|
381
|
-
// Should still produce debug info even if encoding fails
|
|
382
|
-
expect(debugInfo).toContain("Debug Information:");
|
|
383
|
-
});
|
|
384
|
-
});
|
|
385
|
-
|
|
386
|
-
describe("integration", () => {
|
|
387
|
-
it("should format complete debug info with all data set", () => {
|
|
388
|
-
const gatherer = new DebugInfoGatherer(mockConfig, mockIframe);
|
|
389
|
-
const mockRequest = {
|
|
390
|
-
id: 1,
|
|
391
|
-
method: "frak_sendInteraction",
|
|
392
|
-
params: [],
|
|
393
|
-
} as any;
|
|
394
|
-
const mockResponse = {
|
|
395
|
-
id: 1,
|
|
396
|
-
result: { delegationId: "123" },
|
|
397
|
-
} as any;
|
|
398
|
-
const error = new FrakRpcError(
|
|
399
|
-
RpcErrorCodes.serverError,
|
|
400
|
-
"Server error"
|
|
401
|
-
);
|
|
402
|
-
|
|
403
|
-
gatherer.setLastRequest(mockRequest);
|
|
404
|
-
gatherer.setLastResponse(mockRequest, mockResponse);
|
|
405
|
-
gatherer.updateSetupStatus(true);
|
|
406
|
-
|
|
407
|
-
const debugInfo = gatherer.formatDebugInfo(error);
|
|
408
|
-
|
|
409
|
-
expect(debugInfo).toContain("Debug Information:");
|
|
410
|
-
expect(debugInfo).toContain("Client Status: setup");
|
|
411
|
-
expect(debugInfo).toContain(
|
|
412
|
-
`FrakRpcError: ${RpcErrorCodes.serverError} 'Server error'`
|
|
413
|
-
);
|
|
414
|
-
expect(debugInfo).not.toContain("No Frak request logged");
|
|
415
|
-
expect(debugInfo).not.toContain("No Frak response logged");
|
|
416
|
-
});
|
|
417
|
-
});
|
|
418
|
-
});
|