Skip to content

Commit

Permalink
Improve wallet connect (#54)
Browse files Browse the repository at this point in the history
* add reconnect once connected, also connect on accountschanged

* fix : format code
  • Loading branch information
eenagy authored May 1, 2021
1 parent 900c810 commit f77f131
Showing 1 changed file with 57 additions and 20 deletions.
77 changes: 57 additions & 20 deletions contexts/user.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import React, { createContext, useState } from 'react';
import React, {
createContext,
useState,
useEffect,
useMemo,
useCallback,
} from 'react';
import PropTypes from 'prop-types';
import { ethers } from 'ethers';
import Web3Modal from 'web3modal';
import Web3Modal, { getInjectedProvider } from 'web3modal';

const DefaultUser = {
address: '',
Expand All @@ -12,27 +18,58 @@ const UserContext = createContext(DefaultUser);
export const UserProvider = ({ children }) => {
// const [currentAddress, setAddress] = useState(DefaultUser.currentAddress);
const [provider, setProvider] = useState();
const [web3Provider, setWeb3Provider] = useState();
const [signer, setSigner] = useState();
const [address, setAddress] = useState();

const getWeb3ModalProvider = async () => {
const providerOptions = {};
const web3Modal = new Web3Modal({
cacheProvider: false,
providerOptions, // required
});
return await web3Modal.connect();
};

const connect = async () => {
const provider = await getWeb3ModalProvider();
const web3provider = new ethers.providers.Web3Provider(provider);
const _signer = await web3provider.getSigner();
setSigner(_signer);
setAddress((await _signer.getAddress()).toLowerCase());
setProvider(web3provider);
return Promise.resolve(web3provider);
};
const providerOptions = {};
// web3modal is only working in browser\]
const web3Modal = useMemo(() => {
return typeof window !== 'undefined'
? new Web3Modal({
cacheProvider: false,
providerOptions, // required
})
: null;
}, [typeof window]);

// TODO connect only works if metamask is installed, otherwise it just creates a grayed empty popup
const connect = useCallback(async () => {
if (web3Modal) {
const provider = await web3Modal.connect();
const web3provider = new ethers.providers.Web3Provider(provider);
const _signer = await web3provider.getSigner();
setSigner(_signer);
setAddress((await _signer.getAddress()).toLowerCase());
setProvider(provider);
setWeb3Provider(web3Provider);
return Promise.resolve(web3provider);
}
}, [web3Modal]);

// reconnect if connected once
// this is necessary, because metamask window shows connected state in it's wallet
// this will not connect if never connected or clicked on disconnect, try it in private window
useEffect(() => {
const injectedProvider = getInjectedProvider();
if (web3Modal) {
if (injectedProvider && !provider) {
connect();
}
}
}, [web3Modal]);

// change account
useEffect(() => {
if (provider) {
provider.on('accountsChanged', connect);
}
return () => {
if (provider) {
provider.off('accountsChanged', connect);
}
};
}, [provider]);

return (
<UserContext.Provider value={{ connect, provider, signer, address }}>
Expand Down

1 comment on commit f77f131

@vercel
Copy link

@vercel vercel bot commented on f77f131 May 1, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.