feat: merge api (#658)

This commit is contained in:
Cafe137
2024-06-03 15:07:01 -07:00
committed by GitHub
parent b3f521ca20
commit 8cbd812a2c
43 changed files with 218 additions and 717 deletions
+28 -128
View File
@@ -2,7 +2,6 @@ import {
BeeModes,
ChainState,
ChequebookAddressResponse,
Health,
LastChequesResponse,
NodeAddresses,
NodeInfo,
@@ -10,8 +9,6 @@ import {
Topology,
} from '@ethersphere/bee-js'
import { ReactChild, ReactElement, createContext, useContext, useEffect, useState } from 'react'
import semver from 'semver'
import PackageJson from '../../package.json'
import { useLatestBeeRelease } from '../hooks/apiHooks'
import { BzzToken } from '../models/BzzToken'
import { Token } from '../models/Token'
@@ -38,9 +35,6 @@ interface StatusItem {
interface Status {
all: CheckState
version: StatusItem
blockchainConnection: StatusItem
debugApiConnection: StatusItem
apiConnection: StatusItem
topology: StatusItem
chequebook: StatusItem
@@ -48,15 +42,8 @@ interface Status {
interface ContextInterface {
status: Status
latestPublishedVersion?: string
latestUserVersion?: string
latestUserVersionExact?: string
isLatestBeeVersion: boolean
latestBeeVersionUrl: string
error: Error | null
apiHealth: boolean
debugApiHealth: Health | null
debugApiReadiness: boolean
nodeAddresses: NodeAddresses | null
nodeInfo: NodeInfo | null
topology: Topology | null
@@ -80,22 +67,12 @@ interface ContextInterface {
const initialValues: ContextInterface = {
status: {
all: CheckState.ERROR,
version: { isEnabled: false, checkState: CheckState.ERROR },
blockchainConnection: { isEnabled: false, checkState: CheckState.ERROR },
debugApiConnection: { isEnabled: false, checkState: CheckState.ERROR },
apiConnection: { isEnabled: false, checkState: CheckState.ERROR },
topology: { isEnabled: false, checkState: CheckState.ERROR },
chequebook: { isEnabled: false, checkState: CheckState.ERROR },
},
latestPublishedVersion: undefined,
latestUserVersion: undefined,
latestUserVersionExact: undefined,
isLatestBeeVersion: false,
latestBeeVersionUrl: 'https://github.com/ethersphere/bee/releases/latest',
error: null,
apiHealth: false,
debugApiHealth: null,
debugApiReadiness: false,
nodeAddresses: null,
nodeInfo: null,
topology: null,
@@ -124,40 +101,16 @@ interface Props {
}
function getStatus(
debugApiHealth: Health | null,
debugApiReadiness: boolean,
nodeInfo: NodeInfo | null,
apiHealth: boolean,
topology: Topology | null,
chequebookAddress: ChequebookAddressResponse | null,
chequebookBalance: ChequebookBalance | null,
error: Error | null,
isDesktop: boolean,
startedAt: number,
latestPublishedVersion: string | undefined,
latestUserVersion: string | undefined,
): Status {
const status: Status = { ...initialValues.status }
// Version check
status.version.isEnabled = !isDesktop
status.version.checkState =
latestPublishedVersion &&
latestUserVersion &&
semver.satisfies(latestPublishedVersion, latestUserVersion, {
includePrerelease: true,
})
? CheckState.OK
: CheckState.WARNING
// Blockchain connection check
status.blockchainConnection.isEnabled = true
status.blockchainConnection.checkState = Boolean(debugApiHealth?.status === 'ok') ? CheckState.OK : CheckState.ERROR
// Debug API connection check
status.debugApiConnection.isEnabled = true
status.debugApiConnection.checkState = Boolean(debugApiHealth?.status === 'ok') ? CheckState.OK : CheckState.ERROR
// API connection check
status.apiConnection.isEnabled = true
status.apiConnection.checkState = apiHealth ? CheckState.OK : CheckState.ERROR
@@ -177,17 +130,12 @@ function getStatus(
} else status.chequebook.checkState = CheckState.OK
}
status.all = determineOverallStatus(debugApiHealth, debugApiReadiness, status, startedAt)
status.all = determineOverallStatus(status, startedAt)
return status
}
function determineOverallStatus(
debugApiHealth: Health | null,
debugApiReadiness: boolean,
status: Status,
startedAt: number,
): CheckState {
function determineOverallStatus(status: Status, startedAt: number): CheckState {
const hasErrors = Object.values(status).some(
({ isEnabled, checkState }) => isEnabled && checkState === CheckState.ERROR,
)
@@ -196,9 +144,7 @@ function determineOverallStatus(
)
const isInGracePeriod = Date.now() - startedAt < LAUNCH_GRACE_PERIOD
if (debugApiHealth?.status === 'ok' && !debugApiReadiness) {
return CheckState.STARTING
} else if (hasErrors && isInGracePeriod) {
if (hasErrors && isInGracePeriod) {
return CheckState.CONNECTING
} else if (hasErrors) {
return CheckState.ERROR
@@ -212,19 +158,13 @@ function determineOverallStatus(
// This does not need to be exposed and works much better as variable than state variable which may trigger some unnecessary re-renders
let isRefreshing = false
interface InitialSettings {
isDesktop?: boolean
}
interface Props extends InitialSettings {
interface Props {
children: ReactChild
}
export function Provider({ children, isDesktop }: Props): ReactElement {
const { beeApi, beeDebugApi } = useContext(SettingsContext)
export function Provider({ children }: Props): ReactElement {
const { beeApi } = useContext(SettingsContext)
const [apiHealth, setApiHealth] = useState<boolean>(false)
const [debugApiHealth, setDebugApiHealth] = useState<Health | null>(null)
const [debugApiReadiness, setDebugApiReadiness] = useState(false)
const [nodeAddresses, setNodeAddresses] = useState<NodeAddresses | null>(null)
const [nodeInfo, setNodeInfo] = useState<NodeInfo | null>(null)
const [topology, setNodeTopology] = useState<Topology | null>(null)
@@ -246,10 +186,6 @@ export function Provider({ children, isDesktop }: Props): ReactElement {
const [lastUpdate, setLastUpdate] = useState<number | null>(initialValues.lastUpdate)
const [frequency, setFrequency] = useState<number | null>(30000)
const latestPublishedVersion = semver.coerce(latestBeeRelease?.name)?.version
const latestUserVersion = semver.coerce(debugApiHealth?.version)?.version
const latestUserVersionExact = debugApiHealth?.version
useEffect(() => {
setIsLoading(true)
@@ -260,8 +196,6 @@ export function Provider({ children, isDesktop }: Props): ReactElement {
useEffect(() => {
setIsLoading(true)
setDebugApiHealth(null)
setNodeAddresses(null)
setNodeTopology(null)
setNodeInfo(null)
@@ -273,15 +207,19 @@ export function Provider({ children, isDesktop }: Props): ReactElement {
setSettlements(null)
setChainState(null)
if (beeDebugApi !== null) refresh()
}, [beeDebugApi]) // eslint-disable-line react-hooks/exhaustive-deps
if (beeApi !== null) {
refresh()
}
}, [beeApi]) // eslint-disable-line react-hooks/exhaustive-deps
const refresh = async () => {
// Don't want to refresh when already refreshing
if (isRefreshing) return
if (isRefreshing) {
return
}
// Not a valid bee api
if (!beeApi || !beeDebugApi) {
if (!beeApi) {
setIsLoading(false)
return
@@ -293,7 +231,7 @@ export function Provider({ children, isDesktop }: Props): ReactElement {
// Wrap the chequebook balance call to return BZZ values as Token object
const chequeBalanceWrapper = async () => {
const { totalBalance, availableBalance } = await beeDebugApi.getChequebookBalance({ timeout: TIMEOUT })
const { totalBalance, availableBalance } = await beeApi.getChequebookBalance({ timeout: TIMEOUT })
return {
totalBalance: new Token(totalBalance),
@@ -303,14 +241,14 @@ export function Provider({ children, isDesktop }: Props): ReactElement {
// Wrap the balances call to return BZZ values as Token object
const peerBalanceWrapper = async () => {
const { balances } = await beeDebugApi.getAllBalances({ timeout: TIMEOUT })
const { balances } = await beeApi.getAllBalances({ timeout: TIMEOUT })
return balances.map(({ peer, balance }) => ({ peer, balance: new Token(balance) }))
}
// Wrap the settlements call to return BZZ values as Token object
const settlementsWrapper = async () => {
const { totalReceived, settlements, totalSent } = await beeDebugApi.getAllSettlements({ timeout: TIMEOUT })
const { totalReceived, settlements, totalSent } = await beeApi.getAllSettlements({ timeout: TIMEOUT })
return {
totalReceived: new Token(totalReceived),
@@ -330,62 +268,50 @@ export function Provider({ children, isDesktop }: Props): ReactElement {
.then(setApiHealth)
.catch(() => setApiHealth(false)),
// Debug API health
beeDebugApi
.getHealth({ timeout: TIMEOUT })
.then(setDebugApiHealth)
.catch(() => setDebugApiHealth(null)),
// Debug API readiness
beeDebugApi
.getReadiness({ timeout: TIMEOUT })
.then(setDebugApiReadiness)
.catch(() => setDebugApiReadiness(false)),
// Node Addresses
beeDebugApi
beeApi
.getNodeAddresses({ timeout: TIMEOUT })
.then(setNodeAddresses)
.catch(() => setNodeAddresses(null)),
// NodeInfo
beeDebugApi
beeApi
.getNodeInfo({ timeout: TIMEOUT })
.then(setNodeInfo)
.catch(() => setNodeInfo(null)),
// Network Topology
beeDebugApi
beeApi
.getTopology({ timeout: TIMEOUT })
.then(setNodeTopology)
.catch(() => setNodeTopology(null)),
// Peers
beeDebugApi
beeApi
.getPeers({ timeout: TIMEOUT })
.then(setPeers)
.catch(() => setPeers(null)),
// Chequebook address
beeDebugApi
beeApi
.getChequebookAddress({ timeout: TIMEOUT })
.then(setChequebookAddress)
.catch(() => setChequebookAddress(null)),
// Cheques
beeDebugApi
beeApi
.getLastCheques({ timeout: TIMEOUT })
.then(setPeerCheques)
.catch(() => setPeerCheques(null)),
// Chain state
beeDebugApi
beeApi
.getChainState({ timeout: TIMEOUT })
.then(setChainState)
.catch(() => setChainState(null)),
// Wallet
beeDebugApi
beeApi
.getWalletBalance({ timeout: TIMEOUT })
.then(({ chainID }) => setChainId(chainID))
.catch(() => setChainId(null)),
@@ -395,7 +321,7 @@ export function Provider({ children, isDesktop }: Props): ReactElement {
.then(setChequebookBalance)
.catch(() => setChequebookBalance(null)),
beeDebugApi
beeApi
.getStake({ timeout: TIMEOUT })
.then(stake => setStake(new BzzToken(stake)))
.catch(() => setStake(null)),
@@ -427,20 +353,7 @@ export function Provider({ children, isDesktop }: Props): ReactElement {
}
const stop = () => setFrequency(null)
const status = getStatus(
debugApiHealth,
debugApiReadiness,
nodeInfo,
apiHealth,
topology,
chequebookAddress,
chequebookBalance,
error,
Boolean(isDesktop),
startedAt,
latestPublishedVersion,
latestUserVersion,
)
const status = getStatus(nodeInfo, apiHealth, topology, chequebookAddress, chequebookBalance, error, startedAt)
useEffect(() => {
let newFrequency = REFRESH_WHEN_OK
@@ -458,27 +371,14 @@ export function Provider({ children, isDesktop }: Props): ReactElement {
return () => clearInterval(interval)
}
}, [frequency, beeDebugApi, beeApi]) // eslint-disable-line react-hooks/exhaustive-deps
}, [frequency, beeApi]) // eslint-disable-line react-hooks/exhaustive-deps
return (
<Context.Provider
value={{
status,
latestUserVersion,
latestUserVersionExact,
latestPublishedVersion,
isLatestBeeVersion: Boolean(
latestPublishedVersion &&
latestUserVersion &&
semver.satisfies(latestPublishedVersion, latestUserVersion, {
includePrerelease: true,
}),
),
latestBeeVersionUrl: latestBeeRelease?.html_url || 'https://github.com/ethersphere/bee/releases/latest',
error,
apiHealth,
debugApiHealth,
debugApiReadiness,
nodeAddresses,
nodeInfo,
topology,