mdtanrikulu / use-metamask Goto Github PK
View Code? Open in Web Editor NEWa custom React Hook to manage Metamask in Ethereum ĐApp projects
Home Page: https://mdtanrikulu.github.io/use-metamask
License: MIT License
a custom React Hook to manage Metamask in Ethereum ĐApp projects
Home Page: https://mdtanrikulu.github.io/use-metamask
License: MIT License
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?
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.
}
To be able to awaiting transactions in UI, give an abstracted event handler or tx lifetime state. So user can be informed based on it.
Be able to change chains
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.
✌️
use-metamask/src/useMetamask.js
Lines 89 to 92 in af4f218
Param method
is expected to be eth_chainId
, according to MetaMask document:
If you need to retrieve the current chain ID, use ethereum.request({ method: 'eth_chainId' }). See also the chainChanged event for more information about how to handle chain IDs.
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:
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>
);
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
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:
The connect
function of use-metamask
expects to receive an object that can be instantiated with new
. Link to connect
's source code
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);
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:
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.
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
I am unable to get this package to work when I have both metamask and coinbase wallet as an extension.
Hello, this project seems to be very good, do you know how I could integrate this library in a project with Next?
Thanks
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 ?
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.
I'm building a website with the latest version of [email protected] and [email protected].
I'm seeing the following error:
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! 🍻
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.