Merge pull request #24 from yamijuan/wallet-connect

Wallet connect
This commit is contained in:
B 2021-03-17 20:35:44 -05:00 committed by GitHub
commit c17300e8a9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 137 additions and 75 deletions

View File

@ -0,0 +1,44 @@
import React from 'react';
import { Button } from 'antd';
import { useCorrectNetwork } from '../../hooks/useCorrectNetwork';
import metamaskIcon from '../../assets/metamask.svg';
import { shortenAddress } from '@oyster/common';
import { useEthereum } from '../../contexts';
export const EthereumConnect = () => {
const { accounts, onConnectEthereum, connected } = useEthereum();
const { hasCorrespondingNetworks } = useCorrectNetwork();
return (
<div style={{ marginRight: 8 }}>
{connected ? (
hasCorrespondingNetworks ? (
<>
<img
alt={'metamask-icon'}
width={20}
height={20}
src={metamaskIcon}
/>
{shortenAddress(accounts[0], 4)}
</>
) : (
<Button danger type={'primary'}>
WRONG NETWORK
</Button>
)
) : (
<Button onClick={() => onConnectEthereum && onConnectEthereum()}>
<img
alt={'metamask-icon'}
width={20}
height={20}
src={metamaskIcon}
/>
Connect Metamask
</Button>
)}
</div>
);
};

View File

@ -11,15 +11,17 @@ export const Footer = () => {
<SecurityAuditButton />
<Button
shape={'circle'}
target={'_blank'}
href={'https://github.com/solana-labs/oyster'}
icon={<GithubOutlined />}
style={{ marginRight: '20px' }}
onClick={() => window.open('https://github.com/solana-labs/oyster', '_blank')}
>
</Button>
<Button shape={'circle'}
icon={<TwitterOutlined />}
onClick={() => window.open('https://twitter.com/solana', '_blank')}>
</Button>
></Button>
<Button
shape={'circle'}
target={'_blank'}
href={'https://twitter.com/solana'}
icon={<TwitterOutlined />}
></Button>
</div>
);
};

View File

@ -6,20 +6,16 @@ import { Link, useLocation } from 'react-router-dom';
import metamaskIcon from '../../assets/metamask.svg';
import { LABELS } from '../../constants';
import { contexts, AppBar, shortenAddress, useWallet } from '@oyster/common';
import { AppBar } from '@oyster/common';
import Wormhole from '../Wormhole';
import { useEthereum } from '../../contexts';
import { useCorrectNetwork } from '../../hooks/useCorrectNetwork';
import { Footer as AppFooter } from './../Footer';
import { EthereumConnect } from '../EthereumConnect';
const { Header, Content, Footer } = Layout;
const { useConnectionConfig } = contexts.Connection;
export const AppLayout = React.memo((props: any) => {
const location = useLocation();
const [wormholeReady, setWormholeReady] = useState(false);
const { accounts, provider } = useEthereum();
const hasCorrespondingNetworks = useCorrectNetwork();
const paths: { [key: string]: string } = {
'/faucet': '7',
@ -46,32 +42,7 @@ export const AppLayout = React.memo((props: any) => {
<h2>WORMHOLE</h2>
</Link>
</div>
<AppBar
useWalletBadge={true}
left={
<>
{accounts[0] && (
<div style={{ marginRight: 8 }}>
{hasCorrespondingNetworks ? (
<>
<img
alt={'metamask-icon'}
width={20}
height={20}
src={metamaskIcon}
/>
{shortenAddress(accounts[0], 4)}
</>
) : (
<Button danger type={'primary'}>
WRONG NETWORK
</Button>
)}
</div>
)}
</>
}
/>
<AppBar useWalletBadge={true} left={<EthereumConnect />} />
</Header>
)}
<Content style={{ padding: '0 50px', flexDirection: 'column' }}>

View File

@ -5,8 +5,11 @@ import './index.less';
export const SecurityAuditButton = () => {
return (
<Button className={'audit-button'}
onClick={() => window.open('https://github.com/certusone/wormhole', '_blank')}>
<Button
className={'audit-button'}
target={'_blank'}
href={'https://github.com/certusone/wormhole'}
>
Security Audit
</Button>
);

View File

@ -5,7 +5,12 @@ import { Input } from '../Input';
import './style.less';
import { ASSET_CHAIN, chainToName } from '../../utils/assets';
import { fromSolana, ProgressUpdate, toSolana, TransferRequest } from '../../models/bridge';
import {
fromSolana,
ProgressUpdate,
toSolana,
TransferRequest,
} from '../../models/bridge';
import { useEthereum } from '../../contexts';
import { TokenDisplay } from '../TokenDisplay';
import { WrappedAssetFactory } from '../../contracts/WrappedAssetFactory';
@ -89,8 +94,7 @@ export const Transfer = () => {
return;
}
try {
if(request.from === ASSET_CHAIN.Solana) {
if (request.from === ASSET_CHAIN.Solana) {
const bridgeAddress = programIds().wormhole.bridge;
let signer = provider.getSigner();
@ -235,7 +239,7 @@ export const Transfer = () => {
(async () => {
let steps: ProgressUpdate[] = [];
try {
if(request.from === ASSET_CHAIN.Solana) {
if (request.from === ASSET_CHAIN.Solana) {
debugger;
await fromSolana(
connection,

View File

@ -20,7 +20,7 @@ const WormholeCanvas = ({
<Canvas onCreated={onCreated} style={{ opacity: 0.4 }}>
<Camera />
<React.Suspense fallback={null}>
<WormholeGeometry rotate={rotate}/>
<WormholeGeometry rotate={rotate} />
</React.Suspense>
</Canvas>
);

View File

@ -13,7 +13,6 @@ import { useWallet as useEthereumWallet } from 'use-wallet';
import WalletConnectProvider from '@walletconnect/web3-provider';
// @ts-ignore
import Fortmatic from 'fortmatic';
import Torus from '@toruslabs/torus-embed';
import { useConnectionConfig, useWallet, ENV } from '@oyster/common';
import { TokenList, TokenInfo } from '@uniswap/token-lists';
import { ethers } from 'ethers';
@ -24,20 +23,27 @@ export interface EthereumContextState {
tokens: TokenInfo[];
tokenMap: Map<string, TokenInfo>;
accounts: string[];
connected: boolean;
chainId: number;
onConnectEthereum?: () => void;
}
export const EthereumContext = createContext<EthereumContextState>({
tokens: [],
tokenMap: new Map<string, TokenInfo>(),
accounts: [''],
chainId: 0,
connected: false,
});
export const EthereumProvider: FunctionComponent = ({ children }) => {
const [accounts, setAccounts] = useState<string[]>(['']);
const [provider, setProvider] = useState<ethers.providers.Web3Provider>();
const { env } = useConnectionConfig();
const { connected } = useWallet();
const wallet = useEthereumWallet();
const [connected, setConnected] = useState<boolean>(false);
const [chainId, setChainId] = useState<number>(0);
//const { env } = useConnectionConfig();
const { connected: walletConnected } = useWallet();
//const wallet = useEthereumWallet();
const [tokens, setTokens] = useState<{
map: Map<string, TokenInfo>;
list: TokenInfo[];
@ -94,26 +100,59 @@ export const EthereumProvider: FunctionComponent = ({ children }) => {
})();
}, [setTokens]);
const onConnectEthereum = () => {
// @ts-ignore
window.ethereum.request({ method: 'eth_requestAccounts' }).then(() => {
// @ts-ignore
const provider = new ethers.providers.Web3Provider(
(window as any).ethereum,
);
const signer = provider.getSigner();
signer.getAddress().then(account => {
setAccounts([account]);
setConnected(true);
});
provider.getNetwork().then(network => {
setChainId(network.chainId);
});
setProvider(provider);
});
};
useEffect(() => {
if (connected) {
// @ts-ignore
window.ethereum.enable().then(() => {
// @ts-ignore
const provider = new ethers.providers.Web3Provider(
(window as any).ethereum,
);
const signer = provider.getSigner();
signer.getAddress().then(account => {
setAccounts([account]);
});
setProvider(provider);
window.ethereum.on('disconnect', error => {
setConnected(false);
});
// @ts-ignore
window.ethereum.on('accountsChanged', accounts => {
if (!accounts || !accounts[0]) setConnected(false);
});
// @ts-ignore
window.ethereum.on('chainChanged', (chainId: string) => {
setChainId(parseInt(chainId, 16));
});
}
}, [connected]);
useEffect(() => {
if (walletConnected && !connected) {
onConnectEthereum();
}
}, [walletConnected]);
return (
<EthereumContext.Provider
value={{ tokens: tokens.list, tokenMap: tokens.map, accounts, provider }}
value={{
tokens: tokens.list,
tokenMap: tokens.map,
accounts,
provider,
connected,
chainId,
onConnectEthereum: () => onConnectEthereum(),
}}
>
{children}
</EthereumContext.Provider>

View File

@ -7,22 +7,21 @@ export const useCorrectNetwork = () => {
const [hasCorrespondingNetworks, setHasCorrespondingNetworks] = useState(
true,
);
const { provider } = useEthereum();
const { connected, chainId } = useEthereum();
useEffect(() => {
if (provider) {
provider.getNetwork().then(network => {
if (network.chainId === 5) {
setHasCorrespondingNetworks(env === 'testnet');
} else if (network.chainId === 1) {
setHasCorrespondingNetworks(env === 'mainnet-beta');
} else {
setHasCorrespondingNetworks(false);
}
});
if (connected) {
if (chainId === 5) {
setHasCorrespondingNetworks(env === 'testnet');
} else if (chainId === 1) {
setHasCorrespondingNetworks(env === 'mainnet-beta');
} else {
setHasCorrespondingNetworks(false);
}
} else {
setHasCorrespondingNetworks(true);
}
setHasCorrespondingNetworks(true);
}, [provider, env]);
}, [connected, env, chainId]);
return hasCorrespondingNetworks;
return { hasCorrespondingNetworks };
};