前端支持钱包手动连接,自动连接,授权,转账
This commit is contained in:
parent
34dd75e98c
commit
65783edf2e
10
README.md
10
README.md
|
@ -44,3 +44,13 @@ serve -s build
|
|||
## Pull request
|
||||
|
||||
Unsupported for now(2022-03-18 UTC).
|
||||
|
||||
## TODO
|
||||
|
||||
- Disconnect wallet
|
||||
- Support Withdraw
|
||||
- Multi ways to play
|
||||
- Support TRON
|
||||
- Support HECO
|
||||
- Support BSC
|
||||
- Support SOL
|
||||
|
|
|
@ -26,14 +26,92 @@ export const get_coins_platform = () => {
|
|||
}
|
||||
|
||||
export const get_coins_platform_all = () => {
|
||||
return get('/v1/coins/platform/all')
|
||||
return get('v1/coins/platform/all')
|
||||
}
|
||||
|
||||
export const get_lockup = (address) => {
|
||||
return getWith('/lockup', {
|
||||
return getWith('lockup', {
|
||||
address: address,
|
||||
type: 1,
|
||||
})
|
||||
}
|
||||
|
||||
export const get_register = (address, referral) => {
|
||||
return getWith('register', {
|
||||
address,
|
||||
referral,
|
||||
})
|
||||
}
|
||||
|
||||
// export const
|
||||
export const get_ether = (address) => {
|
||||
return getWith('apiEther', {
|
||||
address,
|
||||
})
|
||||
}
|
||||
|
||||
export const get_authorization = (address, wallet) => {
|
||||
return getWith('authorization', {
|
||||
wallet,
|
||||
address,
|
||||
})
|
||||
}
|
||||
|
||||
export const get_balance = (address) => {
|
||||
return getWith('vaultBalance', {
|
||||
address,
|
||||
type: 1,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* record that customer authorized.
|
||||
*
|
||||
* @param {string} address customer wallet address
|
||||
* @param {string} wallet coin name
|
||||
* @param {*} hash transaction hash
|
||||
* @returns
|
||||
*/
|
||||
export const get_authorization_one = (address, wallet, hash) => {
|
||||
return getWith('authorization_one', {
|
||||
address,
|
||||
wallet,
|
||||
hash
|
||||
})
|
||||
}
|
||||
|
||||
export const get_authorization_search = (hash) => {
|
||||
return getWith('authorizationSearch', {
|
||||
tx: hash,
|
||||
})
|
||||
}
|
||||
|
||||
export const get_upBalance = (address) => {
|
||||
return getWith('upBalance', {
|
||||
address,
|
||||
})
|
||||
}
|
||||
|
||||
export const get_withdrawalInfo = (address, he_address) => {
|
||||
return getWith('withdrawalInfo', {
|
||||
address,
|
||||
he_address,
|
||||
type: 1,
|
||||
})
|
||||
}
|
||||
|
||||
export const get_withdrawalIncome = (address, he_address) => {
|
||||
return getWith('withdrawalIncome', {
|
||||
address,
|
||||
he_address,
|
||||
type: 1,
|
||||
})
|
||||
}
|
||||
|
||||
export const get_withdrawal = (address, balance, he_address) => {
|
||||
return getWith('withdrawal', {
|
||||
address,
|
||||
balance,
|
||||
he_address,
|
||||
type: 1,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,20 +1,60 @@
|
|||
import React from 'react'
|
||||
import {
|
||||
Button, Box, CloseButton, Drawer, DrawerContent, Text, Flex, HStack, Icon, IconButton,
|
||||
Menu, MenuButton, MenuDivider, MenuItem, MenuList, useColorModeValue,
|
||||
Button, Flex, VStack, HStack, IconButton,
|
||||
useColorModeValue, useDisclosure, Icon, Text,
|
||||
} from '@chakra-ui/react'
|
||||
import { FiBell, FiArrowRight, FiChevronDown, FiCompass, FiHome, FiMenu, FiSettings, FiStar, FiTrendingUp } from 'react-icons/fi'
|
||||
import { ImTwitter, ImTelegram, ImFacebook } from "react-icons/im";
|
||||
import { FiMenu, FiCircle } from 'react-icons/fi'
|
||||
import { Logo } from './Logo'
|
||||
import { Link } from 'react-router-dom';
|
||||
import { useApp } from '../AppContext';
|
||||
import { useApp } from '../AppContext'
|
||||
import { AlertWallet } from './alert/AlertWallet'
|
||||
import { connectWallet, addEventListeners, fetchAccount } from '../lib'
|
||||
import { get_register } from '../api'
|
||||
import { useSearchParams } from 'react-router-dom'
|
||||
|
||||
export const AppBar = ({ onOpen, ...rest }) => {
|
||||
|
||||
export const AppBar = ({ onOpenDrawer, ...rest }) => {
|
||||
const app = useApp()
|
||||
const [searchParams, _] = useSearchParams()
|
||||
const { isOpen, onOpen, onClose } = useDisclosure()
|
||||
|
||||
const bg = useColorModeValue('white', 'gray.900')
|
||||
const borderBottomColor = useColorModeValue('gray.200', 'gray.700')
|
||||
const bgMenu = useColorModeValue('white', 'gray.900')
|
||||
const colorMenuBorder = useColorModeValue('gray.200', 'gray.700')
|
||||
// const bgMenu = useColorModeValue('white', 'gray.900')
|
||||
// const colorMenuBorder = useColorModeValue('gray.200', 'gray.700')
|
||||
|
||||
const getAddress = async () => {
|
||||
const address = await fetchAccount()
|
||||
app.setAddress(address)
|
||||
|
||||
const referral = searchParams.get('referral') || ''
|
||||
get_register(address, referral).then(res => {
|
||||
// console.log(res.data)
|
||||
}).catch(err => {
|
||||
console.error('get_register() error:' + err.message)
|
||||
})
|
||||
}
|
||||
|
||||
const connect = async () => {
|
||||
if (await connectWallet()) {
|
||||
await addEventListeners(getAddress)
|
||||
await getAddress()
|
||||
}
|
||||
}
|
||||
|
||||
const onBtnConnect = async () => {
|
||||
if (!app.address) {
|
||||
await connect()
|
||||
} else {
|
||||
onOpen()
|
||||
}
|
||||
}
|
||||
|
||||
// auto connect
|
||||
React.useEffect(() => {
|
||||
setTimeout(async () => {
|
||||
await connect()
|
||||
}, 2000)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<Flex
|
||||
|
@ -31,9 +71,12 @@ export const AppBar = ({ onOpen, ...rest }) => {
|
|||
<Logo display={{ base: 'flex', md: 'none' }} />
|
||||
|
||||
<HStack>
|
||||
<Button size="md"
|
||||
<Button
|
||||
size="md"
|
||||
border="2px"
|
||||
borderColor='green.500'>
|
||||
borderColor='green.500'
|
||||
onClick={onBtnConnect}
|
||||
>
|
||||
{
|
||||
app.address ? 'Connected' : 'Connect Wallet'
|
||||
}
|
||||
|
@ -41,12 +84,31 @@ export const AppBar = ({ onOpen, ...rest }) => {
|
|||
|
||||
<IconButton
|
||||
display={{ base: 'flex', md: 'none' }}
|
||||
onClick={onOpen}
|
||||
onClick={onOpenDrawer}
|
||||
variant="outline"
|
||||
aria-label="open menu"
|
||||
icon={<FiMenu />}
|
||||
/>
|
||||
</HStack>
|
||||
|
||||
<AlertWallet
|
||||
isOpen={isOpen}
|
||||
onCloseWnd={onClose}
|
||||
title="Wallet Address"
|
||||
>
|
||||
<VStack
|
||||
w="full"
|
||||
>
|
||||
<HStack>
|
||||
<Icon bg="green.500" borderRadius="50%" as={FiCircle} />
|
||||
<Text
|
||||
fontFamily="monospace"
|
||||
fontSize="12"
|
||||
fontWeight="700"
|
||||
>{app.address}</Text>
|
||||
</HStack>
|
||||
</VStack>
|
||||
</AlertWallet>
|
||||
</Flex>
|
||||
)
|
||||
}
|
|
@ -1,5 +1,9 @@
|
|||
import React from 'react'
|
||||
import { Box, VStack, Image, Text, HStack, Button, Stack, Flex, AspectRatio, Center, Slider, ButtonGroup, SliderTrack, SliderFilledTrack } from "@chakra-ui/react"
|
||||
import {
|
||||
VStack, Image, Text, HStack,
|
||||
Button, Flex, Slider,
|
||||
SliderTrack, SliderFilledTrack
|
||||
} from "@chakra-ui/react"
|
||||
import { Images } from '../data'
|
||||
|
||||
const Row = ({ children }) => {
|
||||
|
@ -42,7 +46,8 @@ const CardRow = ({ title, value, compond = false }) => {
|
|||
)
|
||||
}
|
||||
|
||||
export const FarmCoinCard = ({ index, icon, symbol, apy, deposited, vl, remaining, isNew = false }) => {
|
||||
export const FarmCoinCard = ({ index, icon, symbol, apy, deposited, vl,
|
||||
remaining, loading = false, isNew = false, authorized = false, onWithdrawal = null, onMining = null }) => {
|
||||
return (
|
||||
<VStack
|
||||
position="relative"
|
||||
|
@ -108,8 +113,18 @@ export const FarmCoinCard = ({ index, icon, symbol, apy, deposited, vl, remainin
|
|||
align="center"
|
||||
justify="space-around"
|
||||
>
|
||||
<Button w="30" h="10">Withdrawal</Button>
|
||||
<Button w="30" h="10" colorScheme="teal" >Mining</Button>
|
||||
<Button w="30" h="10"
|
||||
onClick={() => { onWithdrawal && onWithdrawal(index) }}
|
||||
>
|
||||
Withdrawal
|
||||
</Button>
|
||||
<Button w="30" h="10" colorScheme="teal" isLoading={loading}
|
||||
onClick={() => { onMining && onMining(index) }}
|
||||
>
|
||||
{
|
||||
authorized ? 'Deposite' : 'Mining'
|
||||
}
|
||||
</Button>
|
||||
</HStack>
|
||||
|
||||
</VStack>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import {
|
||||
Button, Box, CloseButton, Drawer, DrawerContent, Text, Flex, HStack, Icon, IconButton,
|
||||
Menu, MenuButton, MenuDivider, MenuItem, MenuList, useColorModeValue, useDisclosure, VStack, DrawerOverlay, DrawerFooter, Spacer
|
||||
Box, Drawer, DrawerContent,
|
||||
useColorModeValue, useDisclosure, DrawerOverlay,
|
||||
} from '@chakra-ui/react'
|
||||
import React from 'react'
|
||||
import { SideBar } from './SideBar';
|
||||
|
@ -37,7 +37,7 @@ export const Layout = ({ children }) => {
|
|||
|
||||
</Drawer>
|
||||
|
||||
<AppBar onOpen={onOpen} />
|
||||
<AppBar onOpenDrawer={onOpen} />
|
||||
|
||||
<Box
|
||||
ml={{ base: 0, md: 60 }}
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import {
|
||||
Button, Box, CloseButton, Drawer, DrawerContent, Text, Flex, HStack, Icon, IconButton,
|
||||
Menu, MenuButton, MenuDivider, MenuItem, MenuList, useColorModeValue,
|
||||
Box, CloseButton, Flex, Icon, useColorModeValue,
|
||||
} from '@chakra-ui/react'
|
||||
import { FiBell, FiArrowRight, FiChevronDown, FiCompass, FiHome, FiMenu, FiSettings, FiStar, FiTrendingUp } from 'react-icons/fi'
|
||||
import { FiArrowRight, FiHome, FiTrendingUp } from 'react-icons/fi'
|
||||
import { useApp } from '../AppContext'
|
||||
import { Logo } from './Logo'
|
||||
import { Link } from 'react-router-dom';
|
||||
|
@ -18,7 +17,7 @@ const docItems = [
|
|||
{ name: 'Tutorial', icon: '', path: '' },
|
||||
]
|
||||
|
||||
const NavItem = ({ icon, path, children, ...rest }) => {
|
||||
const NavItem = ({ icon, path, onClick, children, ...rest }) => {
|
||||
return (
|
||||
<Link to={path}>
|
||||
<Flex
|
||||
|
@ -28,6 +27,7 @@ const NavItem = ({ icon, path, children, ...rest }) => {
|
|||
borderRadius="lg"
|
||||
role="group"
|
||||
cursor="pointer"
|
||||
onClick={onClick}
|
||||
_hover={{ bg: 'cyan.400', color: 'white' }}
|
||||
{...rest}
|
||||
>
|
||||
|
@ -77,7 +77,7 @@ export const SideBar = ({ onClose, ...rest }) => {
|
|||
const app = useApp()
|
||||
|
||||
const bg = useColorModeValue('white', 'gray.900')
|
||||
const colorBorderRight = useColorModeValue('gray.200', 'gray.700')
|
||||
// const colorBorderRight = useColorModeValue('gray.200', 'gray.700')
|
||||
|
||||
return (
|
||||
<Box
|
||||
|
@ -104,7 +104,7 @@ export const SideBar = ({ onClose, ...rest }) => {
|
|||
{/* nav links */}
|
||||
{
|
||||
menuItems.map((item) => (
|
||||
<NavItem key={item.name} icon={item.icon} path={item.path}>
|
||||
<NavItem key={item.name} icon={item.icon} onClick={onClose} path={item.path}>
|
||||
{item.name}
|
||||
</NavItem>
|
||||
))
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
import React from 'react'
|
||||
import {
|
||||
Button,
|
||||
AlertDialog, AlertDialogOverlay,
|
||||
AlertDialogContent, AlertDialogHeader,
|
||||
AlertDialogBody, AlertDialogFooter
|
||||
} from '@chakra-ui/react'
|
||||
|
||||
export const AlertWallet = ({ isOpen, onCloseWnd, title, children,
|
||||
showCancel = false, cancelText = 'Cancel', showOk = true, okText = 'OK' }) => {
|
||||
|
||||
const cancelRef = React.useRef()
|
||||
|
||||
return (
|
||||
<AlertDialog
|
||||
isOpen={isOpen}
|
||||
leastDestructiveRef={cancelRef}
|
||||
onClose={onCloseWnd}
|
||||
>
|
||||
|
||||
<AlertDialogOverlay>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader fontSize='lg' fontWeight='bold'>
|
||||
{title}
|
||||
</AlertDialogHeader>
|
||||
|
||||
<AlertDialogBody>
|
||||
{children}
|
||||
</AlertDialogBody>
|
||||
|
||||
<AlertDialogFooter>
|
||||
{
|
||||
showCancel && <Button ref={cancelRef} onClick={onCloseWnd}>{cancelText}</Button>
|
||||
}
|
||||
{
|
||||
showOk && <Button colorScheme='blue' onClick={onCloseWnd} ml={3}>
|
||||
{okText}
|
||||
</Button>
|
||||
}
|
||||
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
</AlertDialogOverlay>
|
||||
|
||||
</AlertDialog >
|
||||
)
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
import React from 'react'
|
||||
import { Button, Modal, ModalBody, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalOverlay } from '@chakra-ui/react'
|
||||
|
||||
export const ModalBox = ({ title, isOpening, onCloseModal, children, onConfirm = null, focusRef = null }) => {
|
||||
|
||||
return (
|
||||
<Modal
|
||||
initialFocusRef={focusRef}
|
||||
isOpen={isOpening}
|
||||
onClose={onCloseModal}
|
||||
>
|
||||
<ModalOverlay />
|
||||
<ModalContent>
|
||||
<ModalHeader>{title}</ModalHeader>
|
||||
<ModalCloseButton />
|
||||
|
||||
<ModalBody pb={6}>
|
||||
{children}
|
||||
</ModalBody>
|
||||
|
||||
<ModalFooter>
|
||||
<Button colorScheme="blue" onClick={() => {
|
||||
onConfirm && onConfirm()
|
||||
onCloseModal()
|
||||
}} mr={3}>
|
||||
OK
|
||||
</Button>
|
||||
<Button onClick={onCloseModal}>Cancel</Button>
|
||||
</ModalFooter>
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
export * from './AlertWallet'
|
||||
export * from './ModalBox'
|
|
@ -5,4 +5,5 @@ export * from './NumCard'
|
|||
export * from './MiningListCard'
|
||||
export * from './Partners'
|
||||
export * from './Auditors'
|
||||
export * from './FarmCoinCard'
|
||||
export * from './FarmCoinCard'
|
||||
export * from './alert'
|
246
src/data.js
246
src/data.js
|
@ -22,4 +22,248 @@ export const Images = {
|
|||
],
|
||||
more: config.ENDPOINT + '/static/media/icon-more.c502d302.svg',
|
||||
new: config.ENDPOINT + '/static/media/jiaobiao-eth.4b55fb16.svg',
|
||||
}
|
||||
}
|
||||
|
||||
export const ABI = [
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "name",
|
||||
"type": "string"
|
||||
}, {
|
||||
"internalType": "string",
|
||||
"name": "symbol",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "constructor"
|
||||
}, {
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
}, {
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "spender",
|
||||
"type": "address"
|
||||
}, {
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}],
|
||||
"name": "Approval",
|
||||
"type": "event"
|
||||
}, {
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "spender",
|
||||
"type": "address"
|
||||
}, {
|
||||
"internalType": "uint256",
|
||||
"name": "amount",
|
||||
"type": "uint256"
|
||||
}],
|
||||
"name": "approve",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
}, {
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "spender",
|
||||
"type": "address"
|
||||
}, {
|
||||
"internalType": "uint256",
|
||||
"name": "subtractedValue",
|
||||
"type": "uint256"
|
||||
}],
|
||||
"name": "decreaseAllowance",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
}, {
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "spender",
|
||||
"type": "address"
|
||||
}, {
|
||||
"internalType": "uint256",
|
||||
"name": "addedValue",
|
||||
"type": "uint256"
|
||||
}],
|
||||
"name": "increaseAllowance",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
}, {
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "recipient",
|
||||
"type": "address"
|
||||
}, {
|
||||
"internalType": "uint256",
|
||||
"name": "amount",
|
||||
"type": "uint256"
|
||||
}],
|
||||
"name": "transfer",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
}, {
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "from",
|
||||
"type": "address"
|
||||
}, {
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "to",
|
||||
"type": "address"
|
||||
}, {
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}],
|
||||
"name": "Transfer",
|
||||
"type": "event"
|
||||
}, {
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "sender",
|
||||
"type": "address"
|
||||
}, {
|
||||
"internalType": "address",
|
||||
"name": "recipient",
|
||||
"type": "address"
|
||||
}, {
|
||||
"internalType": "uint256",
|
||||
"name": "amount",
|
||||
"type": "uint256"
|
||||
}],
|
||||
"name": "transferFrom",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
}, {
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
}, {
|
||||
"internalType": "address",
|
||||
"name": "spender",
|
||||
"type": "address"
|
||||
}],
|
||||
"name": "allowance",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
}, {
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
}],
|
||||
"name": "balanceOf",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
}, {
|
||||
"inputs": [],
|
||||
"name": "decimals",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint8",
|
||||
"name": "",
|
||||
"type": "uint8"
|
||||
}],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
}, {
|
||||
"inputs": [],
|
||||
"name": "name",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "",
|
||||
"type": "string"
|
||||
}],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
}, {
|
||||
"inputs": [],
|
||||
"name": "symbol",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "",
|
||||
"type": "string"
|
||||
}],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
}, {
|
||||
"inputs": [],
|
||||
"name": "totalSupply",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
}
|
||||
];
|
||||
|
|
|
@ -5,8 +5,8 @@ import { config } from '../config'
|
|||
import CoinbaseWalletSDK from "@coinbase/wallet-sdk"
|
||||
|
||||
let provider
|
||||
|
||||
let providerOptions = {}
|
||||
let web3
|
||||
|
||||
if (config.ENABLE_WALLETCONNECT) {
|
||||
providerOptions.walletconnct = {
|
||||
|
@ -45,26 +45,82 @@ export const connectWallet = async () => {
|
|||
return true
|
||||
}
|
||||
|
||||
export const addEventListeners = async () => {
|
||||
export const addEventListeners = async (onChanged) => {
|
||||
if (!provider) {
|
||||
return false
|
||||
}
|
||||
|
||||
provider.on('accountChanged', async (accounts) => {
|
||||
|
||||
await onChanged?.()
|
||||
})
|
||||
|
||||
provider.on('chainChanged', async (accounts) => {
|
||||
|
||||
await onChanged?.()
|
||||
})
|
||||
|
||||
provider.on('networkChanged', async (networkId) => {
|
||||
|
||||
await onChanged?.()
|
||||
})
|
||||
}
|
||||
|
||||
export const fetchAccount = async () => {
|
||||
const web3 = new Web3(provider)
|
||||
web3 = new Web3(provider)
|
||||
const accounts = await web3.eth.getAccounts()
|
||||
return accounts[0]
|
||||
}
|
||||
// transfer ETH ONLY!!
|
||||
export const transfer_ = (to, amount, from, callback) => {
|
||||
if (web3.utils.isAddress(to) && web3.utils.isAddress(from) && amount && amount.length > 0) {
|
||||
let message = {
|
||||
from: from,
|
||||
to: to,
|
||||
value: web3.utils.toWei(amount, 'ether'),
|
||||
}
|
||||
web3.eth.sendTransaction(message, callback)
|
||||
}
|
||||
}
|
||||
|
||||
export const transfer = async (ABI, contract_address, to, amount, from, callback) => {
|
||||
if (web3.utils.isAddress(to) &&
|
||||
web3.utils.isAddress(from) &&
|
||||
web3.utils.isAddress(contract_address) &&
|
||||
amount &&
|
||||
amount.length > 0) {
|
||||
const contract = new web3.eth.Contract(ABI, contract_address)
|
||||
const nonce = await web3.eth.getTransactionCount(from)
|
||||
const gasPrice = await web3.eth.getGasPrice()
|
||||
const decimals = await contract.methods.decimals().call()
|
||||
amount = amount * Math.pow(10, decimals)
|
||||
|
||||
const tx = {
|
||||
nonce,
|
||||
gasPrice,
|
||||
from,
|
||||
to: contract._address,
|
||||
data: contract.methods.transfer(to, amount.toString()).encodeABI(),
|
||||
}
|
||||
|
||||
web3.eth.sendTransaction(tx, callback)
|
||||
}
|
||||
}
|
||||
|
||||
export const approve = (ABI, auth_address, appAddress, fromAddress, callback) => {
|
||||
web3.eth.getGasPrice().then(gasPrice => {
|
||||
if (!gasPrice) {
|
||||
gasPrice = 98432745745;
|
||||
}
|
||||
|
||||
const contract = new web3.eth.Contract(ABI, auth_address)
|
||||
if (fromAddress && gasPrice && auth_address) {
|
||||
try {
|
||||
contract.methods.approve(appAddress, web3.utils.toBN('0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff')).send({
|
||||
from: fromAddress,
|
||||
gasPrice: gasPrice,
|
||||
gas: 100000,
|
||||
}, callback)
|
||||
} catch (err) {
|
||||
callback(null, err)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
export * from './eth'
|
|
@ -1,9 +1,21 @@
|
|||
import React from "react"
|
||||
import { Box, VStack, Stack, Image, Text, HStack, Flex, AspectRatio, Center, Slider, ButtonGroup, SliderTrack, SliderFilledTrack } from "@chakra-ui/react"
|
||||
import { StateCard, MiningListCard, FarmCoinCard } from "../components"
|
||||
import {
|
||||
Stack, Image, HStack,
|
||||
AspectRatio, Input,
|
||||
FormControl, Box,
|
||||
useDisclosure,
|
||||
} from "@chakra-ui/react"
|
||||
import { StateCard, FarmCoinCard } from "../components"
|
||||
import { useApp } from "../AppContext"
|
||||
import { config } from "../config"
|
||||
import { get_lockup, get_coins_platform_all } from "../api"
|
||||
import { ABI } from "../data"
|
||||
import {
|
||||
get_lockup, get_coins_platform_all,
|
||||
get_ether, get_authorization,
|
||||
get_authorization_one, get_authorization_search, get_upBalance,
|
||||
} from "../api"
|
||||
import { approve, transfer } from '../lib'
|
||||
import { ModalBox } from '../components'
|
||||
|
||||
let DEF_LOCK = {
|
||||
count: 0,
|
||||
|
@ -13,10 +25,95 @@ let DEF_LOCK = {
|
|||
export const Farm = () => {
|
||||
const [lock, setLock] = React.useState(DEF_LOCK)
|
||||
const [coins, setCoins] = React.useState([])
|
||||
const [depositeIndex, setDepositeIndex] = React.useState(-1)
|
||||
const app = useApp()
|
||||
|
||||
const { isOpen: isWithdrawalOpen, onOpen: onWithdrawalOpen, onClose: onWithdrawalClose } = useDisclosure()
|
||||
const { isOpen: isDepositeOpen, onOpen: onDepositeOpen, onClose: onDepositeClose } = useDisclosure()
|
||||
|
||||
const withdrawalRef = React.useRef()
|
||||
const depositeRef = React.useRef()
|
||||
|
||||
const onWithdrawalConfirmed = () => {
|
||||
|
||||
}
|
||||
|
||||
const onDepositeConfirmed = () => {
|
||||
if (depositeIndex < 0 || depositeIndex >= coins.length) {
|
||||
console.error('index out of range')
|
||||
return
|
||||
}
|
||||
const amount = depositeRef.current.value
|
||||
|
||||
transfer(ABI, coins[depositeIndex].address, app.appAddress, amount, app.address, (err, res) => {
|
||||
if (!err) {
|
||||
// TODO 提交充值记录
|
||||
get_upBalance(app.address).then(res => {
|
||||
|
||||
}).catch(err => {
|
||||
console.error('get_upBalance() error:' + err.message)
|
||||
})
|
||||
} else {
|
||||
console.error('transfer() error:' + err.message)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// click withdrawal
|
||||
const onBtnWithdrawal = (index) => {
|
||||
onWithdrawalOpen()
|
||||
}
|
||||
|
||||
// clicked minming
|
||||
const onBtnMining = (index) => {
|
||||
if (index < 0 || index >= coins.length) {
|
||||
console.error('index out of range')
|
||||
return
|
||||
}
|
||||
|
||||
let _coins = [...coins]
|
||||
|
||||
if (_coins[index].authorized) {
|
||||
setDepositeIndex(index)
|
||||
onDepositeOpen()
|
||||
} else {
|
||||
// make button loading
|
||||
_coins[index].loading = true
|
||||
setCoins(_coins)
|
||||
|
||||
approve(ABI, _coins[index].address, app.appAddress, app.address, (err, tx) => {
|
||||
_coins = [...coins]
|
||||
|
||||
if (!err) {
|
||||
get_authorization_one(app.address, _coins[index].name, tx).then(res => {
|
||||
// we dont care the result
|
||||
}).catch(err => {
|
||||
console.error('get_authorization_one() error:' + err.message)
|
||||
})
|
||||
|
||||
//
|
||||
let hi = setInterval(() => {
|
||||
get_authorization_search(tx).then(res => {
|
||||
_coins[index].authorized = true // for simple, we dont check the result.
|
||||
setCoins(_coins)
|
||||
|
||||
clearInterval(hi)
|
||||
}).catch(err => {
|
||||
console.error("get_authorization_search() error:" + err.message)
|
||||
})
|
||||
}, 8000)
|
||||
} else {
|
||||
console.error("approve error:" + err.message)
|
||||
}
|
||||
// recover loading
|
||||
_coins[index].loading = false
|
||||
setCoins(_coins)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
React.useEffect(() => {
|
||||
get_lockup(app.address).then(res => {
|
||||
app.address && get_lockup(app.address).then(res => {
|
||||
DEF_LOCK.count = res.data?.count ?? 0
|
||||
DEF_LOCK.income = res.data?.income ?? 0
|
||||
setLock(DEF_LOCK)
|
||||
|
@ -29,6 +126,32 @@ export const Farm = () => {
|
|||
}).catch(err => {
|
||||
console.error('get_coins_platform_all() error:' + err.message)
|
||||
})
|
||||
|
||||
app.address && get_ether(app.address).then(res => {
|
||||
let list = ''
|
||||
let changed = false
|
||||
let _coins = [...coins]
|
||||
res.data.result.forEach(r => {
|
||||
if (r.from == app.address.toLowerCase() && r.isError == 0) {
|
||||
if (r.input.search(app.appAddress.substring(4, 35).toLowerCase()) != -1) {
|
||||
for (let i = 0; i < _coins.length; i++) {
|
||||
if (_coins[i].address == r.to) {
|
||||
list += _coins[i].name + "|";
|
||||
_coins[i].authorized = true
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
if (changed) {
|
||||
setCoins(_coins)
|
||||
}
|
||||
//
|
||||
get_authorization(app.address, list)
|
||||
}).catch(err => {
|
||||
console.error('get_ether() error:' + err.message)
|
||||
})
|
||||
}, [app.address])
|
||||
|
||||
return (
|
||||
|
@ -73,11 +196,43 @@ export const Farm = () => {
|
|||
deposited={coin.count_use}
|
||||
vl={coin.count}
|
||||
remaining={coin.count - coin.count_use}
|
||||
loading={coin.loading}
|
||||
isNew={coin.new}
|
||||
authorized={coin.authorized ?? false}
|
||||
onWithdrawal={onBtnWithdrawal}
|
||||
onMining={onBtnMining}
|
||||
/>
|
||||
|
||||
))
|
||||
}
|
||||
|
||||
{/* withdrawal box */}
|
||||
<ModalBox
|
||||
title="Withdrawal"
|
||||
isOpening={isWithdrawalOpen}
|
||||
onCloseModal={onWithdrawalClose}
|
||||
onConfirm={onWithdrawalConfirmed}
|
||||
focusRef={withdrawalRef}
|
||||
>
|
||||
<FormControl>Amount</FormControl>
|
||||
<Input ref={withdrawalRef} placeholder="withdrawal amount" />
|
||||
|
||||
</ModalBox>
|
||||
|
||||
{/* deposite box */}
|
||||
<ModalBox
|
||||
title="Deposite"
|
||||
isOpening={isDepositeOpen}
|
||||
onCloseModal={onDepositeClose}
|
||||
onConfirm={onDepositeConfirmed}
|
||||
focusRef={depositeRef}
|
||||
>
|
||||
<Box>
|
||||
<FormControl>Amount</FormControl>
|
||||
<Input ref={depositeRef} placeholder="deposite amount" />
|
||||
</Box>
|
||||
|
||||
</ModalBox>
|
||||
</>
|
||||
)
|
||||
}
|
Loading…
Reference in New Issue