Custom authentication with Torus

Hello,

I am trying to integrate authentication with Torus wallet and I am struggling with creation of my custom connector class.

Before moving to Moralis, I had been using web3modal connection:

  const Torus = (await import('@toruslabs/torus-embed')).default
  const providerOptions = {
    torus: {
      package: Torus, // required
    },
  }

  const web3Modal = new Web3Modal({
    network: 'mainnet', // optional
    cacheProvider: true, // optional
    providerOptions, // required
  })

  const connector = await web3Modal.connectTo('torus')
  const provider = new ethers.providers.Web3Provider(connector)
  [...]

So far I was able to implement the custom class like this:

class TorusWeb3Connector extends AbstractWeb3Connector {
  type = 'Torus'

  async activate({ chainId: providedChainId, mobileLinks } = {}) {
    // Cleanup old data if present to avoid using previous sessions
    try {
      await this.deactivate()
    } catch (error) {
      // Do nothing
    }

    if (!this.provider) {
      let TorusProvider
      const config = {
        rpc: getMoralisRpcs('Torus'),
        chainId: providedChainId,
      }

      try {
        TorusProvider = (await import('@toruslabs/torus-embed')).default
      } catch (error) {
        // Do nothing. User might not need Torus
      }

      if (!TorusProvider) {
        throw new Error(
          'Cannot enable Torus: dependency "@toruslabs/torus-embed" is missing'
        )
      }

      if (typeof TorusProvider === 'function') {
        this.provider = new TorusProvider(config)
      } else {
        this.provider = new window.TorusProvider()
      }
    }

    if (!this.provider) {
      throw new Error(
        'Could not connect with Torus, error in connecting to provider'
      )
    }

    console.log('this.provider', this.provider)

    const accounts = await this.provider.ethereum.enable()
    const account = accounts[0].toLowerCase()
    const { chainId } = this.provider
    const verifiedChainId = verifyChainId(chainId)

    console.log('accounts', accounts)

    this.account = account
    this.chainId = verifiedChainId

    this.subscribeToEvents(this.provider)

    return { provider: this.provider, account, chainId: verifiedChainId }
  }

  async deactivate() {
    this.unsubscribeToEvents(this.provider)

    try {
      if (window) {
        window.localStorage.removeItem('Torus')
      }
    } catch (error) {
      // Do nothing
    }

    this.account = null
    this.chainId = null

    if (this.provider) {
      try {
        await this.provider.disconnect()
      } catch {
        // Do nothing
      }
    }
  }
}

export default TorusWeb3Connector

And then integrate it through authentication like below:

authenticate({ connector: TorusWeb3Connector })

Unfortunately, “ethereum” property in “this.provider” is null and I cannot get through with the authentication process. Does anyone know how to approach it so I can make my full migration towards Moralis?

You can check other forum threads to see if you find some idea, like

I think that you have to define a custom web3 provider and set that custom web3 provider

I have already checked them. Unfortunately, since December 21’ that code is no longer valid. Would you be able to provide me some further advice?

I guess that you also checked this one:

this is the part that doesn’t work?

@juldam did you get any further with this implementation? Also struggling to integrate Torus.

1 Like

@agalloch88 @juldam i wouldnt recommend implementing Torus like that. use Web3React version6 instead its way better and makes it SUPER EASY PEASY its great. to install

npm i @web3-react/[email protected] //needs to be v6

then install the web3React torus connector

npm i @web3-react/torus-connector

then once both are installed make sure you have ethers installed as we need this for our provider. if not then same old same old

npm install ethers

now with that out of the way we need to wrap our app in the Web3ReaxtProvider. to do so naviagte to index.js and

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { Web3ReactProvider } from "@web3-react/core";
import { Web3Provider } from "@ethersproject/providers";

function getLibrary(provider) {
  const library = new Web3Provider(provider);
  library.pollingInterval = 8000;
  return library;
}

ReactDOM.render(
      <Web3ReactProvider getLibrary={getLibrary}>
          <App />
      </Web3ReactProvider>
  document.getElementById('root')
);

import web3Provider fro react and wrap app in it. however this provider is dependand on a web3 library like ethers or web3. i prefer ethers. so in the function getLibrary we are setting up our web3 instance using ethers as our provider. pass this function as porps for the library depandancy to the web3React provider. boom your good to go

setting up torus is easy. make new file call it whatever
torus.js

import React, { useEffect } from 'react';
import { useWeb3React, UnsupportedChainIdError } from "@web3-react/core"

//set up torus connector
export const torus = new TorusConnector({ chainId: 42 })


function useAuth() {

    var { active, account, library, activate, deactivate } = useWeb3React()
   
    const disconnect= async () => {
        try {
            await deactivate()
        } catch (err) {
            console.error(err)
        }
    }

function connectToTorus() {   
  
    activate(torus, undefined, true).then(() => {
        ///do optional stuff
    })
    .catch((error) => {
        if (error instanceof UnsupportedChainIdError) {
            activate(torus) // a little janky...can't use setError because the connector isn't set
        } else {
            disconnect()
        } 
    })
}


  return { connect }
}

export default useAuth

this is a hook so it returns out torus connect function. note you need to import this hook into the component you want to use it im, destructure the connect function from it the use the connect function as a onlick handler function and boom you can connect to torus EASY PEASY

PS
also this is a very simplified version of an auth file ive been making and reworking across different projects of mine for months now. ive created my own web3 auth hook that supports like every wallet, filters through wallets that only work on crertain chains (for example my wallet list only shows sollet and solana is the chain is solana etc) all wallets also presist their connections on load withut having to reconnect. and the full my full auth hook handles chainswitching with popups etc etc and error handling for unsupported chains. so if you want the full file above let me know, but the above example is a good intro for the torus wallet

1 Like