Skip to content

Commit

Permalink
Merge pull request #425 from skalenetwork/add-validator-management-page
Browse files Browse the repository at this point in the history
Add validator management page
  • Loading branch information
dmytrotkk authored Dec 6, 2024
2 parents a618f3c + b75f2d7 commit 708ee7e
Show file tree
Hide file tree
Showing 59 changed files with 1,975 additions and 1,801 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "portal",
"private": true,
"version": "3.1.0",
"version": "3.2.0",
"type": "module",
"scripts": {
"build:testnet": "NETWORK_NAME=testnet bash build.sh",
Expand Down
Binary file modified packages/core/bun.lockb
Binary file not shown.
1 change: 0 additions & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
},
"author": "SKALE Labs",
"devDependencies": {
"ethers": "*.*.*",
"typescript": "^4.9.5"
}
}
19 changes: 19 additions & 0 deletions packages/core/src/types/staking/Delegation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,22 @@ export interface IDelegationInfo {
delegationId: bigint
delegationType: DelegationType
}

export interface IDelegationTotals {
proposed: {
count: number
amount: bigint
}
accepted: {
count: number
amount: bigint
}
delegated: {
count: number
amount: bigint
}
completed: {
count: number
amount: bigint
}
}
79 changes: 52 additions & 27 deletions src/App.scss
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ body {
width: 100%;
}

.fullH {
height: 100%;
}

.mp__btnConnect {
position: relative;

Expand Down Expand Up @@ -449,12 +453,8 @@ body::-webkit-scrollbar {
box-shadow: none !important;
}

.btnerror {
background: #f4433621;
}

.btnwarning {
background: rgb(244 139 54 / 13%);
.btnDisabled {
background: #262626;
}

.btnSmLoading {
Expand Down Expand Up @@ -543,6 +543,12 @@ body::-webkit-scrollbar {
}
}

.MuiToggleButton-root {
border-radius: 25px !important;
padding: 4px 10px;
border: none !important;
}

.copyBoard {
margin: 10px 0 !important;
padding: 13pt 15pt !important;
Expand Down Expand Up @@ -791,6 +797,22 @@ input[type=number] {
}
}

.chipNotification {
background: #e94e4e;
border-radius: 20px;
width: 20px;
height: 20px;
text-align: center;
display: flex;
align-items: center;
justify-content: center;

p {
color: #000000de !important;
font-weight: 600 !important;
}
}

.chipTrending {
background: linear-gradient(180deg, #e56d36, #D0602D) !important;

Expand Down Expand Up @@ -825,12 +847,13 @@ input[type=number] {
}

.chipXs {
border-radius: 20px;
padding: 3px 6px;
border-radius: 15px;
padding: 6px 8px;
text-align: center;

svg {
width: 14px;
height: 14px;
width: 12px;
height: 12px;
}
}

Expand All @@ -844,16 +867,6 @@ input[type=number] {
}
}

.chipXs {
border-radius: 15px;
padding: 4px 6px;

svg {
width: 12px;
height: 12px;
}
}

.skChip {
background: linear-gradient(180deg, rgb(52 52 52), rgb(31 31 31));
}
Expand Down Expand Up @@ -885,6 +898,11 @@ input[type=number] {
color: #3cda94;
}

.chip_REWARDS {
background: linear-gradient(180deg, #3d390f, #2a230a);
color: #dac83c;
}

.chip_ACCEPTED {
background: linear-gradient(180deg, #233d0f, #0a1b07);
color: #3cda4e;
Expand Down Expand Up @@ -1149,7 +1167,6 @@ input[type=number] {
}
}


.trustedBadge {
color: #0095f6;
}
Expand All @@ -1158,12 +1175,6 @@ input[type=number] {
color: #ffb817;
}

.validatorCard {
height: 100% !important;
cursor: pointer;
}


.pOneLine {
overflow: hidden;
white-space: nowrap;
Expand Down Expand Up @@ -1426,7 +1437,21 @@ input[type=number] {
display: none;
}

.opacity0 {
opacity: 0;
}

.MuiTooltip-tooltip {
font-size: 0.8rem !important;
padding: 8px 12px !important;
}

.delegationFlowText {
border-top: 2px #4a4a4a solid;
margin: 0 10px;
padding: 2px 5px 0 5px;
}

.delegationFlowIcon {
margin-top: -20px;
}
122 changes: 119 additions & 3 deletions src/Portal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,27 +21,143 @@
* @copyright SKALE Labs 2023-Present
*/

import { useState, useEffect } from 'react'
import { types } from '@/core'

import Box from '@mui/material/Box'
import CssBaseline from '@mui/material/CssBaseline'
import { useMetaportStore, useWagmiAccount, Debug, cls, cmn } from '@skalenetwork/metaport'
import {
useMetaportStore,
useWagmiAccount,
Debug,
cls,
cmn,
PROXY_ENDPOINTS
} from '@skalenetwork/metaport'

import Header from './Header'
import SkDrawer from './SkDrawer'
import Router from './Router'
import SkBottomNavigation from './SkBottomNavigation'
import ProfileModal from './components/profile/ProfileModal'

import { formatSChains } from './core/chain'
import { STATS_API } from './core/constants'
import { getValidatorDelegations } from './core/delegation/staking'
import { getValidator } from './core/delegation'
import { initContracts } from './core/contracts'

export default function Portal() {
const mpc = useMetaportStore((state) => state.mpc)

const [schains, setSchains] = useState<types.ISChain[]>([])
const [metrics, setMetrics] = useState<types.IMetrics | null>(null)
const [stats, setStats] = useState<types.IStats | null>(null)
const [validator, setValidator] = useState<types.staking.IValidator | null | undefined>(null)
const [validatorDelegations, setValidatorDelegations] = useState<
types.staking.IDelegation[] | null
>(null)
const [customAddress, setCustomAddress] = useState<types.AddressType | undefined>(undefined)
const [sc, setSc] = useState<types.staking.ISkaleContractsMap | null>(null)
const [loadCalled, setLoadCalled] = useState<boolean>(false)

const endpoint = PROXY_ENDPOINTS[mpc.config.skaleNetwork]
const statsApi = STATS_API[mpc.config.skaleNetwork]

const { address } = useWagmiAccount()
if (!mpc) return <div></div>

useEffect(() => {
initSkaleContracts()
loadData()
}, [])

useEffect(() => {
loadValidator()
}, [address, customAddress, sc])

async function initSkaleContracts() {
setLoadCalled(true)
if (loadCalled) return
setSc(await initContracts(mpc))
}

async function loadChains() {
try {
const response = await fetch(`https://${endpoint}/files/chains.json`)
const chainsJson = await response.json()
setSchains(formatSChains(chainsJson))
} catch (e) {
console.log('Failed to load chains')
console.error(e)
}
}

async function loadMetrics() {
try {
const response = await fetch(`https://${endpoint}/files/metrics.json`)
const metricsJson = await response.json()
setMetrics(metricsJson)
} catch (e) {
console.log('Failed to load metrics')
console.error(e)
}
}

async function loadStats() {
if (statsApi === null) return
try {
const response = await fetch(statsApi)
const statsResp = await response.json()
setStats(statsResp.payload)
} catch (e) {
console.log('Failed to load stats')
console.error(e)
}
}

async function loadValidator() {
const addr = customAddress ?? address
if (!sc || !addr) {
setValidator(null)
setValidatorDelegations(null)
return
}
const validatorData = await getValidator(sc.validatorService, addr)
setValidator(validatorData)
if (validatorData && validatorData.id) {
setValidatorDelegations(await getValidatorDelegations(sc, validatorData.id))
} else {
setValidator(undefined)
setValidatorDelegations(null)
}
}

async function loadData() {
loadChains()
loadMetrics()
loadStats()
loadValidator()
}

return (
<Box sx={{ display: 'flex' }} className="AppWrap">
<CssBaseline />
<Header address={address} mpc={mpc} />
<SkDrawer />
<SkDrawer validatorDelegations={validatorDelegations} />
<div className={cls(cmn.fullWidth)} id="appContentScroll">
<Router />
<Router
loadData={loadData}
schains={schains}
metrics={metrics}
stats={stats}
validator={validator}
validatorDelegations={validatorDelegations}
customAddress={customAddress}
setCustomAddress={setCustomAddress}
sc={sc}
loadValidator={loadValidator}
/>
<ProfileModal />
<div className={cls(cmn.mtop20, cmn.fullWidth)}>
<Debug />
Expand Down
Loading

0 comments on commit 708ee7e

Please sign in to comment.