@frak-labs/core-sdk 0.1.0-beta.afa252b0 → 0.1.0-beta.b0bd1f8a
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.iife.js +14 -0
- package/dist/actions-CEEObPYc.js +1 -0
- package/dist/actions-DbQhWYx8.cjs +1 -0
- package/dist/actions.cjs +1 -1
- package/dist/actions.d.cts +3 -1481
- package/dist/actions.d.ts +3 -1481
- package/dist/actions.js +1 -1
- package/dist/bundle.cjs +1 -13
- package/dist/bundle.d.cts +6 -2087
- package/dist/bundle.d.ts +6 -2087
- package/dist/bundle.js +1 -13
- package/dist/index-7OZ39x1U.d.ts +195 -0
- package/dist/index-C6FxkWPC.d.cts +511 -0
- package/dist/index-UFX7xCg3.d.ts +351 -0
- package/dist/index-d8xS4ryI.d.ts +511 -0
- package/dist/index-p4FqSp8z.d.cts +351 -0
- package/dist/index-zDq-VlKx.d.cts +195 -0
- package/dist/index.cjs +1 -13
- package/dist/index.d.cts +4 -1387
- package/dist/index.d.ts +4 -1387
- package/dist/index.js +1 -13
- package/dist/interaction-DMJ3ZfaF.d.cts +45 -0
- package/dist/interaction-KX1h9a7V.d.ts +45 -0
- package/dist/interactions-DnfM3oe0.js +1 -0
- package/dist/interactions-EIXhNLf6.cjs +1 -0
- package/dist/interactions.cjs +1 -1
- package/dist/interactions.d.cts +2 -182
- package/dist/interactions.d.ts +2 -182
- package/dist/interactions.js +1 -1
- package/dist/openSso-D--Airj6.d.cts +1018 -0
- package/dist/openSso-DsKJ4y0j.d.ts +1018 -0
- package/dist/productTypes-BUkXJKZ7.cjs +1 -0
- package/dist/productTypes-CGb1MmBF.js +1 -0
- package/dist/src-B_xO0AR6.cjs +13 -0
- package/dist/src-D2d52OZa.js +13 -0
- package/dist/trackEvent-CHnYa85W.js +1 -0
- package/dist/trackEvent-GuQm_1Nm.cjs +1 -0
- package/package.json +23 -18
- package/src/actions/displayEmbeddedWallet.test.ts +194 -0
- package/src/actions/displayEmbeddedWallet.ts +20 -0
- package/src/actions/displayModal.test.ts +387 -0
- package/src/actions/displayModal.ts +131 -0
- package/src/actions/getProductInformation.test.ts +133 -0
- package/src/actions/getProductInformation.ts +14 -0
- package/src/actions/index.ts +29 -0
- package/src/actions/openSso.test.ts +407 -0
- package/src/actions/openSso.ts +116 -0
- package/src/actions/prepareSso.test.ts +223 -0
- package/src/actions/prepareSso.ts +48 -0
- package/src/actions/referral/processReferral.ts +230 -0
- package/src/actions/referral/referralInteraction.ts +57 -0
- package/src/actions/sendInteraction.test.ts +219 -0
- package/src/actions/sendInteraction.ts +32 -0
- package/src/actions/trackPurchaseStatus.test.ts +287 -0
- package/src/actions/trackPurchaseStatus.ts +53 -0
- package/src/actions/watchWalletStatus.test.ts +372 -0
- package/src/actions/watchWalletStatus.ts +94 -0
- package/src/actions/wrapper/modalBuilder.ts +212 -0
- package/src/actions/wrapper/sendTransaction.ts +62 -0
- package/src/actions/wrapper/siweAuthenticate.ts +94 -0
- package/src/bundle.ts +3 -0
- package/src/clients/DebugInfo.ts +182 -0
- package/src/clients/createIFrameFrakClient.ts +287 -0
- package/src/clients/index.ts +3 -0
- package/src/clients/setupClient.test.ts +343 -0
- package/src/clients/setupClient.ts +73 -0
- package/src/clients/transports/iframeLifecycleManager.test.ts +399 -0
- package/src/clients/transports/iframeLifecycleManager.ts +90 -0
- package/src/constants/interactionTypes.ts +44 -0
- package/src/constants/locales.ts +14 -0
- package/src/constants/productTypes.ts +33 -0
- package/src/index.ts +101 -0
- package/src/interactions/index.ts +5 -0
- package/src/interactions/pressEncoder.test.ts +215 -0
- package/src/interactions/pressEncoder.ts +53 -0
- package/src/interactions/purchaseEncoder.test.ts +291 -0
- package/src/interactions/purchaseEncoder.ts +99 -0
- package/src/interactions/referralEncoder.test.ts +170 -0
- package/src/interactions/referralEncoder.ts +47 -0
- package/src/interactions/retailEncoder.test.ts +107 -0
- package/src/interactions/retailEncoder.ts +37 -0
- package/src/interactions/webshopEncoder.test.ts +56 -0
- package/src/interactions/webshopEncoder.ts +30 -0
- package/src/types/client.ts +14 -0
- package/src/types/compression.ts +22 -0
- package/src/types/config.ts +111 -0
- package/src/types/context.ts +13 -0
- package/src/types/index.ts +71 -0
- package/src/types/lifecycle/client.ts +46 -0
- package/src/types/lifecycle/iframe.ts +35 -0
- package/src/types/lifecycle/index.ts +2 -0
- package/src/types/rpc/displayModal.ts +84 -0
- package/src/types/rpc/embedded/index.ts +68 -0
- package/src/types/rpc/embedded/loggedIn.ts +55 -0
- package/src/types/rpc/embedded/loggedOut.ts +28 -0
- package/src/types/rpc/interaction.ts +43 -0
- package/src/types/rpc/modal/final.ts +46 -0
- package/src/types/rpc/modal/generic.ts +46 -0
- package/src/types/rpc/modal/index.ts +20 -0
- package/src/types/rpc/modal/login.ts +32 -0
- package/src/types/rpc/modal/openSession.ts +25 -0
- package/src/types/rpc/modal/siweAuthenticate.ts +37 -0
- package/src/types/rpc/modal/transaction.ts +33 -0
- package/src/types/rpc/productInformation.ts +59 -0
- package/src/types/rpc/sso.ts +80 -0
- package/src/types/rpc/walletStatus.ts +35 -0
- package/src/types/rpc.ts +158 -0
- package/src/types/transport.ts +34 -0
- package/src/utils/FrakContext.test.ts +407 -0
- package/src/utils/FrakContext.ts +158 -0
- package/src/utils/compression/b64.test.ts +181 -0
- package/src/utils/compression/b64.ts +29 -0
- package/src/utils/compression/compress.test.ts +123 -0
- package/src/utils/compression/compress.ts +11 -0
- package/src/utils/compression/decompress.test.ts +145 -0
- package/src/utils/compression/decompress.ts +11 -0
- package/src/utils/compression/index.ts +3 -0
- package/src/utils/computeProductId.test.ts +80 -0
- package/src/utils/computeProductId.ts +11 -0
- package/src/utils/constants.test.ts +23 -0
- package/src/utils/constants.ts +4 -0
- package/src/utils/formatAmount.test.ts +113 -0
- package/src/utils/formatAmount.ts +18 -0
- package/src/utils/getCurrencyAmountKey.test.ts +44 -0
- package/src/utils/getCurrencyAmountKey.ts +15 -0
- package/src/utils/getSupportedCurrency.test.ts +51 -0
- package/src/utils/getSupportedCurrency.ts +14 -0
- package/src/utils/getSupportedLocale.test.ts +64 -0
- package/src/utils/getSupportedLocale.ts +16 -0
- package/src/utils/iframeHelper.test.ts +450 -0
- package/src/utils/iframeHelper.ts +143 -0
- package/src/utils/index.ts +21 -0
- package/src/utils/sso.test.ts +361 -0
- package/src/utils/sso.ts +119 -0
- package/src/utils/ssoUrlListener.ts +60 -0
- package/src/utils/trackEvent.test.ts +162 -0
- package/src/utils/trackEvent.ts +26 -0
- package/cdn/bundle.js +0 -19
- package/cdn/bundle.js.LICENSE.txt +0 -10
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e={press:{openArticle:`0xc0a24ffb`,readArticle:`0xd5bd0fbe`},dapp:{proofVerifiableStorageUpdate:`0x2ab2aeef`,callableVerifiableStorageUpdate:`0xa07da986`},webshop:{open:`0xb311798f`},referral:{referred:`0x010cc3b9`,createLink:`0xb2c0f17c`},purchase:{started:`0xd87e90c3`,completed:`0x8403aeb4`,unsafeCompleted:`0x4d5b14e0`},retail:{customerMeeting:`0x74489004`}},t={dapp:1,press:2,webshop:3,retail:4,referral:30,purchase:31},n=Object.entries(t).reduce((e,[t,n])=>(e[t]=BigInt(1)<<BigInt(n),e),{});Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return n}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return e}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return t}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e={press:{openArticle:`0xc0a24ffb`,readArticle:`0xd5bd0fbe`},dapp:{proofVerifiableStorageUpdate:`0x2ab2aeef`,callableVerifiableStorageUpdate:`0xa07da986`},webshop:{open:`0xb311798f`},referral:{referred:`0x010cc3b9`,createLink:`0xb2c0f17c`},purchase:{started:`0xd87e90c3`,completed:`0x8403aeb4`,unsafeCompleted:`0x4d5b14e0`},retail:{customerMeeting:`0x74489004`}},t={dapp:1,press:2,webshop:3,retail:4,referral:30,purchase:31},n=Object.entries(t).reduce((e,[t,n])=>(e[t]=BigInt(1)<<BigInt(n),e),{});export{n,e as r,t};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const e=require(`./trackEvent-GuQm_1Nm.cjs`);let t=require(`@frak-labs/frame-connector`),n=require(`@frak-labs/frame-connector/middleware`),r=require(`@openpanel/web`);const i=`nexus-wallet-backup`;function a(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: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 s={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 c({walletBaseUrl:e,config:t}){let n=document.querySelector(`#frak-wallet`);n&&n.remove();let r=document.createElement(`iframe`);return r.id=s.id,r.name=s.name,r.allow=s.allow,r.style.zIndex=s.style.zIndex.toString(),l({iframe:r,isVisible:!1}),document.body.appendChild(r),new Promise(n=>{r?.addEventListener(`load`,()=>n(r)),r.src=`${t?.walletUrl??e??`https://wallet.frak.id`}/listener`})}function l({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 u(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 d({iframe:e}){let n=new t.Deferred;return{handleEvent:async t=>{if(!(`iframeLifecycle`in t))return;let{iframeLifecycle:r,data:a}=t;switch(r){case`connected`:n.resolve(!0);break;case`do-backup`:a.backup?localStorage.setItem(i,a.backup):localStorage.removeItem(i);break;case`remove-backup`:localStorage.removeItem(i);break;case`show`:case`hide`:l({iframe:e,isVisible:r===`show`});break;case`handshake`:e.contentWindow?.postMessage({clientLifecycle:`handshake-response`,data:{token:a.token,currentUrl:window.location.href}},`*`);break;case`redirect`:{let e=new URL(a.baseRedirectUrl);e.searchParams.has(`u`)?(e.searchParams.delete(`u`),e.searchParams.append(`u`,window.location.href),window.location.href=e.toString()):window.location.href=a.baseRedirectUrl;break}}},isConnected:n.promise}}function f({config:e,iframe:i}){let a=e?.walletUrl??`https://wallet.frak.id`,s=d({iframe:i}),c=new o(e,i);if(!i.contentWindow)throw new t.FrakRpcError(t.RpcErrorCodes.configError,`The iframe does not have a content window`);let l=(0,t.createRpcClient)({emittingTransport:i.contentWindow,listeningTransport:window,targetOrigin:a,middleware:[{async onRequest(e,n){if(!await s.isConnected)throw new t.FrakRpcError(t.RpcErrorCodes.clientNotConnected,`The iframe provider isn't connected yet`);return n}},(0,n.createClientCompressionMiddleware)(),{onRequest(e,t){return c.setLastRequest(e),t},onResponse(e,t){return c.setLastResponse(e,t),t}}],lifecycleHandlers:{iframeLifecycle:async(e,t)=>{await s.handleEvent(e)}}}),u=p(l,s),f=async()=>{u(),l.cleanup(),i.remove()},h;console.log(`[Frak SDK] Initializing OpenPanel`),h=new r.OpenPanel({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.1.0`}),!0)}),h.setGlobalProperties({sdkVersion:`0.1.0`}),h.init();let g=m({config:e,rpcClient:l,lifecycleManager:s}).then(()=>c.updateSetupStatus(!0));return{config:e,debugInfo:c,waitForConnection:s.isConnected,waitForSetup:g,request:l.request,listenerRequest:l.listen,destroy:f,openPanel:h}}function p(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 m({config:e,rpcClient:t,lifecycleManager:n}){await n.isConnected,a(t,n.isConnected);async function r(){let n=e.customizations?.css;if(!n)return;let r={clientLifecycle:`modal-css`,data:{cssLink:n}};t.sendLifecycle(r)}async function o(){let n=e.customizations?.i18n;if(!n)return;let r={clientLifecycle:`modal-i18n`,data:{i18n:n}};t.sendLifecycle(r)}async function s(){if(typeof window>`u`)return;let e=window.localStorage.getItem(i);if(!e)return;let n={clientLifecycle:`restore-backup`,data:{backup:e}};t.sendLifecycle(n)}await Promise.allSettled([r(),o(),s()])}function h(n){return(0,t.decompressJson)(e.c(n))}const g={eur:`fr-FR`,usd:`en-US`,gbp:`en-GB`};function _(e){return e&&e in g?e:`eur`}function v(e){return e?g[e]??g.eur:g.eur}function y(e,t){let n=v(t),r=_(t);return e.toLocaleString(n,{style:`currency`,currency:r,minimumFractionDigits:0,maximumFractionDigits:2})}function b(e){return e?`${e}Amount`:`eurAmount`}async function x({config:e}){let t=S(e),n=await c({config:t});if(!n){console.error(`Failed to create iframe`);return}let r=f({config:t,iframe:n});if(await r.waitForSetup,!await r.waitForConnection){console.error(`Failed to connect to client`);return}return r}function S(e){let t=_(e.metadata?.currency);return{...e,metadata:{...e.metadata,currency:t}}}Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return _}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return f}}),Object.defineProperty(exports,`d`,{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,`f`,{enumerable:!0,get:function(){return o}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return v}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return b}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return g}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return y}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return h}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return x}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return c}});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import{c as e}from"./trackEvent-CHnYa85W.js";import{Deferred as t,FrakRpcError as n,RpcErrorCodes as r,createRpcClient as i,decompressJson as a}from"@frak-labs/frame-connector";import{createClientCompressionMiddleware as o}from"@frak-labs/frame-connector/middleware";import{OpenPanel as s}from"@openpanel/web";const c=`nexus-wallet-backup`;function l(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 u=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(),r=this.getNavigatorInfo(),i=`Unknown`;return e instanceof n?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:t?this.base64Encode(t):`not-iframe`,lastRequest:this.lastRequest?this.base64Encode(this.lastRequest):`No Frak request logged`,lastResponse:this.lastResponse?this.base64Encode(this.lastResponse):`No Frak response logged`,clientStatus:this.isSetupDone?`setup`:`not-setup`,error:i}}static empty(){return new e}formatDebugInfo(e){let t=this.gatherDebugInfo(e);return`
|
|
2
|
+
Debug Information:
|
|
3
|
+
-----------------
|
|
4
|
+
Timestamp: ${t.timestamp}
|
|
5
|
+
URL: ${t.encodedUrl}
|
|
6
|
+
Config: ${t.encodedConfig}
|
|
7
|
+
Navigator Info: ${t.navigatorInfo}
|
|
8
|
+
IFrame Status: ${t.iframeStatus}
|
|
9
|
+
Last Request: ${t.lastRequest}
|
|
10
|
+
Last Response: ${t.lastResponse}
|
|
11
|
+
Client Status: ${t.clientStatus}
|
|
12
|
+
Error: ${t.error}
|
|
13
|
+
`.trim()}};const d={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 f({walletBaseUrl:e,config:t}){let n=document.querySelector(`#frak-wallet`);n&&n.remove();let r=document.createElement(`iframe`);return r.id=d.id,r.name=d.name,r.allow=d.allow,r.style.zIndex=d.style.zIndex.toString(),p({iframe:r,isVisible:!1}),document.body.appendChild(r),new Promise(n=>{r?.addEventListener(`load`,()=>n(r)),r.src=`${t?.walletUrl??e??`https://wallet.frak.id`}/listener`})}function p({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 m(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 h({iframe:e}){let n=new t;return{handleEvent:async t=>{if(!(`iframeLifecycle`in t))return;let{iframeLifecycle:r,data:i}=t;switch(r){case`connected`:n.resolve(!0);break;case`do-backup`:i.backup?localStorage.setItem(c,i.backup):localStorage.removeItem(c);break;case`remove-backup`:localStorage.removeItem(c);break;case`show`:case`hide`:p({iframe:e,isVisible:r===`show`});break;case`handshake`:e.contentWindow?.postMessage({clientLifecycle:`handshake-response`,data:{token:i.token,currentUrl:window.location.href}},`*`);break;case`redirect`:{let e=new URL(i.baseRedirectUrl);e.searchParams.has(`u`)?(e.searchParams.delete(`u`),e.searchParams.append(`u`,window.location.href),window.location.href=e.toString()):window.location.href=i.baseRedirectUrl;break}}},isConnected:n.promise}}function g({config:e,iframe:t}){let a=e?.walletUrl??`https://wallet.frak.id`,c=h({iframe:t}),l=new u(e,t);if(!t.contentWindow)throw new n(r.configError,`The iframe does not have a content window`);let d=i({emittingTransport:t.contentWindow,listeningTransport:window,targetOrigin:a,middleware:[{async onRequest(e,t){if(!await c.isConnected)throw new n(r.clientNotConnected,`The iframe provider isn't connected yet`);return t}},o(),{onRequest(e,t){return l.setLastRequest(e),t},onResponse(e,t){return l.setLastResponse(e,t),t}}],lifecycleHandlers:{iframeLifecycle:async(e,t)=>{await c.handleEvent(e)}}}),f=_(d,c),p=async()=>{f(),d.cleanup(),t.remove()},m;console.log(`[Frak SDK] Initializing OpenPanel`),m=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.1.0`}),!0)}),m.setGlobalProperties({sdkVersion:`0.1.0`}),m.init();let g=v({config:e,rpcClient:d,lifecycleManager:c}).then(()=>l.updateSetupStatus(!0));return{config:e,debugInfo:l,waitForConnection:c.isConnected,waitForSetup:g,request:d.request,listenerRequest:d.listen,destroy:p,openPanel:m}}function _(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 v({config:e,rpcClient:t,lifecycleManager:n}){await n.isConnected,l(t,n.isConnected);async function r(){let n=e.customizations?.css;if(!n)return;let r={clientLifecycle:`modal-css`,data:{cssLink:n}};t.sendLifecycle(r)}async function i(){let n=e.customizations?.i18n;if(!n)return;let r={clientLifecycle:`modal-i18n`,data:{i18n:n}};t.sendLifecycle(r)}async function a(){if(typeof window>`u`)return;let e=window.localStorage.getItem(c);if(!e)return;let n={clientLifecycle:`restore-backup`,data:{backup:e}};t.sendLifecycle(n)}await Promise.allSettled([r(),i(),a()])}function y(t){return a(e(t))}const b={eur:`fr-FR`,usd:`en-US`,gbp:`en-GB`};function x(e){return e&&e in b?e:`eur`}function S(e){return e?b[e]??b.eur:b.eur}function C(e,t){let n=S(t),r=x(t);return e.toLocaleString(n,{style:`currency`,currency:r,minimumFractionDigits:0,maximumFractionDigits:2})}function w(e){return e?`${e}Amount`:`eurAmount`}async function T({config:e}){let t=E(e),n=await f({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 E(e){let t=x(e.metadata?.currency);return{...e,metadata:{...e.metadata,currency:t}}}export{x as a,g as c,m as d,u as f,S as i,d as l,w as n,b as o,C as r,y as s,T as t,f as u};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{bytesToHex as e,hexToBytes as t,keccak256 as n,toHex as r}from"viem";import{compressJson as i}from"@frak-labs/frame-connector";function a({domain:e}={}){return n(r((e??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(i(e))}function l(e,t,n,r,i){let a=c(u({redirectUrl:t.redirectUrl,directExit:t.directExit,lang:t.lang,productId:n,metadata:{name:r,css:i,logoUrl:t.metadata?.logoUrl,homepageLink:t.metadata?.homepageLink}})),o=new URL(e);return o.pathname=`/sso`,o.searchParams.set(`p`,a),o.toString()}function u(e){return{r:e.redirectUrl,d:e.directExit,l:e.lang,p:e.productId,m:{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:i}=e.config;if(t.openInSameWindow??!!t.redirectUrl)return await e.request({method:`frak_openSso`,params:[t,n.name,r?.css]});let o=t.ssoPopupUrl??l(i??`https://wallet.frak.id`,t,a(),n.name,r?.css),s=window.open(o,f,d);if(!s)throw Error(`Popup was blocked. Please allow popups for this site.`);return s.focus(),await e.request({method:`frak_openSso`,params:[t,n.name,r?.css]})??{}}const m=`fCtx`;function h(e){if(e?.r)try{return o(t(e.r))}catch(t){console.error(`Error compressing Frak context`,{e:t,context:e})}}function g(t){if(!(!t||t.length===0))try{return{r:e(s(t),{size:20})}}catch(e){console.error(`Error decompressing Frak context`,{e,context:t})}}function _({url:e}){if(!e)return null;let t=new URL(e).searchParams.get(m);return t?g(t):null}function v({url:e,context:t}){if(!e)return null;let n=_({url:e}),r=n?{...n,...t}:t;if(!r.r)return null;let i=h(r);if(!i)return null;let a=new URL(e);return a.searchParams.set(m,i),a.toString()}function y(e){let t=new URL(e);return t.searchParams.delete(m),t.toString()}function b({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?y(n):v({url:n,context:t}),r&&window.history.replaceState(null,``,r.toString())}const x={compress:h,decompress:g,parse:_,update:v,remove:y,replaceUrl:b};function S(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{f as a,s as c,d as i,o as l,x as n,l as o,p as r,c as s,S as t,a as u};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
let e=require(`viem`),t=require(`@frak-labs/frame-connector`);function n({domain:t}={}){return(0,e.keccak256)((0,e.toHex)((t??window.location.host).replace(`www.`,``)))}function r(e){return btoa(Array.from(e,e=>String.fromCharCode(e)).join(``)).replace(/\+/g,`-`).replace(/\//g,`_`).replace(/=+$/,``)}function i(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 a(e){return r((0,t.compressJson)(e))}function o(e,t,n,r,i){let o=a(s({redirectUrl:t.redirectUrl,directExit:t.directExit,lang:t.lang,productId:n,metadata:{name:r,css:i,logoUrl:t.metadata?.logoUrl,homepageLink:t.metadata?.homepageLink}})),c=new URL(e);return c.pathname=`/sso`,c.searchParams.set(`p`,o),c.toString()}function s(e){return{r:e.redirectUrl,d:e.directExit,l:e.lang,p:e.productId,m:{n:e.metadata?.name,css:e.metadata?.css,l:e.metadata?.logoUrl,h:e.metadata?.homepageLink}}}const c=`menubar=no,status=no,scrollbars=no,fullscreen=no,width=500, height=800`,l=`frak-sso`;async function u(e,t){let{metadata:r,customizations:i,walletUrl:a}=e.config;if(t.openInSameWindow??!!t.redirectUrl)return await e.request({method:`frak_openSso`,params:[t,r.name,i?.css]});let s=t.ssoPopupUrl??o(a??`https://wallet.frak.id`,t,n(),r.name,i?.css),u=window.open(s,l,c);if(!u)throw Error(`Popup was blocked. Please allow popups for this site.`);return u.focus(),await e.request({method:`frak_openSso`,params:[t,r.name,i?.css]})??{}}const d=`fCtx`;function f(t){if(t?.r)try{return r((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{return{r:(0,e.bytesToHex)(i(t),{size:20})}}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(d);return t?p(t):null}function h({url:e,context:t}){if(!e)return null;let n=m({url:e}),r=n?{...n,...t}:t;if(!r.r)return null;let i=f(r);if(!i)return null;let a=new URL(e);return a.searchParams.set(d,i),a.toString()}function g(e){let t=new URL(e);return t.searchParams.delete(d),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?g(n):h({url:n,context:t}),r&&window.history.replaceState(null,``,r.toString())}const v={compress:f,decompress:p,parse:m,update:h,remove:g,replaceUrl:_};function y(e,t,n={}){if(!e){console.debug(`[Frak] No client provided, skipping event tracking`);return}try{e.openPanel?.track(t,n)}catch(e){console.debug(`[Frak] Failed to track event:`,t,e)}}Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return l}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return i}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return c}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return r}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return v}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return o}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return a}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return y}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return n}});
|
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"url": "https://twitter.com/QNivelais"
|
|
12
12
|
}
|
|
13
13
|
],
|
|
14
|
-
"version": "0.1.0-beta.
|
|
14
|
+
"version": "0.1.0-beta.b0bd1f8a",
|
|
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",
|
|
@@ -34,7 +34,8 @@
|
|
|
34
34
|
"type": "module",
|
|
35
35
|
"files": [
|
|
36
36
|
"/dist",
|
|
37
|
-
"/cdn"
|
|
37
|
+
"/cdn",
|
|
38
|
+
"/src"
|
|
38
39
|
],
|
|
39
40
|
"browser": "./cdn/bundle.js",
|
|
40
41
|
"exports": {
|
|
@@ -86,33 +87,37 @@
|
|
|
86
87
|
"lint": "biome lint .",
|
|
87
88
|
"format:check": "biome check .",
|
|
88
89
|
"format": "biome check --write .",
|
|
89
|
-
"clean": "rimraf dist",
|
|
90
|
-
"build": "
|
|
91
|
-
"build:watch": "
|
|
90
|
+
"clean": "rimraf dist cdn",
|
|
91
|
+
"build": "tsdown",
|
|
92
|
+
"build:watch": "tsdown --watch",
|
|
92
93
|
"check-exports": "attw --pack --profile node16 .",
|
|
93
94
|
"typecheck": "tsc --noEmit",
|
|
95
|
+
"test": "vitest",
|
|
96
|
+
"test:ui": "vitest --ui",
|
|
97
|
+
"test:coverage": "vitest --coverage",
|
|
94
98
|
"prepublish": "bun run lint && bun run build",
|
|
95
99
|
"publish": "echo 'Publishing core...'"
|
|
96
100
|
},
|
|
97
101
|
"peerDependencies": {
|
|
98
|
-
"viem": "^2.
|
|
102
|
+
"viem": "^2.x"
|
|
99
103
|
},
|
|
100
104
|
"dependencies": {
|
|
101
105
|
"@frak-labs/frame-connector": "0.1.0",
|
|
102
|
-
"@
|
|
103
|
-
"@openpanel/web": "^1.0.1"
|
|
106
|
+
"@openpanel/web": "^1.0.6"
|
|
104
107
|
},
|
|
105
108
|
"devDependencies": {
|
|
106
109
|
"@arethetypeswrong/cli": "^0.18.2",
|
|
107
110
|
"@frak-labs/dev-tooling": "0.0.0",
|
|
108
|
-
"@
|
|
109
|
-
"@
|
|
110
|
-
"@
|
|
111
|
-
"@types/node": "^24.
|
|
112
|
-
"
|
|
113
|
-
"
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
"
|
|
117
|
-
|
|
111
|
+
"@frak-labs/test-foundation": "0.1.0",
|
|
112
|
+
"@rolldown/plugin-node-polyfills": "^1.0.0",
|
|
113
|
+
"@types/jsdom": "^27.0.0",
|
|
114
|
+
"@types/node": "^24.10.4",
|
|
115
|
+
"@vitest/coverage-v8": "^4.0.16",
|
|
116
|
+
"@vitest/ui": "^4.0.16",
|
|
117
|
+
"jsdom": "^27.3.0",
|
|
118
|
+
"tsdown": "^0.18.2",
|
|
119
|
+
"typescript": "^5.9.3",
|
|
120
|
+
"viem": "^2.39.0",
|
|
121
|
+
"vitest": "^4.0.16"
|
|
122
|
+
}
|
|
118
123
|
}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for displayEmbeddedWallet action
|
|
3
|
+
* Tests displaying embedded wallet via RPC
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { Address } from "viem";
|
|
7
|
+
import { describe, expect, it, vi } from "../../tests/vitest-fixtures";
|
|
8
|
+
import type {
|
|
9
|
+
DisplayEmbeddedWalletParamsType,
|
|
10
|
+
DisplayEmbeddedWalletResultType,
|
|
11
|
+
FrakClient,
|
|
12
|
+
} from "../types";
|
|
13
|
+
import { displayEmbeddedWallet } from "./displayEmbeddedWallet";
|
|
14
|
+
|
|
15
|
+
describe("displayEmbeddedWallet", () => {
|
|
16
|
+
describe("success cases", () => {
|
|
17
|
+
it("should call client.request with correct method and params", async () => {
|
|
18
|
+
const mockParams: DisplayEmbeddedWalletParamsType = {
|
|
19
|
+
loggedIn: {
|
|
20
|
+
action: {
|
|
21
|
+
key: "sharing",
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const mockResponse: DisplayEmbeddedWalletResultType = {
|
|
27
|
+
wallet: "0x1234567890123456789012345678901234567890" as Address,
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const mockClient = {
|
|
31
|
+
config: {
|
|
32
|
+
metadata: {
|
|
33
|
+
name: "Test App",
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
request: vi.fn().mockResolvedValue(mockResponse),
|
|
37
|
+
} as unknown as FrakClient;
|
|
38
|
+
|
|
39
|
+
await displayEmbeddedWallet(mockClient, mockParams);
|
|
40
|
+
|
|
41
|
+
expect(mockClient.request).toHaveBeenCalledWith({
|
|
42
|
+
method: "frak_displayEmbeddedWallet",
|
|
43
|
+
params: [mockParams, { name: "Test App" }],
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it("should return wallet address", async () => {
|
|
48
|
+
const mockParams: DisplayEmbeddedWalletParamsType = {
|
|
49
|
+
loggedIn: {
|
|
50
|
+
action: {
|
|
51
|
+
key: "sharing",
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const mockResponse: DisplayEmbeddedWalletResultType = {
|
|
57
|
+
wallet: "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd" as Address,
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const mockClient = {
|
|
61
|
+
config: {
|
|
62
|
+
metadata: {
|
|
63
|
+
name: "Test App",
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
request: vi.fn().mockResolvedValue(mockResponse),
|
|
67
|
+
} as unknown as FrakClient;
|
|
68
|
+
|
|
69
|
+
const result = await displayEmbeddedWallet(mockClient, mockParams);
|
|
70
|
+
|
|
71
|
+
expect(result).toEqual(mockResponse);
|
|
72
|
+
expect(result.wallet).toBe(
|
|
73
|
+
"0xabcdefabcdefabcdefabcdefabcdefabcdefabcd"
|
|
74
|
+
);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it("should handle loggedOut view params", async () => {
|
|
78
|
+
const mockParams: DisplayEmbeddedWalletParamsType = {
|
|
79
|
+
loggedOut: {
|
|
80
|
+
metadata: {
|
|
81
|
+
text: "Login to get rewards",
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const mockResponse: DisplayEmbeddedWalletResultType = {
|
|
87
|
+
wallet: "0x1234567890123456789012345678901234567890" as Address,
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const mockClient = {
|
|
91
|
+
config: {
|
|
92
|
+
metadata: {
|
|
93
|
+
name: "Test App",
|
|
94
|
+
logoUrl: "https://example.com/logo.png",
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
request: vi.fn().mockResolvedValue(mockResponse),
|
|
98
|
+
} as unknown as FrakClient;
|
|
99
|
+
|
|
100
|
+
await displayEmbeddedWallet(mockClient, mockParams);
|
|
101
|
+
|
|
102
|
+
expect(mockClient.request).toHaveBeenCalledWith({
|
|
103
|
+
method: "frak_displayEmbeddedWallet",
|
|
104
|
+
params: [
|
|
105
|
+
mockParams,
|
|
106
|
+
{
|
|
107
|
+
name: "Test App",
|
|
108
|
+
logoUrl: "https://example.com/logo.png",
|
|
109
|
+
},
|
|
110
|
+
],
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it("should handle referred action", async () => {
|
|
115
|
+
const mockParams: DisplayEmbeddedWalletParamsType = {
|
|
116
|
+
loggedIn: {
|
|
117
|
+
action: {
|
|
118
|
+
key: "referred",
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
const mockResponse: DisplayEmbeddedWalletResultType = {
|
|
124
|
+
wallet: "0x1234567890123456789012345678901234567890" as Address,
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
const mockClient = {
|
|
128
|
+
config: {
|
|
129
|
+
metadata: {
|
|
130
|
+
name: "Test App",
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
request: vi.fn().mockResolvedValue(mockResponse),
|
|
134
|
+
} as unknown as FrakClient;
|
|
135
|
+
|
|
136
|
+
const result = await displayEmbeddedWallet(mockClient, mockParams);
|
|
137
|
+
|
|
138
|
+
expect(result).toEqual(mockResponse);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it("should pass client metadata to request", async () => {
|
|
142
|
+
const mockParams: DisplayEmbeddedWalletParamsType = {};
|
|
143
|
+
|
|
144
|
+
const mockMetadata = {
|
|
145
|
+
name: "My App",
|
|
146
|
+
logoUrl: "https://example.com/logo.png",
|
|
147
|
+
css: "body { color: red; }",
|
|
148
|
+
lang: "fr" as const,
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
const mockClient = {
|
|
152
|
+
config: {
|
|
153
|
+
metadata: mockMetadata,
|
|
154
|
+
},
|
|
155
|
+
request: vi.fn().mockResolvedValue({
|
|
156
|
+
wallet: "0x1234567890123456789012345678901234567890" as Address,
|
|
157
|
+
}),
|
|
158
|
+
} as unknown as FrakClient;
|
|
159
|
+
|
|
160
|
+
await displayEmbeddedWallet(mockClient, mockParams);
|
|
161
|
+
|
|
162
|
+
expect(mockClient.request).toHaveBeenCalledWith({
|
|
163
|
+
method: "frak_displayEmbeddedWallet",
|
|
164
|
+
params: [mockParams, mockMetadata],
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
describe("error handling", () => {
|
|
170
|
+
it("should propagate errors from client.request", async () => {
|
|
171
|
+
const mockParams: DisplayEmbeddedWalletParamsType = {
|
|
172
|
+
loggedIn: {
|
|
173
|
+
action: {
|
|
174
|
+
key: "sharing",
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
const error = new Error("Display failed");
|
|
180
|
+
const mockClient = {
|
|
181
|
+
config: {
|
|
182
|
+
metadata: {
|
|
183
|
+
name: "Test App",
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
request: vi.fn().mockRejectedValue(error),
|
|
187
|
+
} as unknown as FrakClient;
|
|
188
|
+
|
|
189
|
+
await expect(
|
|
190
|
+
displayEmbeddedWallet(mockClient, mockParams)
|
|
191
|
+
).rejects.toThrow("Display failed");
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
DisplayEmbeddedWalletParamsType,
|
|
3
|
+
DisplayEmbeddedWalletResultType,
|
|
4
|
+
FrakClient,
|
|
5
|
+
} from "../types";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Function used to display the Frak embedded wallet popup
|
|
9
|
+
* @param client - The current Frak Client
|
|
10
|
+
* @param params - The parameter used to customise the embedded wallet
|
|
11
|
+
*/
|
|
12
|
+
export async function displayEmbeddedWallet(
|
|
13
|
+
client: FrakClient,
|
|
14
|
+
params: DisplayEmbeddedWalletParamsType
|
|
15
|
+
): Promise<DisplayEmbeddedWalletResultType> {
|
|
16
|
+
return await client.request({
|
|
17
|
+
method: "frak_displayEmbeddedWallet",
|
|
18
|
+
params: [params, client.config.metadata],
|
|
19
|
+
});
|
|
20
|
+
}
|