You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

162 lines
4.9 KiB

import '~/styles/recharge.scss'
import { observer } from 'mobx-react'
import store from '../../store'
import { useMemo, useRef, useState } from 'react'
import { useRouter } from '../../hooks/useRouter'
import { ethers } from 'ethers'
import { Button, Toast } from 'react-vant'
import { switchNetWork } from '../../utils'
import { IERC20__factory } from '../../contract/IERC20__factory'
import { toWei } from '../../utils/wei'
import BackBar from '~/components/BackBar'
const Recharge = () => {
const { coinIndex, coinList, userInfo } = store.state
const { push } = useRouter()
const inputRef = useRef<HTMLInputElement>(null);
const currentCoin = useMemo(() => coinList[coinIndex], [coinIndex, coinList])
const [loading, setLoading] = useState(false);
const provider = useMemo(() => {
if (window.ethereum) {
return new ethers.providers.Web3Provider(window.ethereum)
};
return null;
}, []);
const handleTransferParams = async () => {
let from = window.ethereum.selectedAddress;
let toAddress = userInfo.deposit_address;
let contractAddress = currentCoin.address;
if (!provider) {
Toast.info('請檢查網絡是否正常');
return -1
}
if (!inputRef.current) {
Toast.info('請稍後重試');
return -1
}
let value = inputRef.current.value;
if (!value) {
Toast.info('請輸入數量');
return -1
}
let _contract = IERC20__factory.connect(contractAddress as string, provider);
// 判断 gas 余额
let eth = await provider.getBalance(from)
const needGas = toWei("0.01")
if (eth.lt(needGas)) {
Toast.info('Gas 費不足 0.01');
return -1
}
// 判断代币余额
let balanceToken = await _contract.balanceOf(from)
let currToken = toWei(value)
if (balanceToken.lt(currToken)) {
Toast.info('Token 餘額不足');
return -1
}
let { to, data } = await _contract.populateTransaction.transfer(toAddress, toWei(value));
let requestData = {
from,
to,
data,
value: '0x0'
};
return requestData;
};
const handleExchange = async () => {
if (!provider || loading) return;
let value = inputRef.current?.value;
if (!value) {
Toast.info('請輸入數量');
return;
};
setLoading(true);
try {
let isNode = await switchNetWork();
if (!isNode) return;
let data = await handleTransferParams();
if (data == -1) {
// Toast.info('请检查网络是否正常');
setLoading(false);
return;
}
let txHash = await window.ethereum.request({
method: 'eth_sendTransaction',
params: [
data
]
});
let tx = await provider.getTransaction(txHash);
let { status } = await tx.wait();
setLoading(false);
if (status === 1) {
Toast.success('充值成功');
setTimeout(() => {
push(-1)
}, 1000)
} else {
Toast.fail('充值失敗');
}
} catch (error) {
setLoading(false);
}
};
return (
<div className='recharge plr-2'>
<BackBar title='充值' />
<div className='container row-center mt-2'>
<div className='box plr-2 row-between' onClick={() => push('/choose')}>
<div className='row-items'>
{
currentCoin && <img src={require(`~/assets/${currentCoin.symbol}.png`)} alt="" />
}
<div className='fz-wb-550 ml-1'>{currentCoin && currentCoin.symbol}</div>
</div>
<div>
<i className='iconfont icon-arrow-right-bold'></i>
</div>
</div>
<div className='box-img row-center'>
<i className='iconfont icon-datijilu fz-22'></i>
</div>
</div>
<div className='mt-2'>
<div className='white-bg p-2 r-1'>
<div className='fz-14'></div>
<div className='mt-1 fz-wb-550'>BNB Smart Chain(BEP20)</div>
</div>
<div className='mt-2 white-bg r-1 p-2'>
<div className='fz-14' style={{ color: '#828284' }}></div>
<div className='mt-1 input-box plr-1'>
<input type="number" placeholder='請輸入數量' ref={inputRef} />
<div className='row-items'>
{
currentCoin && <img src={require(`~/assets/${currentCoin.symbol}.png`)} alt="" />
}
<div className='ml-5px'>{currentCoin && currentCoin.symbol}</div>
{/* <div className='primary-color ml-5px'>最大</div> */}
</div>
</div>
</div>
<div className='mt-3'>
<Button className='button' onClick={handleExchange} loading={loading} loadingType="ball" ></Button>
</div>
</div>
</div>
)
}
export default observer(Recharge)