Moralis JS SDK v1.0 (migration to Ethers.js)

Migration Guide JS SDK v0.0.x > v1

  • Removed dependency of web3.js in favour of ethers.js

  • Introducing custom connectors

Update

To update, you need to update your dependency

For CDN::


<script src="https://unpkg.com/moralis@latest/dist/moralis.js"></script>

Please update latest to the release version you want to use. For all releases, see: https://github.com/MoralisWeb3/Moralis-JS-SDK/releases

Via npm:


npm install moralis@latest

If you do NOT want to update yet

Then you you specify the version to v0.0.184

For CDN:


<script src="https://unpkg.com/[email protected]/dist/moralis.js"></script>

Via npm:


npm install [email protected]

Breaking changes

Moralis.web3 and Moralis.enableWeb3

Moralis.web3 and Moralis.enableWeb3 will now return an instance of Ethers.js instead of an instance of Web3.js.

To account for these changes you should

  1. Adjust your code to use the Ethers.js library

Or

  1. Keep using Web3.js or any other library by importing it and initializing it using Moralis.provider. Code below shows how to keep using web3.js specifically:
    Install web3.js via npm/yarn OR by importing it as a script, then:
    
    import Web3 from 'web3' // Only when using package mananger. 
    import Moralis from 'moralis'  // Only when using package mananger
    
    await Moralis.enableWeb3()
    const web3 = new Web3(Moralis.provider)
    
    

Return values of Moralis.executeFunction and Moralis.transfer

Return values are changed for Moralis.executeFunction and Moralis.transfer. They are now a transaction response from Ethers.js:

This object contains all data about the transaction. If you need data about the result of the transation, then you need to wait for the transaction to be confirmed.

You can do this via transaction.wait() to wait for 1 confirmation (or transaction.wait(5) to wait for 5 confirmations for example):


const transaction = await Moralis.transfer(options)

const result = await transaction.wait()

Moralis.onXXX events have changed

Instead of subscribing to Metamask events directly, moralis generalizes these events so that they can be used for any connector: metamask, walletconnect, network etc. So now the events are fired from the connector that is use to authenticate/enableWeb3.

For example: a user signs in using walletconnect, then switches accounts in walletconnect. Then Moralis.onAccountChange will respond to this change.

To use the previous implementation of listening to Metamask events, you can use:

    window.ethereum.on("accountsChanged", (account) =>
      console.log("account")
    );
    window.ethereum.on("chainChanged", (chain) =>
      console.log("chain")
    );

A notable change is the renamning of Moralis.onAccountsChanged to Moralis.onAccountChanged

Customize enableWeb3 / custom connectors

Previously, it was possible to overwrite the enableWeb3() function. This allowed for custom implementation to connect wallets that are not supported by Moralis out-of-the-box.

This approach is not possible anymore, to allow for better scaling and more consistent behavior.

Instead, now you can implement your own connector, which extends the AbstractConnector class.

This class should implement

  • An activate() function that resolves to an object with:

  • provider: A valid EIP-1193 provider

  • chainId (optional): the chain that is being connected to (in hex)

  • account (optional): the account of the user that is being connected

  • Subscribes to the EIP-1193 events. This should be mostly done automatically by calling this.subscribeToEvents(provider) in the activate function.

  • the type field to indicate a name for the connector

  • (optionally) a deactivate function that extends the default deactivate function. Implement this when you need to clean up data/subscriptions upon ending/switching the connection.

Then you can include this CustomConnector in the authenticate/enableWeb3 call as an option:


Moralis.authenticate({ connector: CustomConnector })

See for example implementations:

10 Likes

Will Moralis now work with Webpack5?

I know that web3.js was giving problems. But I’m not sure if that was the only dependency giving issues. Every dependency that is using NodeJs functionalities needs to be poly-filled (see the discussion on create-react-app https://github.com/facebook/create-react-app/issues/11756).
It wouldn’t surprise me that it still is not working, we will make a boilerplate that is compatible with v5 soon though.

1 Like

As suggested, Moralis.onChainChanged() and Moralis.onAccountChanged() no longer work. What should we be using in their place to detect when Metamask changes chaing or account?

2 Likes

How could I get the getSigner in react-moralis v1? is it something like below?

const { provider } = useMoralis()

const signer = provider.getSigner() // compile error in TS

I’ve checked the provider it’s the unknown type which is not friendly in TypeScript.

That should still work @Erno will check

They should still be working and not removed, the only thing that change is this one

I had changed the onAccountsChanged to onAccountChanged which stopped errors but none of the events were activating. I’ll play around and see if I can see what’s going on.

I see @Erno can probably take a look on this if there is really an issue on this :raised_hands:

The events are now fired differently. Before it was firing the Metamask onChain/onAccountsChanged events. Now it is firing the onChain/onAccountsChanged of the method that is used for authentication/enableWeb3.

So before you call authenticate/enableWeb3, no events will be fired. Then if you authenticate via Walletconnect, you will get events from WalletConnect.

I assume you use the events before enableWeb3/authenticate was called?

If so, then if you want to listen for Metamask events, you can use window.ethereum.on:

    window.ethereum.on("accountsChanged", (account) =>
      console.log("account")
    );
    window.ethereum.on("chainChanged", (chain) =>
      console.log("chain")
    );

Correct, the provider can be any EIP1193 provider that is returned from Metamask/WalletConnect/etc., so that’s why we have it typed as unknown right now.

To get the signer, you need to use the instance of the Ethers web3. You can use something like:

  const { web3 } = useMoralis();

  useEffect(() => {
    if (web3) {
      const signer = (web3 as any).getSigner();
      console.log("signer", signer);
    }
  }, [web3]);

Just noticed that we have no proper types for the returned web3, will look into that one to provide better types.

1 Like

My Dapp was working fine ; but now I get prompted with the following error ‘TypeError: Moralis.Web3.onAccountsChanged is not a function’. I updated npm install moralis@latest and also npm install moralis@latest. I believe this error is coming internally as I did not use Moralis.Web3.onAccountsChanged function on my Dapp or scripts.

1 Like

Will Moralis.Web3API remain available in the cloud functions after updating the server?

What version of react-moralis do you use?
If you upgraded moralis to v1.0 then you should also update react-moralis to v1.0

@Erno
Those are my dependencies

"dependencies": {

    "@walletconnect/web3-provider": "^1.7.1",

    "axios": "^0.24.0",

    "install": "^0.13.0",

    "moralis": "^1.0.1",

    "next": "^12.0.8",

    "react": "^17.0.2",

    "react-dom": "^17.0.2",

    "react-moralis": "^0.3.11",

    "timeago-react": "^3.0.4"

  },

So you need to update react-moralis as well to v1.0

@Erno could you please give me the commands on how to do so
. Thanks

Try npm install react-moralis@latest

Thanks @Erno :muscle:

1 Like