diff --git a/src/chains.ts b/src/chains.ts index e6e380e5..47783e05 100644 --- a/src/chains.ts +++ b/src/chains.ts @@ -25,10 +25,9 @@ const ETH: AddEthereumChainParameter['nativeCurrency'] = { decimals: 18, } -export const RPC_URL_ETHEREUM = - process.env.REACT_APP_RPC_URL_ETHEREUM && process.env.NODE_ENV !== 'development' - ? process.env.REACT_APP_RPC_URL_ETHEREUM - : 'https://eth.llamarpc.com' +export const RPC_URL_ETHEREUM = process.env.REACT_APP_RPC_URL_ETHEREUM + ? process.env.REACT_APP_RPC_URL_ETHEREUM + : 'https://eth.llamarpc.com' export const RPC_URL_ARBITRUM = 'https://arbitrum.blockpi.network/v1/rpc/public' export const RPC_URL_OPTIMISM = 'https://op-pokt.nodies.app' export const RPC_URL_POLYGON = 'https://polygon-bor-rpc.publicnode.com' diff --git a/src/components/Bolts/AddressCell.tsx b/src/components/Bolts/AddressCell.tsx index ff154c42..528100d3 100644 --- a/src/components/Bolts/AddressCell.tsx +++ b/src/components/Bolts/AddressCell.tsx @@ -7,18 +7,18 @@ import styled from 'styled-components' interface AddressCellProps { address: string - userFuulDataAddress: string + userBoltsDataAddress: string data: LeaderboardUser[] } -const AddressCell: React.FC = ({ address, userFuulDataAddress, data }) => { +const AddressCell: React.FC = ({ address, userBoltsDataAddress, data }) => { const userInTop10 = useMemo(() => data.find((user) => user.rank <= 10 && user.address === address), [data, address]) // Skip ENS check for users not in the top 10 const resolvedAddress = useAddress(address, 0, !userInTop10) return (
- {userFuulDataAddress === address && ( + {userBoltsDataAddress === address && ( = ({ address, userFuulDataAddress, export default React.memo(AddressCell, (prevProps, nextProps) => { return ( prevProps.address === nextProps.address && - prevProps.userFuulDataAddress === nextProps.userFuulDataAddress && + prevProps.userBoltsDataAddress === nextProps.userBoltsDataAddress && prevProps.data === nextProps.data ) }) diff --git a/src/containers/Bolts/Leaderboard.tsx b/src/containers/Bolts/Leaderboard.tsx index 7a64955d..cbf759b9 100644 --- a/src/containers/Bolts/Leaderboard.tsx +++ b/src/containers/Bolts/Leaderboard.tsx @@ -21,7 +21,7 @@ import { LeaderboardUser } from '~/model/boltsModel' const columnHelper = createColumnHelper() // @ts-ignore -const Table = ({ data, userFuulData }) => { +const Table = ({ data, userBoltsData }) => { const [sorting, setSorting] = useState([]) const [globalFilter, setGlobalFilter] = useState('') const [isTableReady, setIsTableReady] = useState(false) @@ -39,16 +39,16 @@ const Table = ({ data, userFuulData }) => { const displayData = useMemo(() => { let dataToDisplay = [...data.slice(0, 10)] - if (userFuulData.points) { + if (userBoltsData.bolts) { const userInTop10 = data.find( - (user: LeaderboardUser) => user.address === userFuulData.address && user.rank <= 10 + (user: LeaderboardUser) => user.address === userBoltsData.address && user.rank <= 10 ) if (!userInTop10) { - dataToDisplay.push(userFuulData) + dataToDisplay.push(userBoltsData) } } return dataToDisplay - }, [data, userFuulData]) + }, [data, userBoltsData]) const columns = [ columnHelper.accessor('rank', { @@ -60,7 +60,7 @@ const Table = ({ data, userFuulData }) => { if (rank <= 3) { color = '#FFFFFF' badge = - } else if (rank === userFuulData.rank) { + } else if (rank === userBoltsData.rank) { color = '#1A74EC' } return ( @@ -75,11 +75,11 @@ const Table = ({ data, userFuulData }) => { header: 'Address', cell: (info) => { const address = info.getValue() - return + return }, }), - columnHelper.accessor('points', { - header: 'Points', + columnHelper.accessor('bolts', { + header: 'Bolts', // @ts-ignore cell: (info) => {info.getValue().toLocaleString()}, }), @@ -144,7 +144,7 @@ const Table = ({ data, userFuulData }) => { key={row.id} style={ // @ts-ignore - row.original.address === userFuulData.address + row.original.address === userBoltsData.address ? { backgroundColor: '#8DB2FF99' } : { backgroundColor: '#1A74EC' } } @@ -156,7 +156,7 @@ const Table = ({ data, userFuulData }) => { else tdStyle = { paddingTop: '10px', color: '#eeeeee' } if (index === 0) tdStyle.paddingBottom = '10px' // @ts-ignore - if (row?.original.address === userFuulData.address) tdStyle.color = '#1A74EC' + if (row?.original.address === userBoltsData.address) tdStyle.color = '#1A74EC' return ( diff --git a/src/containers/Bolts/index.tsx b/src/containers/Bolts/index.tsx index a845ccd0..57c30f28 100644 --- a/src/containers/Bolts/index.tsx +++ b/src/containers/Bolts/index.tsx @@ -11,7 +11,7 @@ import { useStoreState, useStoreActions } from '~/store' const Bolts = () => { const { account } = useActiveWeb3React() - const userFuulData = useStoreState((state) => state.boltsModel.userFuulData) + const userBoltsData = useStoreState((state) => state.boltsModel.userBoltsData) const leaderboardData = useStoreState((state) => state.boltsModel.leaderboardData) const boltsEarnedData = useStoreState((state) => state.boltsModel.boltsEarnedData) const fetchData = useStoreActions((actions) => actions.boltsModel.fetchData) @@ -28,7 +28,7 @@ const Bolts = () => {
Leaderboard - +
diff --git a/src/containers/Bolts/quests.tsx b/src/containers/Bolts/quests.tsx index f7e444eb..af5b519b 100644 --- a/src/containers/Bolts/quests.tsx +++ b/src/containers/Bolts/quests.tsx @@ -108,31 +108,11 @@ export type BoltsEarnedData = { [key: string]: string } -export const MULTIPLIERS = (boltsEarnedData: BoltsEarnedData) => [ - { - title: 'Invite a Friend', - text: ( - <> - Create a referral link by signing a message with your wallet. - - - ), - button: '', - items: [ - { - title: 'Source', - status: , - }, - { - title: 'Bolts', - status: '10% of referrals + friends receive 250 Bolts per ETH deposited for 30 days', - }, - { - title: 'Earned', - status: boltsEarnedData['Invite a Friend'] || '-', - }, - ], - }, +export type MultipliersData = { + [key: string]: string +} + +export const MULTIPLIERS = (multipliersData: MultipliersData) => [ { title: 'Genesis NFV User', button: ( @@ -147,7 +127,7 @@ export const MULTIPLIERS = (boltsEarnedData: BoltsEarnedData) => [ status: , }, { title: 'Bolts', status: '+10% to deposit/borrow' }, - { title: 'Holder', status: boltsEarnedData['GenesisNFV'] || '-' }, + { title: 'Holder', status: multipliersData['GENESIS_NFV'] || '-' }, ], }, { @@ -180,7 +160,7 @@ export const MULTIPLIERS = (boltsEarnedData: BoltsEarnedData) => [ items: [ { title: 'Source', status: 'Guild.xyz' }, { title: 'Bolts', status: '+3% to all points' }, - { title: 'Holder', status: boltsEarnedData['OgNFT'] || '-' }, + { title: 'Holder', status: multipliersData['OG_NFT'] || '-' }, ], }, { @@ -212,7 +192,7 @@ export const MULTIPLIERS = (boltsEarnedData: BoltsEarnedData) => [ items: [ { title: 'Source', status: 'NFTs2Me' }, { title: 'Bolts', status: '+7% to all points' }, - { title: 'Holder', status: boltsEarnedData['GenesisNFT'] || '-' }, + { title: 'Holder', status: multipliersData['GENESIS_NFT'] || '-' }, ], }, { @@ -225,7 +205,7 @@ export const MULTIPLIERS = (boltsEarnedData: BoltsEarnedData) => [ status: , }, { title: 'Bolts', status: '+30%' }, - { title: 'Earned', status: boltsEarnedData['Community Goal: 20K ETH TVL'] || '-' }, + { title: 'Earned', status: multipliersData['ETH_TVL_20K'] || '-' }, ], }, ] @@ -250,7 +230,7 @@ export const QUESTS = (boltsEarnedData: BoltsEarnedData) => [ status: , }, { title: 'Bolts', status: '500 per ETH' }, - { title: 'Earned', status: boltsEarnedData[3] || '-' }, + { title: 'Earned', status: boltsEarnedData['COLLATERAL_DEPOSIT'] || '-' }, ], }, { @@ -270,7 +250,7 @@ export const QUESTS = (boltsEarnedData: BoltsEarnedData) => [ status: , }, { title: 'Bolts', status: '1,000 per ETH' }, - { title: 'Earned', status: boltsEarnedData[1] || '-' }, + { title: 'Earned', status: boltsEarnedData['DEBT_BORROW'] || '-' }, ], }, { @@ -297,7 +277,7 @@ export const QUESTS = (boltsEarnedData: BoltsEarnedData) => [ items: [ { title: 'Source', status: }, { title: 'Bolts', status: '2,000 per ETH' }, - { title: 'Earned', status: boltsEarnedData[8] || '-' }, + { title: 'Earned', status: boltsEarnedData['ODG_ETH_LP'] || '-' }, ], }, { @@ -324,34 +304,53 @@ export const QUESTS = (boltsEarnedData: BoltsEarnedData) => [ items: [ { title: 'Source', status: }, { title: 'Bolts', status: '3,000 per ETH' }, - { title: 'Earned', status: boltsEarnedData[7] || '-' }, + { title: 'Earned', status: boltsEarnedData['OD_ETH_LP'] || '-' }, ], }, { - title: 'Galxe and Zealy', + title: 'Galxe', button: ( <> + + ), + text: 'Complete quests on Galxe.', + items: [ + { + title: 'Source', + status: ( + <> + + + ), + }, + { title: 'Bolts', status: '1 per Point' }, + { title: 'Earned', status: boltsEarnedData['GALXE'] || '-' }, + ], + }, + { + title: 'Zealy', + button: ( + <> ), - text: 'Complete tasks on Galxe and Zealy to earn Bolts.', + text: 'Complete quests on Zealy.', items: [ { title: 'Source', status: ( <> - ), }, - { title: 'Bolts', status: 'Varies' }, - { title: 'Earned', status: boltsEarnedData[6] || '-' }, + { title: 'Bolts', status: '1 per Point' }, + { title: 'Earned', status: boltsEarnedData['ZEALY'] || '-' }, ], }, ] diff --git a/src/model/boltsModel.ts b/src/model/boltsModel.ts index d9386ad1..349fae49 100644 --- a/src/model/boltsModel.ts +++ b/src/model/boltsModel.ts @@ -1,26 +1,24 @@ import { action, Action, thunk, Thunk } from 'easy-peasy' -import { BoltsEarnedData } from '~/containers/Bolts/quests' +import { BoltsEarnedData, MultipliersData } from '~/containers/Bolts/quests' -type Conversion = { - is_referrer: boolean - conversion_id: number - conversion_name: string - total_amount: string +type Campaign = { + type: number + amount: string } export type LeaderboardUser = { rank: number address: string - points: number + bolts: number ens?: string } export interface BoltsModel { - userFuulData: { + userBoltsData: { rank: string - points: string + bolts: string } - setUserFuulData: Action + setUserBoltsData: Action leaderboardData: LeaderboardUser[] setLeaderboardData: Action @@ -28,6 +26,9 @@ export interface BoltsModel { boltsEarnedData: BoltsEarnedData setBoltsEarnedData: Action + multipliersData: MultipliersData + setMultipliersData: Action + hasFetched: boolean setHasFetched: Action @@ -38,12 +39,12 @@ export interface BoltsModel { } const boltsModel: BoltsModel = { - userFuulData: { + userBoltsData: { rank: '', - points: '', + bolts: '', }, - setUserFuulData: action((state, payload) => { - state.userFuulData = payload + setUserBoltsData: action((state, payload) => { + state.userBoltsData = payload }), leaderboardData: [], @@ -56,6 +57,11 @@ const boltsModel: BoltsModel = { state.boltsEarnedData = payload }), + multipliersData: {}, + setMultipliersData: action((state, payload) => { + state.multipliersData = payload + }), + hasFetched: false, setHasFetched: action((state, payload) => { state.hasFetched = payload @@ -68,46 +74,38 @@ const boltsModel: BoltsModel = { fetchData: thunk(async (actions, { account }, { getState }) => { try { - const BOT_DOMAIN = 'https://bot.opendollar.com' + const BOT_DOMAIN = process.env.REACT_APP_OD_API_URL + ? process.env.REACT_APP_OD_API_URL + : 'https://bot.opendollar.com' const BOT_API = `${BOT_DOMAIN}/api/bolts` const response = account ? await fetch(`${BOT_API}?address=${account}`) : await fetch(BOT_API) const result = await response.json() if (result.success) { - const users = result.data.fuul.leaderboard.users + const { leaderboard, user } = result.data const state = getState() // Populate ENS cache for leaderboard users - users.forEach((user: LeaderboardUser) => { + leaderboard.forEach((user: LeaderboardUser) => { const ens = state.ensCache[user.address] || null if (ens) { user.ens = ens } }) - actions.setLeaderboardData(users) - - if (account) { - actions.setUserFuulData(result.data.fuul.user) - + actions.setLeaderboardData(leaderboard) + if (account && user) { const boltsEarned: BoltsEarnedData = {} - const { data } = result - let combinedBorrowBolts = 0 - let combinedDepositBolts = 0 - data.fuul.user.conversions.forEach((conversion: Conversion) => { - if ([1, 2].includes(conversion.conversion_id)) - combinedBorrowBolts += parseInt(conversion.total_amount) - else if ([3, 4].includes(conversion.conversion_id)) - combinedDepositBolts += parseInt(conversion.total_amount) - else boltsEarned[conversion.conversion_id] = parseInt(conversion.total_amount).toLocaleString() + const multipliers: MultipliersData = {} + user.campaigns?.forEach((campaign: Campaign) => { + boltsEarned[campaign.type] = campaign.amount.toLocaleString() + }) + user.multipliers?.forEach((multiplier: Campaign) => { + multipliers[multiplier.type] = multiplier.amount }) - boltsEarned[1] = combinedBorrowBolts.toLocaleString() - boltsEarned[3] = combinedDepositBolts.toLocaleString() - - boltsEarned['OgNFT'] = data.OgNFT ? 'Yes' : 'No' - boltsEarned['GenesisNFV'] = data.GenesisNFV ? 'Yes' : 'No' - boltsEarned['GenesisNFT'] = data.GenesisNFT ? 'Yes' : 'No' + actions.setUserBoltsData(user) actions.setBoltsEarnedData(boltsEarned) + actions.setMultipliersData(multipliers) } } actions.setHasFetched(true) diff --git a/src/services/checkSanctions.ts b/src/services/checkSanctions.ts index dddf6ec9..fb134d70 100644 --- a/src/services/checkSanctions.ts +++ b/src/services/checkSanctions.ts @@ -3,7 +3,11 @@ import axios from 'axios' async function checkSanctions(address: string) { let res try { - res = await axios.get(`https://bot.opendollar.com/api/screen?address=${address}`, { + const BOT_DOMAIN = process.env.REACT_APP_OD_API_URL + ? process.env.REACT_APP_OD_API_URL + : 'https://bot.opendollar.com' + const BOT_API = `${BOT_DOMAIN}/screen?address=${address}` + res = await axios.get(BOT_API, { headers: { Accept: 'application/json', },