This commit is contained in:
bartosz-lipinski 2021-03-12 16:20:26 -06:00
commit 5b123a4ebf
8 changed files with 131 additions and 80 deletions

View File

@ -1,23 +1,24 @@
import React, { useState } from 'react';
import React, { useEffect, useState } from 'react';
import './../../App.less';
import './index.less';
import { Layout } from 'antd';
import { Layout, Button } from 'antd';
import { Link, useLocation } from 'react-router-dom';
import metamaskIcon from '../../assets/metamask.svg';
import { LABELS } from '../../constants';
import { contexts, AppBar, shortenAddress } from '@oyster/common';
import { contexts, AppBar, shortenAddress, useWallet } from '@oyster/common';
import Wormhole from '../Wormhole';
import { useEthereum } from '../../contexts';
import { useCorrectNetwork } from '../../hooks/useCorrectNetwork';
const { Header, Content } = Layout;
const { useConnectionConfig } = contexts.Connection;
export const AppLayout = React.memo((props: any) => {
const { env } = useConnectionConfig();
const location = useLocation();
const [wormholeReady, setWormholeReady] = useState(false);
const { accounts } = useEthereum();
const { accounts, provider } = useEthereum();
const hasCorrespondingNetworks = useCorrectNetwork();
const paths: { [key: string]: string } = {
'/faucet': '7',
@ -48,15 +49,22 @@ export const AppLayout = React.memo((props: any) => {
left={
<>
{accounts[0] && (
<div>
<img
alt={'metamask-icon'}
width={20}
height={20}
src={metamaskIcon}
style={{ marginRight: 8 }}
/>
{shortenAddress(accounts[0], 4)}
<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>
)}
</>

View File

@ -5,6 +5,7 @@ import {
ConnectButton,
programIds,
formatAmount,
notify,
} from '@oyster/common';
import { Input } from './../Input';
@ -17,6 +18,8 @@ import { WrappedAssetFactory } from '../../contracts/WrappedAssetFactory';
import { WormholeFactory } from '../../contracts/WormholeFactory';
import BN from 'bn.js';
import { useTokenChainPairState } from '../../contexts/chainPair';
import { LABELS } from '../../constants';
import { useCorrectNetwork } from '../../hooks/useCorrectNetwork';
const { useConnection } = contexts.Connection;
const { useWallet } = contexts.Wallet;
@ -40,7 +43,8 @@ export const typeToIcon = (type: string, isLast: boolean) => {
export const Transfer = () => {
const connection = useConnection();
const { wallet } = useWallet();
const { provider, tokenMap, tokens } = useEthereum();
const { provider, accounts, tokenMap } = useEthereum();
const hasCorrespondingNetworks = useCorrectNetwork();
const {
A,
B,
@ -87,54 +91,62 @@ export const Transfer = () => {
}
(async () => {
if (!provider) {
if (!provider || !accounts[0]) {
return;
}
try {
const bridgeAddress = programIds().wormhole.bridge;
const bridgeAddress = programIds().wormhole.bridge;
let signer = provider.getSigner();
let e = WrappedAssetFactory.connect(asset, provider);
let addr = await signer.getAddress();
let balance = await e.balanceOf(addr);
let decimals = await e.decimals();
let symbol = await e.symbol();
let signer = provider.getSigner();
let e = WrappedAssetFactory.connect(asset, provider);
let addr = await signer.getAddress();
let balance = await e.balanceOf(addr);
let decimals = await e.decimals();
let symbol = await e.symbol();
let allowance = await e.allowance(addr, bridgeAddress);
let allowance = await e.allowance(addr, bridgeAddress);
let info = {
address: asset,
name: symbol,
balance: balance,
balanceAsNumber:
new BN(balance.toString())
.div(new BN(10).pow(new BN(decimals - 2)))
.toNumber() / 100,
allowance: allowance,
decimals: decimals,
isWrapped: false,
chainID: ASSET_CHAIN.Ethereum,
assetAddress: Buffer.from(asset.slice(2), 'hex'),
mint: '',
};
let info = {
address: asset,
name: symbol,
balance: balance,
balanceAsNumber:
new BN(balance.toString())
.div(new BN(10).pow(new BN(decimals - 2)))
.toNumber() / 100,
allowance: allowance,
decimals: decimals,
isWrapped: false,
chainID: ASSET_CHAIN.Ethereum,
assetAddress: Buffer.from(asset.slice(2), 'hex'),
mint: '',
};
let b = WormholeFactory.connect(bridgeAddress, provider);
let b = WormholeFactory.connect(bridgeAddress, provider);
let isWrapped = await b.isWrappedAsset(asset);
if (isWrapped) {
info.chainID = await e.assetChain();
info.assetAddress = Buffer.from(
(await e.assetAddress()).slice(2),
'hex',
);
info.isWrapped = true;
}
let isWrapped = await b.isWrappedAsset(asset);
if (isWrapped) {
info.chainID = await e.assetChain();
info.assetAddress = Buffer.from(
(await e.assetAddress()).slice(2),
'hex',
);
info.isWrapped = true;
setRequest({
...request,
asset,
info,
});
} catch (e) {
console.error(e.toString());
notify({
message: `Error getting asset (${asset}) information`,
description: e.toString(),
type: 'error',
});
}
setRequest({
...request,
asset,
info,
});
})();
}, [request, provider]);
@ -193,6 +205,9 @@ export const Transfer = () => {
</div>
<ConnectButton
type="primary"
size="large"
style={{ width: '100%' }}
disabled={!(A.amount && B.amount)}
onClick={async () => {
if (!wallet || !provider) {
return;
@ -327,7 +342,11 @@ export const Transfer = () => {
});
}}
>
Transfer
{hasCorrespondingNetworks
? !(A.amount && B.amount)
? LABELS.ENTER_AMOUNT
: LABELS.TRANSFER
: LABELS.SET_CORRECT_WALLET_NETWORK}
</ConnectButton>
</>
);

View File

@ -17,4 +17,7 @@ export const LABELS = {
SETTINGS_TOOLTIP: 'Settings',
GO_BACK_ACTION: 'Go back',
TOTAL_TITLE: 'Total',
ENTER_AMOUNT: 'Enter an amount',
TRANSFER: 'Transfer',
SET_CORRECT_WALLET_NETWORK: 'Set correct wallet network',
};

View File

@ -62,7 +62,7 @@ function getDefaultTokens(tokens: TokenInfo[], search: string) {
const from = urlParams.get('from');
defaultChain = from === 'SOL' ? from : 'ETH';
const token = urlParams.get('token') || defaultToken;
if (nameToToken.has(token) || isValidAddress(token)) {
if (nameToToken.has(token)) {
defaultToken = token;
}
}
@ -116,35 +116,26 @@ export function TokenChainPairProvider({ children = null as any }) {
// updates browser history on token changes
useEffect(() => {
// set history
const token =
tokens.find(t => t.address === mintAddress)?.symbol || mintAddress;
const token = tokens.find(t => t.address === mintAddress)?.symbol;
if (token && chainA) {
history.push({
search: `?from=${toChainSymbol(chainA)}&token=${token}`,
});
} else {
if (mintAddress) {
history.push({
search: ``,
});
} else {
return;
}
}
}, [mintAddress, tokens, chainA]);
// Updates tokens on location change
useEffect(() => {
if (
!tokens.length ||
!ethTokens.length ||
(!location.search && mintAddress) ||
location.pathname.indexOf('move') < 0
) {
return;
}
let { defaultChain, defaultToken } = getDefaultTokens(
tokens,
ethTokens,
location.search,
);
if (!defaultToken || !defaultChain) {

View File

@ -2,7 +2,7 @@ import { EventEmitter } from '@oyster/common';
import React, { useContext, useEffect, useState } from 'react';
import { MarketsContextState } from './market';
export const COINGECKO_POOL_INTERVAL = 10000; // 2 min
export const COINGECKO_POOL_INTERVAL = 1000 * 30; // 30 sec
export const COINGECKO_API = 'https://api.coingecko.com/api/v3/';
export const COINGECKO_COIN_LIST_API = `${COINGECKO_API}coins/list`;
export const COINGECKO_COIN_PRICE_API = `${COINGECKO_API}simple/price`;

View File

@ -97,15 +97,17 @@ export const EthereumProvider: FunctionComponent = ({ children }) => {
useEffect(() => {
if (connected) {
// @ts-ignore
window.ethereum.enable();
// @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.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);
});
}
}, [connected]);

View File

@ -0,0 +1,28 @@
import { useEthereum } from '../contexts';
import { useEffect, useState } from 'react';
import { useConnectionConfig } from '@oyster/common';
export const useCorrectNetwork = () => {
const { env } = useConnectionConfig();
const [hasCorrespondingNetworks, setHasCorrespondingNetworks] = useState(
true,
);
const { provider } = 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);
}
});
}
setHasCorrespondingNetworks(true);
}, [provider, env]);
return hasCorrespondingNetworks;
};

View File

@ -362,14 +362,14 @@ export const useWormholeAccounts = () => {
}, [externalAssets, setAmountInUSD]);
useEffect(() => {
if (externalAssets && coinList) {
if (externalAssets && coinList && !loading) {
dataSourcePriceQuery();
}
return () => {
window.clearTimeout(coingeckoTimer.current);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [externalAssets, coinList, dataSourcePriceQuery]);
}, [externalAssets, coinList, loading]);
return {
loading,