GithubHelp home page GithubHelp logo

mdtanrikulu / use-metamask Goto Github PK

View Code? Open in Web Editor NEW
166.0 7.0 35.0 3.41 MB

a custom React Hook to manage Metamask in Ethereum ĐApp projects

Home Page: https://mdtanrikulu.github.io/use-metamask

License: MIT License

HTML 6.72% JavaScript 86.42% CSS 6.86%
reactjs hooks react-hooks metamask blockchain ethereum

use-metamask's Issues

window is not defined when using Next.js

As you know, Next.js, Gatsby.js and other static site builders build react apps using Node.js engine and not the browser, thus the window object is not available at build time.

So it give us the error window is not defined .
Writing a logic like:

    if (typeof window !== 'undefined') {
        const { connect, metaState } = useMetamask();
    }

will make the connect and metaState constant variables unavailable outside the scoped block (yeah we could use var but... come on! var ???)

Please add the logic to check for the availability of the window object before using it (I might do a pull request but Im busy nowadays, and it takes time to get my head around this repo's code!)

A sample is like this:

    if (typeof window !== 'undefined') {
        // use window object here.
    }

TypeScript type declarations

Hi there, do you have any plans on adding TypeScript type declarations? There is no @types/use-metamask package yet, so many developers will face this issue:
Screenshot 2021-08-12 at 10 37 15

Didn't work with Webpack5

Everytime i'm tying to implement use-metamask with a simple create-react-app.

I got all of those errors:


ERROR in ./node_modules/cipher-base/index.js 3:16-43

Module not found: Error: Can't resolve 'stream' in '/home/myuser/dev/react-use-metamask/node_modules/cipher-base'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "stream": require.resolve("stream-browserify") }'
	- install 'stream-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "stream": false }


ERROR in ./node_modules/eth-lib/lib/bytes.js 9:193-227

Module not found: Error: Can't resolve 'crypto' in '/home/myuser/dev/react-use-metamask/node_modules/eth-lib/lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "crypto": require.resolve("crypto-browserify") }'
	- install 'crypto-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "crypto": false }


ERROR in ./node_modules/ethereumjs-util/dist.browser/account.js 71:31-48

Module not found: Error: Can't resolve 'assert' in '/home/myuser/dev/react-use-metamask/node_modules/ethereumjs-util/dist.browser'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "assert": require.resolve("assert/") }'
	- install 'assert'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "assert": false }


ERROR in ./node_modules/ethereumjs-util/dist.browser/address.js 14:31-48

Module not found: Error: Can't resolve 'assert' in '/home/myuser/dev/react-use-metamask/node_modules/ethereumjs-util/dist.browser'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "assert": require.resolve("assert/") }'
	- install 'assert'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "assert": false }


ERROR in ./node_modules/ethereumjs-util/dist.browser/object.js 46:31-48

Module not found: Error: Can't resolve 'assert' in '/home/myuser/dev/react-use-metamask/node_modules/ethereumjs-util/dist.browser'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "assert": require.resolve("assert/") }'
	- install 'assert'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "assert": false }


ERROR in ./node_modules/web3-eth-accounts/lib/index.js 31:74-91

Module not found: Error: Can't resolve 'crypto' in '/home/myuser/dev/react-use-metamask/node_modules/web3-eth-accounts/lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "crypto": require.resolve("crypto-browserify") }'
	- install 'crypto-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "crypto": false }


ERROR in ./node_modules/web3-eth-accounts/node_modules/eth-lib/lib/bytes.js 7:193-227

Module not found: Error: Can't resolve 'crypto' in '/home/myuser/dev/react-use-metamask/node_modules/web3-eth-accounts/node_modules/eth-lib/lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "crypto": require.resolve("crypto-browserify") }'
	- install 'crypto-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "crypto": false }


ERROR in ./node_modules/web3-providers-http/lib/index.js 30:11-26

Module not found: Error: Can't resolve 'http' in '/home/myuser/dev/react-use-metamask/node_modules/web3-providers-http/lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "http": require.resolve("stream-http") }'
	- install 'stream-http'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "http": false }


ERROR in ./node_modules/web3-providers-http/lib/index.js 32:12-28

Module not found: Error: Can't resolve 'https' in '/home/myuser/dev/react-use-metamask/node_modules/web3-providers-http/lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "https": require.resolve("https-browserify") }'
	- install 'https-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "https": false }


ERROR in ./node_modules/xhr2-cookies/dist/xml-http-request.js 37:11-26

Module not found: Error: Can't resolve 'http' in '/home/myuser/dev/react-use-metamask/node_modules/xhr2-cookies/dist'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "http": require.resolve("stream-http") }'
	- install 'stream-http'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "http": false }


ERROR in ./node_modules/xhr2-cookies/dist/xml-http-request.js 39:12-28

Module not found: Error: Can't resolve 'https' in '/home/myuser/dev/react-use-metamask/node_modules/xhr2-cookies/dist'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "https": require.resolve("https-browserify") }'
	- install 'https-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "https": false }


ERROR in ./node_modules/xhr2-cookies/dist/xml-http-request.js 41:9-22

Module not found: Error: Can't resolve 'os' in '/home/myuser/dev/react-use-metamask/node_modules/xhr2-cookies/dist'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "os": require.resolve("os-browserify/browser") }'
	- install 'os-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "os": false }

I tryied to create webpack.config.js but same result.

module.exports = {
  resolve: {
    fallback: {
      "stream": false,
      "crypto": false,
      "assert": false,
      "http": false,
      "https": false,
      "os": false,
    },
  }
};

I also try to implement all, but exactly the same result.

npm i -s assert buffer crypto-browserify stream-http https-browserify os-browserify stream-browserify

module.exports = {
  resolve: {
    fallback: {
      assert: require.resolve('assert'),
      buffer: require.resolve('buffer'),
      crypto: require.resolve('crypto-browserify'),
      http: require.resolve('stream-http'),
      https: require.resolve('https-browserify'),
      os: require.resolve('os-browserify/browser'),
      stream: require.resolve('stream-browserify'),
    },
  },
};

Any idea ?

Compatibility with Alchemy Web3, a wrapper around Web3.js

Hi there! I'm developing a project using Alchemy Web3, a wrapper around Web3.js. See the Alchemy Web3 docs for more context: https://docs.alchemy.com/alchemy/documentation/alchemy-web3

I encountered a roadblock when combining it with use-metamask, so I open this issue to:

  1. Confirm if this assessment is correct, or I missed something!
  2. Offer a workaround.
  3. Suggest the workaround to be documented, or a code change to account for this scenario.

Context

The connect function of use-metamask expects to receive an object that can be instantiated with new. Link to connect's source code

Screen Shot 2021-12-29 at 00 01 00

Working example using web3 or ethers:

import Web3 from "web3"; // or import { ethers } from "ethers";

const { connect, metaState } = useMetamask();
connect(Web3); // or connect(ethers.providers.Web3Provider);

Problem

Alchemy Web3 offers a factory function to instantiate the Web3 provider, as opposed to letting programmers create it using the new keyword. Passing that web3 instance to the connect function of useMetamask doesn't work.

// Doesn't work, throws an error
import { createAlchemyWeb3 } from '@alch/alchemy-web3';

const web3 = createAlchemyWeb3('https://eth-mainnet.alchemyapi.io/<api-key>');

connect(web3); // throws an error

Error stack trace:

Screen Shot 2021-12-29 at 00 05 49

Workaround

Create a constructor that returns the existing instance, and pass it to connect:

const web3 = createAlchemyWeb3('https://eth-mainnet.alchemyapi.io/<api-key>');

function Web3Wrapper() {
  return web3;
}

const { connect, metaState } = useMetamask();
connect(Web3Wrapper);

For more context, here is where I'm applying the workaround in my project. Note that the project is unfinished.

Next steps

If I didn't miss anything, I would propose documenting this workaround on the README, for having better developer experience. Depending on how common the factory function pattern is across libraries, it might make sense to update the connect function.

Cheers

'Component is not mounted' error when calling connect() from an onClick handler

EDIT: Seems to be an issue with React 18. Possible workaround would be to remove the Reac.StricMode component wrapping the app (not recommended).

Hi. I'm getting the following error when calling the connect() function from anything other than the initial useEffect hook:
image

I tested this just using an out-of-the-box create-react-app, so I'm not sure what's going on. Seems something really simple to need to add a workaround. Using React 18.2.

import logo from "./logo.svg";
import "./App.css";
import { useMetamask } from "use-metamask";
import { ethers } from "ethers";

function App() {
  const { connect } = useMetamask();

  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <button
          onClick={async () => {
            await connect(ethers.providers.Web3Provider, "any");
          }}
        >
          Click me!
        </button>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import { MetamaskStateProvider } from "use-metamask";

import reportWebVitals from "./reportWebVitals";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
    <MetamaskStateProvider>
      <App />
    </MetamaskStateProvider>
  </React.StrictMode>
);

Would it be possible to build a version without Context and simply useState instead?

Hello, first of all, thanks a lot for your work on this library.

Secondly, I'm wondering if it wouldn't be possible to instead use only useState inside of the hook or change the hook implementation in order to remove the "wrap your app in this context" requirement...

I find that requiring a user to wrap the application in a "context/state component" can start clogging the overall app.

✌️

Missing dependency when build with vite

I'm building a website with the latest version of [email protected] and [email protected].

I'm seeing the following error:
Uncaught ReferenceError: regeneratorRuntime is not defined

this is the line 93:
Uncaught ReferenceError: regeneratorRuntime is not defined - regeneratorRuntime.mark(function _callee(Web3Interface)

after a little bit of googling I saw that create-react-app has somewhere this package: regenerator runtime since I'm not using creat-react-app I don't have that package.

I don't know why, but on Firefox sometimes the website works... and sometimes it doesn't.

All my code works fine if I try create-react-app, but with vite it does not. I can create a stackblitz if you please, just let me know.

I fix this bug adding regenerator runtime to my website. even if I'm not using it I just import it on my entry point and eventing works fine.

Cheers! 🍻

NextJS Error Cannot read properties of null (reading 'useReducer')

With a fresh NextJS w/typescript installation, I'm trying

import '../styles/globals.css';
import type { AppProps } from 'next/app';
import { MetamaskStateProvider } from 'use-metamask';

function MyApp({ Component, pageProps }: AppProps) {
  return (
    <MetamaskStateProvider>
      <Component {...pageProps} />
    </MetamaskStateProvider>
  );
}

export default MyApp;

and getting

Warning: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
TypeError: Cannot read properties of null (reading 'useReducer')

Any help is much obliged.

Edit: Fixed

TypeError: #<Object> is not a constructor

I'm getting this error the first time using this package. I'm using the ethers Web3Interface

TypeError: #<Object> is not a constructor
    at _construct (useMetamask.js:18:1)
    at _callee$ (useMetamask.js:137:1)
    at tryCatch (runtime.js:63:1)
    at Generator.invoke [as _invoke] (runtime.js:294:1)
    at Generator.next (runtime.js:119:1)
    at asyncGeneratorStep (useMetamask.js:32:1)
    at _next (useMetamask.js:34:1)
    at useMetamask.js:34:1
    at new Promise (<anonymous>)
    at useMetamask.js:34:1

How can I resolve this issue?

Integration with NextJS

Hello, this project seems to be very good, do you know how I could integrate this library in a project with Next?

Thanks

update isConnected silently

Note: If you would like to check if Metamask is whether already connected to your dapp or not , you can call getAccounts method beforehand.

Calling getAccounts will still popup the plugin window of Metamask.
Is it possible to update the connecting status( isConnected ) silently as isConnected won't be updated automatically after refreshing the page.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.