How to call asynchronous Javascript functions from Unity scripts?

I have been trying to follow Unity’s documentation for creating JavaScript files/functions so that I can get access to the web browsers apis to interface with the browsers JavaScript engine. Unity - Manual: Interaction with browser scripting

I am making a Unity 2d game for WebGL platforms and I want to have users be able to connect their MetaMask wallet and get access to their wallet addresses through MetaMasks api.

Following the documentation, I created a .jslib file in my /Assets/Plugins directory, that has the following function inside:

mergeInto(LibraryManager.library, {

  GetMetaMaskWallet: async function (x, y) {
    const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' })
    .catch((err) => {
      if (err.code === 4001) {
        // EIP-1193 userRejectedRequest error
        // If this happens, the user rejected the connection request.
        console.log('Please connect to MetaMask.');
      } else {
        console.error(err);
      }
    });
    const account = accounts[0];
    return account;
  },
});

Inside my Unity project, I have a empty game object with a C# script attached, that takes in a Button and attaches a click event listener to it. This click event function, calls the JavaScript function I have above

    [DllImport("__Internal")]
    private static extern string GetMetaMaskWallet();


    public Button connectMetaMaskButton;

    void Start ()
    {
        // 'Connect with MetaMask button'
        Button btn = connectMetaMaskButton.GetComponent<Button>();
        btn.onClick.AddListener(ConnectWallet);
    }

    void ConnectWallet()
    {
    string account = GetMetaMaskWallet();

        if (account != "") {
            connectMetaMaskButton.gameObject.SetActive(false);
        }
    }

For some reason, async functions do not seem to work in returning their expected values. When I Build and Run the WebGL project, and click the Connect with MetaMask button, the MetaMask prompt pops up and everything works as expected, but nothing seems to be returning back to my C# script.

I verified that async JS functions are not returning anything by copying some of the examples provided in the Unity docs, for example the:

AddNumbers: function (x, y) {
    return x + y;
},

and turning it to:

AddNumbers: async function (x, y) {
    return x + y;
},

This causes nothing to return. I am aware the AddNumbers example makes no sense in being an async function, but testing removing the async makes the function work and return the appropriate number I am expecting back to my C# script.

Does anyone have some insight or guidance on how I could get my MetaMask example working, or help on what i am doing wrong with async functions in my JavaScript examples.

That will not work, at all. That’s because async methods are not methods in the traditional sense. Well they are but they return a Promise object. All that object allows you to do is to “attach” a handler / callback to handle the result of the promise when it resolves or errors out. So of course you don’t get the return value you may expect as this value would be passed to the callback that may be registered to the promise. The async / await syntax is just syntactic sugar that makes it easier to build such promise chains.

I don’t think you can do much with a javascript Promise object on the C# side. You probably can create a javascript method where you pass a callback function and have the async method called on the javascript side and simply call the callback from the “then” handler. Though I haven’t tried this yet. The documentation always suggests using “SendMessage” from the javascript side to call C# code. However afaik I successfully passed a C# method as callback to javascript code and have it invoke the C# method. I think this may be helpful .