walletconnect-monorepo icon indicating copy to clipboard operation
walletconnect-monorepo copied to clipboard

this.events.off is not a function error if Node polyfill

Open peterpeterparker opened this issue 1 year ago • 20 comments

Issue

@walletconnect/web3wallet throws an error this.events.off is not a function when pairing a session when Node libraries are polyfilled for local development in vite based project.

This issue started to occur in recent releases, and my current workaround is to stick to version v1.9.1.

Notes

This is a follow-up to issue #3913, which you closed, requesting a minimal sample repo to replicate this issue. I am providing it here.

Versions

  • Client: SvelteKit and Vite
  • Version v1.9.5

Reproduction

Steps to reproduce the behavior:

  1. git clone https://github.com/peterpeterparker/web3wallet-issue-3913
  2. cd web3wallet-issue-3913
  3. npm ci
  4. npm run dev

Try to establish a connection for example with https://app.uniswap.org/swap?chain=goerli

Expected behavior

Being able to pair a session without errors.

Screenshots

error

peterpeterparker avatar Dec 20 '23 09:12 peterpeterparker

I am getting the same issue in my react native wallet app, have you found any solution for this? #3913

iPriyaranjan avatar Jan 03 '24 07:01 iPriyaranjan

hey @peterpeterparker any good news on this? I'm facing the same problem 😢

adrianotadao avatar Jan 05 '24 11:01 adrianotadao

Not really, @adrianotadao. I opened the issue, documented it, and provided a sample repo, but I did not debug the WalletConnect code.

That said, in our app, after bumping a few dependencies, I actually noticed that we weren't requiring the usage of the polyfier plugin (@esbuild-plugins/node-modules-polyfill) that leads to the issue. So, I removed the plugin from our vite config, and, by extension, it resolved the issue I was facing.

peterpeterparker avatar Jan 05 '24 11:01 peterpeterparker

Issue closed without without any comments or references? Was it solved or it won't be solved? Any PR, references or commit to share?

peterpeterparker avatar Jan 10 '24 13:01 peterpeterparker

Just to share how we solved it here with esbuild.

import { polyfillNode } from "esbuild-plugin-polyfill-node";

const esbuildOptions = {
  ...otherOptions,
  plugins: [
    polyfillNode({
      globals: {
        global: false,
        __dirname: false,
        __filename: false,
        buffer: false,
        process: false,
        navigator: false,
      },
      polyfills: {
        _stream_duplex: true,
        _stream_passthrough: true,
        _stream_readable: true,
        _stream_transform: true,
        _stream_writable: true,
        assert: true,
        "assert/strict": false,
        async_hooks: false,
        buffer: false,
        child_process: "empty",
        cluster: "empty",
        console: false,
        constants: true,
        crypto: "empty",
        dgram: "empty",
        diagnostics_channel: false,
        dns: "empty",
        domain: true,
        events: true,
        fs: "empty",
        "fs/promises": false,
        http: true,
        http2: false,
        https: true,
        module: "empty",
        net: "empty",
        os: true,
        path: true,
        perf_hooks: false,
        process: true,
        punycode: true,
        querystring: true,
        readline: "empty",
        repl: "empty",
        stream: true,
        string_decoder: true,
        sys: true,
        timers: true,
        "timers/promises": false,
        tls: "empty",
        tty: true,
        url: true,
        util: true,
        v8: false,
        vm: true,
        wasi: false,
        worker_threads: false,
        zlib: true,
      },
    }),
  ],
};

ps. Of course you must enable or disable the ones that make sense for you.

adrianotadao avatar Jan 10 '24 19:01 adrianotadao

Hey @glitch-txs don't want to annoy you but, can I ask you a short feedback given that you closed this issue? Just to get to know if it solved or just something you do not want to fix? Thanks in advance.

peterpeterparker avatar Jan 16 '24 13:01 peterpeterparker

So, I removed the plugin from our vite config, and, by extension, it resolved the issue I was facing.

Hi @peterpeterparker I have might missread, thought this was resolved.

Seems like the plugin is overriding some global methods used by the SDK, is this correct? Feel free to reopen otherwise.

Sorry I missed the earlier comments 🙏

glitch-txs avatar Jan 16 '24 14:01 glitch-txs

Thanks for the feedback @glitch-txs !

Indeed I think polyfilling NodeJS with vite / esbuild seems to override some global methods used by the SDK.

I removed the plugin which "resolved" the issue but, I just noticed that I may need to polyfill in some other cases. So I'm still interested for a solution.

I cannot reopen the issue, only option provided by GitHub is "comment".

So, can you reopen it?

peterpeterparker avatar Jan 16 '24 14:01 peterpeterparker

is the plugin in the latest version?

glitch-txs avatar Jan 16 '24 14:01 glitch-txs

Yeah I think everything is up-to-date in the sample repo I provided if I remember correctly.

https://github.com/peterpeterparker/web3wallet-issue-3913

peterpeterparker avatar Jan 16 '24 15:01 peterpeterparker

Any update on this ?

shan-c avatar Feb 05 '24 10:02 shan-c

Update on this for react native?

earthflower avatar Feb 07 '24 17:02 earthflower

@glitch-txs ?

shan-c avatar Feb 15 '24 06:02 shan-c

Pulling in latest v2.0 build seems to have fixed for me

nanewalt avatar Mar 08 '24 01:03 nanewalt

Pulling in latest v2.0 build seems to have fixed for me

Just tried "@walletconnect/web3wallet": "^1.11.2", issue is still here.

chunk-Z2AD4WP7.js?v=4a70899d:4835 Uncaught (in promise) TypeError: this.events.off is not a function
    at JsonRpcProvider.off (chunk-Z2AD4WP7.js?v=4a70899d:4835:17)
    at a3 (chunk-Z2AD4WP7.js?v=4a70899d:5947:25)
off @ chunk-Z2AD4WP7.js?v=4a70899d:4835
a3 @ chunk-Z2AD4WP7.js?v=4a70899d:5947
await in a3 (async)
request @ chunk-Z2AD4WP7.js?v=4a70899d:5941
await in request (async)
rpcSubscribe @ chunk-Z2AD4WP7.js?v=4a70899d:5788
Ut.subscribe @ chunk-Z2AD4WP7.js?v=4a70899d:5703
await in Ut.subscribe (async)
(anonymous) @ chunk-Z2AD4WP7.js?v=4a70899d:6012
subscribe @ chunk-Z2AD4WP7.js?v=4a70899d:6011
pair @ chunk-Z2AD4WP7.js?v=4a70899d:6251
await in pair (async)
pair @ wallet-connect.providers.ts:144
connect @ WalletConnectSession.svelte:245
await in connect (async)
userConnect @ WalletConnectSession.svelte:115
(anonymous) @ chunk-TURRLMQY.js?v=4a70899d:1253
(anonymous) @ chunk-TURRLMQY.js?v=4a70899d:1252
connect @ WalletConnectForm.svelte:33
Show 10 more frames
Show less

peterpeterparker avatar Apr 17 '24 11:04 peterpeterparker

Hey everybody, we encountered a similar issue today and this is what we learned:

  1. The JsonRpcProvider class uses the events package https://github.com/WalletConnect/walletconnect-utils/blob/ff9e57adcd08b1610f13eba659def97dcf21bb83/jsonrpc/provider/src/provider.ts#L1

  2. events package is a built in package in a Node.js environment, but not in the browser. There is a polyfill available that is a dependency of @walletconnect/core: https://github.com/WalletConnect/walletconnect-monorepo/blob/82298c93e31b8b05ee190cd23f0aab61bdded12a/packages/core/package.json#L47

  3. @walletconnect/jsonrpc-provider (and probably other walletconnect packages) does not have the events polyfill in its dependencies: https://github.com/WalletConnect/walletconnect-utils/blob/ff9e57adcd08b1610f13eba659def97dcf21bb83/jsonrpc/provider/package.json#L48-L51

  4. Our project uses another package (aws-sdk) that requires an old version of the events polyfill (this version does not have the EventEmitter.prototype.off function): https://github.com/aws/aws-sdk-js/blob/fd95d9fe09aaef540f6a50763e385506d4c9abb6/package.json#L45

  5. Because @walletconnect/jsonrpc-provider doe not have the events package in its dependencies, webpack resolves the wrong version of the events package during build (the one required by aws-sdk). Because of the missing EventEmitter.prototype.off in this version, the following line will throw an error: https://github.com/WalletConnect/walletconnect-utils/blob/ff9e57adcd08b1610f13eba659def97dcf21bb83/jsonrpc/provider/src/provider.ts#L47

If this interpretion is right, the problem can be solved by adding the required version of the events package to the package.json of @walletconnect/jsonrpc-provider. The same might be needed for other packages with the same missing dependency (eg. @walletconnect/heartbeat).

If you are using pnpm, you can patch the package.json of these packages like in the following snippet. Otherwise I think you need to wait for a release with adjusted dependencies or configure how your bundler resolves the events package.

"pnpm": {
  "packageExtensions": {
    "@walletconnect/jsonrpc-provider": {
      "dependencies": {
        "events": "^3.3.0"
      }
    }
  }
},

niklasnatter avatar Apr 23 '24 15:04 niklasnatter

Same issue with vite used by Nuxt 3

mahapo avatar Apr 26 '24 12:04 mahapo

Hey everyone! I found the same issue in a React Native project, and in my case after getting this error no more events were received from the paired apps, and neither send requests, and the application had to be closed and opened again. And even so, eventually the error would still appear again and the communication with paired apps lost again.

I was able to solve the issue thanks this comment. In my case, despite the having @walletconnect/react-native-compat which indicates [email protected] as dependency, I also had [email protected] indicated as a dependency in my package.json. Problem disappeared after upgrading to 3.3.0, but I was not being able to spot it. So big thank you @niklasnatter for your analysis, it was my starting point to solve my end of the deal.

heraldovalenti avatar May 01 '24 12:05 heraldovalenti

Hi everyone,

Thank you for the feedback and suggestions here, in particular @niklasnatter with the detailed analysis 💯 🙏

We're looking to patch affected packages where there is an apparent possibility of events being resolved transitively (as described) when @ganchoradkov returns tomorrow (proposed fix PR linked above).

bkrem avatar May 06 '24 15:05 bkrem

For what it's worth, I tested the latest version of WalletConnect v1.14.0, and an issue persists.

If Buffer is polyfilled for local development with esbuild, using WalletConnect results in the following error:

@walletconnect_web3wallet.js?v=bb62c12a:2006 Uncaught (in promise) TypeError: this.signClient.events[n] is not a function
    at se2.setEvent (@walletconnect_web3wallet.js?v=bb62c12a:2006:36)
    at se2.on (@walletconnect_web3wallet.js?v=bb62c12a:1986:1324)
    at T2.on (@walletconnect_web3wallet.js?v=bb62c12a:2040:78)
    at Object.sessionProposal (wallet-connect.providers.ts:65:14)
    at connect (WalletConnectSession.svelte:168:12)
    at async WalletConnectForm.userConnect (WalletConnectSession.svelte:116:11)

peterpeterparker avatar Aug 16 '24 05:08 peterpeterparker