@frak-labs/core-sdk
Version:
Core SDK of the Frak wallet, low level library to interact directly with the frak ecosystem.
1 lines • 9.93 kB
JavaScript
let e=require(`@frak-labs/frame-connector`);const t=`frak-client-id`;function n(){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 r(){if(typeof window>`u`||!window.localStorage)return console.warn(`[Frak SDK] No Window / localStorage available to save the clientId`),n();let e=localStorage.getItem(t);return e||(e=n(),localStorage.setItem(t,e)),e}var i=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 a=new i(1024),o=new i(1024),s=new i(1024);async function c(e,{cacheKey:t,cacheTime:n=3e4}){if(n>0){let e=o.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=a.get(t);i||(i=e(),a.set(t,i));try{let e=await i;return o.set(t,{data:e,created:Date.now()}),s.delete(t),e}catch(e){throw s.set(t,Date.now()),e}finally{a.delete(t)}}function l(){a.clear(),o.clear(),s.clear()}const u=`https://backend.frak.id`;function d(e){return e.includes(`localhost:3000`)||e.includes(`localhost:3010`)}function f(e){return d(e)?`https://localhost:3030`:e.includes(`wallet-dev.frak.id`)||e.includes(`wallet.gcp-dev.frak.id`)?`https://backend.gcp-dev.frak.id`:u}function p(e){if(e)return f(e);if(typeof window<`u`){let e=window.FrakSetup?.client?.config?.walletUrl;if(e)return f(e)}return u}const m=`__frakSdkConfig`,h=`frak-config-cache`,g=`frak-merchant-id`,_={key:h},v=typeof window<`u`;function y(){return{isResolved:!1,merchantId:``}}let b=null;function x(){if(!v)return null;try{let e=localStorage.getItem(_.key);if(!e)return null;let t=JSON.parse(e);return t.config?.isResolved?(b=t,t):null}catch{return null}}function S(){return(b??x())?.config}function C(){let e=b??x();return e?Date.now()-e.timestamp<3e4:!1}function ee(e){if(!(!v||!e.isResolved))try{let t={config:e,timestamp:Date.now()};localStorage.setItem(_.key,JSON.stringify(t)),b=t}catch{}}function w(){if(v){b=null;try{localStorage.removeItem(_.key)}catch{}}}function T(){v&&(window[m]||(window[m]=S()??y()))}T();function E(){return v?window[m]??y():y()}function D(e){v&&window.dispatchEvent(new CustomEvent(`frak:config`,{detail:e}))}function O(e){return e??(v?window.location.hostname:``)}async function te(e,t,n){try{let r=p(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(v)try{sessionStorage.setItem(g,o.merchantId)}catch{}return o}catch(e){console.warn(`[Frak SDK] Failed to fetch merchant config:`,e);return}}const k={getConfig:E,get isResolved(){return E().isResolved},get isCacheFresh(){return C()},setCacheScope(e,t){_.key=`${h}:${`${e}:${t??``}`}`,b=null},setConfig(e){if(v&&(window[m]=e),ee(e),D(e),v&&e.merchantId)try{sessionStorage.setItem(g,e.merchantId)}catch{}},reset(){let e=S()??y();v&&(window[m]=e),D(e)},clearCache(){if(w(),l(),v)try{sessionStorage.removeItem(g)}catch{}},resolve(e,t,n){let r=O(e);return r?c(async()=>{let e=await te(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=E();if(e.isResolved&&e.merchantId)return e.merchantId;if(v)try{return sessionStorage.getItem(g)??void 0}catch{}},async resolveMerchantId(e,t){return k.getMerchantId()||(await k.resolve(e,t))?.merchantId}};function A(e){return btoa(Array.from(e,e=>String.fromCharCode(e)).join(``)).replace(/\+/g,`-`).replace(/\//g,`_`).replace(/=+$/,``)}function j(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 M(t){return A((0,e.jsonEncode)(t))}function N(e,t,n,r,i,a){let o=M(P({redirectUrl:t.redirectUrl,directExit:t.directExit,lang:t.lang,merchantId:n,metadata:{name:r,css:a,logoUrl:t.metadata?.logoUrl,homepageLink:t.metadata?.homepageLink},clientId:i})),s=new URL(e);return s.pathname=`/sso`,s.searchParams.set(`p`,o),s.toString()}function P(e){return{r:e.redirectUrl,cId:e.clientId,d:e.directExit,l:e.lang,m:e.merchantId,md:{n:e.metadata?.name,css:e.metadata?.css,l:e.metadata?.logoUrl,h:e.metadata?.homepageLink}}}const F=`menubar=no,status=no,scrollbars=no,fullscreen=no,width=500, height=800`,I=`frak-sso`;async function ne(e,t){let{metadata:n,customizations:i,walletUrl:a}=e.config,o={...t,directExit:t.directExit??!t.redirectUrl};if(o.openInSameWindow??!!o.redirectUrl)return await e.request({method:`frak_openSso`,params:[o,n.name,i?.css]});let s=o.ssoPopupUrl??N(a??`https://wallet.frak.id`,o,await k.resolveMerchantId()??``,n.name,r(),i?.css),c=window.open(s,I,F);if(!c)throw Error(`Popup was blocked. Please allow popups for this site.`);return c.focus(),await e.request({method:`frak_openSso`,params:[o,n.name,i?.css]})??{}}function re(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 ie=/^0x[a-fA-F0-9]{40}$/;function L(e){return typeof e==`string`&&ie.test(e)}function ae(e,t){return e.toLowerCase()===t.toLowerCase()}function R(e){let t=new Uint8Array(20);for(let n=0;n<20;n++){let r=Number.parseInt(e.substring(2+n*2,4+n*2),16);if(Number.isNaN(r))throw Error(`Invalid address: ${e}`);t[n]=r}return t}const z=Array.from({length:256},(e,t)=>t.toString(16).padStart(2,`0`));function B(e){let t=`0x`;for(let n=0;n<20;n++)t+=z[e[n]];return t}function V(e){return`r`in e&&!(`v`in e)}function H(e){return`v`in e&&e.v===2}const U=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function W(e){return typeof e==`string`&&U.test(e)}function G(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 K(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 q(e){if(!W(e.m)||!Number.isInteger(e.t)||e.t<0||e.t>4294967295)return null;let t=typeof e.c==`string`&&e.c.length>0,n=typeof e.w==`string`&&L(e.w);if(!t&&!n||t&&!W(e.c))return null;let r=new Uint8Array(21+(t?16:0)+(n?20:0)),i=new DataView(r.buffer,r.byteOffset,r.byteLength),a=0;return r[a++]=2|(t?16:0)|(n?32:0),r.set(G(e.m),a),a+=16,i.setUint32(a,e.t,!1),a+=4,t&&(r.set(G(e.c),a),a+=16),n&&(r.set(R(e.w),a),a+=20),r}function oe(e){if(e.length<21)return null;let t=e[0];if((t&15)!=2||t&192)return null;let n=(t&16)!=0,r=(t&32)!=0;if(!n&&!r)return null;let i=21+(n?16:0)+(r?20:0);if(e.length!==i)return null;let a=1,o=K(e.subarray(a,a+16));a+=16;let s=new DataView(e.buffer,e.byteOffset,e.byteLength).getUint32(a,!1);a+=4;let c={v:2,m:o,t:s};if(n&&(c.c=K(e.subarray(a,a+16)),a+=16),r){let t=B(e.subarray(a,a+20));if(!L(t))return null;c.w=t,a+=20}return c}const J=`fCtx`;function Y(e){if(e)try{if(H(e)){let t=q(e);return t?A(t):void 0}return A(R(e.r))}catch(t){console.error(`Error compressing Frak context`,{e:t,context:e})}}function X(e){if(!(!e||e.length===0))try{let t=j(e);if(t.length!==20)return oe(t)||void 0;let n=B(t);if(L(n))return{r:n}}catch(t){console.error(`Error decompressing Frak context`,{e:t,context:e})}}function se({url:e}){if(!e)return null;let t=new URL(e).searchParams.get(J);return t?X(t):null}function ce(e){return{utm_source:e.utmSource??`frak`,utm_medium:e.utmMedium??void 0,utm_campaign:e.utmCampaign??void 0,utm_content:e.utmContent,utm_term:e.utmTerm,via:e.via??void 0,ref:e.ref??void 0}}function le(e,t){let n=ce(t??{});for(let[t,r]of Object.entries(n))r===void 0||r===``||e.searchParams.has(t)||e.searchParams.set(t,r)}function Z({url:e,context:t,attribution:n}){if(!e)return null;let r=Y(t);if(!r)return null;let i=new URL(e);return i.searchParams.set(J,r),le(i,n),i.toString()}function Q(e){let t=new URL(e);return t.searchParams.delete(J),t.toString()}function $({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?Q(n):Z({url:n,context:t}),r&&window.history.replaceState(null,``,r.toString())}const ue={compress:Y,decompress:X,parse:se,update:Z,remove:Q,replaceUrl:$};Object.defineProperty(exports,`_`,{enumerable:!0,get:function(){return r}}),Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return re}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return I}}),Object.defineProperty(exports,`d`,{enumerable:!0,get:function(){return j}}),Object.defineProperty(exports,`f`,{enumerable:!0,get:function(){return A}}),Object.defineProperty(exports,`g`,{enumerable:!0,get:function(){return c}}),Object.defineProperty(exports,`h`,{enumerable:!0,get:function(){return l}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return ae}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return N}}),Object.defineProperty(exports,`m`,{enumerable:!0,get:function(){return p}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return V}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return ne}}),Object.defineProperty(exports,`p`,{enumerable:!0,get:function(){return k}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return H}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return F}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return ue}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return M}});