Moralis JS-SDK v1.0.0 [beta] (Ethers.js support)

JS-SDK v1 Beta (Ethers.js support)

The JS-SDK is switching to using ethers.js instead of web3.js.

This is a change that will affect current builds, and thatā€™s why we make it only accessible in beta releases for now.

The main changes are

  • Ethers.js is used as internal web3-library
  • Support Web3.js for Moralis.web3 calls
  • Changed responses of on-chain functions
  • Custom authentication / enableWeb3 (previously overwriting enableWeb3)

How to use

Install the sdk via

npm install moralis@next

Or install moralis by specifying a beta release. (see all releases here)

For the CDN script version, you can use:

https://unpkg.com/[email protected].<VERSION>/dist/moralis.js

And replace <VERSION> the beta release version to the latest release (see all releases here)

Note: if you use react-moralis, then make sure to also install the latest beta release of react-moralis
See: https://github.com/MoralisWeb3/react-moralis/issues/144

Note: if you want to switch back to a non-beta build, then install a moralis via npm install moralis@latest (or specify a release) or use a non-beta CDN script.

Breaking Changes

Ethers.js as internal web3-library

the Moralis SDK will use Ethers.js instead of Web3.js as internal library. This means:

  • When you call enableWeb3() or authenticate() then Moralis.web3 will be an instance of Ethers.js instead of Web3.js.
  • Smaller bundle size
  • The responses of on-chain functionalities (Moralis.transfer, Moralis.executeFunction and some plugins) are different

Support Web3.js for Moralis.web3 calls

If you want to use a Web3.js instance when calling Moralis.authenticate() or Moralis.enableWeb3(), then you need to specify the library constructor when you call Moralis.start.:

Example where web3 is an instance of Ethers.js

await Moralis.start({
  serverUrl: "YOUR_SERVER_URL",
  appId: "YOUR_APP_ID",
});
// Get the initialized web3 instance from Ethers.js
await Moralis.enableWeb3();
const web3 = Moralis.web3;

Example where web3 is an instance of Web3.js

When using CDN build, make sure to include the Web3.js library:

<script src="https://cdn.jsdelivr.net/npm/web3@latest/dist/web3.min.js"></script>

When using npm/yarn: make sure to install web3:

npm install web3
import Web3 from "web3"; // Only when using npm/yarn

await Moralis.start({
  serverUrl: "YOUR_SERVER_URL",
  appId: "YOUR_APP_ID",
  web3Library: Web3,
});
// Get the initialized web3 instance from Web3.js
await Moralis.enableWeb3();
const web3 = Moralis.web3;

Changed responses

  • Responses for on-chain calls are different, as Ethers.js is used for these calls. The main difference is that Web3.js returned a PromiEvent, where you could subscribe to events, for callbacks. The responses from Ethers.js do not have this functionality. Instead, you get more information in the receipt, and can wait for the result (after confirmation) via response.wait() (see docs).
  • Data might be differently formatted. For example, Ethers.js includes numbers as a BigNumber object in the response.

This has effect on:

  • Moralis.transfer()
  • Moralis.executeFunction()
  • Some plugins

Custom authentication / enableWeb3 (previously overwriting enableWeb3)

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:

Feedback

Please provide any feedback regarding the changes in this forum post. In your post, please include:

  • What beta version do you use
  • If you use npm, yarn or a CDN (script) build
  • if you use react-moralis along with it (if so, what beta-build)
7 Likes

Moralis JS-SDK has moved out of beta to the main build. for more info, see: Moralis JS SDK v1.0 (migration to Ethers.js)

1 Like

Hi! I have a problem with getChainId() method. Moralis.getChainId() returns always null after my page has just loaded.

const user = await Moralis.User.currentUserAsync();
if (user) {
    const chainId = Moralis.getChainId();
}

The method returns a correct value only after I call .authorize() method.

1 Like

Hi, that is correct, it now returns the chainId of the authenticated/enabled account. And will always sync if the user changes chains.
We now donā€™t assume that everyone is using Metamask (but can also be walletconnect or any other provider). So we have no idea what the chainId is before the user connects.

If you want to get the chainId of metamask, then you can check their docs: https://docs.metamask.io/guide/ethereum-provider.html#methods

This is something like:

const chainId = await window.ethereum.request({ method: 'eth_chainId' });
1 Like

OK, I understand this part. But how I can restore the previous session? I donā€™t want to force a user to authenticate himself every time (e.g. after a page is reloaded). Should I store chainId to localStorage when I have this information available?

EDIT: localStorage solution doesnā€™t solve the problem, because a user could change the network during my app was offline.

Using the latest version I would expect any of these to work?

https://unpkg.com/[email protected]/dist/moralis.js
https://unpkg.com/[email protected]/dist/moralis.js

Hi,

I am using react-moralis for authentication:

const { Moralis, account, isAuthenticated } = useMoralis();
const { chainId } = useChain();

  useEffect(() => {
    Moralis.enableWeb3();
  }, [Moralis]);

  useEffect(() => {
    if (!account || !chainId) return;

    //do some work
    dispatch(action)
  }, [account, chainId, dispatch]);

Is it normal that isAuthenticated=true whereas account=undefined?

Also, from my tests, account and chainId switch from defined to undefined multiple times, making my dispatched action triggered multiple times but it shouldnā€™t.

And sometimes I am getting the following error in the console:

Uncaught (in promise) TypeError: Cannot read properties of null (reading 'on')
    at InternalWeb3Provider.<anonymous> (InternalWeb3Provider.js:134:1)
    at tryCatch (runtime.js:63:1)
    at Generator.invoke [as _invoke] (runtime.js:293:1)
    at Generator.next (runtime.js:118:1)
    at asyncGeneratorStep (asyncToGenerator.js:5:1)
    at _next (asyncToGenerator.js:27:1)

I donā€™t if I am doing something wrong here or if there is a real bug :frowning:

Thanks for your help!

Hello ! I have one problem , how do I do that in react ?

import "../styles/globals.css";

import { MoralisProvider } from "react-moralis";

function MyApp({ Component, pageProps }) {

  const serverURL = process.env.NEXT_PUBLIC_SERVERURL;

  const appID = process.env.NEXT_PUBLIC_APPID;

  return (

    <MoralisProvider appId={appID} serverUrl={serverURL}>

      <div className="containerBlack">

        <Component {...pageProps} />

      </div>

    </MoralisProvider>

  );

}

export default MyApp;

Iā€™m using next with react.

Please provide some clarity on this :pray:t4:

How to run function formatBytes32String ?

For the best integration with react, you should use enableWeb3/authenticate etc. from react-moralis (useMoralis). That way account, chainId etc. should be correctly returned as well.

For the second error, it might be the case that enableWeb3 gets called multiple times in a row. This can happen if you call the function in a component render function, or in a useEffect that gets triggered too often. See enableWeb3() is not working

We have moved out of beta. See Moralis JS SDK v1.0 (migration to Ethers.js)

You need to use https://unpkg.com/[email protected]/dist/moralis.js for example without the beta tag