Skip to content

Commit

Permalink
Merge pull request #2253 from blockscout/fe-2233
Browse files Browse the repository at this point in the history
add blackfort validators
  • Loading branch information
isstuev authored Sep 23, 2024
2 parents 3716c2f + 35b715c commit 55bc66e
Show file tree
Hide file tree
Showing 32 changed files with 648 additions and 91 deletions.
44 changes: 44 additions & 0 deletions configs/envs/.env.blackfort_testnet
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Set of ENVs for BXN Testnet network explorer
# https://blackfort-testnet.blockscout.com
# This is an auto-generated file. To update all values, run "yarn dev:preset:sync --name=blackfort_testnet"

# Local ENVs
NEXT_PUBLIC_APP_PROTOCOL=http
NEXT_PUBLIC_APP_HOST=localhost
NEXT_PUBLIC_APP_PORT=3000
NEXT_PUBLIC_APP_ENV=development
NEXT_PUBLIC_API_WEBSOCKET_PROTOCOL=ws

# Instance ENVs
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=blackfort-testnet.blockscout.com
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
NEXT_PUBLIC_CONTRACT_CODE_IDES=[{'title':'Remix IDE','url':'https://remix.ethereum.org/?address={hash}&blockscout={domain}','icon_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/ide-icons/remix.png'}]
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com
NEXT_PUBLIC_FEATURED_NETWORKS=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/featured-networks/blackfort-testnet.json
NEXT_PUBLIC_FOOTER_LINKS=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/footer-links/blackfort.json
NEXT_PUBLIC_GRAPHIQL_TRANSACTION=0xcb4140e22cde3412eb5aecdedf2403032c7a251f5c96b11122aca5b1b88ed953
NEXT_PUBLIC_HOMEPAGE_CHARTS=['daily_txs']
NEXT_PUBLIC_HOMEPAGE_PLATE_BACKGROUND=linear-gradient(92deg, rgb(3, 150, 254) 0.24%, rgb(36, 209, 245) 98.31%)
NEXT_PUBLIC_IS_TESTNET=true
NEXT_PUBLIC_MARKETPLACE_ENABLED=false
NEXT_PUBLIC_METADATA_SERVICE_API_HOST=https://metadata.services.blockscout.com
NEXT_PUBLIC_NETWORK_CURRENCY_DECIMALS=18
NEXT_PUBLIC_NETWORK_CURRENCY_NAME=TBXN
NEXT_PUBLIC_NETWORK_CURRENCY_SYMBOL=TBXN
NEXT_PUBLIC_NETWORK_ICON=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-icons/blackfort.svg
NEXT_PUBLIC_NETWORK_ICON_DARK=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-icons/blackfort-dark.svg
NEXT_PUBLIC_NETWORK_ID=4777
NEXT_PUBLIC_NETWORK_LOGO=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-logos/blackfort.svg
NEXT_PUBLIC_NETWORK_LOGO_DARK=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-logos/blackfort-dark.svg
NEXT_PUBLIC_NETWORK_NAME=BXN Testnet
NEXT_PUBLIC_NETWORK_RPC_URL=https://testnet.blackfort.network/rpc
NEXT_PUBLIC_NETWORK_SHORT_NAME=BXN Testnet
NEXT_PUBLIC_OG_ENHANCED_DATA_ENABLED=true
NEXT_PUBLIC_OG_IMAGE_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/og-images/blackfort.png
NEXT_PUBLIC_STATS_API_HOST=https://stats-blackfort-testnet.k8s.blockscout.com
NEXT_PUBLIC_TRANSACTION_INTERPRETATION_PROVIDER=blockscout
NEXT_PUBLIC_VIEWS_CONTRACT_SOLIDITYSCAN_ENABLED=true
NEXT_PUBLIC_VISUALIZE_API_HOST=https://visualizer.services.blockscout.com
NEXT_PUBLIC_VALIDATORS_CHAIN_TYPE=blackfort
2 changes: 1 addition & 1 deletion docs/ENVS.md
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,7 @@ The feature enables the Validators page which provides detailed information abou

| Variable | Type| Description | Compulsoriness | Default value | Example value | Version |
| --- | --- | --- | --- | --- | --- | --- |
| NEXT_PUBLIC_VALIDATORS_CHAIN_TYPE | `'stability'` | Chain type | Required | - | `'stability'` | v1.25.0+ |
| NEXT_PUBLIC_VALIDATORS_CHAIN_TYPE | `'stability' \| 'blackfort'` | Chain type | Required | - | `'stability'` | v1.25.0+ |

 

Expand Down
40 changes: 28 additions & 12 deletions lib/api/resources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,15 @@ import type { TxInterpretationResponse } from 'types/api/txInterpretation';
import type { TTxsFilters, TTxsWithBlobsFilters } from 'types/api/txsFilters';
import type { TxStateChanges } from 'types/api/txStateChanges';
import type { UserOpsResponse, UserOp, UserOpsFilters, UserOpsAccount } from 'types/api/userOps';
import type { ValidatorsCountersResponse, ValidatorsFilters, ValidatorsResponse, ValidatorsSorting } from 'types/api/validators';
import type {
ValidatorsStabilityCountersResponse,
ValidatorsStabilityFilters,
ValidatorsStabilityResponse,
ValidatorsStabilitySorting,
ValidatorsBlackfortCountersResponse,
ValidatorsBlackfortResponse,
ValidatorsBlackfortSorting,
} from 'types/api/validators';
import type { VerifiedContractsSorting } from 'types/api/verifiedContracts';
import type { WithdrawalsResponse, WithdrawalsCounters } from 'types/api/withdrawals';
import type {
Expand Down Expand Up @@ -897,14 +905,19 @@ export const RESOURCES = {
},

// VALIDATORS
validators: {
path: '/api/v2/validators/:chainType',
pathParams: [ 'chainType' as const ],
validators_stability: {
path: '/api/v2/validators/stability',
filterFields: [ 'address_hash' as const, 'state_filter' as const ],
},
validators_counters: {
path: '/api/v2/validators/:chainType/counters',
pathParams: [ 'chainType' as const ],
validators_stability_counters: {
path: '/api/v2/validators/stability/counters',
},
validators_blackfort: {
path: '/api/v2/validators/blackfort',
filterFields: [],
},
validators_blackfort_counters: {
path: '/api/v2/validators/blackfort/counters',
},

// BLOBS
Expand Down Expand Up @@ -1002,7 +1015,7 @@ export type PaginatedResources = 'blocks' | 'block_txs' | 'block_election_reward
'zksync_l2_txn_batches' | 'zksync_l2_txn_batch_txs' |
'withdrawals' | 'address_withdrawals' | 'block_withdrawals' |
'watchlist' | 'private_tags_address' | 'private_tags_tx' |
'domains_lookup' | 'addresses_lookup' | 'user_ops' | 'validators' | 'noves_address_history';
'domains_lookup' | 'addresses_lookup' | 'user_ops' | 'validators_stability' | 'validators_blackfort' | 'noves_address_history';

export type PaginatedResponse<Q extends PaginatedResources> = ResourcePayload<Q>;

Expand Down Expand Up @@ -1123,8 +1136,10 @@ Q extends 'address_metadata_tag_types' ? PublicTagTypesResponse :
Q extends 'blob' ? Blob :
Q extends 'marketplace_dapps' ? Array<MarketplaceAppOverview> :
Q extends 'marketplace_dapp' ? MarketplaceAppOverview :
Q extends 'validators' ? ValidatorsResponse :
Q extends 'validators_counters' ? ValidatorsCountersResponse :
Q extends 'validators_stability' ? ValidatorsStabilityResponse :
Q extends 'validators_stability_counters' ? ValidatorsStabilityCountersResponse :
Q extends 'validators_blackfort' ? ValidatorsBlackfortResponse :
Q extends 'validators_blackfort_counters' ? ValidatorsBlackfortCountersResponse :
Q extends 'shibarium_withdrawals' ? ShibariumWithdrawalsResponse :
Q extends 'shibarium_deposits' ? ShibariumDepositsResponse :
Q extends 'shibarium_withdrawals_count' ? number :
Expand Down Expand Up @@ -1200,7 +1215,7 @@ Q extends 'verified_contracts' ? VerifiedContractsFilters :
Q extends 'addresses_lookup' ? EnsAddressLookupFilters :
Q extends 'domains_lookup' ? EnsDomainLookupFilters :
Q extends 'user_ops' ? UserOpsFilters :
Q extends 'validators' ? ValidatorsFilters :
Q extends 'validators_stability' ? ValidatorsStabilityFilters :
Q extends 'address_mud_tables' ? AddressMudTablesFilter :
Q extends 'address_mud_records' ? AddressMudRecordsFilter :
never;
Expand All @@ -1214,7 +1229,8 @@ Q extends 'verified_contracts' ? VerifiedContractsSorting :
Q extends 'address_txs' ? TransactionsSorting :
Q extends 'addresses_lookup' ? EnsLookupSorting :
Q extends 'domains_lookup' ? EnsLookupSorting :
Q extends 'validators' ? ValidatorsSorting :
Q extends 'validators_stability' ? ValidatorsStabilitySorting :
Q extends 'validators_blackfort' ? ValidatorsBlackfortSorting :
Q extends 'address_mud_records' ? AddressMudRecordsSorting :
never;
/* eslint-enable @typescript-eslint/indent */
41 changes: 41 additions & 0 deletions mocks/validators/blackfort.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import type {
ValidatorBlackfort,
ValidatorsBlackfortCountersResponse,
ValidatorsBlackfortResponse,
} from 'types/api/validators';

import * as addressMock from '../address/address';

export const validator1: ValidatorBlackfort = {
address: addressMock.withName,
name: 'testnet-3',
commission: 10,
delegated_amount: '0',
self_bonded_amount: '10000',
};

export const validator2: ValidatorBlackfort = {
address: addressMock.withEns,
name: 'GooseGanG GooseGanG GooseGanG GooseGanG GooseGanG GooseGanG GooseGanG',
commission: 5000,
delegated_amount: '10000',
self_bonded_amount: '100',
};

export const validator3: ValidatorBlackfort = {
address: addressMock.withoutName,
name: 'testnet-1',
commission: 0,
delegated_amount: '0',
self_bonded_amount: '10000',
};

export const validatorsResponse: ValidatorsBlackfortResponse = {
items: [ validator1, validator2, validator3 ],
next_page_params: null,
};

export const validatorsCountersResponse: ValidatorsBlackfortCountersResponse = {
new_validators_counter_24h: '11',
validators_counter: '140',
};
16 changes: 10 additions & 6 deletions mocks/validators/index.ts → mocks/validators/stability.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,35 @@
import type { Validator, ValidatorsCountersResponse, ValidatorsResponse } from 'types/api/validators';
import type {
ValidatorStability,
ValidatorsStabilityCountersResponse,
ValidatorsStabilityResponse,
} from 'types/api/validators';

import * as addressMock from '../address/address';

export const validator1: Validator = {
export const validator1: ValidatorStability = {
address: addressMock.withName,
blocks_validated_count: 7334224,
state: 'active',
};

export const validator2: Validator = {
export const validator2: ValidatorStability = {
address: addressMock.withEns,
blocks_validated_count: 8937453,
state: 'probation',
};

export const validator3: Validator = {
export const validator3: ValidatorStability = {
address: addressMock.withoutName,
blocks_validated_count: 1234,
state: 'inactive',
};

export const validatorsResponse: ValidatorsResponse = {
export const validatorsResponse: ValidatorsStabilityResponse = {
items: [ validator1, validator2, validator3 ],
next_page_params: null,
};

export const validatorsCountersResponse: ValidatorsCountersResponse = {
export const validatorsCountersResponse: ValidatorsStabilityCountersResponse = {
active_validators_counter: '42',
active_validators_percentage: 7.14,
new_validators_counter_24h: '11',
Expand Down
16 changes: 15 additions & 1 deletion pages/validators.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,21 @@ import React from 'react';

import PageNextJs from 'nextjs/PageNextJs';

const Validators = dynamic(() => import('ui/pages/Validators'), { ssr: false });
import config from 'configs/app';

const validatorsFeature = config.features.validators;

const Validators = dynamic(() => {
if (validatorsFeature.isEnabled && validatorsFeature.chainType === 'stability') {
return import('ui/pages/ValidatorsStability');
}

if (validatorsFeature.isEnabled && validatorsFeature.chainType === 'blackfort') {
return import('ui/pages/ValidatorsBlackfort');
}

throw new Error('Validators feature is not enabled.');
}, { ssr: false });

const Page: NextPage = () => {
return (
Expand Down
24 changes: 21 additions & 3 deletions stubs/validators.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,34 @@
import type { Validator, ValidatorsCountersResponse } from 'types/api/validators';
import type {
ValidatorStability,
ValidatorsStabilityCountersResponse,
ValidatorBlackfort,
ValidatorsBlackfortCountersResponse,
} from 'types/api/validators';

import { ADDRESS_PARAMS } from './addressParams';

export const VALIDATOR: Validator = {
export const VALIDATOR_STABILITY: ValidatorStability = {
address: ADDRESS_PARAMS,
blocks_validated_count: 25987,
state: 'active',
};

export const VALIDATORS_COUNTERS: ValidatorsCountersResponse = {
export const VALIDATORS_STABILITY_COUNTERS: ValidatorsStabilityCountersResponse = {
active_validators_counter: '42',
active_validators_percentage: 7.14,
new_validators_counter_24h: '11',
validators_counter: '140',
};

export const VALIDATOR_BLACKFORT: ValidatorBlackfort = {
address: ADDRESS_PARAMS,
name: 'testnet-1',
commission: 10,
delegated_amount: '0',
self_bonded_amount: '10000',
};

export const VALIDATORS_BLACKFORT_COUNTERS: ValidatorsBlackfortCountersResponse = {
new_validators_counter_24h: '11',
validators_counter: '140',
};
1 change: 1 addition & 0 deletions tools/preset-sync/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import path from 'path';
const PRESETS = {
arbitrum: 'https://arbitrum.blockscout.com',
base: 'https://base.blockscout.com',
blackfort_testnet: 'https://blackfort-testnet.blockscout.com',
celo_alfajores: 'https://celo-alfajores.blockscout.com',
eth: 'https://eth.blockscout.com',
eth_goerli: 'https://eth-goerli.blockscout.com',
Expand Down
49 changes: 39 additions & 10 deletions types/api/validators.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,67 @@
import type { AddressParam } from './addressParams';

export interface Validator {
export interface ValidatorStability {
address: AddressParam;
blocks_validated_count: number;
state: 'active' | 'probation' | 'inactive';
}

export interface ValidatorsResponse {
items: Array<Validator>;
export interface ValidatorsStabilityResponse {
items: Array<ValidatorStability>;
next_page_params: {
'address_hash': string;
'blocks_validated': string;
'items_count': string;
'state': Validator['state'];
'state': ValidatorStability['state'];
} | null;
}

export interface ValidatorsCountersResponse {
export interface ValidatorsStabilityCountersResponse {
active_validators_counter: string;
active_validators_percentage: number;
new_validators_counter_24h: string;
validators_counter: string;
}

export interface ValidatorsFilters {
export interface ValidatorsStabilityFilters {
// address_hash: string | undefined; // right now API doesn't support filtering by address_hash
state_filter: Validator['state'] | undefined;
state_filter: ValidatorStability['state'] | undefined;
}

export interface ValidatorsSorting {
export interface ValidatorsStabilitySorting {
sort: 'state' | 'blocks_validated';
order: 'asc' | 'desc';
}

export type ValidatorsSortingField = ValidatorsSorting['sort'];
export type ValidatorsStabilitySortingField = ValidatorsStabilitySorting['sort'];

export type ValidatorsSortingValue = `${ ValidatorsSortingField }-${ ValidatorsSorting['order'] }`;
export type ValidatorsStabilitySortingValue = `${ ValidatorsStabilitySortingField }-${ ValidatorsStabilitySorting['order'] }`;

export interface ValidatorBlackfort {
address: AddressParam;
name: string;
commission: number;
delegated_amount: string;
self_bonded_amount: string;
}

export interface ValidatorsBlackfortResponse {
items: Array<ValidatorBlackfort>;
next_page_params: {
'address_hash': string;
} | null;
}

export interface ValidatorsBlackfortCountersResponse {
new_validators_counter_24h: string;
validators_counter: string;
}

export interface ValidatorsBlackfortSorting {
sort: 'address_hash';
order: 'asc' | 'desc';
}

export type ValidatorsBlackfortSortingField = ValidatorsBlackfortSorting['sort'];

export type ValidatorsBlackfortSortingValue = `${ ValidatorsBlackfortSortingField }-${ ValidatorsBlackfortSorting['order'] }`;
1 change: 1 addition & 0 deletions types/client/validators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { ArrayElement } from 'types/utils';

export const VALIDATORS_CHAIN_TYPE = [
'stability',
'blackfort',
] as const;

export type ValidatorsChainType = ArrayElement<typeof VALIDATORS_CHAIN_TYPE>;
21 changes: 21 additions & 0 deletions ui/pages/ValidatorsBlackfort.pw.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react';

import * as validatorsMock from 'mocks/validators/blackfort';
import { test, expect } from 'playwright/lib';

import Validators from './ValidatorsBlackfort';

const chainType = 'blackfort';

test('base view +@mobile', async({ render, mockApiResponse, mockEnvs, mockTextAd }) => {
await mockEnvs([
[ 'NEXT_PUBLIC_VALIDATORS_CHAIN_TYPE', chainType ],
]);
await mockApiResponse('validators_blackfort', validatorsMock.validatorsResponse);
await mockApiResponse('validators_blackfort_counters', validatorsMock.validatorsCountersResponse);
await mockTextAd();

const component = await render(<Validators/>);

await expect(component).toHaveScreenshot();
});
Loading

0 comments on commit 55bc66e

Please sign in to comment.