From bb561b445397ba6c36c20bf82ae6116c4f52c4cd Mon Sep 17 00:00:00 2001
From: gary <1032230992@qq.com>
Date: Thu, 14 Apr 2022 11:13:49 +0800
Subject: [PATCH] =?UTF-8?q?feat:=20=E9=82=80=E8=AF=B7=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/App.tsx | 4 +
src/components/Menu/config.ts | 5 +
src/config/abi/board.json | 464 ++++++++++++++++++++++++++++++
src/config/abi/referral.json | 324 +++++++++++++++++++++
src/config/constants/contracts.ts | 8 +
src/hooks/useContract.ts | 11 +-
src/services/referral.ts | 32 +++
src/state/actions.ts | 1 +
src/state/index.ts | 2 +
src/state/referral/index.ts | 50 ++++
src/state/types.ts | 14 +-
src/utils/addressHelpers.ts | 6 +
src/utils/contractHelpers.ts | 10 +
src/utils/formatBalance.ts | 5 +-
src/views/Referral/index.tsx | 180 ++++++++++++
15 files changed, 1112 insertions(+), 4 deletions(-)
create mode 100644 src/config/abi/board.json
create mode 100644 src/config/abi/referral.json
create mode 100644 src/services/referral.ts
create mode 100644 src/state/referral/index.ts
create mode 100644 src/views/Referral/index.tsx
diff --git a/src/App.tsx b/src/App.tsx
index bf158a6..f3312bc 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -47,6 +47,7 @@ const AddLiquidity = lazy(() => import('./views/AddLiquidity'))
const Pool = lazy(() => import('./views/Pool'))
const PoolFinder = lazy(() => import('./views/PoolFinder'))
const RemoveLiquidity = lazy(() => import('./views/RemoveLiquidity'))
+const Referral = lazy(() => import('./views/Referral'))
// This config is required for number formatting
BigNumber.config({
@@ -85,6 +86,9 @@ const App: React.FC = () => {
+
+
+
{/*
diff --git a/src/components/Menu/config.ts b/src/components/Menu/config.ts
index 990263c..0377318 100644
--- a/src/components/Menu/config.ts
+++ b/src/components/Menu/config.ts
@@ -35,6 +35,11 @@ const config: (t: ContextApi['t']) => MenuEntry[] = (t) => [
icon: 'PoolIcon',
href: '/pools',
},
+ {
+ label: t('Referral'),
+ icon: 'PoolIcon',
+ href: '/referral',
+ },
// {
// label: t('Prediction (BETA)'),
// icon: 'PredictionsIcon',
diff --git a/src/config/abi/board.json b/src/config/abi/board.json
new file mode 100644
index 0000000..1299954
--- /dev/null
+++ b/src/config/abi/board.json
@@ -0,0 +1,464 @@
+[
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_candy",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_xCandy",
+ "type": "address"
+ },
+ {
+ "internalType": "bool",
+ "name": "_turnOnCondition",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "constructor"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "user",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "Deposit",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "user",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "EmergencyWithdraw",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "NodeReward",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "user",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "Withdraw",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "WithdrawNodeReward",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "Candy",
+ "outputs": [
+ {
+ "internalType": "contract IHRC20",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "XCandy",
+ "outputs": [
+ {
+ "internalType": "contract IHRC20",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "rewardNum",
+ "type": "uint256"
+ }
+ ],
+ "name": "addNodeReward",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "addWhitelisted",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "canGetRewardMap",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_thresholdDivider",
+ "type": "uint256"
+ }
+ ],
+ "name": "changeThresholdDivider",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "conditionTurnOn",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "enterStake",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "firstStakeThreshold",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_findAddress",
+ "type": "address"
+ }
+ ],
+ "name": "getIsNodeMembers",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "isWhitelisted",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "leaveStake",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "leaveStakePrecheck",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "nodeMembers",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "nodeToPeriod",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "removeWhitelisted",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bool",
+ "name": "_turnOn",
+ "type": "bool"
+ }
+ ],
+ "name": "switchCondition",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "thresholdDivider",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "userInfo",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "stakeTs",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "withDrawReward",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+]
diff --git a/src/config/abi/referral.json b/src/config/abi/referral.json
new file mode 100644
index 0000000..8a9935f
--- /dev/null
+++ b/src/config/abi/referral.json
@@ -0,0 +1,324 @@
+[
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "InviteReward",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "WithdrawInviteReward",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "_candy",
+ "outputs": [
+ {
+ "internalType": "contract ICandy",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "child",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "invite",
+ "type": "address"
+ }
+ ],
+ "name": "addInviteAddress",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "invite",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "rewardNum",
+ "type": "uint256"
+ }
+ ],
+ "name": "addInviteReward",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "addWhitelisted",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "canGetRewardMap",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "findAddress",
+ "type": "address"
+ }
+ ],
+ "name": "getInviteAddress",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "inviteNumMap",
+ "outputs": [
+ {
+ "internalType": "int128",
+ "name": "",
+ "type": "int128"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "inviteTotalRewardMap",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "isWhitelisted",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "leaderMap",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "removeWhitelisted",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "candy",
+ "type": "address"
+ }
+ ],
+ "name": "setCandyTokenAddress",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "withDrawReward",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+]
diff --git a/src/config/constants/contracts.ts b/src/config/constants/contracts.ts
index 6262118..96866a4 100644
--- a/src/config/constants/contracts.ts
+++ b/src/config/constants/contracts.ts
@@ -7,6 +7,14 @@ export default {
97: '0xd3af5fe61dbaf8f73149bfcfa9fb653ff096029a',
56: '0x6ab8463a4185b80905e05a9ff80a2d6b714b9e95',
},
+ boardChef: {
+ 97: '0x4BC67bBC22a245035fDd1F00DCa7d4F2E1e8f636',
+ 56: '0xD34871F12ace1BB8034E18009104b9dA60B84250', // NEED CHANGE 节点董事会合约
+ },
+ referralChef: {
+ 97: '0x3Dcf2586519a25719658Afb2cDB4CEf0DD647Ea3',
+ 56: '0x88F46EF2Ee08494D84942DCA3bd24cDEf7C88Ae2', // NEED CHANGE 邀请合约
+ },
lotteryV2: {
97: '0x5790c3534F30437641541a0FA04C992799602998',
56: '0x5aF6D33DE2ccEC94efb1bDF8f92Bd58085432d2c',
diff --git a/src/hooks/useContract.ts b/src/hooks/useContract.ts
index 56e5464..89affe0 100644
--- a/src/hooks/useContract.ts
+++ b/src/hooks/useContract.ts
@@ -24,6 +24,8 @@ import {
getLotteryV2Contract,
getBunnySpecialCakeVaultContract,
getBunnySpecialPredictionContract,
+ getReferralchefContract,
+ getBoardchefContract,
} from 'utils/contractHelpers'
// Imports below migrated from Exchange useContract.ts
@@ -98,7 +100,14 @@ export const useMasterchef = () => {
const { library } = useActiveWeb3React()
return useMemo(() => getMasterchefContract(library.getSigner()), [library])
}
-
+export const useBoardchef = () => {
+ const { library } = useActiveWeb3React()
+ return useMemo(() => getBoardchefContract(library.getSigner()), [library])
+}
+export const useReferralchef = () => {
+ const { library } = useActiveWeb3React()
+ return useMemo(() => getReferralchefContract(library.getSigner()), [library])
+}
export const useSousChef = (id) => {
const { library } = useActiveWeb3React()
return useMemo(() => getSouschefContract(id, library.getSigner()), [id, library])
diff --git a/src/services/referral.ts b/src/services/referral.ts
new file mode 100644
index 0000000..b4765c5
--- /dev/null
+++ b/src/services/referral.ts
@@ -0,0 +1,32 @@
+import request from 'utils/request'
+
+export const setInviteCode = (data) => {
+ return request.request({
+ url: '/api/v1/setInviteCode',
+ method: 'post',
+ data,
+ })
+}
+
+export const getAddressInviteInfo = (data) => {
+ return request.request({
+ url: '/api/v1/getAddressInviteInfo',
+ method: 'post',
+ data,
+ })
+}
+
+export const getAddressInviteList = (data) => {
+ return request.request({
+ url: '/api/v1/getAddressInviteList',
+ method: 'post',
+ data,
+ })
+}
+export const getAddressOtherReward = (data) => {
+ return request.request({
+ url: '/api/v1/getAddressOtherReward',
+ method: 'post',
+ data,
+ })
+}
diff --git a/src/state/actions.ts b/src/state/actions.ts
index 968253b..f9d27ae 100644
--- a/src/state/actions.ts
+++ b/src/state/actions.ts
@@ -11,6 +11,7 @@ export {
updateUserStakedBalance,
} from './pools'
export { setUserInfo, clearUserInfo } from './userInfo'
+export { fetchReferralInfoAsync } from './referral'
export { profileFetchStart, profileFetchSucceeded, profileFetchFailed } from './profile'
export { fetchStart, teamFetchSucceeded, fetchFailed, teamsFetchSucceeded } from './teams'
export { setBlock } from './block'
diff --git a/src/state/index.ts b/src/state/index.ts
index 3800834..9954eef 100644
--- a/src/state/index.ts
+++ b/src/state/index.ts
@@ -11,6 +11,7 @@ import collectiblesReducer from './collectibles'
import votingReducer from './voting'
import lotteryReducer from './lottery'
import userInfo from './userInfo'
+import referral from './referral'
import application from './application/reducer'
import { updateVersion } from './global/actions'
@@ -36,6 +37,7 @@ const store = configureStore({
voting: votingReducer,
lottery: lotteryReducer,
userInfo,
+ referral,
// Exchange
application,
user,
diff --git a/src/state/referral/index.ts b/src/state/referral/index.ts
new file mode 100644
index 0000000..3a673a5
--- /dev/null
+++ b/src/state/referral/index.ts
@@ -0,0 +1,50 @@
+/* eslint-disable no-param-reassign */
+import { createSlice } from '@reduxjs/toolkit'
+import { getAddressInviteInfo, getAddressOtherReward } from 'services/referral'
+import referralChefAbi from 'config/abi/referral.json'
+import multicall from 'utils/multicall'
+import BigNumber from 'bignumber.js'
+import { getReferralAddress } from 'utils/addressHelpers'
+import { getBalanceNumber } from 'utils/formatBalance'
+import { Referral, ReferralState } from '../types'
+
+const initialState: ReferralState = { data: {} }
+export const referralSlice = createSlice({
+ name: 'Referral',
+ initialState,
+ reducers: {
+ setInfo: (state, action) => {
+ state.data = action.payload
+ },
+ },
+})
+
+// Actions
+export const { setInfo } = referralSlice.actions
+// Thunks
+export const fetchReferralInfoAsync = (account) => async (dispatch) => {
+ if (!account) {
+ dispatch(setInfo({}))
+ return
+ }
+ const data: any = await getAddressInviteInfo({ address: account })
+ const otherReward = await getAddressOtherReward({ address: account })
+ const [totalReward, canWithdrawReward] = await multicall(referralChefAbi, [
+ {
+ address: getReferralAddress(),
+ name: 'inviteTotalRewardMap',
+ params: [account],
+ },
+ {
+ address: getReferralAddress(),
+ name: 'canGetRewardMap',
+ params: [account],
+ },
+ ])
+ data.totalReward = getBalanceNumber(new BigNumber(totalReward), 18, 5)
+ data.canWithdrawReward = getBalanceNumber(new BigNumber(canWithdrawReward), 18, 5)
+ data.otherReward = otherReward
+ dispatch(setInfo(data))
+}
+
+export default referralSlice.reducer
diff --git a/src/state/types.ts b/src/state/types.ts
index 49b1165..a576ac2 100644
--- a/src/state/types.ts
+++ b/src/state/types.ts
@@ -487,7 +487,18 @@ export interface UserInfoState {
token?: string
account?: string
}
-
+export interface Referral {
+ Address?: string
+ ID?: number
+ InviteAddress?: string
+ InviteCode?: string
+ totalReward?: string
+ otherReward?: number // 其他特殊奖励
+ canWithdrawReward?: number
+}
+export interface ReferralState {
+ data: Referral
+}
// Global state
export interface State {
@@ -501,5 +512,6 @@ export interface State {
collectibles: CollectiblesState
voting: VotingState
userInfo: UserInfoState
+ referral: ReferralState
lottery: LotteryState
}
diff --git a/src/utils/addressHelpers.ts b/src/utils/addressHelpers.ts
index 9d988c8..563de00 100644
--- a/src/utils/addressHelpers.ts
+++ b/src/utils/addressHelpers.ts
@@ -20,6 +20,12 @@ export const getMasterChefAddress = () => {
export const getMulticallAddress = () => {
return getAddress(addresses.multiCall)
}
+export const getBoardAddress = () => {
+ return getAddress(addresses.boardChef)
+}
+export const getReferralAddress = () => {
+ return getAddress(addresses.referralChef)
+}
export const getWbnbAddress = () => {
return getAddress(tokens.wbnb.address)
}
diff --git a/src/utils/contractHelpers.ts b/src/utils/contractHelpers.ts
index a2a0e2e..da53ff5 100644
--- a/src/utils/contractHelpers.ts
+++ b/src/utils/contractHelpers.ts
@@ -24,6 +24,8 @@ import {
getMulticallAddress,
getBunnySpecialCakeVaultAddress,
getBunnySpecialPredictionAddress,
+ getBoardAddress,
+ getReferralAddress,
} from 'utils/addressHelpers'
// ABI
@@ -41,6 +43,8 @@ import ifoV2Abi from 'config/abi/ifoV2.json'
import pointCenterIfo from 'config/abi/pointCenterIfo.json'
import lotteryV2Abi from 'config/abi/lotteryV2.json'
import masterChef from 'config/abi/masterchef.json'
+import referralChef from 'config/abi/referral.json'
+import boardChef from 'config/abi/board.json'
import sousChef from 'config/abi/sousChef.json'
import sousChefV2 from 'config/abi/sousChefV2.json'
import sousChefBnb from 'config/abi/sousChefBnb.json'
@@ -111,6 +115,12 @@ export const getLotteryV2Contract = (signer?: ethers.Signer | ethers.providers.P
export const getMasterchefContract = (signer?: ethers.Signer | ethers.providers.Provider) => {
return getContract(masterChef, getMasterChefAddress(), signer)
}
+export const getBoardchefContract = (signer?: ethers.Signer | ethers.providers.Provider) => {
+ return getContract(boardChef, getBoardAddress(), signer)
+}
+export const getReferralchefContract = (signer?: ethers.Signer | ethers.providers.Provider) => {
+ return getContract(referralChef, getReferralAddress(), signer)
+}
export const getClaimRefundContract = (signer?: ethers.Signer | ethers.providers.Provider) => {
return getContract(claimRefundAbi, getClaimRefundAddress(), signer)
}
diff --git a/src/utils/formatBalance.ts b/src/utils/formatBalance.ts
index d6dc839..860fba1 100644
--- a/src/utils/formatBalance.ts
+++ b/src/utils/formatBalance.ts
@@ -17,8 +17,9 @@ export const getBalanceAmount = (amount: BigNumber, decimals = 18) => {
/**
* This function is not really necessary but is used throughout the site.
*/
-export const getBalanceNumber = (balance: BigNumber, decimals = 18) => {
- return getBalanceAmount(balance, decimals).toNumber()
+export const getBalanceNumber = (balance: BigNumber, decimals = 18, decimalPlaces?: number) => {
+ const displayBalance = getBalanceAmount(balance, decimals)
+ return decimalPlaces ?displayBalance.decimalPlaces(decimalPlaces).toNumber():displayBalance.toNumber()
}
export const getFullDisplayBalance = (balance: BigNumber, decimals = 18, displayDecimals?: number) => {
diff --git a/src/views/Referral/index.tsx b/src/views/Referral/index.tsx
new file mode 100644
index 0000000..99dbbda
--- /dev/null
+++ b/src/views/Referral/index.tsx
@@ -0,0 +1,180 @@
+/* eslint-disable react-hooks/exhaustive-deps */
+/* eslint-disable no-unneeded-ternary */
+import React, { useEffect, useCallback, useState, useRef, useMemo } from 'react'
+import { Button, Heading, CopyToClipboard, Text, Flex } from '@pancakeswap/uikit'
+import styled from 'styled-components'
+import { State } from 'state/types'
+import { useDispatch, useSelector } from 'react-redux'
+import { useWeb3React } from '@web3-react/core'
+import { useTranslation } from 'contexts/Localization'
+import PageHeader from 'components/PageHeader'
+import Page from 'components/Layout/Page'
+import { getAddressInviteList } from 'services/referral'
+// import { useInviteHarvest } from 'hooks/useHarvest'
+import { fetchReferralInfoAsync } from 'state/actions'
+
+const Header = styled.div`
+ padding: 32px 0px;
+ padding-left: 16px;
+ padding-right: 16px;
+ text-align: center;
+
+ ${({ theme }) => theme.mediaQueries.sm} {
+ padding-left: 24px;
+ padding-right: 24px;
+ }
+`
+const PageContainer = styled(Page)`
+ max-width: 600px;
+ margin: 0 auto;
+`
+const LinkContainer = styled.div`
+ border: 1px solid rgb(216, 222, 227);
+ padding: 10px 0px;
+ line-height: 46px;
+ display: flex;
+ text-align: center;
+ flex-direction: column;
+ align-items: center;
+ border-radius: 2px;
+`
+const AddressContainer = styled.div`
+ border: 1px solid rgb(216, 222, 227);
+ margin-top: 20px;
+ text-align: center;
+`
+const AddressTitle = styled.div`
+ border-bottom: 1px solid rgb(216, 222, 227);
+ color: ${({ theme }) => theme.colors.primary};
+ font-size: 18px;
+ padding: 10px 20px;s
+ line-height: 28px;
+ background: rgb(244, 247, 250);
+ font-weight: 600;
+`
+const AddressList = styled.div`
+ font-size: 14px;
+ padding: 10px;
+ line-height: 24px;
+`
+const NoData = styled.div`
+ color: rgb(153, 153, 153);
+`
+const RewardContainer = styled.div`
+ text-align: center;
+ margin-bottom: 20px;
+`
+const SecondText = styled(Text)`
+ white-space: break-spaces;
+`
+const Farms: React.FC = () => {
+ const { t } = useTranslation()
+
+ const dispatch = useDispatch()
+ const { account } = useWeb3React()
+ const [inviteList, setInviteList] = useState([])
+ const [loading, setLoading] = useState(false)
+ const inviteInfo = useSelector((state: State) => state.referral.data)
+ const inviteAddress = useMemo(() => {
+ return inviteInfo.InviteCode
+ ? `${window.location.origin}/#/farms?code=${inviteInfo.InviteCode}`
+ : window.location.origin
+ }, [inviteInfo])
+ useEffect(() => {
+ if (account) {
+ getInviteList()
+ } else {
+ setInviteList([])
+ }
+ }, [account])
+ // const { onReward } = useInviteHarvest()
+ const handleWithdraw = async () => {
+ // setLoading(true)
+ // try {
+ // await onReward()
+ // dispatch(fetchReferralInfoAsync(account))
+ // setLoading(false)
+ // } catch (e) {
+ // setLoading(false)
+ // }
+ }
+ const getInviteList = async () => {
+ const data: any = await getAddressInviteList({ address: account })
+ setInviteList(data)
+ }
+ return (
+ <>
+
+
+
+
+ {t('Referral')}
+
+
+ {t('Share referral link and get rewards daily.')}
+
+
+ {t('Invite more friends, earn more rewards.')}
+
+
+
+ {/* */}
+
+
+
+ {/*
+
+ {t('Referral')}
+
+
+ {t('Share referral link and get rewards daily.')}
+
+ {t('Invite more friends, earn more rewards.')}
+
+ */}
+
+
+ {t('Total Rewards')}
+
+ {inviteInfo.totalReward ? Number(inviteInfo.totalReward).toFixed(5) : '0.00000'}
+
+
+
+ {t('Unclaimed Rewards')}
+
+ {inviteInfo.canWithdrawReward ? Number(inviteInfo.canWithdrawReward).toFixed(5) : '0.00000'}
+
+
+
+
+
+ {inviteAddress}
+
+ {t('Copy Link')}
+
+
+ {t('Address')}
+
+ {inviteList.length === 0 ? (
+ {t('No Data')}
+ ) : (
+ inviteList.map((item, index) => (
+
+ {item.Address}
+
+ ))
+ )}
+
+
+
+ >
+ )
+}
+
+export default Farms