web3 / web3.js

Collection of comprehensive TypeScript libraries for Interaction with the Ethereum JSON RPC API and utility functions.
https://web3js.org/
Other
19.11k stars 4.89k forks source link

TypeError: Cannot convert a BigInt value to a number #6830

Open damianlluch opened 6 months ago

damianlluch commented 6 months ago

Hi, we are in a project with the super complex task of moving a project running web3.js v1 to v4 (with web3-react v6 to v8). And we have been having this error when importing web3 and we can't find a solution.

Any suggestions?

Thanks

TypeError: Cannot convert a BigInt value to a number
m
node_modules/web3/dist/web3.min.js:2
SantiagoDevRel commented 6 months ago

Hola @damianlluch ! Can u pls share the piece of code u are running that is not working pls? thank u!

damianlluch commented 6 months ago

Hi @SantiagoDevRel

import { useCallback, useEffect, useState } from 'react';
import { Web3ReactHooks, useWeb3React } from '@web3-react/core';
import { useSelector } from 'react-redux';
// tslint:disable-next-line: no-submodule-imports
import { MetaMask } from '@web3-react/metamask';
import { WalletConnect } from '@web3-react/walletconnect-v2';
import WalletConnectProvider from '@walletconnect/web3-provider';
import dayjs from 'dayjs';
import { NETWORKS } from 'config/networks/networks';
import { notifyError } from 'components/Authentication/toast';
import Web3 from 'web3';
import { selectUserAuthState } from '../redux/authentication/selectors';
import { metaMask, metaMaskHooks } from '../config/web3/connectors/metaMask';
import { getAddChainParameters } from '../config/web3/chains';
import { useChainContext } from '../contexts/chainContext/useChainContext';
import { addresses } from '../contracts/addresses';
import { IChainState, InitChainContext } from '../contexts/chainContext/ChainContext';
import { network } from '../config/web3/connectors/network';
import { walletConnectV2 } from '../config/web3/connectors/walletConnectV2';

const methods = {
  switchEthChain: 'wallet_switchEthereumChain',
  addEthChain: 'wallet_addEthereumChain',
};

function toHexChainId(chainId: number): string {
  return `0x${chainId.toString(16)}`;
}

function recoverChainState(chainId: number): IChainState {
  return NETWORKS?.find((ntw) => ntw?.id === chainId);
}

const switchChainOrAdd = async (params: any[]) => {
  console.log(params[0].chainId, 'params[0].chainId');
  return (window as any).ethereum
    .request({
      method: methods.switchEthChain,
      params: [{ chainId: toHexChainId(params[0].chainId) }],
    })
    .catch(async (err) => {
      console.error(err);

      return (window as any).ethereum.request({
        method: methods.addEthChain,
        params,
      });
    });
};

export const useWallet = (): {
  account: string;
  connect: (walletName: string, network: IChainState) => Promise<void>;
  disconnect: () => Promise<void>;
  addMyToken: (network: number) => Promise<any>;
} => {
  const { account } = useWeb3React();
  const [error, setError] = useState<Error | undefined>(undefined);
  const userData = useSelector(selectUserAuthState);
  const { chainState, chainDispatch } = useChainContext();

  const addMyToken = async (networkBlockchain: number) => {
    const wasAdded = await (window as any).ethereum.request({
      method: 'wallet_watchAsset',
      params: {
        type: 'ERC20',
        options: {
          address: addresses.myToken[networkBlockchain],
          symbol: 'MYTOKEN',
          decimals: 18,
          image: 'https://d1dlq0zr6mzu0g.cloudfront.net/static/media/MYTOKEN.199adee8.svg', // A string url of the token erroro
        },
      },
    });
    return wasAdded;
  };

  const connect = useCallback(
    async (walletName, chainId) => {
      let chain: IChainState | null = null;
      let connector: MetaMask | WalletConnect;

      // Metamask NOT found
      if (walletName === 'Metamask' && typeof window?.ethereum === 'undefined') {
        console.warn('Web3 injection not found!');
        notifyError({
          title: 'Provider not found',
          message: 'Provider was not found, please try again',
        });
        return;
      }

      // Connect to metamask and recover chain state
      if (walletName === 'Metamask') {
        connector = metaMask;
        await switchChainOrAdd([getAddChainParameters(chainId.id)]);
        chain = { ...recoverChainState(chainId.id), provider: null };
      }

      // Connect to walletconnect and recover chain state
      if (walletName === 'Trust Wallet') {
        connector = walletConnectV2;
        console.log(connector, 'connector');

        chain = { ...recoverChainState(chainId.id), provider: null };
      }

      try {
        localStorage.setItem(
          'Wallet',
          JSON.stringify({ name: walletName, chainId: network.provider, expireDate: dayjs().add(2, 'hour').format() })
        );
        chainDispatch({ type: 'chainSwitch', payload: chain });
        await connector.activate(chainId.id);
      } catch (e) {
        console.error('Error connecting to wallet:', e);
        setError(e instanceof Error ? e : new Error('Failed to connect to the wallet'));
      }
    },
    [chainDispatch]
  );
  // eslint-disable-next-line @typescript-eslint/no-empty-function
  const disconnect = async () => {
    let connector: MetaMask | WalletConnect;

    try {
      if (chainState.provider instanceof WalletConnectProvider || connector instanceof WalletConnect) {
        await connector.deactivate();
      } else {
        chainDispatch({ type: 'chainSwitch', payload: InitChainContext });
        if (chainState.provider instanceof WalletConnectProvider) {
          await chainState.provider.disconnect();
        }
        await connector.deactivate();
      }
    } catch (ex) {
      console.info(ex);
    }
    localStorage.removeItem('Wallet');
  };

  return { account: account || userData.walletAddress, connect, disconnect, addMyToken };
};
import { createContext } from 'react';

export interface IChainState {
  name: string;
  icon: string;
  id: number;
  chainRsp: string;
  currency: string;
  // @TODO: WEB3
  provider?: any;
  txScan: string;
  rpcUrl: string;
  defaultChainId?: any;
}

export const ChainContext = createContext(null);

export const InitChainContext: IChainState = {
  name: '',
  icon: '',
  id: 0,
  chainRsp: '',
  currency: '',
  provider: null,
  txScan: '',
  rpcUrl: '',
};

The error is when using Web3, in the line that does Web3.giverProvider

luu-alex commented 5 months ago

Hey there! Sorry that you are running into this issue, it looks like that your using react to build and the versions of browsers in your list might not be supporting bigint. BigInt is being used in v4, where in v1 it used BN. I think i found a similar issue with someone getting the same error here with a solution. https://web3auth.io/community/t/big-int-error-in-react-production-build/3289
Please try this, as well if you can paste your package.json if you run into other issues

damianlluch commented 5 months ago

Hello, thank you. I read what you passed, but it wasn't a solution. @luu-alex My solution was to migrate the project from React to Vite (keeping in mind that I had an example project where they used Vite, and the same code worked)....

mconnelly8 commented 5 months ago

Hey @damianlluch, thanks for the information. Can you create a sample repo in a sandbox to reproduce the issue and to let us review it?