@frak-labs/core-sdk 0.2.1-beta.d04602ec → 0.2.1-beta.eb3cff34
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/cdn/bundle.js +3 -55
- package/dist/actions-D4aBXbdp.cjs +1 -0
- package/dist/actions-Dq_uN-wn.js +1 -0
- package/dist/actions.cjs +1 -1
- package/dist/actions.d.cts +3 -3
- package/dist/actions.d.ts +3 -3
- package/dist/actions.js +1 -1
- package/dist/bundle.cjs +1 -1
- package/dist/bundle.d.cts +4 -4
- package/dist/bundle.d.ts +4 -4
- package/dist/bundle.js +1 -1
- package/dist/{computeLegacyProductId-fKvxbC4k.d.ts → index-BV5D9DsW.d.ts} +1 -1
- package/dist/{siweAuthenticate-Dc_Yg9Bg.d.cts → index-BphwTmKA.d.cts} +22 -2
- package/dist/{computeLegacyProductId-rYIvY4c3.d.cts → index-Dwmo109y.d.cts} +1 -1
- package/dist/{siweAuthenticate-Ddhl-o4N.d.ts → index-_f8EuN_1.d.ts} +22 -2
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1 -1
- package/dist/{openSso-CMZM06uR.d.ts → openSso-BwEK2M98.d.cts} +31 -4
- package/dist/{openSso-CebB8mFv.d.cts → openSso-C1Wzl5-i.d.ts} +31 -4
- package/dist/src-B3Dusips.cjs +13 -0
- package/dist/src-CnnhYPyK.js +13 -0
- package/dist/trackEvent-BqJqRZ-u.cjs +1 -0
- package/dist/trackEvent-Bqq4jd6R.js +1 -0
- package/package.json +9 -10
- package/src/actions/getMergeToken.ts +33 -0
- package/src/actions/index.ts +1 -0
- package/src/clients/createIFrameFrakClient.ts +3 -2
- package/src/clients/transports/iframeLifecycleManager.test.ts +14 -14
- package/src/clients/transports/iframeLifecycleManager.ts +35 -9
- package/src/stubs/rrweb.ts +9 -0
- package/src/types/lifecycle/iframe.ts +7 -0
- package/src/types/resolvedConfig.ts +6 -0
- package/src/types/rpc/displaySharingPage.ts +5 -0
- package/src/types/rpc/embedded/index.ts +1 -1
- package/src/types/rpc.ts +12 -0
- package/src/utils/cache/withCache.test.ts +6 -0
- package/src/utils/cache/withCache.ts +19 -0
- package/dist/setupClient-B_XMB52l.cjs +0 -13
- package/dist/setupClient-jYx-fbxB.js +0 -13
- package/dist/siweAuthenticate-CWcVvP-G.cjs +0 -1
- package/dist/siweAuthenticate-DQfdb5UQ.js +0 -1
- package/dist/trackEvent-Ce1XlsIE.js +0 -1
- package/dist/trackEvent-CvbJTTqA.cjs +0 -1
|
@@ -0,0 +1 @@
|
|
|
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)?`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 E(e){return(0,t.jsonDecode)(s(e))}function D(e){return`r`in e&&!(`v`in e)}function O(e){return`v`in e&&e.v===2}const k=`fCtx`;function A(t){if(t)try{return O(t)?!t.c||!t.m||!t.t?void 0:c({v:2,c:t.c,m:t.m,t:t.t}):o((0,e.hexToBytes)(t.r))}catch(e){console.error(`Error compressing Frak context`,{e,context:t})}}function j(t){if(!(!t||t.length===0))try{let n=E(t);if(n&&typeof n==`object`&&n.v===2)return n.c&&n.m&&n.t?{v:2,c:n.c,m:n.m,t:n.t}:void 0;let r=(0,e.bytesToHex)(s(t),{size:20});if((0,e.isAddress)(r))return{r}}catch(e){console.error(`Error decompressing Frak context`,{e,context:t})}}function M({url:e}){if(!e)return null;let t=new URL(e).searchParams.get(k);return t?j(t):null}function N({url:e,context:t}){if(!e)return null;let n=A(t);if(!n)return null;let r=new URL(e);return r.searchParams.set(k,n),r.toString()}function P(e){let t=new URL(e);return t.searchParams.delete(k),t.toString()}function ee({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?P(n):N({url:n,context:t}),r&&window.history.replaceState(null,``,r.toString())}const F={compress:A,decompress:j,parse:M,update:N,remove:P,replaceUrl:ee},I=`__frakSdkConfig`,L=`frak-config-cache`,R=`frak-merchant-id`,z={key:L},B=typeof window<`u`;function V(){return{isResolved:!1,merchantId:``}}let H=null;function U(){if(!B)return null;try{let e=localStorage.getItem(z.key);if(!e)return null;let t=JSON.parse(e);return t.config?.isResolved?(H=t,t):null}catch{return null}}function W(){return(H??U())?.config}function G(){let e=H??U();return e?Date.now()-e.timestamp<3e4:!1}function K(e){if(!(!B||!e.isResolved))try{let t={config:e,timestamp:Date.now()};localStorage.setItem(z.key,JSON.stringify(t)),H=t}catch{}}function q(){if(B){H=null;try{localStorage.removeItem(z.key)}catch{}}}function J(){B&&(window[I]||(window[I]=W()??V()))}J();function Y(){return B?window[I]??V():V()}function X(e){B&&window.dispatchEvent(new CustomEvent(`frak:config`,{detail:e}))}function Z(e){return e??(B?window.location.hostname:``)}async function Q(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(B)try{sessionStorage.setItem(R,o.merchantId)}catch{}return o}catch(e){console.warn(`[Frak SDK] Failed to fetch merchant config:`,e);return}}const $={getConfig:Y,get isResolved(){return Y().isResolved},get isCacheFresh(){return G()},setCacheScope(e,t){z.key=`${L}:${`${e}:${t??``}`}`,H=null},setConfig(e){if(B&&(window[I]=e),K(e),X(e),B&&e.merchantId)try{sessionStorage.setItem(R,e.merchantId)}catch{}},reset(){let e=W()??V();B&&(window[I]=e),X(e)},clearCache(){if(q(),T(),B)try{sessionStorage.removeItem(R)}catch{}},resolve(e,t,n){let r=Z(e);return r?C(async()=>{let e=await Q(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=Y();if(e.isResolved&&e.merchantId)return e.merchantId;if(B)try{return sessionStorage.getItem(R)??void 0}catch{}},async resolveMerchantId(e,t){return $.getMerchantId()||(await $.resolve(e,t))?.merchantId}};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)}}Object.defineProperty(exports,`_`,{enumerable:!0,get:function(){return o}}),Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return O}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return w}}),Object.defineProperty(exports,`d`,{enumerable:!0,get:function(){return p}}),Object.defineProperty(exports,`f`,{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,`g`,{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,`h`,{enumerable:!0,get:function(){return c}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return D}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return C}}),Object.defineProperty(exports,`m`,{enumerable:!0,get:function(){return l}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return $}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return E}}),Object.defineProperty(exports,`p`,{enumerable:!0,get:function(){return f}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return F}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return T}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return te}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return _}}),Object.defineProperty(exports,`v`,{enumerable:!0,get:function(){return a}}),Object.defineProperty(exports,`y`,{enumerable:!0,get:function(){return i}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{bytesToHex as e,hexToBytes as t,isAddress as n,keccak256 as r,toHex as i}from"viem";import{jsonDecode as a,jsonEncode as o}from"@frak-labs/frame-connector";const s=`frak-client-id`;function c(){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 l(){if(typeof window>`u`||!window.localStorage)return console.warn(`[Frak SDK] No Window / localStorage available to save the clientId`),c();let e=localStorage.getItem(s);return e||(e=c(),localStorage.setItem(s,e)),e}function u({domain:e}={}){return r(i((e??window.location.host).replace(`www.`,``)))}function d(e){return btoa(Array.from(e,e=>String.fromCharCode(e)).join(``)).replace(/\+/g,`-`).replace(/\//g,`_`).replace(/=+$/,``)}function f(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 p(e){return d(o(e))}function m(e,t,n,r,i,a){let o=p(ee({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 ee(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 te(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??m(i??`https://wallet.frak.id`,t,u(),n.name,l(),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]})??{}}const _=`https://backend.frak.id`;function v(e){return e.includes(`localhost:3000`)||e.includes(`localhost:3010`)}function y(e){return v(e)?`https://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 _}var x=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 S=new x(1024),C=new x(1024),w=3e4,T=new x(1024);async function E(e,{cacheKey:t,cacheTime:n=w}){if(n>0){let e=C.get(t);if(e&&Date.now()-e.created<n)return e.data}let r=T.get(t);if(r&&Date.now()-r<1e3)throw Error(`Cache: ${t} recently failed, backing off`);let i=S.get(t);i||(i=e(),S.set(t,i));try{let e=await i;return C.set(t,{data:e,created:Date.now()}),T.delete(t),e}catch(e){throw T.set(t,Date.now()),e}finally{S.delete(t)}}function D(e){return{clear:()=>{S.delete(e),C.delete(e)},has:(t=w)=>{let n=C.get(e);return n?Date.now()-n.created<t:!1}}}function O(){S.clear(),C.clear(),T.clear()}function k(e){return a(f(e))}function ne(e){return`r`in e&&!(`v`in e)}function A(e){return`v`in e&&e.v===2}const j=`fCtx`;function M(e){if(e)try{return A(e)?!e.c||!e.m||!e.t?void 0:p({v:2,c:e.c,m:e.m,t:e.t}):d(t(e.r))}catch(t){console.error(`Error compressing Frak context`,{e:t,context:e})}}function N(t){if(!(!t||t.length===0))try{let r=k(t);if(r&&typeof r==`object`&&r.v===2)return r.c&&r.m&&r.t?{v:2,c:r.c,m:r.m,t:r.t}:void 0;let i=e(f(t),{size:20});if(n(i))return{r:i}}catch(e){console.error(`Error decompressing Frak context`,{e,context:t})}}function P({url:e}){if(!e)return null;let t=new URL(e).searchParams.get(j);return t?N(t):null}function F({url:e,context:t}){if(!e)return null;let n=M(t);if(!n)return null;let r=new URL(e);return r.searchParams.set(j,n),r.toString()}function I(e){let t=new URL(e);return t.searchParams.delete(j),t.toString()}function L({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?I(n):F({url:n,context:t}),r&&window.history.replaceState(null,``,r.toString())}const R={compress:M,decompress:N,parse:P,update:F,remove:I,replaceUrl:L},z=`__frakSdkConfig`,B=`frak-config-cache`,V=`frak-merchant-id`,H={key:B},U=typeof window<`u`;function W(){return{isResolved:!1,merchantId:``}}let G=null;function K(){if(!U)return null;try{let e=localStorage.getItem(H.key);if(!e)return null;let t=JSON.parse(e);return t.config?.isResolved?(G=t,t):null}catch{return null}}function q(){return(G??K())?.config}function J(){let e=G??K();return e?Date.now()-e.timestamp<3e4:!1}function Y(e){if(!(!U||!e.isResolved))try{let t={config:e,timestamp:Date.now()};localStorage.setItem(H.key,JSON.stringify(t)),G=t}catch{}}function X(){if(U){G=null;try{localStorage.removeItem(H.key)}catch{}}}function re(){U&&(window[z]||(window[z]=q()??W()))}re();function Z(){return U?window[z]??W():W()}function Q(e){U&&window.dispatchEvent(new CustomEvent(`frak:config`,{detail:e}))}function ie(e){return e??(U?window.location.hostname:``)}async function ae(e,t,n){try{let r=b(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(U)try{sessionStorage.setItem(V,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 J()},setCacheScope(e,t){H.key=`${B}:${`${e}:${t??``}`}`,G=null},setConfig(e){if(U&&(window[z]=e),Y(e),Q(e),U&&e.merchantId)try{sessionStorage.setItem(V,e.merchantId)}catch{}},reset(){let e=q()??W();U&&(window[z]=e),Q(e)},clearCache(){if(X(),O(),U)try{sessionStorage.removeItem(V)}catch{}},resolve(e,t,n){let r=ie(e);return r?E(async()=>{let e=await ae(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(U)try{return sessionStorage.getItem(V)??void 0}catch{}},async resolveMerchantId(e,t){return $.getMerchantId()||(await $.resolve(e,t))?.merchantId}};function oe(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{d as _,A as a,D as c,te as d,h as f,f as g,p as h,ne as i,E as l,m,$ as n,k as o,g as p,R as r,O as s,oe as t,b as u,u as v,l as y};
|
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"url": "https://twitter.com/QNivelais"
|
|
12
12
|
}
|
|
13
13
|
],
|
|
14
|
-
"version": "0.2.1-beta.
|
|
14
|
+
"version": "0.2.1-beta.eb3cff34",
|
|
15
15
|
"description": "Core SDK of the Frak wallet, low level library to interact directly with the frak ecosystem.",
|
|
16
16
|
"repository": {
|
|
17
17
|
"url": "https://github.com/frak-id/wallet",
|
|
@@ -91,22 +91,21 @@
|
|
|
91
91
|
"viem": "^2.x"
|
|
92
92
|
},
|
|
93
93
|
"dependencies": {
|
|
94
|
-
"@frak-labs/frame-connector": "0.2.0-beta.
|
|
94
|
+
"@frak-labs/frame-connector": "0.2.0-beta.eb3cff34",
|
|
95
95
|
"@openpanel/web": "^1.2.0"
|
|
96
96
|
},
|
|
97
97
|
"devDependencies": {
|
|
98
98
|
"@arethetypeswrong/cli": "^0.18.2",
|
|
99
|
-
"@frak-labs/dev-tooling": "0.0.0",
|
|
100
99
|
"@frak-labs/test-foundation": "0.1.0",
|
|
101
100
|
"@rolldown/plugin-node-polyfills": "^1.0.3",
|
|
102
101
|
"@types/jsdom": "^28.0.0",
|
|
103
|
-
"@types/node": "^
|
|
104
|
-
"@vitest/coverage-v8": "^4.1.
|
|
105
|
-
"@vitest/ui": "^4.1.
|
|
102
|
+
"@types/node": "^25.6.0",
|
|
103
|
+
"@vitest/coverage-v8": "^4.1.4",
|
|
104
|
+
"@vitest/ui": "^4.1.4",
|
|
106
105
|
"jsdom": "^29.0.0",
|
|
107
|
-
"tsdown": "^0.
|
|
108
|
-
"typescript": "^
|
|
109
|
-
"viem": "^2.
|
|
110
|
-
"vitest": "^4.1.
|
|
106
|
+
"tsdown": "^0.21.8",
|
|
107
|
+
"typescript": "^6.0.2",
|
|
108
|
+
"viem": "^2.47.16",
|
|
109
|
+
"vitest": "^4.1.4"
|
|
111
110
|
}
|
|
112
111
|
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { FrakClient } from "../types";
|
|
2
|
+
import { withCache } from "../utils/cache";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Fetch a merge token for the current anonymous identity.
|
|
6
|
+
*
|
|
7
|
+
* Used by in-app browser redirect flows to preserve identity
|
|
8
|
+
* when switching from a WebView to the system browser.
|
|
9
|
+
* The token is appended as `?fmt=` to the redirect URL.
|
|
10
|
+
*
|
|
11
|
+
* Results are cached in memory for 30 seconds by default. Concurrent calls
|
|
12
|
+
* while a request is in-flight are deduplicated automatically.
|
|
13
|
+
*
|
|
14
|
+
* @param client - The current Frak Client
|
|
15
|
+
* @param options - Optional cache configuration
|
|
16
|
+
* @param options.cacheTime - Time in ms to cache the result. Default: 30_000 (30s). Set to 0 to disable.
|
|
17
|
+
* @returns The merge token string, or null if unavailable
|
|
18
|
+
*/
|
|
19
|
+
export async function getMergeToken(
|
|
20
|
+
client: FrakClient,
|
|
21
|
+
options?: { cacheTime?: number }
|
|
22
|
+
): Promise<string | null> {
|
|
23
|
+
return withCache(
|
|
24
|
+
() =>
|
|
25
|
+
client.request({
|
|
26
|
+
method: "frak_getMergeToken",
|
|
27
|
+
}),
|
|
28
|
+
{
|
|
29
|
+
cacheKey: "frak_getMergeToken",
|
|
30
|
+
cacheTime: options?.cacheTime,
|
|
31
|
+
}
|
|
32
|
+
);
|
|
33
|
+
}
|
package/src/actions/index.ts
CHANGED
|
@@ -3,6 +3,7 @@ export { displayModal } from "./displayModal";
|
|
|
3
3
|
export { displaySharingPage } from "./displaySharingPage";
|
|
4
4
|
export { ensureIdentity } from "./ensureIdentity";
|
|
5
5
|
export { getMerchantInformation } from "./getMerchantInformation";
|
|
6
|
+
export { getMergeToken } from "./getMergeToken";
|
|
6
7
|
export { getUserReferralStatus } from "./getUserReferralStatus";
|
|
7
8
|
export { openSso } from "./openSso";
|
|
8
9
|
export { prepareSso } from "./prepareSso";
|
|
@@ -125,9 +125,9 @@ export function createIFrameFrakClient({
|
|
|
125
125
|
],
|
|
126
126
|
// Add lifecycle handlers to process iframe lifecycle events
|
|
127
127
|
lifecycleHandlers: {
|
|
128
|
-
iframeLifecycle:
|
|
128
|
+
iframeLifecycle: (event, _context) => {
|
|
129
129
|
// Delegate to lifecycle manager (cast for type compatibility)
|
|
130
|
-
|
|
130
|
+
lifecycleManager.handleEvent(event);
|
|
131
131
|
},
|
|
132
132
|
},
|
|
133
133
|
});
|
|
@@ -318,6 +318,7 @@ async function postConnectionSetup({
|
|
|
318
318
|
css: raw.css,
|
|
319
319
|
translations: raw.translations,
|
|
320
320
|
placements: raw.placements,
|
|
321
|
+
components: raw.components,
|
|
321
322
|
}
|
|
322
323
|
: {
|
|
323
324
|
isResolved: true,
|
|
@@ -102,7 +102,7 @@ describe("createIFrameLifecycleManager", () => {
|
|
|
102
102
|
iframeLifecycle: "connected" as const,
|
|
103
103
|
};
|
|
104
104
|
|
|
105
|
-
|
|
105
|
+
manager.handleEvent(event);
|
|
106
106
|
|
|
107
107
|
await expect(manager.isConnected).resolves.toBe(true);
|
|
108
108
|
});
|
|
@@ -126,7 +126,7 @@ describe("createIFrameLifecycleManager", () => {
|
|
|
126
126
|
data: { backup },
|
|
127
127
|
};
|
|
128
128
|
|
|
129
|
-
|
|
129
|
+
manager.handleEvent(event);
|
|
130
130
|
|
|
131
131
|
expect(localStorage.getItem("frak-backup-key")).toBe(backup);
|
|
132
132
|
});
|
|
@@ -150,7 +150,7 @@ describe("createIFrameLifecycleManager", () => {
|
|
|
150
150
|
data: {},
|
|
151
151
|
};
|
|
152
152
|
|
|
153
|
-
|
|
153
|
+
manager.handleEvent(event);
|
|
154
154
|
|
|
155
155
|
expect(localStorage.getItem("frak-backup-key")).toBeNull();
|
|
156
156
|
});
|
|
@@ -173,7 +173,7 @@ describe("createIFrameLifecycleManager", () => {
|
|
|
173
173
|
iframeLifecycle: "remove-backup" as const,
|
|
174
174
|
};
|
|
175
175
|
|
|
176
|
-
|
|
176
|
+
manager.handleEvent(event);
|
|
177
177
|
|
|
178
178
|
expect(localStorage.getItem("frak-backup-key")).toBeNull();
|
|
179
179
|
});
|
|
@@ -198,7 +198,7 @@ describe("createIFrameLifecycleManager", () => {
|
|
|
198
198
|
iframeLifecycle: "show" as const,
|
|
199
199
|
};
|
|
200
200
|
|
|
201
|
-
|
|
201
|
+
manager.handleEvent(event);
|
|
202
202
|
|
|
203
203
|
expect(changeIframeVisibility).toHaveBeenCalledWith({
|
|
204
204
|
iframe: mockIframe,
|
|
@@ -224,7 +224,7 @@ describe("createIFrameLifecycleManager", () => {
|
|
|
224
224
|
iframeLifecycle: "hide" as const,
|
|
225
225
|
};
|
|
226
226
|
|
|
227
|
-
|
|
227
|
+
manager.handleEvent(event);
|
|
228
228
|
|
|
229
229
|
expect(changeIframeVisibility).toHaveBeenCalledWith({
|
|
230
230
|
iframe: mockIframe,
|
|
@@ -259,7 +259,7 @@ describe("createIFrameLifecycleManager", () => {
|
|
|
259
259
|
},
|
|
260
260
|
};
|
|
261
261
|
|
|
262
|
-
|
|
262
|
+
manager.handleEvent(event);
|
|
263
263
|
|
|
264
264
|
expect(window.location.href).toBe(
|
|
265
265
|
"https://redirect.com/?u=https%3A%2F%2Foriginal.com"
|
|
@@ -291,7 +291,7 @@ describe("createIFrameLifecycleManager", () => {
|
|
|
291
291
|
},
|
|
292
292
|
};
|
|
293
293
|
|
|
294
|
-
|
|
294
|
+
manager.handleEvent(event);
|
|
295
295
|
|
|
296
296
|
expect(window.location.href).toBe("https://redirect.com/path");
|
|
297
297
|
});
|
|
@@ -325,7 +325,7 @@ describe("createIFrameLifecycleManager", () => {
|
|
|
325
325
|
},
|
|
326
326
|
};
|
|
327
327
|
|
|
328
|
-
|
|
328
|
+
manager.handleEvent(event);
|
|
329
329
|
|
|
330
330
|
expect(triggerDeepLinkWithFallback).toHaveBeenCalledWith(
|
|
331
331
|
"frakwallet://wallet",
|
|
@@ -370,7 +370,7 @@ describe("createIFrameLifecycleManager", () => {
|
|
|
370
370
|
},
|
|
371
371
|
};
|
|
372
372
|
|
|
373
|
-
|
|
373
|
+
manager.handleEvent(event);
|
|
374
374
|
|
|
375
375
|
// Extract the onFallback callback from the mock call
|
|
376
376
|
const callArgs = (triggerDeepLinkWithFallback as any).mock.calls[0];
|
|
@@ -419,7 +419,7 @@ describe("createIFrameLifecycleManager", () => {
|
|
|
419
419
|
},
|
|
420
420
|
};
|
|
421
421
|
|
|
422
|
-
|
|
422
|
+
manager.handleEvent(event);
|
|
423
423
|
|
|
424
424
|
// Should NOT call fallback detection
|
|
425
425
|
expect(triggerDeepLinkWithFallback).not.toHaveBeenCalled();
|
|
@@ -445,7 +445,7 @@ describe("createIFrameLifecycleManager", () => {
|
|
|
445
445
|
} as any;
|
|
446
446
|
|
|
447
447
|
// Should not throw
|
|
448
|
-
|
|
448
|
+
expect(manager.handleEvent(event)).toBeUndefined();
|
|
449
449
|
});
|
|
450
450
|
|
|
451
451
|
test("should only process events with iframeLifecycle", async () => {
|
|
@@ -463,13 +463,13 @@ describe("createIFrameLifecycleManager", () => {
|
|
|
463
463
|
});
|
|
464
464
|
|
|
465
465
|
// Event without iframeLifecycle
|
|
466
|
-
|
|
466
|
+
manager.handleEvent({ randomEvent: "show" } as any);
|
|
467
467
|
|
|
468
468
|
// changeIframeVisibility should not be called
|
|
469
469
|
expect(changeIframeVisibility).not.toHaveBeenCalled();
|
|
470
470
|
|
|
471
471
|
// Event with iframeLifecycle
|
|
472
|
-
|
|
472
|
+
manager.handleEvent({ iframeLifecycle: "show" as const });
|
|
473
473
|
|
|
474
474
|
// Now it should be called
|
|
475
475
|
expect(changeIframeVisibility).toHaveBeenCalled();
|
|
@@ -32,7 +32,7 @@ const isIOSInAppBrowser = (() => {
|
|
|
32
32
|
/** @ignore */
|
|
33
33
|
export type IframeLifecycleManager = {
|
|
34
34
|
isConnected: Promise<boolean>;
|
|
35
|
-
handleEvent: (messageEvent: FrakLifecycleEvent) =>
|
|
35
|
+
handleEvent: (messageEvent: FrakLifecycleEvent) => void;
|
|
36
36
|
};
|
|
37
37
|
|
|
38
38
|
/**
|
|
@@ -59,12 +59,12 @@ function computeRedirectUrl(
|
|
|
59
59
|
return baseRedirectUrl;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
// Append merge token to the page URL so it survives
|
|
63
|
+
// the backend /common/social redirect chain
|
|
64
|
+
const finalPageUrl = appendMergeToken(window.location.href, mergeToken);
|
|
64
65
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}
|
|
66
|
+
redirectUrl.searchParams.delete("u");
|
|
67
|
+
redirectUrl.searchParams.append("u", finalPageUrl);
|
|
68
68
|
|
|
69
69
|
return redirectUrl.toString();
|
|
70
70
|
} catch {
|
|
@@ -93,6 +93,21 @@ function isSocialRedirect(url: string): boolean {
|
|
|
93
93
|
return url.includes("/common/social");
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
+
/**
|
|
97
|
+
* Append merge token to a URL as the `fmt` query parameter.
|
|
98
|
+
*/
|
|
99
|
+
function appendMergeToken(urlString: string, mergeToken?: string): string {
|
|
100
|
+
if (!mergeToken) return urlString;
|
|
101
|
+
try {
|
|
102
|
+
const url = new URL(urlString);
|
|
103
|
+
url.searchParams.set("fmt", mergeToken);
|
|
104
|
+
return url.toString();
|
|
105
|
+
} catch {
|
|
106
|
+
const sep = urlString.includes("?") ? "&" : "?";
|
|
107
|
+
return `${urlString}${sep}fmt=${encodeURIComponent(mergeToken)}`;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
96
111
|
/**
|
|
97
112
|
* Handle redirect with deep link fallback
|
|
98
113
|
*/
|
|
@@ -100,8 +115,18 @@ function handleRedirect(
|
|
|
100
115
|
iframe: HTMLIFrameElement,
|
|
101
116
|
baseRedirectUrl: string,
|
|
102
117
|
targetOrigin: string,
|
|
103
|
-
mergeToken?: string
|
|
118
|
+
mergeToken?: string,
|
|
119
|
+
openInNewTab?: boolean
|
|
104
120
|
): void {
|
|
121
|
+
// If requested, open in a new tab instead of navigating the current page.
|
|
122
|
+
// This preserves the merchant page while triggering universal links.
|
|
123
|
+
// Requires the iframe postMessage to include user activation delegation.
|
|
124
|
+
if (openInNewTab) {
|
|
125
|
+
const finalUrl = computeRedirectUrl(baseRedirectUrl, mergeToken);
|
|
126
|
+
window.open(finalUrl, "_blank");
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
|
|
105
130
|
if (isFrakDeepLink(baseRedirectUrl)) {
|
|
106
131
|
const finalUrl = computeRedirectUrl(baseRedirectUrl, mergeToken);
|
|
107
132
|
triggerDeepLinkWithFallback(finalUrl, {
|
|
@@ -143,7 +168,7 @@ export function createIFrameLifecycleManager({
|
|
|
143
168
|
const isConnectedDeferred = new Deferred<boolean>();
|
|
144
169
|
|
|
145
170
|
// Build the handler itself
|
|
146
|
-
const handler =
|
|
171
|
+
const handler = (messageEvent: FrakLifecycleEvent) => {
|
|
147
172
|
if (!("iframeLifecycle" in messageEvent)) return;
|
|
148
173
|
|
|
149
174
|
const { iframeLifecycle: event, data } = messageEvent;
|
|
@@ -172,7 +197,8 @@ export function createIFrameLifecycleManager({
|
|
|
172
197
|
iframe,
|
|
173
198
|
data.baseRedirectUrl,
|
|
174
199
|
targetOrigin,
|
|
175
|
-
data.mergeToken
|
|
200
|
+
data.mergeToken,
|
|
201
|
+
data.openInNewTab
|
|
176
202
|
);
|
|
177
203
|
break;
|
|
178
204
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stub for rrweb. The @openpanel/web package statically imports `record` from
|
|
3
|
+
* rrweb even when session replay is disabled. This stub replaces the module so
|
|
4
|
+
* that rrweb is not included in the bundle.
|
|
5
|
+
* @see https://github.com/Openpanel-dev/openpanel/issues/336
|
|
6
|
+
*/
|
|
7
|
+
export function record() {
|
|
8
|
+
return () => {};
|
|
9
|
+
}
|
|
@@ -29,5 +29,12 @@ type RedirectRequestEvent = {
|
|
|
29
29
|
* Used when redirecting out of social browsers to preserve identity across contexts
|
|
30
30
|
*/
|
|
31
31
|
mergeToken?: string;
|
|
32
|
+
/**
|
|
33
|
+
* When true, open the URL in a new tab via window.open(_blank)
|
|
34
|
+
* instead of navigating the current page.
|
|
35
|
+
* Requires the postMessage to include user activation delegation
|
|
36
|
+
* (includeUserActivation: true) so Safari allows the popup.
|
|
37
|
+
*/
|
|
38
|
+
openInNewTab?: boolean;
|
|
32
39
|
};
|
|
33
40
|
};
|
|
@@ -36,6 +36,7 @@ export type ResolvedPlacement = {
|
|
|
36
36
|
css?: string;
|
|
37
37
|
};
|
|
38
38
|
postPurchase?: {
|
|
39
|
+
badgeText?: string;
|
|
39
40
|
refereeText?: string;
|
|
40
41
|
refereeNoRewardText?: string;
|
|
41
42
|
referrerText?: string;
|
|
@@ -77,6 +78,8 @@ export type ResolvedSdkConfig = {
|
|
|
77
78
|
css?: string;
|
|
78
79
|
translations?: Record<string, string>;
|
|
79
80
|
placements?: Record<string, ResolvedPlacement>;
|
|
81
|
+
/** Global component defaults (used when no placement override exists) */
|
|
82
|
+
components?: ResolvedPlacement["components"];
|
|
80
83
|
};
|
|
81
84
|
|
|
82
85
|
/**
|
|
@@ -119,4 +122,7 @@ export type SdkResolvedConfig = {
|
|
|
119
122
|
|
|
120
123
|
/** Named placements (keyed by placement ID) */
|
|
121
124
|
placements?: Record<string, ResolvedPlacement>;
|
|
125
|
+
|
|
126
|
+
/** Global component defaults (fallback for placement-level overrides) */
|
|
127
|
+
components?: ResolvedPlacement["components"];
|
|
122
128
|
};
|
|
@@ -14,6 +14,11 @@ export type SharingPageProduct = {
|
|
|
14
14
|
* Optional product image URL
|
|
15
15
|
*/
|
|
16
16
|
imageUrl?: string;
|
|
17
|
+
/**
|
|
18
|
+
* Optional product-specific sharing link
|
|
19
|
+
* When provided and the product is selected, this link is used instead of the default sharing link
|
|
20
|
+
*/
|
|
21
|
+
link?: string;
|
|
17
22
|
};
|
|
18
23
|
|
|
19
24
|
/**
|
|
@@ -9,10 +9,10 @@ import type {
|
|
|
9
9
|
import type { LoggedOutEmbeddedView } from "./loggedOut";
|
|
10
10
|
|
|
11
11
|
export type {
|
|
12
|
+
EmbeddedViewActionReferred,
|
|
12
13
|
EmbeddedViewActionSharing,
|
|
13
14
|
LoggedInEmbeddedView,
|
|
14
15
|
LoggedOutEmbeddedView,
|
|
15
|
-
EmbeddedViewActionReferred,
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
/**
|
package/src/types/rpc.ts
CHANGED
|
@@ -184,4 +184,16 @@ export type IFrameRpcSchema = [
|
|
|
184
184
|
];
|
|
185
185
|
ReturnType: DisplaySharingPageResultType;
|
|
186
186
|
},
|
|
187
|
+
/**
|
|
188
|
+
* Method to get a merge token for the current anonymous identity.
|
|
189
|
+
* Used by in-app browser redirect flows to preserve identity
|
|
190
|
+
* when switching from a WebView to the system browser.
|
|
191
|
+
* Returns the merge token string, or null if unavailable.
|
|
192
|
+
* This is a one-shot request.
|
|
193
|
+
*/
|
|
194
|
+
{
|
|
195
|
+
Method: "frak_getMergeToken";
|
|
196
|
+
Parameters?: undefined;
|
|
197
|
+
ReturnType: string | null;
|
|
198
|
+
},
|
|
187
199
|
];
|
|
@@ -129,6 +129,7 @@ describe("withCache", () => {
|
|
|
129
129
|
});
|
|
130
130
|
|
|
131
131
|
it("should not cache errors — subsequent call retries", async () => {
|
|
132
|
+
vi.useFakeTimers();
|
|
132
133
|
const fn = vi
|
|
133
134
|
.fn()
|
|
134
135
|
.mockRejectedValueOnce(new Error("fail"))
|
|
@@ -138,9 +139,14 @@ describe("withCache", () => {
|
|
|
138
139
|
withCache(fn, { cacheKey: "retry-key" })
|
|
139
140
|
).rejects.toThrow("fail");
|
|
140
141
|
|
|
142
|
+
// Advance past the negative cache backoff (1s)
|
|
143
|
+
vi.advanceTimersByTime(1_001);
|
|
144
|
+
|
|
141
145
|
const result = await withCache(fn, { cacheKey: "retry-key" });
|
|
142
146
|
expect(result).toBe("recovered");
|
|
143
147
|
expect(fn).toHaveBeenCalledTimes(2);
|
|
148
|
+
|
|
149
|
+
vi.useRealTimers();
|
|
144
150
|
});
|
|
145
151
|
});
|
|
146
152
|
|
|
@@ -14,6 +14,12 @@ const responseCache = new LruMap<CacheEntry<unknown>>(1024);
|
|
|
14
14
|
/** Default cache time: 30 seconds */
|
|
15
15
|
export const DEFAULT_CACHE_TIME = 30_000;
|
|
16
16
|
|
|
17
|
+
/** Short negative cache to avoid flooding on transient failures */
|
|
18
|
+
const NEGATIVE_CACHE_TIME = 1_000;
|
|
19
|
+
|
|
20
|
+
/** Tracks recently failed keys to avoid request floods */
|
|
21
|
+
const failureCache = new LruMap<number>(1024);
|
|
22
|
+
|
|
17
23
|
type WithCacheOptions = {
|
|
18
24
|
/** The key to cache the data against */
|
|
19
25
|
cacheKey: string;
|
|
@@ -52,6 +58,12 @@ export async function withCache<TData>(
|
|
|
52
58
|
}
|
|
53
59
|
}
|
|
54
60
|
|
|
61
|
+
// Check if this key recently failed — back off briefly
|
|
62
|
+
const lastFailure = failureCache.get(cacheKey);
|
|
63
|
+
if (lastFailure && Date.now() - lastFailure < NEGATIVE_CACHE_TIME) {
|
|
64
|
+
throw new Error(`Cache: ${cacheKey} recently failed, backing off`);
|
|
65
|
+
}
|
|
66
|
+
|
|
55
67
|
// Check if there's already a pending promise (dedup concurrent calls)
|
|
56
68
|
let promise = promiseCache.get(cacheKey) as Promise<TData> | undefined;
|
|
57
69
|
if (!promise) {
|
|
@@ -63,7 +75,13 @@ export async function withCache<TData>(
|
|
|
63
75
|
const data = await promise;
|
|
64
76
|
// Store the response with a timestamp
|
|
65
77
|
responseCache.set(cacheKey, { data, created: Date.now() });
|
|
78
|
+
// Clear any previous failure
|
|
79
|
+
failureCache.delete(cacheKey);
|
|
66
80
|
return data;
|
|
81
|
+
} catch (error) {
|
|
82
|
+
// Record the failure timestamp
|
|
83
|
+
failureCache.set(cacheKey, Date.now());
|
|
84
|
+
throw error;
|
|
67
85
|
} finally {
|
|
68
86
|
// Clear the promise cache so subsequent calls can re-fetch after TTL
|
|
69
87
|
promiseCache.delete(cacheKey);
|
|
@@ -102,4 +120,5 @@ export function getCache(cacheKey: string) {
|
|
|
102
120
|
export function clearAllCache() {
|
|
103
121
|
promiseCache.clear();
|
|
104
122
|
responseCache.clear();
|
|
123
|
+
failureCache.clear();
|
|
105
124
|
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
const e=require(`./trackEvent-CvbJTTqA.cjs`);let t=require(`@frak-labs/frame-connector`),n=require(`@openpanel/web`);const r=`nexus-wallet-backup`,i=`frakwallet://`;function a(){let e=navigator.userAgent;return/Android/i.test(e)&&/Chrome\/\d+/i.test(e)}function o(e){return`intent://${e.slice(13)}#Intent;scheme=frakwallet;end`}function s(e,t){let n=t?.timeout??2500,r=!1,i=()=>{document.hidden&&(r=!0)};document.addEventListener(`visibilitychange`,i);let s=a()&&c(e)?o(e):e;window.location.href=s,setTimeout(()=>{document.removeEventListener(`visibilitychange`,i),r||t?.onFallback?.()},n)}function c(e){return e.startsWith(i)}const l={eur:`fr-FR`,usd:`en-US`,gbp:`en-GB`};function u(e){return e&&e in l?e:`eur`}function d(e){return e?l[e]??l.eur:l.eur}function f(e,t){let n=d(t),r=u(t);return e.toLocaleString(n,{style:`currency`,currency:r,minimumFractionDigits:0,maximumFractionDigits:2})}function p(e){return e?`${e}Amount`:`eurAmount`}const m={id:`frak-wallet`,name:`frak-wallet`,title:`Frak Wallet`,allow:`publickey-credentials-get *; clipboard-write; web-share *`,style:{width:`0`,height:`0`,border:`0`,position:`absolute`,zIndex:2000001,top:`-1000px`,left:`-1000px`,colorScheme:`auto`}};function h({walletBaseUrl:t,config:n}){let r=document.querySelector(`#frak-wallet`);r&&r.remove();let i=document.createElement(`iframe`);i.id=m.id,i.name=m.name,i.allow=m.allow,i.style.zIndex=m.style.zIndex.toString(),g({iframe:i,isVisible:!1});let a=n?.walletUrl??t??`https://wallet.frak.id`,o=e.y();return i.src=`${a}/listener?clientId=${encodeURIComponent(o)}`,new Promise(e=>{i.addEventListener(`load`,()=>e(i)),document.body.appendChild(i)})}function g({iframe:e,isVisible:t}){if(!t){e.style.width=`0`,e.style.height=`0`,e.style.border=`0`,e.style.position=`fixed`,e.style.top=`-1000px`,e.style.left=`-1000px`;return}e.style.position=`fixed`,e.style.top=`0`,e.style.left=`0`,e.style.width=`100%`,e.style.height=`100%`,e.style.pointerEvents=`auto`}function _(e=`/listener`){if(!window.opener)return null;let t=t=>{try{return t.location.origin===window.location.origin&&t.location.pathname===e}catch{return!1}};if(t(window.opener))return window.opener;try{let e=window.opener.frames;for(let n=0;n<e.length;n++)if(t(e[n]))return e[n];return null}catch(t){return console.error(`[findIframeInOpener] Error finding iframe with pathname ${e}:`,t),null}}function v(){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 y=v();function b(){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 x=b();function S(e){y&&e.startsWith(`https://`)?window.location.href=`x-safari-https://${e.slice(8)}`:y&&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 C(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 w=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 T=(()=>{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 E(e){e?localStorage.setItem(r,e):localStorage.removeItem(r)}function D(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 O(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 k(e){return e.includes(`/common/social`)}function A(e,t,n,r){if(c(t)){let i=D(t,r);s(i,{onFallback:()=>{e.contentWindow?.postMessage({clientLifecycle:`deep-link-failed`,data:{originalUrl:i}},n)}})}else if(T&&k(t))O(r);else{let e=D(t,r);window.location.href=e}}function j({iframe:e,targetOrigin:n}){let i=new t.Deferred;return{handleEvent:async t=>{if(!(`iframeLifecycle`in t))return;let{iframeLifecycle:a,data:o}=t;switch(a){case`connected`:i.resolve(!0);break;case`do-backup`:E(o.backup);break;case`remove-backup`:localStorage.removeItem(r);break;case`show`:case`hide`:g({iframe:e,isVisible:a===`show`});break;case`redirect`:A(e,o.baseRedirectUrl,n,o.mergeToken);break}},isConnected:i.promise}}function M({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.n.setCacheScope(c,s),e.n.reset();let l=e.n.isCacheFresh?void 0:e.n.resolve(r.domain,r.walletUrl,s),u=j({iframe:i,targetOrigin:a}),d=new t.Deferred,f=new w(r,i);if(!i.contentWindow)throw new t.FrakRpcError(t.RpcErrorCodes.configError,`The iframe does not have a content window`);let p=(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 f.setLastRequest(e),t},onResponse(e,t){return f.setLastResponse(e,t),t}}],lifecycleHandlers:{iframeLifecycle:async(e,t)=>{await u.handleEvent(e)}}}),m=N(p,u),h=async()=>{m(),p.cleanup(),i.remove(),e.s(),e.n.clearCache(),e.n.reset()},g;console.log(`[Frak SDK] Initializing OpenPanel`),g=new n.OpenPanel({apiUrl:`https://op-api.gcp.frak.id`,clientId:`6eacc8d7-49ac-4936-95e9-81ef29449570`,trackScreenViews:!0,trackOutgoingLinks:!0,trackAttributes:!1,filter:({type:t,payload:n})=>(t!==`track`||!n?.properties||`sdkVersion`in n.properties||(n.properties={...n.properties,sdkVersion:`0.2.1`,userAnonymousClientId:e.y()}),!0)}),g.setGlobalProperties({sdkVersion:`0.2.1`,userAnonymousClientId:e.y()}),g.init();let _=P({config:r,rpcClient:p,lifecycleManager:u,configPromise:l,contextSent:d}).then(()=>f.updateSetupStatus(!0)).catch(e=>{throw d.reject(e),e});return{config:r,debugInfo:f,waitForConnection:u.isConnected,waitForSetup:_,request:p.request,listenerRequest:p.listen,destroy:h,openPanel:g}}function N(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 P({config:t,rpcClient:n,lifecycleManager:i,configPromise:a,contextSent:o}){await i.isConnected,C(n,i.isConnected);let s=new URL(window.location.href),c=s.searchParams.get(`fmt`)??void 0;c&&(s.searchParams.delete(`fmt`),window.history.replaceState({},``,s.toString()));let l=n=>{let r=n?.merchantId??t.metadata.merchantId??``,i=n?.domain??``,a=n?.allowedDomains??[],o=n?.sdkConfig;e.n.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}:{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})},u=!1,d=e=>{let t=u?void 0:c;u=!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}:void 0;n.sendLifecycle({clientLifecycle:`resolved-config`,data:{merchantId:e.merchantId,domain:e.domain??``,allowedDomains:e.allowedDomains??[],sourceUrl:window.location.href,...t&&{pendingMergeToken:t},...r&&{sdkConfig:r}}})};e.n.isResolved&&(d(e.n.getConfig()),o.resolve()),a&&(l(await a),d(e.n.getConfig()),o.resolve());async function f(){let e=t.customizations?.css;e&&n.sendLifecycle({clientLifecycle:`modal-css`,data:{cssLink:e}})}async function p(){let e=t.customizations?.i18n;e&&n.sendLifecycle({clientLifecycle:`modal-i18n`,data:{i18n:e}})}async function m(){if(typeof window>`u`)return;let e=window.localStorage.getItem(r);e&&n.sendLifecycle({clientLifecycle:`restore-backup`,data:{backup:e}})}await Promise.allSettled([f(),p(),m()])}async function F({config:e}){let t=I(e),n=await h({config:t});if(!n){console.error(`Failed to create iframe`);return}let r=M({config:t,iframe:n});if(await r.waitForSetup,!await r.waitForConnection){console.error(`Failed to connect to client`);return}return r}function I(e){let t=u(e.metadata?.currency);return{...e,metadata:{...e.metadata,currency:t}}}Object.defineProperty(exports,`_`,{enumerable:!0,get:function(){return o}}),Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return x}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return h}}),Object.defineProperty(exports,`d`,{enumerable:!0,get:function(){return f}}),Object.defineProperty(exports,`f`,{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,`g`,{enumerable:!0,get:function(){return c}}),Object.defineProperty(exports,`h`,{enumerable:!0,get:function(){return a}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return y}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return _}}),Object.defineProperty(exports,`m`,{enumerable:!0,get:function(){return l}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return M}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return S}}),Object.defineProperty(exports,`p`,{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return w}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return m}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return F}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return p}}),Object.defineProperty(exports,`v`,{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,`y`,{enumerable:!0,get:function(){return i}});
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import{n as e,s as t,y as n}from"./trackEvent-Ce1XlsIE.js";import{Deferred as r,FrakRpcError as i,RpcErrorCodes as a,createRpcClient as o}from"@frak-labs/frame-connector";import{OpenPanel as s}from"@openpanel/web";const c=`nexus-wallet-backup`,l=`frakwallet://`;function u(){let e=navigator.userAgent;return/Android/i.test(e)&&/Chrome\/\d+/i.test(e)}function d(e){return`intent://${e.slice(13)}#Intent;scheme=frakwallet;end`}function f(e,t){let n=t?.timeout??2500,r=!1,i=()=>{document.hidden&&(r=!0)};document.addEventListener(`visibilitychange`,i);let a=u()&&p(e)?d(e):e;window.location.href=a,setTimeout(()=>{document.removeEventListener(`visibilitychange`,i),r||t?.onFallback?.()},n)}function p(e){return e.startsWith(l)}const m={eur:`fr-FR`,usd:`en-US`,gbp:`en-GB`};function h(e){return e&&e in m?e:`eur`}function g(e){return e?m[e]??m.eur:m.eur}function _(e,t){let n=g(t),r=h(t);return e.toLocaleString(n,{style:`currency`,currency:r,minimumFractionDigits:0,maximumFractionDigits:2})}function v(e){return e?`${e}Amount`:`eurAmount`}const y={id:`frak-wallet`,name:`frak-wallet`,title:`Frak Wallet`,allow:`publickey-credentials-get *; clipboard-write; web-share *`,style:{width:`0`,height:`0`,border:`0`,position:`absolute`,zIndex:2000001,top:`-1000px`,left:`-1000px`,colorScheme:`auto`}};function b({walletBaseUrl:e,config:t}){let r=document.querySelector(`#frak-wallet`);r&&r.remove();let i=document.createElement(`iframe`);i.id=y.id,i.name=y.name,i.allow=y.allow,i.style.zIndex=y.style.zIndex.toString(),x({iframe:i,isVisible:!1});let a=t?.walletUrl??e??`https://wallet.frak.id`,o=n();return i.src=`${a}/listener?clientId=${encodeURIComponent(o)}`,new Promise(e=>{i.addEventListener(`load`,()=>e(i)),document.body.appendChild(i)})}function x({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 S(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 C(){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 w=C();function T(){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 E=T();function D(e){w&&e.startsWith(`https://`)?window.location.href=`x-safari-https://${e.slice(8)}`:w&&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 O(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 k=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(),r=`Unknown`;return e instanceof i?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 A=(()=>{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 j(e){e?localStorage.setItem(c,e):localStorage.removeItem(c)}function M(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 N(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 P(e){return e.includes(`/common/social`)}function F(e,t,n,r){if(p(t)){let i=M(t,r);f(i,{onFallback:()=>{e.contentWindow?.postMessage({clientLifecycle:`deep-link-failed`,data:{originalUrl:i}},n)}})}else if(A&&P(t))N(r);else{let e=M(t,r);window.location.href=e}}function I({iframe:e,targetOrigin:t}){let n=new r;return{handleEvent:async r=>{if(!(`iframeLifecycle`in r))return;let{iframeLifecycle:i,data:a}=r;switch(i){case`connected`:n.resolve(!0);break;case`do-backup`:j(a.backup);break;case`remove-backup`:localStorage.removeItem(c);break;case`show`:case`hide`:x({iframe:e,isVisible:i===`show`});break;case`redirect`:F(e,a.baseRedirectUrl,t,a.mergeToken);break}},isConnected:n.promise}}function L({config:c,iframe:l}){let u=c?.walletUrl??`https://wallet.frak.id`,d=typeof navigator<`u`?navigator.language?.split(`-`)[0]:void 0,f=c.metadata.lang??(d===`en`||d===`fr`?d:void 0),p=c.domain??(typeof window<`u`?window.location.hostname:``);e.setCacheScope(p,f),e.reset();let m=e.isCacheFresh?void 0:e.resolve(c.domain,c.walletUrl,f),h=I({iframe:l,targetOrigin:u}),g=new r,_=new k(c,l);if(!l.contentWindow)throw new i(a.configError,`The iframe does not have a content window`);let v=o({emittingTransport:l.contentWindow,listeningTransport:window,targetOrigin:u,middleware:[{async onRequest(e,t){if(!await h.isConnected)throw new i(a.clientNotConnected,`The iframe provider isn't connected yet`);return await g.promise,t}},{onRequest(e,t){return _.setLastRequest(e),t},onResponse(e,t){return _.setLastResponse(e,t),t}}],lifecycleHandlers:{iframeLifecycle:async(e,t)=>{await h.handleEvent(e)}}}),y=R(v,h),b=async()=>{y(),v.cleanup(),l.remove(),t(),e.clearCache(),e.reset()},x;console.log(`[Frak SDK] Initializing OpenPanel`),x=new s({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:`0.2.1`,userAnonymousClientId:n()}),!0)}),x.setGlobalProperties({sdkVersion:`0.2.1`,userAnonymousClientId:n()}),x.init();let S=z({config:c,rpcClient:v,lifecycleManager:h,configPromise:m,contextSent:g}).then(()=>_.updateSetupStatus(!0)).catch(e=>{throw g.reject(e),e});return{config:c,debugInfo:_,waitForConnection:h.isConnected,waitForSetup:S,request:v.request,listenerRequest:v.listen,destroy:b,openPanel:x}}function R(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 z({config:t,rpcClient:n,lifecycleManager:r,configPromise:i,contextSent:a}){await r.isConnected,O(n,r.isConnected);let o=new URL(window.location.href),s=o.searchParams.get(`fmt`)??void 0;s&&(o.searchParams.delete(`fmt`),window.history.replaceState({},``,o.toString()));let l=n=>{let r=n?.merchantId??t.metadata.merchantId??``,i=n?.domain??``,a=n?.allowedDomains??[],o=n?.sdkConfig;e.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}:{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})},u=!1,d=e=>{let t=u?void 0:s;u=!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}:void 0;n.sendLifecycle({clientLifecycle:`resolved-config`,data:{merchantId:e.merchantId,domain:e.domain??``,allowedDomains:e.allowedDomains??[],sourceUrl:window.location.href,...t&&{pendingMergeToken:t},...r&&{sdkConfig:r}}})};e.isResolved&&(d(e.getConfig()),a.resolve()),i&&(l(await i),d(e.getConfig()),a.resolve());async function f(){let e=t.customizations?.css;e&&n.sendLifecycle({clientLifecycle:`modal-css`,data:{cssLink:e}})}async function p(){let e=t.customizations?.i18n;e&&n.sendLifecycle({clientLifecycle:`modal-i18n`,data:{i18n:e}})}async function m(){if(typeof window>`u`)return;let e=window.localStorage.getItem(c);e&&n.sendLifecycle({clientLifecycle:`restore-backup`,data:{backup:e}})}await Promise.allSettled([f(),p(),m()])}async function B({config:e}){let t=V(e),n=await b({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=h(e.metadata?.currency);return{...e,metadata:{...e.metadata,currency:t}}}export{d as _,E as a,b as c,_ as d,g as f,p as g,u as h,w as i,S as l,m,L as n,D as o,h as p,k as r,y as s,B as t,v as u,f as v,l as y};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const e=require(`./trackEvent-CvbJTTqA.cjs`);let t=require(`viem`),n=require(`@frak-labs/frame-connector`),r=require(`viem/siwe`);async function i(e,t,n){return await e.request({method:`frak_displayEmbeddedWallet`,params:n?[t,e.config.metadata,n]:[t,e.config.metadata]})}async function a(e,{steps:t,metadata:n},r){return await e.request({method:`frak_displayModal`,params:r?[t,n,e.config.metadata,r]:[t,n,e.config.metadata]})}async function o(e,t,n){return await e.request({method:`frak_displaySharingPage`,params:n?[t,e.config.metadata,n]:[t,e.config.metadata]})}async function s(t){if(typeof window>`u`)return;let n=e.y();if(!n)return;let r=await e.n.resolveMerchantId();if(!r)return;let i=`frak-identity-ensured-${r}`;if(!window.sessionStorage.getItem(i))try{let a=e.u();(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 c(t,n){return e.l(()=>t.request({method:`frak_getMerchantInformation`}),{cacheKey:`frak_getMerchantInformation`,cacheTime:n?.cacheTime})}async function l(t,n){return e.l(()=>t.request({method:`frak_getUserReferralStatus`}),{cacheKey:`frak_getUserReferralStatus`,cacheTime:n?.cacheTime})}async function u(e,t){let{metadata:n,customizations:r}=e.config;return await e.request({method:`frak_prepareSso`,params:[t,n.name,r?.css]})}async function d(t,n){try{await t.request({method:`frak_sendInteraction`,params:[n,{clientId:e.y()}]})}catch{console.warn(`[Frak SDK] Failed to send interaction:`,n.type)}}function f(t,n,r){let i=typeof window<`u`?window.location.href:void 0;return e.a(n)?(e.t(t,`user_referred_started`,{properties:{referrerClientId:n.c,walletStatus:r?.key}}),d(t,{type:`arrival`,referrerClientId:n.c,referrerMerchantId:n.m,referralTimestamp:n.t,landingUrl:i}),!0):e.i(n)?(e.t(t,`user_referred_started`,{properties:{referrer:n.r,walletStatus:r?.key}}),d(t,{type:`arrival`,referrerWallet:n.r,landingUrl:i}),!0):!1}function p(t){let n=e.y();return n?{v:2,c:n,m:t,t:Math.floor(Date.now()/1e3)}:null}function m(n,r){return e.a(n)?e.y()===n.c:e.i(n)&&r?.wallet?(0,t.isAddressEqual)(n.r,r.wallet):!1}function h(t,{walletStatus:n,frakContext:r,options:i}){if(!r)return`no-referrer`;if(m(r,n))return`self-referral`;if(!f(t,r,n))return`no-referrer`;let a=e.a(r)?r.m:i?.merchantId,o=i?.alwaysAppendUrl&&a?p(a):null;return e.r.replaceUrl({url:window.location?.href,context:o}),e.t(t,`user_referred_completed`,{properties:{status:`success`}}),`success`}async function g(t,{options:n}={}){let r=e.r.parse({url:window.location.href}),i=await b(t);try{return h(t,{walletStatus:i,frakContext:r,options:n})}catch(e){console.warn(`Error processing referral`,{error:e})}}const _=`frak:referral-success`;async function v(e){try{await g(e)===`success`&&window.dispatchEvent(new Event(_))}catch(e){console.warn(`[Frak] Referral setup failed`,e)}}async function y(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.y();if(!n&&!r){console.warn(`[Frak] No identity found, skipping purchase check`);return}let i=t.merchantId??await e.n.resolveMerchantId();if(!i){console.warn(`[Frak] No merchant id found, skipping purchase check`);return}let a={Accept:`application/json`,"Content-Type":`application/json`};n&&(a[`x-wallet-sdk-auth`]=n),r&&(a[`x-frak-client-id`]=r);let o=e.u();await fetch(`${o}/user/track/purchase`,{method:`POST`,headers:a,body:JSON.stringify({customerId:t.customerId,orderId:t.orderId,token:t.token,merchantId:i})})}function b(e,t){if(!t)return e.request({method:`frak_listenToWalletStatus`}).then(t=>(x(e,t),t));let r=new n.Deferred,i=!1;return e.listenerRequest({method:`frak_listenToWalletStatus`},n=>{x(e,n),t(n),i||=(r.resolve(n),!0)}),r.promise}function x(e,t){typeof window>`u`||(e.openPanel?.setGlobalProperties({wallet:t.wallet??null}),t.interactionToken?(window.sessionStorage.setItem(`frak-wallet-interaction-token`,t.interactionToken),s(t.interactionToken)):window.sessionStorage.removeItem(`frak-wallet-interaction-token`))}function S(e,{metadata:t,login:n}){return C(e,{steps:{login:n??{}},metadata:t})}function C(e,t){function n(n){return C(e,{...t,steps:{...t.steps,sendTransaction:n}})}function r(n){return C(e,{...t,steps:{...t.steps,final:{...n,action:{key:`reward`}}}})}function i(n,r){return C(e,{...t,steps:{...t.steps,final:{...r,action:{key:`sharing`,options:n}}}})}async function o(n,r){return n&&(t.metadata=n(t.metadata??{})),await a(e,t,r)}return{params:t,sendTx:n,reward:r,sharing:i,display:o}}async function w(e,{tx:t,metadata:n}){return(await a(e,{metadata:n,steps:{login:{},sendTransaction:{tx:t}}})).sendTransaction}async function T(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,`_`,{enumerable:!0,get:function(){return i}}),Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return y}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return g}}),Object.defineProperty(exports,`d`,{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,`f`,{enumerable:!0,get:function(){return l}}),Object.defineProperty(exports,`g`,{enumerable:!0,get:function(){return a}}),Object.defineProperty(exports,`h`,{enumerable:!0,get:function(){return o}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return b}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return h}}),Object.defineProperty(exports,`m`,{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return w}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return _}}),Object.defineProperty(exports,`p`,{enumerable:!0,get:function(){return c}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return S}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return v}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return T}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return d}});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{a as e,i as t,l as n,n as r,r as i,t as a,u as o,y as s}from"./trackEvent-Ce1XlsIE.js";import{isAddressEqual as c}from"viem";import{Deferred as l}from"@frak-labs/frame-connector";import{generateSiweNonce as u}from"viem/siwe";async function d(e,t,n){return await e.request({method:`frak_displayEmbeddedWallet`,params:n?[t,e.config.metadata,n]:[t,e.config.metadata]})}async function f(e,{steps:t,metadata:n},r){return await e.request({method:`frak_displayModal`,params:r?[t,n,e.config.metadata,r]:[t,n,e.config.metadata]})}async function p(e,t,n){return await e.request({method:`frak_displaySharingPage`,params:n?[t,e.config.metadata,n]:[t,e.config.metadata]})}async function m(e){if(typeof window>`u`)return;let t=s();if(!t)return;let n=await r.resolveMerchantId();if(!n)return;let i=`frak-identity-ensured-${n}`;if(!window.sessionStorage.getItem(i))try{let r=o();(await fetch(`${r}/user/identity/ensure`,{method:`POST`,headers:{Accept:`application/json`,"Content-Type":`application/json`,"x-wallet-sdk-auth":e,"x-frak-client-id":t},body:JSON.stringify({merchantId:n})})).ok&&window.sessionStorage.setItem(i,`1`)}catch{}}async function h(e,t){return n(()=>e.request({method:`frak_getMerchantInformation`}),{cacheKey:`frak_getMerchantInformation`,cacheTime:t?.cacheTime})}async function g(e,t){return n(()=>e.request({method:`frak_getUserReferralStatus`}),{cacheKey:`frak_getUserReferralStatus`,cacheTime:t?.cacheTime})}async function _(e,t){let{metadata:n,customizations:r}=e.config;return await e.request({method:`frak_prepareSso`,params:[t,n.name,r?.css]})}async function v(e,t){try{await e.request({method:`frak_sendInteraction`,params:[t,{clientId:s()}]})}catch{console.warn(`[Frak SDK] Failed to send interaction:`,t.type)}}function y(n,r,i){let o=typeof window<`u`?window.location.href:void 0;return e(r)?(a(n,`user_referred_started`,{properties:{referrerClientId:r.c,walletStatus:i?.key}}),v(n,{type:`arrival`,referrerClientId:r.c,referrerMerchantId:r.m,referralTimestamp:r.t,landingUrl:o}),!0):t(r)?(a(n,`user_referred_started`,{properties:{referrer:r.r,walletStatus:i?.key}}),v(n,{type:`arrival`,referrerWallet:r.r,landingUrl:o}),!0):!1}function b(e){let t=s();return t?{v:2,c:t,m:e,t:Math.floor(Date.now()/1e3)}:null}function x(n,r){return e(n)?s()===n.c:t(n)&&r?.wallet?c(n.r,r.wallet):!1}function S(t,{walletStatus:n,frakContext:r,options:o}){if(!r)return`no-referrer`;if(x(r,n))return`self-referral`;if(!y(t,r,n))return`no-referrer`;let s=e(r)?r.m:o?.merchantId,c=o?.alwaysAppendUrl&&s?b(s):null;return i.replaceUrl({url:window.location?.href,context:c}),a(t,`user_referred_completed`,{properties:{status:`success`}}),`success`}async function C(e,{options:t}={}){let n=i.parse({url:window.location.href}),r=await D(e);try{return S(e,{walletStatus:r,frakContext:n,options:t})}catch(e){console.warn(`Error processing referral`,{error:e})}}const w=`frak:referral-success`;async function T(e){try{await C(e)===`success`&&window.dispatchEvent(new Event(w))}catch(e){console.warn(`[Frak] Referral setup failed`,e)}}async function E(e){if(typeof window>`u`){console.warn(`[Frak] No window found, can't track purchase`);return}let t=window.sessionStorage.getItem(`frak-wallet-interaction-token`),n=s();if(!t&&!n){console.warn(`[Frak] No identity found, skipping purchase check`);return}let i=e.merchantId??await r.resolveMerchantId();if(!i){console.warn(`[Frak] No merchant id found, skipping purchase check`);return}let a={Accept:`application/json`,"Content-Type":`application/json`};t&&(a[`x-wallet-sdk-auth`]=t),n&&(a[`x-frak-client-id`]=n);let c=o();await fetch(`${c}/user/track/purchase`,{method:`POST`,headers:a,body:JSON.stringify({customerId:e.customerId,orderId:e.orderId,token:e.token,merchantId:i})})}function D(e,t){if(!t)return e.request({method:`frak_listenToWalletStatus`}).then(t=>(O(e,t),t));let n=new l,r=!1;return e.listenerRequest({method:`frak_listenToWalletStatus`},i=>{O(e,i),t(i),r||=(n.resolve(i),!0)}),n.promise}function O(e,t){typeof window>`u`||(e.openPanel?.setGlobalProperties({wallet:t.wallet??null}),t.interactionToken?(window.sessionStorage.setItem(`frak-wallet-interaction-token`,t.interactionToken),m(t.interactionToken)):window.sessionStorage.removeItem(`frak-wallet-interaction-token`))}function k(e,{metadata:t,login:n}){return A(e,{steps:{login:n??{}},metadata:t})}function A(e,t){function n(n){return A(e,{...t,steps:{...t.steps,sendTransaction:n}})}function r(n){return A(e,{...t,steps:{...t.steps,final:{...n,action:{key:`reward`}}}})}function i(n,r){return A(e,{...t,steps:{...t.steps,final:{...r,action:{key:`sharing`,options:n}}}})}async function a(n,r){return n&&(t.metadata=n(t.metadata??{})),await f(e,t,r)}return{params:t,sendTx:n,reward:r,sharing:i,display:a}}async function j(e,{tx:t,metadata:n}){return(await f(e,{metadata:n,steps:{login:{},sendTransaction:{tx:t}}})).sendTransaction}async function M(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 f(e,{metadata:n,steps:{login:{},siweAuthenticate:{siwe:{...t,statement:i,nonce:t?.nonce??u(),uri:t?.uri??`https://${r}`,version:t?.version??`1`,domain:r}}}})).siweAuthenticate}export{d as _,E as a,C as c,_ as d,g as f,f as g,p as h,D as i,S as l,m,j as n,w as o,h as p,k as r,T as s,M as t,v as u};
|