Search code examples
npmclojurescriptwallet-connectshadow-cljsweb3modal

WalletConnect v2.0 library integration issues with shadow-cljs


I am currently trying to use the WalletConnect v2.0 library using Web3Modal SDK in a clojuscript project with shadow-cljs. To do this I followed the standalone installation: Web3Modal Standalone Installation

I installed the libraries with npm :

npm install @walletconnect/sign-client @web3modal/standalone    

After importing the packages in my code like this :

(ns project.view
  (:require
   ["@web3modal/standalone" :refer [Web3Modal]]
   ["@walletconnect/sign-client" :refer (SignClient)]))

So I try to create my modal object with the required configuration:

(let [modal    (Web3Modal. modal-config)]
  ...
)

And an error occurs when creating this instance. Error that did not appear with a Javascript project. In the console I can read that :

Uncaught (in promise) Module not provided: @web3modal/ui

After looking at the file raising the error, I realized that it was the JavaScript file generated by shadow-cljs corresponding to the @web3modal/standalone library that had the problem. Indeed, it is in this code at the level of an asynchronous method calling an await on @web3modal/ui that the error is raised.

When we look at the shadow-cljs documentation corresponding to the Output Language Options we can read the following warning message:

Note that this mostly affects imported JS code from npm or .js files from the classpath. CLJS will currently only generate ES5 *(*ECMAScript 2009) output and is not affected by setting higher options.

Knowing that the part of the code of the @web3modal/standalone library imported from npm that causes problems is at the level of the await and that the await/sync were introduced with ECMAScript 2017, is it possible that it is the compilation of the libraries imported via npm by shadow-cljs that make it impossible to use this library?

And is there any other way to get around this limitation if the problem comes from the compilation of the libraries imported by npm?

I attempted to play with the :output-feature-set but as mentioned on the warning message, the libraries installed from npm will not be affected by the configuration.

I tried to use the React, HTML and Standalone configuration of WalletConnect V2.0. Within a pure JavaScript project there are no errors in the library. However when I switch to a project with shadow-cljs, I get the error systematically no matter what configuration is used.

By modifying the source code of the npm library at the await level, the code generated by shadow-cljs no longer raises any errors. But this solution is only temporary and can be used locally.

The index.js file of the library imported by npm that calls an await is this one:

    import {ModalCtrl as r, ThemeCtrl as n, ConfigCtrl as l, OptionsCtrl as s} from "@web3modal/core";
    
        [...]
    
        async initUi() {
            if (typeof window < "u") {
                await import("@web3modal/ui");
                const e = document.createElement("w3m-modal");
                document.body.insertAdjacentElement("beforeend", e), s.setIsUiLoaded(!0)
            }
        }
    }
    
    export {f as Web3Modal};
    //# sourceMappingURL=index.js.map

Solution

  • The @web3modal/standalone package appears to try to load the @web3modal/ui package dynamically, via await import("@web3modal/ui");. This currently has very limited support in shadow-cljs, or rather the Closure Compiler.

    It may work if you add a manual (:require ["@web3modal/ui"]) before your ["@web3modal/standalone"] require. This will provide the package eagerly, which might work.

    There however might be other places such things are done. I recommend using :js-provider :external instead.