feat: initial support for stacks connect#585
Conversation
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
| @@ -1,2 +1,2 @@ | |||
| (()=>{"use strict";class e{_chainId="0x1";_eventSubscriptions={};_requestId=0;async backgroundRPC(e){const n=this._requestId++;return new Promise(((t,i)=>{let o=!1;document.addEventListener("LayerzWalletExtension",(function(e){if(o)return;const c=JSON.parse(e.detail);if("webpage"===c.for&&Number(c.id)===n){if(o=!0,c.error)return console.log("rejecting promise.................. error=",c.error),void i(c.error);console.log("resolving promise.................. response=",c.response),t(c.response)}}));const c={...e,for:"contentScript",id:n,from:window.location.hostname};document.dispatchEvent(new CustomEvent("LayerzWalletExtension",{detail:JSON.stringify(c)}))}))}request=e=>this.backgroundRPC(e);constructor(){const e=this;console.log("setting up a listener for callback events::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::"),document.addEventListener("LayerzWalletExtension",(function(n){const t=JSON.parse(n.detail);if("eventCallback"!==t.type)return;console.log("got event callback!",t);const i=e._eventSubscriptions[t.event]??[];console.log("we have",i.length,"to notify");for(const e of i)console.log("actually triggering the callback with the event payload"),e(t.arg)}))}on(e,n){return console.log("Dapp subscribes to an event",e),"connect"===e?(setTimeout((()=>n({chainId:this._chainId})),1e3),this):(this._eventSubscriptions[e]=this._eventSubscriptions[e]||[],this._eventSubscriptions[e].push(n),this)}removeListener(){}send(e,n){return e.method?this.request(e):"string"==typeof e?this.request({method:e,params:n}):void 0}sendAsync(e,n){}_metamask={isUnlocked:function(){return Promise.resolve(!0)}};get chainId(){return this._chainId}isMetaMask=!0;networkVersion="?";selectedAddress="???";enable(){return alert("enable"),Promise.resolve([])}isConnected(){return!0}_events={};_eventsCount=0;_maxListeners=0;_log={};_state={};_handleAccountsChanged=()=>{};_handleConnect=()=>{};_handleChainChanged=()=>{};_handleDisconnect=()=>{};_handleUnlockStateChanged=()=>{};_rpcRequest=()=>{};_rpcEngine={};_handleStreamDisconnect=()=>{};_jsonRpcConnection={};_sentWarnings={};_sendSync=()=>{};_warnOfDeprecation=()=>{}}window.ethereum=new e;const n="6c617965-727a-7761-6C6C-657400000000";document.addEventListener("LayerzWalletExtension",(async function(e){"contentScript"===JSON.parse(e.detail).for&&window.ReactNativeWebView.postMessage(e.detail)})),window.addEventListener("load",(function(){const t=new e;function i(){console.log("announceProvider()");const e={uuid:n,name:"Layerz Wallet",icon:"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTg2IiBoZWlnaHQ9IjE2NiIgdmlld0JveD0iMCAwIDE4NiAxNjYiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxODYiIGhlaWdodD0iMTY2IiBmaWxsPSIjMDAwMDAwIi8+CjxwYXRoIGQ9Ik05Ni42NTU0IDEwMC42NDJIMjMuNTIyM0MxNy4zODg4IDEwMC42NDIgMTQuMjg5MSA5My4yNTkgMTguNTcyMyA4OC44ODJMNjMuMjA3MyA0My4yNTEyQzY3LjU2NTYgMzguNzk5IDczLjUzMDEgMzYuMjkxIDc5Ljc1NzYgMzYuMjkxSDE1Mi44OTFDMTU5LjAyNCAzNi4yOTEgMTYyLjEyNCA0My42NzM5IDE1Ny44NDEgNDguMDUwOUwxMTMuMjA2IDkzLjY4MTdDMTA4Ljg0NyA5OC4xMzM5IDEwMi44ODMgMTAwLjY0MiA5Ni42NTU0IDEwMC42NDJaIiBmaWxsPSJ1cmwoI3BhaW50MF9saW5lYXJfMl8zMzMyKSIvPgo8cGF0aCBkPSJNODkuNDY5NSA2NS4zNTc3SDE2Mi42MDNDMTY4LjczNiA2NS4zNTc3IDE3MS44MzYgNzIuNzQwNSAxNjcuNTUzIDc3LjExNzZMMTIyLjkxOCAxMjIuNzQ4QzExOC41NTkgMTI3LjIgMTEyLjU5NSAxMjkuNzA4IDEwNi4zNjcgMTI5LjcwOEgzMy4yMzQzQzI3LjEwMDcgMTI5LjcwOCAyNC4wMDEgMTIyLjMyNiAyOC4yODQyIDExNy45NDhMNzIuOTE5MiA3Mi4zMTc4Qzc3LjI3NzUgNjcuODY1NiA4My4yNDIgNjUuMzU3NyA4OS40Njk1IDY1LjM1NzdaIiBmaWxsPSJ1cmwoI3BhaW50MV9saW5lYXJfMl8zMzMyKSIvPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzJfMzMzMiIgeDE9IjE2LjY2MzgiIHkxPSIxMDAiIHgyPSIxNjAuMjA1IiB5Mj0iNDAuOTYzMiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSJ3aGl0ZSIgc3RvcC1vcGFjaXR5PSIwIi8+CjxzdG9wIG9mZnNldD0iMC44NSIgc3RvcC1jb2xvcj0id2hpdGUiLz4KPC9saW5lYXJHcmFkaWVudD4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDFfbGluZWFyXzJfMzMzMiIgeDE9IjE2OS45MDciIHkxPSI2NS44MzEiIHgyPSIyNi4zNjY0IiB5Mj0iMTI0Ljg2OCIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSJ3aGl0ZSIgc3RvcC1vcGFjaXR5PSIwIi8+CjxzdG9wIG9mZnNldD0iMC44NSIgc3RvcC1jb2xvcj0id2hpdGUiLz4KPC9saW5lYXJHcmFkaWVudD4KPC9kZWZzPgo8L3N2Zz4K",rdns:"com.layerzwallet.layerzwallet"},i=Object.freeze({info:e,provider:t});window.dispatchEvent(new CustomEvent("eip6963:announceProvider",{detail:i}))}t.signer={uri:n},window.addEventListener("eip6963:requestProvider",(e=>{console.log("Received EIP-6963 provider request"),i()})),i(),console.log("announceProvider() done")}))})(); | |||
| (()=>{"use strict";class e{_chainId="0x1";_eventSubscriptions={};_requestId=0;async backgroundRPC(e){const i=this._requestId++;return new Promise((t,n)=>{let o=!1;document.addEventListener("LayerzWalletExtension",function(e){if(o)return;const c=JSON.parse(e.detail);if("webpage"===c.for&&Number(c.id)===i){if(o=!0,c.error)return console.log("rejecting promise.................. error=",c.error),void n(c.error);console.log("resolving promise.................. response=",c.response),t(c.response)}});const c={...e,for:"contentScript",id:i,from:window.location.hostname};document.dispatchEvent(new CustomEvent("LayerzWalletExtension",{detail:JSON.stringify(c)}))})}request=e=>this.backgroundRPC(e);constructor(){const e=this;console.log("setting up a listener for callback events::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::"),document.addEventListener("LayerzWalletExtension",function(i){const t=JSON.parse(i.detail);if("eventCallback"!==t.type)return;console.log("got event callback!",t);const n=e._eventSubscriptions[t.event]??[];console.log("we have",n.length,"to notify");for(const e of n)console.log("actually triggering the callback with the event payload"),e(t.arg)})}on(e,i){return console.log("Dapp subscribes to an event",e),"connect"===e?(setTimeout(()=>i({chainId:this._chainId}),1e3),this):(this._eventSubscriptions[e]=this._eventSubscriptions[e]||[],this._eventSubscriptions[e].push(i),this)}removeListener(){}send(e,i){return e.method?this.request(e):"string"==typeof e?this.request({method:e,params:i}):void 0}sendAsync(e,i){}_metamask={isUnlocked:function(){return Promise.resolve(!0)}};get chainId(){return this._chainId}isMetaMask=!0;networkVersion="?";selectedAddress="???";enable(){return alert("enable"),Promise.resolve([])}isConnected(){return!0}_events={};_eventsCount=0;_maxListeners=0;_log={};_state={};_handleAccountsChanged=()=>{};_handleConnect=()=>{};_handleChainChanged=()=>{};_handleDisconnect=()=>{};_handleUnlockStateChanged=()=>{};_rpcRequest=()=>{};_rpcEngine={};_handleStreamDisconnect=()=>{};_jsonRpcConnection={};_sentWarnings={};_sendSync=()=>{};_warnOfDeprecation=()=>{}}window.ethereum=new e,window.LayerzWalletProvider={async request(e,i){alert("request() method="+e+" params="+JSON.stringify(i));try{const t=await window.ethereum.request({method:e,params:i});return alert("replying with result="+JSON.stringify(t)),{jsonrpc:"2.0",result:t}}catch(e){return{jsonrpc:"2.0",error:e}}}},window.wbip_providers=window.wbip_providers||[],window.btc_providers=window.btc_providers||[];const i={id:"LayerzWalletProvider",name:"Layerz Wallet",icon:"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTg2IiBoZWlnaHQ9IjE2NiIgdmlld0JveD0iMCAwIDE4NiAxNjYiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxODYiIGhlaWdodD0iMTY2IiBmaWxsPSIjMDAwMDAwIi8+CjxwYXRoIGQ9Ik05Ni42NTU0IDEwMC42NDJIMjMuNTIyM0MxNy4zODg4IDEwMC42NDIgMTQuMjg5MSA5My4yNTkgMTguNTcyMyA4OC44ODJMNjMuMjA3MyA0My4yNTEyQzY3LjU2NTYgMzguNzk5IDczLjUzMDEgMzYuMjkxIDc5Ljc1NzYgMzYuMjkxSDE1Mi44OTFDMTU5LjAyNCAzNi4yOTEgMTYyLjEyNCA0My42NzM5IDE1Ny44NDEgNDguMDUwOUwxMTMuMjA2IDkzLjY4MTdDMTA4Ljg0NyA5OC4xMzM5IDEwMi44ODMgMTAwLjY0MiA5Ni42NTU0IDEwMC42NDJaIiBmaWxsPSJ1cmwoI3BhaW50MF9saW5lYXJfMl8zMzMyKSIvPgo8cGF0aCBkPSJNODkuNDY5NSA2NS4zNTc3SDE2Mi42MDNDMTY4LjczNiA2NS4zNTc3IDE3MS44MzYgNzIuNzQwNSAxNjcuNTUzIDc3LjExNzZMMTIyLjkxOCAxMjIuNzQ4QzExOC41NTkgMTI3LjIgMTEyLjU5NSAxMjkuNzA4IDEwNi4zNjcgMTI5LjcwOEgzMy4yMzQzQzI3LjEwMDcgMTI5LjcwOCAyNC4wMDEgMTIyLjMyNiAyOC4yODQyIDExNy45NDhMNzIuOTE5MiA3Mi4zMTc4Qzc3LjI3NzUgNjcuODY1NiA4My4yNDIgNjUuMzU3NyA4OS40Njk1IDY1LjM1NzdaIiBmaWxsPSJ1cmwoI3BhaW50MV9saW5lYXJfMl8zMzMyKSIvPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzJfMzMzMiIgeDE9IjE2LjY2MzgiIHkxPSIxMDAiIHgyPSIxNjAuMjA1IiB5Mj0iNDAuOTYzMiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSJ3aGl0ZSIgc3RvcC1vcGFjaXR5PSIwIi8+CjxzdG9wIG9mZnNldD0iMC44NSIgc3RvcC1jb2xvcj0id2hpdGUiLz4KPC9saW5lYXJHcmFkaWVudD4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDFfbGluZWFyXzJfMzMzMiIgeDE9IjE2OS45MDciIHkxPSI2NS44MzEiIHgyPSIyNi4zNjY0IiB5Mj0iMTI0Ljg2OCIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSJ3aGl0ZSIgc3RvcC1vcGFjaXR5PSIwIi8+CjxzdG9wIG9mZnNldD0iMC44NSIgc3RvcC1jb2xvcj0id2hpdGUiLz4KPC9saW5lYXJHcmFkaWVudD4KPC9kZWZzPgo8L3N2Zz4K",webUrl:"https://layerzwallet.com",chromeWebStoreUrl:"https://play.google.com/store/apps/details?id=com.layerzwallet.mobile&pli=1",mozillaAddOnsUrl:"https://play.google.com/store/apps/details?id=com.layerzwallet.mobile&pli=1",googlePlayStoreUrl:"https://play.google.com/store/apps/details?id=com.layerzwallet.mobile&pli=1",iOSAppStoreUrl:"https://apps.apple.com/us/app/layerz-wallet/id6745974808"};window.wbip_providers.push(i),window.btc_providers.push(i);const t="6c617965-727a-7761-6C6C-657400000000";document.addEventListener("LayerzWalletExtension",async function(e){"contentScript"===JSON.parse(e.detail).for&&window.ReactNativeWebView.postMessage(e.detail)}),window.addEventListener("load",function(){const i=new e;function n(){console.log("announceProvider()");const e={uuid:t,name:"LZ WalletTTTTTTTTTTTTTTTTtttttttttttttttt",icon:"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTg2IiBoZWlnaHQ9IjE2NiIgdmlld0JveD0iMCAwIDE4NiAxNjYiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxODYiIGhlaWdodD0iMTY2IiBmaWxsPSIjMDAwMDAwIi8+CjxwYXRoIGQ9Ik05Ni42NTU0IDEwMC42NDJIMjMuNTIyM0MxNy4zODg4IDEwMC42NDIgMTQuMjg5MSA5My4yNTkgMTguNTcyMyA4OC44ODJMNjMuMjA3MyA0My4yNTEyQzY3LjU2NTYgMzguNzk5IDczLjUzMDEgMzYuMjkxIDc5Ljc1NzYgMzYuMjkxSDE1Mi44OTFDMTU5LjAyNCAzNi4yOTEgMTYyLjEyNCA0My42NzM5IDE1Ny44NDEgNDguMDUwOUwxMTMuMjA2IDkzLjY4MTdDMTA4Ljg0NyA5OC4xMzM5IDEwMi44ODMgMTAwLjY0MiA5Ni42NTU0IDEwMC42NDJaIiBmaWxsPSJ1cmwoI3BhaW50MF9saW5lYXJfMl8zMzMyKSIvPgo8cGF0aCBkPSJNODkuNDY5NSA2NS4zNTc3SDE2Mi42MDNDMTY4LjczNiA2NS4zNTc3IDE3MS44MzYgNzIuNzQwNSAxNjcuNTUzIDc3LjExNzZMMTIyLjkxOCAxMjIuNzQ4QzExOC41NTkgMTI3LjIgMTEyLjU5NSAxMjkuNzA4IDEwNi4zNjcgMTI5LjcwOEgzMy4yMzQzQzI3LjEwMDcgMTI5LjcwOCAyNC4wMDEgMTIyLjMyNiAyOC4yODQyIDExNy45NDhMNzIuOTE5MiA3Mi4zMTc4Qzc3LjI3NzUgNjcuODY1NiA4My4yNDIgNjUuMzU3NyA4OS40Njk1IDY1LjM1NzdaIiBmaWxsPSJ1cmwoI3BhaW50MV9saW5lYXJfMl8zMzMyKSIvPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzJfMzMzMiIgeDE9IjE2LjY2MzgiIHkxPSIxMDAiIHgyPSIxNjAuMjA1IiB5Mj0iNDAuOTYzMiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSJ3aGl0ZSIgc3RvcC1vcGFjaXR5PSIwIi8+CjxzdG9wIG9mZnNldD0iMC44NSIgc3RvcC1jb2xvcj0id2hpdGUiLz4KPC9saW5lYXJHcmFkaWVudD4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDFfbGluZWFyXzJfMzMzMiIgeDE9IjE2OS45MDciIHkxPSI2NS44MzEiIHgyPSIyNi4zNjY0IiB5Mj0iMTI0Ljg2OCIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSJ3aGl0ZSIgc3RvcC1vcGFjaXR5PSIwIi8+CjxzdG9wIG9mZnNldD0iMC44NSIgc3RvcC1jb2xvcj0id2hpdGUiLz4KPC9saW5lYXJHcmFkaWVudD4KPC9kZWZzPgo8L3N2Zz4K",rdns:"com.layerzwallet.layerzwallet"},n=Object.freeze({info:e,provider:i});window.dispatchEvent(new CustomEvent("eip6963:announceProvider",{detail:n}))}i.signer={uri:t},window.addEventListener("eip6963:requestProvider",e=>{console.log("Received EIP-6963 provider request"),n()}),n(),console.log("announceProvider() done")})})(); | |||
There was a problem hiding this comment.
Test wallet name in EIP-6963 provider announcement
High Severity
The EIP-6963 provider info contains a test/debug wallet name "LZ WalletTTTTTTTTTTTTTTTTtttttttttttttttt" instead of "Layerz Wallet". This garbled name will be displayed to users in wallet selection interfaces across all dApps, making the wallet look unprofessional or broken.
|
|
||
| try { | ||
| const result = await window.ethereum.request({ method: method, params }); | ||
| alert('replying with result=' + JSON.stringify(result)); |
There was a problem hiding this comment.
Debug alert() dialogs will interrupt users
High Severity
The window.LayerzWalletProvider.request() function contains alert() calls that will display modal dialogs to users every time a Stacks dApp makes a request. These debugging statements will severely disrupt user experience by requiring manual dismissal of alert boxes during normal wallet operations.
Note
Initial integration of Stacks Connect and provider injection.
LayerzWalletProviderexposingrequest()that proxies towindow.ethereum.requestwindow.wbip_providersandwindow.btc_providers@stacks/connectand related AppKit/WalletConnect dependencies (lockfile updates)create-hashto1.2.0Written by Cursor Bugbot for commit 5b029f1. This will update automatically on new commits. Configure here.