This commit is contained in:
bartosz-lipinski 2021-03-17 20:49:55 -05:00
commit 1d446c1640
8 changed files with 137 additions and 74 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 /> <SecurityAuditButton />
<Button <Button
shape={'circle'} shape={'circle'}
target={'_blank'}
href={'https://github.com/solana-labs/oyster'}
icon={<GithubOutlined />} icon={<GithubOutlined />}
style={{ marginRight: '20px' }} style={{ marginRight: '20px' }}
onClick={() => window.open('https://github.com/solana-labs/oyster', '_blank')} ></Button>
> <Button
</Button> shape={'circle'}
<Button shape={'circle'} target={'_blank'}
icon={<TwitterOutlined />} href={'https://twitter.com/solana'}
onClick={() => window.open('https://twitter.com/solana', '_blank')}> icon={<TwitterOutlined />}
</Button> ></Button>
</div> </div>
); );
}; };

View File

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

View File

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

View File

@ -5,7 +5,12 @@ import { Input } from '../Input';
import './style.less'; import './style.less';
import { ASSET_CHAIN, chainToName } from '../../utils/assets'; 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 { useEthereum } from '../../contexts';
import { TokenDisplay } from '../TokenDisplay'; import { TokenDisplay } from '../TokenDisplay';
import { WrappedAssetFactory } from '../../contracts/WrappedAssetFactory'; import { WrappedAssetFactory } from '../../contracts/WrappedAssetFactory';
@ -93,7 +98,7 @@ export const Transfer = () => {
try { try {
const bridgeAddress = programIds().wormhole.bridge; const bridgeAddress = programIds().wormhole.bridge;
if(request.from === ASSET_CHAIN.Solana) { if (request.from === ASSET_CHAIN.Solana) {
let signer = provider.getSigner(); let signer = provider.getSigner();
let e = WrappedAssetFactory.connect(asset, provider); let e = WrappedAssetFactory.connect(asset, provider);
@ -243,7 +248,7 @@ export const Transfer = () => {
(async () => { (async () => {
let steps: ProgressUpdate[] = []; let steps: ProgressUpdate[] = [];
try { try {
if(request.from === ASSET_CHAIN.Solana) { if (request.from === ASSET_CHAIN.Solana) {
debugger; debugger;
await fromSolana( await fromSolana(
connection, connection,

View File

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

View File

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

View File

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