Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions .github/workflows/build_deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
with:
fetch-depth: 0

- uses: actions/cache@v2
- uses: actions/cache@v3
with:
path: '**/node_modules'
key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }}
Expand Down Expand Up @@ -57,7 +59,7 @@ jobs:
# </explorer.stage.ssv.network>

# <explorer.ssv.network>
- name: Run prod beta build
- name: Run prod build
if: github.ref == 'refs/heads/main'
env:
NODE_OPTIONS: '--openssl-legacy-provider'
Expand All @@ -68,7 +70,7 @@ jobs:
MIXPANEL_TOKEN: ${{ secrets.MIXPANEL_TOKEN_PROD }}
run: yarn build

- name: Deploy prod beta
- name: Deploy prod
if: github.ref == 'refs/heads/main'
uses: jakejarvis/s3-sync-action@v0.5.0
with:
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,5 @@ cypress/plugins/ssv-network
tmp
tmp/*
yarn.lock
/.vscode/
/.idea/
6 changes: 6 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"cSpell.words": [
"HOLESKY",
"Hoodi"
]
}
8 changes: 6 additions & 2 deletions src/app/common/components/NetworkIcon/NetworkIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@ import { useStores } from '~app/hooks/useStores';
import ApplicationStore from '~app/common/stores/Application.store';
import { EChain } from '~lib/utils/ChainService';

const NetworkIcon = (props: { network: EChain } & ImgHTMLAttributes<unknown>) => {
const NetworkIcon = (
props: { isTestnet: boolean; network: EChain } & ImgHTMLAttributes<unknown>,
) => {
const stores = useStores();
const applicationStore: ApplicationStore = stores.Application;
const imgSrc = `/images/networks/${props.network}${applicationStore.isDarkMode ? '_light' : '_dark'}.svg`;
const imgSrc = `/images/networks/${props.isTestnet ? 'testnet' : 'mainnet'}${
applicationStore.isDarkMode ? '_light' : '_dark'
}.svg`;

return (
<img width="24" height="24" src={imgSrc} alt={props.network} {...props} />
Expand Down
15 changes: 13 additions & 2 deletions src/app/common/components/NetworkSelect/NetworkSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,23 @@ import NetworkIcon from '~app/common/components/NetworkIcon';
import { useStyles } from './NeworkSelect.styles';
import { KeyboardArrowDown } from '@material-ui/icons';

const availableNetworks = [EChain.Ethereum, EChain.Holesky];
const availableNetworks = [EChain.Ethereum, EChain.Holesky, EChain.Hoodi];

const networkToConfigMap = {
[EChain.Ethereum]: {
url: 'https://explorer.ssv.network',
label: 'Ethereum Mainnet',
isTestnet: false,
},
[EChain.Holesky]: {
url: 'https://holesky.explorer.ssv.network',
label: 'Holesky Testnet',
isTestnet: true,
},
[EChain.Hoodi]: {
url: 'https://hoodi.explorer.ssv.network',
label: 'Hoodi Testnet',
isTestnet: true,
},
};

Expand Down Expand Up @@ -66,7 +73,11 @@ export default function NetworkSelect() {
{availableNetworks.map((net) => (
<MenuItem value={net}>
<div className={classes.ItemWrapper}>
<NetworkIcon network={net} className={classes.ItemIcon} />
<NetworkIcon
isTestnet={networkToConfigMap[net].isTestnet}
network={net}
className={classes.ItemIcon}
/>
{networkToConfigMap[net].label}
</div>
</MenuItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,10 @@ const ValidatorsInOperatorTable = (props: ValidatorsInOperatorTableProps) => {
const classes = useStyles({});
const { validators, pagination, params, isLoading, onLoadPage, onChangeRowsPerPage, perPage } = props;
const validatorsTitle = `${pagination?.total ? pagination?.total : ''} Validator${(pagination?.total ?? 0) > 1 || pagination?.total === 0 ? 's' : ''}`;
const currentNetwork = chainService().getNetwork();
const isHoleskyTestnet = currentNetwork === EChain.Holesky;
const isTestnet = chainService().isCurrentNetworkTestnet();

const statusComponent = (validator: any) => {
return isHoleskyTestnet && <Status entry={validator} />;
return isTestnet && <Status entry={validator} />;
};

return (
Expand Down
5 changes: 2 additions & 3 deletions src/app/components/Validator/Validator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,8 @@ const Validator = () => {
const [notFound, setNotFound] = useState(false);
const [validator, setValidator] = useState(defaultValidator);
const [loadingValidator, setLoadingValidator] = useState(false);
const currentNetwork = chainService().getNetwork();
const isHoleskyTestnet = currentNetwork === EChain.Holesky;
const isNotDepositedValidator = (Object.keys(validator.validator_info || {}).length === 0) && isHoleskyTestnet;
const isTestnet = chainService().isCurrentNetworkTestnet();
const isNotDepositedValidator = (Object.keys(validator.validator_info || {}).length === 0) && isTestnet;

/**
* Fetch one operator by it's address
Expand Down
58 changes: 34 additions & 24 deletions src/lib/utils/ChainService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,48 @@
import config from '~app/common/config';

export enum EChain {
Holesky = 'holesky',
Ethereum = 'mainnet', // ethereum
Holesky = 'holesky',
Ethereum = 'mainnet', // ethereum
Hoodi = 'hoodi',
}

export const CHAIN = {
HOLESKY: EChain.Holesky,
ETHEREUM: EChain.Ethereum,
HOLESKY: EChain.Holesky,
ETHEREUM: EChain.Ethereum,
HOODI: EChain.Hoodi,
};

function extractChain(apiUrl: string): string {
const match = apiUrl.match(/\/([^/]+)$/);
if (match) {
return match[1];
}
throw new Error('Failed to instantiate a chain service. Chain missing in api url.');
const match = apiUrl.match(/\/([^/]+)$/);
if (match) {
return match[1];
}
throw new Error(
'Failed to instantiate a chain service. Chain missing in api url.',
);
}

const chainService = () => {
let chain: EChain | string = '';

const extractedChainName: string = extractChain(config.links.API_COMPLETE_BASE_URL);
if (Object.values(EChain).includes(extractedChainName as EChain)) {
chain = extractedChainName;
} else {
throw new Error('Failed to instantiate a chain service. Provided chain name not supported.');
}
const getChainPrefix = (): string => chain === EChain.Ethereum ? '' : `${chain}.`;
const getBeaconchaUrl = (): string => `https://${getChainPrefix()}beaconcha.in`;
const getNetwork = () => chain.toString();
const isChain = (other: EChain): boolean => chain === other;

return { getBeaconchaUrl, getNetwork, isChain };
let chain: EChain | string = '';

const extractedChainName: string = extractChain(
config.links.API_COMPLETE_BASE_URL,
);
if (Object.values(EChain).includes(extractedChainName as EChain)) {
chain = extractedChainName;
} else {
throw new Error(
'Failed to instantiate a chain service. Provided chain name not supported.',
);
}
const getChainPrefix = (): string => chain === EChain.Ethereum ? '' : `${chain}.`;
const getBeaconchaUrl = (): string => `https://${getChainPrefix()}beaconcha.in`;
const getNetwork = () => chain.toString();
const isChain = (other: EChain): boolean => chain === other;

const isCurrentNetworkTestnet = (): boolean => chain === EChain.Holesky || chain === EChain.Hoodi;

return { getBeaconchaUrl, getNetwork, isChain, isCurrentNetworkTestnet };
};

export default chainService;
export default chainService;