WalletConnect / walletconnect-monorepo

WalletConnect Monorepo
Apache License 2.0
1.3k stars 650 forks source link

Websocket connection failed #548

Closed mitGen closed 1 year ago

mitGen commented 3 years ago

Socket connection drops intermittently image How to solve so that this problem does not recur ?? Can you have paid servers with a bridge ??? Or how else to get around this problem????

tonoyandev commented 3 years ago

Have the same issue, any solutions?

DimitarTAtanasov commented 3 years ago

I faced the same issue, it seems caused by one of the last versions, managed to workaround it by downgrading @walletconnect/web3-provider to "1.4.1".

ochikov commented 3 years ago

The same issue here.

undfined commented 3 years ago

Also facing the same issue, we are using "bnc-onboard": "^1.28.0" which currently depends on "@walletconnect/web3-provider": "^1.5.0"

rafinskipg commented 3 years ago

Having this problem consistently. version 1.4.1

foxgem commented 3 years ago

When I changed the provider to 1.5.x, the problem is gone. It is caused by the overload bridge server, the new version will select a server randomly.

My env: web3modal + walletconnect provider 1.5.1.

dmatora commented 2 years ago

same issue with @walletconnect/client 2.0.0 Can't see any mention of walletconnect provider 1.5.x/1.4.x in the code

anoushk1234 commented 2 years ago

Same issue here, running 1.71

devshaaran commented 2 years ago

Same issue here +1

datgrog commented 2 years ago

same +1

javonmcgilberry commented 2 years ago

+1 guys... trying to figure out what's going on...1.7.1

dfordivam commented 2 years ago

I have also been observing this issue a lot.

 WebSocket connection to 'wss://relay.walletconnect.org/?env=browser&host=localhost%3A8001&projectId=...&protocol=wc&version=2' failed: Error during WebSocket handshake: Unexpected response code: 502
 Uncaught TypeError: Cannot read property 'message' of undefined

I think at the very least errors like this should be handled properly. They should not cause the whole client to become unresponsive.

It would be ideal if the client has the functionality to auto-reconnect after some timeout. OR perhaps allow the wallet/dapp to handle the errors (if there is some way to do it)

spencercap commented 2 years ago

+1

the wallet connect clients libs for v1.0 + v2.0 should automatically reconnect to the websocket after the app is backgrounded (to go to Pera to approve the connection).

disabling NSURLSession WebSocket as indicated here solves the issue but that's obviously not ideal...

spencercap commented 2 years ago

while i do still get the error at the top of this issue...

i've had luck completing the walletconnect handshake anyway by keeping some background task running in the webview browser thread like an interval or request animation frame while the webview or browser is backgrounded (to approve + link in Pera Wallet) like:

setInterval(() => {
    // keeps websocket open while app / webpage is backgrounded
    console.log('keep alive');
}, 2000);

or

function repeatOften() {
    requestAnimationFrame(repeatOften);
}
requestAnimationFrame(repeatOften);
rafaelaugustos commented 2 years ago

enquanto eu ainda recebo o erro no topo deste problema ...

Eu tive sorte ao completar o handshake walletconnect de qualquer maneira, mantendo alguma tarefa em segundo plano em execução no thread do navegador webview como um intervalo ou quadro de animação de solicitação enquanto a webview ou o navegador está em segundo plano (para aprovar + link na Pera Wallet) como:

setInterval ( ) =  >  { 
  // mantém o websocket aberto enquanto o aplicativo/página da web está em segundo plano 
  console .log ( ' keep alive' ) ; } , 2000 ) ;

ou

function  repeatOften ( )  { 
  requestAnimationFrame ( repeatOften ) ; 
} 
requestAnimationFrame ( repetirOften ) ;

Can you explain? i tried and didn't work

rafaelaugustos commented 2 years ago

same +1

spencercap commented 2 years ago

@rafaelaugustos 👋 i help maintain a js client library for the Algorand blockchain called algonaut.js which uses walletconnect under the hood to connect to algorand's official mobile wallet Pera (which supports wallet connect v1.0 QR codes) so i had to get to the bottom of this websocket issue too.

i found that when you leave / background the dapp, the webview / browser garbage collects / pauses the websocket connection so the handshake cannot be completed. by keeping some process active in the js thread like a setInterval or even a requestAnimationFrame (probably better for the CPU), the websocket stays active so the native wallet can send messages back to the dapp in the background.

we integrated this fix into our library here: https://github.com/thencc/algonautjs/blob/785742e7a951f0ae1ac897c88b023f25b810f297/src/index.ts#L1745-L1749

for efficiency, if you start the keep alive process on wallet connect session start and stop it on connect you should be golden. cheers, hope it's helpful 👍

dfordivam commented 2 years ago

Regarding Uncaught TypeError: Cannot read property 'message' of undefined, I have fixed this in the index.min.js by doing the following modification. After this fix the websocket automatically reconnects after the error, and the app works.

-        function d(e, t, n) {
-            return e.message.includes("getaddrinfo ENOTFOUND") || e.message.includes("connect ECONNREFUSED") ? new Error(`Unavailable ${n} RPC url at ${t}`) : e
+        function d(e, t, n) {
+            return (e != undefined && e.message != undefined) ? (e.message.includes("getaddrinfo ENOTFOUND") || e.message.includes("connect ECONNREFUSED") ? new Error(`Unavailable ${n} RPC url at ${t}`) : e) : e
rafaelaugustos commented 2 years ago

@rafaelaugustos 👋 eu ajudo a manter uma biblioteca cliente js para a blockchain Algorand chamada algonaut.jsque usa walletconnect sob o capô para se conectar à carteira móvel oficial da algorand Pera (que suporta códigos QR wallet connect v1.0), então eu tive que chegar ao fundo deste problema de websocket também .

eu descobri que quando você deixa / em segundo plano o dapp, o webview / lixo do navegador coleta / pausa a conexão do websocket para que o handshake não possa ser concluído. mantendo algum processo ativo no thread js como a setIntervalou mesmo a requestAnimationFrame(provavelmente melhor para a CPU), o websocket permanece ativo para que a carteira nativa possa enviar mensagens de volta para o dapp em segundo plano.

integramos essa correção em nossa biblioteca aqui: https://github.com/thencc/algonautjs/blob/785742e7a951f0ae1ac897c88b023f25b810f297/src/index.ts#L1745-L1749

para eficiência, se você iniciar o processo de manutenção ativa no início da sessão de conexão da carteira e interrompê-lo na conexão, você deve estar dourado. abraços, espero ter ajudado👍

It worked with Wallet Connect v1? i add in my code but didn't worked. I'm working with Capacitor.

class WalletConnectService {
  connector: typeof WalletConnect

  async connect (): Promise<string> {
    if (!this.connector) {
      if (!import.meta.env.SSR) {
        await importWalletconnect()
      }

      const settings = {
        bridge: 'https://bridge.walletconnect.org',
        qrcodeModal: QRCodeModal
      }
      this.connector = new WalletConnect(settings)
    }
    if (!this.connector?.connected) {
      await this.connector.createSession()
      this.startReqAF()
    }

    return await new Promise<string>((resolve, reject) => {
      this.connector.on('connect', (error: any) => {
        if (error) {
          console.log(error, 'error')
          reject(error)
        }
        const address = this.connector?.accounts[0].toLowerCase()
        const checksumAddress = ethers.utils.getAddress(address)
        this.stopReqAF()
        resolve(checksumAddress)
      })
    })
  }

  startReqAF () {
    if (isBrowser() && isMobile()) {
      const keepAlive = () => {
        console.log('aquiiiiiii')
        wcReqAF = requestAnimationFrame(keepAlive)
      }

      requestAnimationFrame(keepAlive)
    }
  }

  stopReqAF () {
    console.log('stopReqAF')
    // CANCEL wcReqAF to free up CPU
    if (wcReqAF) {
      cancelAnimationFrame(wcReqAF)
      wcReqAF = 0 // reset
    } else {
      console.log('no wcReqAF to cancel') // is this the browser?
    }
  }
antinomy-studio commented 2 years ago

Having the same issue on a Capacitor app. When the app goes in background while opening MetaMask, we get the error going back to the app and therefore no response from Wallet Connect. Did you managed to find a fix @rafaelaugustos ?

Using setInterval didn't change anything unfortunately, and since requestAnimationFrame doesn't run when the web view isn't focused, this didn't fix it either. Not sure how you managed to have requestAnimationFrame work in the background @spencercap ?

antinomy-studio commented 2 years ago

@rafaelaugustos We managed to get this working on Capacitor. What we did is use this Plugin to allow background tasks. https://www.npmjs.com/package/@robingenz/capacitor-background-task

A snippet of our code...

App.addListener('appStateChange', async ({ isActive }) {
  if (isActive || !this.initialConnecting) {
    return;
  }
  // The app state has been changed to inactive.
  // Start the background task by calling `beforeExit`.
  const taskId = await BackgroundTask.beforeExit(async () => {
    // Run your code...
    // Finish the background task as soon as everything is done.
    await this.modal.connect()
    this.onProviderConnected()

    BackgroundTask.finish({ taskId })
  })
})

this.provider = await this.modal.connect()
this.onProviderConnected()

Which basically "force" a re-connect to the Web Sockets inside of the background task. This is definitely hacky, but until a real solution we're gonna use this.

0xTogepi commented 1 year ago

Hey there, not sure if this helps, but somehow my issue was I didn't add in the projectId. Since there's no documentation ATM, so i hope this helps:

import WalletConnectProvider from "@walletconnect/ethereum-provider";

let _provider = new WalletConnectProvider({
    chainId: 1,
    client:{
      projectId:"<your_project_id>"
    }
});
finessevanes commented 1 year ago

@mitGen is this still an issue?