mirror of
https://github.com/luxfi/explore.git
synced 2026-09-24 00:28:18 +00:00
Celo: Cross-link to epoch block on the regular block view and Epoch rewards CSV export (#2386)
* Celo: Cross-link to epoch block on the regular block view Fixes #2365 * [skip ci] fix hover state for gray-blue tag * CSV export of epoch transactions for address
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
import type { Feature } from './types';
|
||||
|
||||
import { getEnvValue } from '../utils';
|
||||
|
||||
const title = 'Celo chain';
|
||||
|
||||
const config: Feature<{ L2UpgradeBlock: number | undefined; BLOCKS_PER_EPOCH: number }> = (() => {
|
||||
|
||||
if (getEnvValue('NEXT_PUBLIC_CELO_ENABLED') === 'true') {
|
||||
return Object.freeze({
|
||||
title,
|
||||
isEnabled: true,
|
||||
L2UpgradeBlock: getEnvValue('NEXT_PUBLIC_CELO_L2_UPGRADE_BLOCK') ? Number(getEnvValue('NEXT_PUBLIC_CELO_L2_UPGRADE_BLOCK')) : undefined,
|
||||
BLOCKS_PER_EPOCH: 17_280,
|
||||
});
|
||||
}
|
||||
|
||||
return Object.freeze({
|
||||
title,
|
||||
isEnabled: false,
|
||||
});
|
||||
})();
|
||||
|
||||
export default config;
|
||||
@@ -6,6 +6,7 @@ export { default as adsText } from './adsText';
|
||||
export { default as beaconChain } from './beaconChain';
|
||||
export { default as bridgedTokens } from './bridgedTokens';
|
||||
export { default as blockchainInteraction } from './blockchainInteraction';
|
||||
export { default as celo } from './celo';
|
||||
export { default as csvExport } from './csvExport';
|
||||
export { default as dataAvailability } from './dataAvailability';
|
||||
export { default as deFiDropdown } from './deFiDropdown';
|
||||
|
||||
@@ -9,6 +9,9 @@ NEXT_PUBLIC_APP_PORT=3000
|
||||
NEXT_PUBLIC_APP_ENV=development
|
||||
NEXT_PUBLIC_API_WEBSOCKET_PROTOCOL=ws
|
||||
|
||||
NEXT_PUBLIC_CELO_ENABLED=true
|
||||
NEXT_PUBLIC_CELO_L2_UPGRADE_BLOCK=26369280
|
||||
|
||||
# Instance ENVs
|
||||
NEXT_PUBLIC_API_BASE_PATH=/
|
||||
NEXT_PUBLIC_API_HOST=celo-alfajores.blockscout.com
|
||||
|
||||
@@ -300,6 +300,22 @@ const rollupSchema = yup
|
||||
}),
|
||||
});
|
||||
|
||||
const celoSchema = yup
|
||||
.object()
|
||||
.shape({
|
||||
NEXT_PUBLIC_CELO_ENABLED: yup.boolean(),
|
||||
NEXT_PUBLIC_CELO_L2_UPGRADE_BLOCK: yup
|
||||
.string()
|
||||
.when('NEXT_PUBLIC_CELO_ENABLED', {
|
||||
is: (value: boolean) => value,
|
||||
then: (schema) => schema.min(0).optional(),
|
||||
otherwise: (schema) => schema.max(
|
||||
-1,
|
||||
'NEXT_PUBLIC_CELO_L2_UPGRADE_BLOCK cannot not be used if NEXT_PUBLIC_CELO_ENABLED is not set to "true"',
|
||||
),
|
||||
}),
|
||||
});
|
||||
|
||||
const adButlerConfigSchema = yup
|
||||
.object<AdButlerConfig>()
|
||||
.transform(replaceQuotes)
|
||||
@@ -867,6 +883,7 @@ const schema = yup
|
||||
.concat(adsBannerSchema)
|
||||
.concat(marketplaceSchema)
|
||||
.concat(rollupSchema)
|
||||
.concat(celoSchema)
|
||||
.concat(beaconChainSchema)
|
||||
.concat(bridgedTokensSchema)
|
||||
.concat(sentrySchema);
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
NEXT_PUBLIC_CELO_ENABLED=true
|
||||
NEXT_PUBLIC_CELO_L2_UPGRADE_BLOCK=420
|
||||
@@ -703,6 +703,17 @@ For blockchains that implement SUAVE architecture additional fields will be show
|
||||
|
||||
|
||||
|
||||
### Celo chain
|
||||
|
||||
For blockchains that use the Celo platform. _Note_, that once the Celo mainnet becomes an L2 chain, these variables will be migrated to the Rollup configuration section.
|
||||
|
||||
| Variable | Type| Description | Compulsoriness | Default value | Example value | Version |
|
||||
| --- | --- | --- | --- | --- | --- | --- |
|
||||
| NEXT_PUBLIC_CELO_ENABLED | `boolean` | Indicates that it is a Celo-based chain. | - | - | `true` | v1.37.0+ |
|
||||
| NEXT_PUBLIC_CELO_L2_UPGRADE_BLOCK | `number` | Indicates the block number when the Celo-type chain transitioned to L2. This is used to display links to the Epoch block page from a regular block page. | - | - | `26369280` | v1.37.0+ |
|
||||
|
||||
|
||||
|
||||
### MetaSuites extension
|
||||
|
||||
Enables [MetaSuites browser extension](https://github.com/blocksecteam/metasuites) to integrate with the app views.
|
||||
|
||||
@@ -1069,6 +1069,9 @@ export const RESOURCES = {
|
||||
csv_export_logs: {
|
||||
path: '/api/v1/logs-csv',
|
||||
},
|
||||
csv_export_epoch_rewards: {
|
||||
path: '/api/v1/celo-election-rewards-csv',
|
||||
},
|
||||
graphql: {
|
||||
path: '/api/v1/graphql',
|
||||
},
|
||||
|
||||
@@ -40,5 +40,11 @@ export const epochRewards: AddressEpochRewardsResponse = {
|
||||
token: tokenInfo,
|
||||
},
|
||||
],
|
||||
next_page_params: null,
|
||||
next_page_params: {
|
||||
amount: '71952055594478242556',
|
||||
associated_account_address_hash: '0x30d060f129817c4de5fbc1366d53e19f43c8c64f',
|
||||
block_number: 25954560,
|
||||
items_count: 50,
|
||||
type: 'delegated_payment',
|
||||
},
|
||||
};
|
||||
|
||||
@@ -21,6 +21,9 @@ const variantSubtle = defineStyle((props) => {
|
||||
return {
|
||||
bg: mode('gray.100', 'gray.800')(props),
|
||||
color: mode('blackAlpha.800', 'whiteAlpha.800')(props),
|
||||
_hover: {
|
||||
opacity: 0.76,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -12,4 +12,8 @@ export type CsvExportParams = {
|
||||
type: 'holders';
|
||||
filterType?: undefined;
|
||||
filterValue?: undefined;
|
||||
} | {
|
||||
type: 'epoch-rewards';
|
||||
filterType?: undefined;
|
||||
filterValue?: undefined;
|
||||
};
|
||||
|
||||
@@ -12,6 +12,7 @@ import DataListDisplay from 'ui/shared/DataListDisplay';
|
||||
import Pagination from 'ui/shared/pagination/Pagination';
|
||||
import useQueryWithPages from 'ui/shared/pagination/useQueryWithPages';
|
||||
|
||||
import AddressCsvExportLink from './AddressCsvExportLink';
|
||||
import AddressEpochRewardsListItem from './epochRewards/AddressEpochRewardsListItem';
|
||||
|
||||
type Props = {
|
||||
@@ -71,7 +72,13 @@ const AddressEpochRewards = ({ scrollRef, shouldRender = true, isQueryEnabled =
|
||||
|
||||
const actionBar = rewardsQuery.pagination.isVisible ? (
|
||||
<ActionBar mt={ -6 }>
|
||||
<Pagination ml="auto" { ...rewardsQuery.pagination }/>
|
||||
<AddressCsvExportLink
|
||||
address={ hash }
|
||||
isLoading={ rewardsQuery.pagination.isLoading }
|
||||
params={{ type: 'epoch-rewards' }}
|
||||
ml={{ lg: 'auto' }}
|
||||
/>
|
||||
<Pagination ml={{ base: 0, lg: 8 }} { ...rewardsQuery.pagination }/>
|
||||
</ActionBar>
|
||||
) : null;
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 42 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 53 KiB |
+15
-1
@@ -6,6 +6,8 @@ import React from 'react';
|
||||
import type { PaginationParams } from 'ui/shared/pagination/types';
|
||||
import type { RoutedTab } from 'ui/shared/Tabs/types';
|
||||
|
||||
import { route } from 'nextjs-routes';
|
||||
|
||||
import config from 'configs/app';
|
||||
import { useAppContext } from 'lib/contexts/app';
|
||||
import throwOnAbsentParamError from 'lib/errors/throwOnAbsentParamError';
|
||||
@@ -24,6 +26,7 @@ import TextAd from 'ui/shared/ad/TextAd';
|
||||
import ServiceDegradationWarning from 'ui/shared/alerts/ServiceDegradationWarning';
|
||||
import Tag from 'ui/shared/chakra/Tag';
|
||||
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
|
||||
import LinkInternal from 'ui/shared/links/LinkInternal';
|
||||
import NetworkExplorers from 'ui/shared/NetworkExplorers';
|
||||
import PageTitle from 'ui/shared/Page/PageTitle';
|
||||
import Pagination from 'ui/shared/pagination/Pagination';
|
||||
@@ -152,9 +155,20 @@ const BlockPageContent = () => {
|
||||
}
|
||||
|
||||
if (!blockQuery.data.celo.is_epoch_block) {
|
||||
const celoConfig = config.features.celo;
|
||||
const epochBlockNumber = celoConfig.isEnabled && celoConfig.L2UpgradeBlock && blockQuery.data.height <= celoConfig.L2UpgradeBlock ?
|
||||
blockQuery.data.celo.epoch_number * celoConfig.BLOCKS_PER_EPOCH :
|
||||
undefined;
|
||||
const tag = <Tag colorScheme={ epochBlockNumber ? 'gray-blue' : 'gray' }>Epoch #{ blockQuery.data.celo.epoch_number }</Tag>;
|
||||
const content = epochBlockNumber ? (
|
||||
<LinkInternal href={ route({ pathname: '/block/[height_or_hash]', query: { height_or_hash: String(epochBlockNumber) } }) }>
|
||||
{ tag }
|
||||
</LinkInternal>
|
||||
) : tag;
|
||||
|
||||
return (
|
||||
<Tooltip label="Displays the epoch this block belongs to before the epoch is finalized" maxW="280px" textAlign="center">
|
||||
<Tag>Epoch #{ blockQuery.data.celo.epoch_number }</Tag>
|
||||
{ content }
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -59,6 +59,11 @@ const EXPORT_TYPES: Record<CsvExportParams['type'], ExportTypeEntity> = {
|
||||
resource: 'csv_export_token_holders',
|
||||
fileNameTemplate: 'holders',
|
||||
},
|
||||
'epoch-rewards': {
|
||||
text: 'epoch rewards',
|
||||
resource: 'csv_export_epoch_rewards',
|
||||
fileNameTemplate: 'epoch_rewards',
|
||||
},
|
||||
};
|
||||
|
||||
const isCorrectExportType = (type: string): type is CsvExportParams['type'] => Object.keys(EXPORT_TYPES).includes(type);
|
||||
|
||||
Reference in New Issue
Block a user