Merge pull request #29 from yamijuan/wallet-connect-2nd

Added disconnect and change wallet for eth
This commit is contained in:
B 2021-03-19 18:24:48 -05:00 committed by GitHub
commit ed660edc5d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 119 additions and 56 deletions

View File

@ -1,14 +1,28 @@
import React from 'react'; import React from 'react';
import { Button } from 'antd'; import { Button, Dropdown, Menu } from 'antd';
import { useCorrectNetwork } from '../../hooks/useCorrectNetwork'; import { useCorrectNetwork } from '../../hooks/useCorrectNetwork';
import { shortenAddress } from '@oyster/common'; import { shortenAddress } from '@oyster/common';
import { useEthereum } from '../../contexts'; import { useEthereum } from '../../contexts';
export const EthereumConnect = () => { export const EthereumConnect = () => {
const { accounts, onConnectEthereum, connected, walletProvider } = useEthereum(); const {
accounts,
onConnectEthereum,
connected,
walletProvider,
select,
} = useEthereum();
const { hasCorrespondingNetworks } = useCorrectNetwork(); const { hasCorrespondingNetworks } = useCorrectNetwork();
const menu = (
<Menu>
<Menu.Item key="3" onClick={select}>
Change Eth Wallet
</Menu.Item>
</Menu>
);
return ( return (
<div style={{ marginRight: 8 }}> <div style={{ marginRight: 8 }}>
{connected ? ( {connected ? (
@ -28,6 +42,13 @@ export const EthereumConnect = () => {
WRONG NETWORK WRONG NETWORK
</Button> </Button>
) )
) : !!walletProvider ? (
<Dropdown.Button
onClick={() => onConnectEthereum && onConnectEthereum()}
overlay={menu}
>
Connect Ethereum
</Dropdown.Button>
) : ( ) : (
<Button onClick={() => onConnectEthereum && onConnectEthereum()}> <Button onClick={() => onConnectEthereum && onConnectEthereum()}>
Connect Ethereum Connect Ethereum

View File

@ -9,10 +9,12 @@ import { AppBar } from '@oyster/common';
import Wormhole from '../Wormhole'; import Wormhole from '../Wormhole';
import { Footer as AppFooter } from './../Footer'; import { Footer as AppFooter } from './../Footer';
import { EthereumConnect } from '../EthereumConnect'; import { EthereumConnect } from '../EthereumConnect';
import { useEthereum } from '../../contexts';
const { Header, Content, Footer } = Layout; const { Header, Content, Footer } = Layout;
export const AppLayout = React.memo((props: any) => { export const AppLayout = React.memo((props: any) => {
const { connected, disconnect } = useEthereum();
const location = useLocation(); const location = useLocation();
const [wormholeReady, setWormholeReady] = useState(false); const [wormholeReady, setWormholeReady] = useState(false);
@ -41,7 +43,21 @@ export const AppLayout = React.memo((props: any) => {
<h2>WORMHOLE</h2> <h2>WORMHOLE</h2>
</Link> </Link>
</div> </div>
<AppBar useWalletBadge={true} left={<EthereumConnect />} /> <AppBar
additionalSettings={
connected ? (
<Button
type="primary"
onClick={() => disconnect()}
style={{ marginTop: '8px' }}
>
Disconnect ETH
</Button>
) : undefined
}
useWalletBadge={true}
left={<EthereumConnect />}
/>
</Header> </Header>
)} )}
<Content style={{ padding: '0 50px', flexDirection: 'column' }}> <Content style={{ padding: '0 50px', flexDirection: 'column' }}>

View File

@ -119,7 +119,7 @@ export const TokenSelectModal = (props: {
visible={isModalVisible} visible={isModalVisible}
onCancel={() => hideModal()} onCancel={() => hideModal()}
footer={null} footer={null}
className={"token-select-modal"} className={'token-select-modal'}
> >
<Input <Input
autoFocus autoFocus

View File

@ -86,7 +86,12 @@ export const Transfer = () => {
useEffect(() => { useEffect(() => {
const asset = mintAddress; const asset = mintAddress;
if (!asset || (asset === request?.info?.address && request.from === from && request.toChain === toChain)) { if (
!asset ||
(asset === request?.info?.address &&
request.from === from &&
request.toChain === toChain)
) {
return; return;
} }
@ -99,7 +104,6 @@ export const Transfer = () => {
try { try {
const bridgeAddress = programIds().wormhole.bridge; const bridgeAddress = programIds().wormhole.bridge;
if (from === ASSET_CHAIN.Ethereum) { if (from === ASSET_CHAIN.Ethereum) {
let signer = provider.getSigner(); let signer = provider.getSigner();
let e = WrappedAssetFactory.connect(asset, provider); let e = WrappedAssetFactory.connect(asset, provider);
let addr = await signer.getAddress(); let addr = await signer.getAddress();

View File

@ -1,8 +1,4 @@
import React, { import React, { createContext, FunctionComponent, useContext } from 'react';
createContext,
FunctionComponent,
useContext,
} from 'react';
import { SolanaBridge } from '../core'; import { SolanaBridge } from '../core';
import { import {
useConnection, useConnection,

View File

@ -14,13 +14,13 @@ import { useWallet as useEthereumWallet } from 'use-wallet';
import WalletConnectProvider from '@walletconnect/web3-provider'; import WalletConnectProvider from '@walletconnect/web3-provider';
// @ts-ignore // @ts-ignore
import Fortmatic from 'fortmatic'; import Fortmatic from 'fortmatic';
import { useWallet, useLocalStorageState} from '@oyster/common'; import { useWallet, useLocalStorageState } from '@oyster/common';
import { WalletAdapter } from '@solana/wallet-base' import { WalletAdapter } from '@solana/wallet-base';
import { TokenList, TokenInfo } from '@uniswap/token-lists'; import { TokenList, TokenInfo } from '@uniswap/token-lists';
import { ethers } from 'ethers'; import { ethers } from 'ethers';
import { MetamaskWalletAdapter } from '../wallet-adapters/metamask'; import { MetamaskWalletAdapter } from '../wallet-adapters/metamask';
import { Button, Modal } from 'antd'; import { Button, Modal } from 'antd';
import {WalletConnectWalletAdapter} from "../wallet-adapters/wallet-connect"; import { WalletConnectWalletAdapter } from '../wallet-adapters/wallet-connect';
const ASSETS_URL = const ASSETS_URL =
'https://raw.githubusercontent.com/solana-labs/oyster/main/assets/wallets/'; 'https://raw.githubusercontent.com/solana-labs/oyster/main/assets/wallets/';
@ -48,6 +48,8 @@ export interface EthereumContextState {
connected: boolean; connected: boolean;
chainId: number; chainId: number;
walletProvider: any; walletProvider: any;
select: () => void;
disconnect: () => void;
onConnectEthereum?: () => void; onConnectEthereum?: () => void;
} }
@ -57,6 +59,8 @@ export const EthereumContext = createContext<EthereumContextState>({
accounts: [''], accounts: [''],
chainId: 0, chainId: 0,
connected: false, connected: false,
select() {},
disconnect() {},
walletProvider: null, walletProvider: null,
}); });
@ -142,12 +146,12 @@ export const EthereumProvider: FunctionComponent = ({ children }) => {
}, [setTokens]); }, [setTokens]);
const onConnectEthereum = useCallback(() => { const onConnectEthereum = useCallback(() => {
if (wallet && providerUrl) { if (wallet && providerUrl && !connected) {
wallet.connect(); wallet.connect();
} else { } else if (!connected) {
select(); select();
} }
}, [wallet, providerUrl]); }, [wallet, connected, providerUrl]);
useEffect(() => { useEffect(() => {
if (wallet) { if (wallet) {
@ -162,6 +166,11 @@ export const EthereumProvider: FunctionComponent = ({ children }) => {
}); });
wallet.on('disconnect', error => { wallet.on('disconnect', error => {
setConnected(false); setConnected(false);
setAccounts([]);
// @ts-ignore
setChainId(0);
// @ts-ignore
setProvider(null);
}); });
// @ts-ignore // @ts-ignore
wallet.on('accountsChanged', accounts => { wallet.on('accountsChanged', accounts => {
@ -184,10 +193,10 @@ export const EthereumProvider: FunctionComponent = ({ children }) => {
const close = useCallback(() => setIsModalVisible(false), []); const close = useCallback(() => setIsModalVisible(false), []);
useEffect(() => { useEffect(() => {
if (walletConnected && !connected) { if (walletConnected) {
onConnectEthereum(); onConnectEthereum();
} }
}, [walletConnected, connected, providerUrl]); }, [walletConnected, providerUrl]);
return ( return (
<EthereumContext.Provider <EthereumContext.Provider
@ -199,6 +208,8 @@ export const EthereumProvider: FunctionComponent = ({ children }) => {
connected, connected,
chainId, chainId,
walletProvider, walletProvider,
select,
disconnect: () => wallet?.disconnect(),
onConnectEthereum: () => onConnectEthereum(), onConnectEthereum: () => onConnectEthereum(),
}} }}
> >

View File

@ -81,7 +81,7 @@ export const HomeView = () => {
style: {}, style: {},
}, },
children: ( children: (
<a href={record.explorer} target="_blank" rel="noopener noreferrer" > <a href={record.explorer} target="_blank" rel="noopener noreferrer">
{shortenAddress(text, 6)} {shortenAddress(text, 6)}
</a> </a>
), ),
@ -98,7 +98,11 @@ export const HomeView = () => {
style: {}, style: {},
}, },
children: ( children: (
<a href={record.wrappedExplorer} target="_blank" rel="noopener noreferrer" > <a
href={record.wrappedExplorer}
target="_blank"
rel="noopener noreferrer"
>
{shortenAddress(text, 6)} {shortenAddress(text, 6)}
</a> </a>
), ),

View File

@ -1,7 +1,7 @@
import EventEmitter from 'eventemitter3'; import EventEmitter from 'eventemitter3';
import { PublicKey, Transaction } from '@solana/web3.js'; import { PublicKey, Transaction } from '@solana/web3.js';
import { notify } from '@oyster/common'; import { notify } from '@oyster/common';
import { WalletAdapter } from '@solana/wallet-base' import { WalletAdapter } from '@solana/wallet-base';
import { ethers } from 'ethers'; import { ethers } from 'ethers';
export class MetamaskWalletAdapter export class MetamaskWalletAdapter
@ -95,8 +95,9 @@ export class MetamaskWalletAdapter
} }
disconnect() { disconnect() {
if (this._publicKey) { if (this._provider) {
this._publicKey = null; this._publicKey = null;
this._provider = null;
this.emit('disconnect'); this.emit('disconnect');
} }
} }

View File

@ -1,9 +1,9 @@
import EventEmitter from 'eventemitter3'; import EventEmitter from 'eventemitter3';
import { PublicKey, Transaction } from '@solana/web3.js'; import { PublicKey, Transaction } from '@solana/web3.js';
import { notify } from '@oyster/common'; import { notify } from '@oyster/common';
import { WalletAdapter } from '@solana/wallet-base' import { WalletAdapter } from '@solana/wallet-base';
import { ethers } from 'ethers'; import { ethers } from 'ethers';
import WalletConnectProvider from "@walletconnect/web3-provider"; import WalletConnectProvider from '@walletconnect/web3-provider';
export class WalletConnectWalletAdapter export class WalletConnectWalletAdapter
extends EventEmitter extends EventEmitter
@ -13,11 +13,13 @@ export class WalletConnectWalletAdapter
_accounts: Array<any>; _accounts: Array<any>;
_chainID: number; _chainID: number;
_provider: any; _provider: any;
_walletProvider: any;
constructor() { constructor() {
super(); super();
this._publicKey = null; this._publicKey = null;
this._provider = null; this._provider = null;
this._walletProvider = null;
this._accounts = []; this._accounts = [];
this._chainID = 0; this._chainID = 0;
this._onProcess = false; this._onProcess = false;
@ -53,44 +55,52 @@ export class WalletConnectWalletAdapter
// Create WalletConnect Provider // Create WalletConnect Provider
const walletConnectProvider = new WalletConnectProvider({ const walletConnectProvider = new WalletConnectProvider({
infuraId: "535ab8649e9f40cface13cbded7d647e", infuraId: '535ab8649e9f40cface13cbded7d647e',
}); });
walletConnectProvider.enable().then(()=>{ walletConnectProvider
const provider = new ethers.providers.Web3Provider(walletConnectProvider); .enable()
const signer = provider.getSigner(); .then(() => {
signer.getAddress().then(account => { const provider = new ethers.providers.Web3Provider(
this._accounts = [account]; walletConnectProvider,
provider.getNetwork().then(network => { );
this._chainID = network.chainId; const signer = provider.getSigner();
this._provider = provider; signer.getAddress().then(account => {
this.emit('connect'); this._accounts = [account];
provider.getNetwork().then(network => {
this._chainID = network.chainId;
this._provider = provider;
this._walletProvider = walletConnectProvider;
this.emit('connect');
});
}); });
// @ts-ignore
walletConnectProvider.on(
'disconnect',
(code: number, reason: string) => {
this.emit('disconnect', { code, reason });
},
);
// @ts-ignore
walletConnectProvider.on('accountsChanged', (accounts: string[]) => {
this.emit('accountsChanged', accounts);
});
// @ts-ignore
walletConnectProvider.on('chainChanged', (chainId: number) => {
this.emit('chainChanged', chainId);
});
})
.catch(() => {
this.disconnect();
})
.finally(() => {
this._onProcess = false;
}); });
// @ts-ignore
walletConnectProvider.on('disconnect', (code: number, reason: string) => {
this.emit('disconnect', {code, reason});
});
// @ts-ignore
walletConnectProvider.on('accountsChanged', (accounts: string[]) => {
this.emit('accountsChanged', accounts);
});
// @ts-ignore
walletConnectProvider.on('chainChanged', (chainId: number) => {
this.emit('chainChanged', chainId);
});
})
.catch(() => {
this.disconnect();
})
.finally(() => {
this._onProcess = false;
});
} }
disconnect() { disconnect() {
if (this._publicKey) { if (this._provider) {
this._publicKey = null; this._publicKey = null;
this._walletProvider.disconnect();
this.emit('disconnect'); this.emit('disconnect');
} }
} }