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
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)
|