diff --git a/.github/workflows/_e2e.yml b/.github/workflows/_e2e.yml index c40ca8da2de..a593824f8bc 100644 --- a/.github/workflows/_e2e.yml +++ b/.github/workflows/_e2e.yml @@ -79,7 +79,7 @@ jobs: - name: Build apps-backend if: inputs.isAppsBackend || github.ref_name == 'develop' - run: pnpm --filter apps-backend build + run: pnpm turbo --filter apps-backend build - name: Run apps-backend e2e tests if: inputs.isAppsBackend || github.ref_name == 'develop' diff --git a/apps/apps-backend/src/features/features.controller.ts b/apps/apps-backend/src/features/features.controller.ts index 78f31bb5a20..ffdf8098b97 100644 --- a/apps/apps-backend/src/features/features.controller.ts +++ b/apps/apps-backend/src/features/features.controller.ts @@ -3,6 +3,7 @@ import { Controller, Get } from '@nestjs/common'; import { Feature } from '@iota/core/enums/features.enums'; +import { Network } from '@iota/iota-sdk/client'; @Controller('/api/features') export class FeaturesController { @@ -70,6 +71,15 @@ export class FeaturesController { [Feature.SupplyIncreaseVesting]: { defaultValue: true, }, + [Feature.BurntAndMintedTokensInEndedEpochs]: { + defaultValue: { + [Network.Mainnet]: false, + [Network.Devnet]: true, + [Network.Testnet]: false, + [Network.Localnet]: false, + [Network.Custom]: false, + }, + }, }, dateUpdated: new Date().toISOString(), }; @@ -139,6 +149,15 @@ export class FeaturesController { [Feature.SupplyIncreaseVesting]: { defaultValue: true, }, + [Feature.BurntAndMintedTokensInEndedEpochs]: { + defaultValue: { + [Network.Mainnet]: false, + [Network.Devnet]: true, + [Network.Testnet]: false, + [Network.Localnet]: false, + [Network.Custom]: false, + }, + }, }, dateUpdated: new Date().toISOString(), }; diff --git a/apps/core/src/enums/features.enums.ts b/apps/core/src/enums/features.enums.ts index 3670db4edc1..5d260493c5f 100644 --- a/apps/core/src/enums/features.enums.ts +++ b/apps/core/src/enums/features.enums.ts @@ -20,4 +20,5 @@ export enum Feature { WalletEffectsOnlySharedTransaction = 'wallet-effects-only-shared-transaction', StardustMigration = 'migration', SupplyIncreaseVesting = 'supply-increase-vesting', + BurntAndMintedTokensInEndedEpochs = 'burnt-and-minted-tokens-in-ended-epochs', } diff --git a/apps/core/src/hooks/index.ts b/apps/core/src/hooks/index.ts index c34108cf478..aee1fb3e15e 100644 --- a/apps/core/src/hooks/index.ts +++ b/apps/core/src/hooks/index.ts @@ -50,5 +50,7 @@ export * from './useStakeRewardStatus'; export * from './useGetNFTs'; export * from './useRecognizedPackages'; export * from './useTransferAsset'; +export * from './useFeatureEnabledByNetwork'; + export * from './stake'; export * from './ui'; diff --git a/apps/core/src/hooks/useFeatureEnabledByNetwork.ts b/apps/core/src/hooks/useFeatureEnabledByNetwork.ts new file mode 100644 index 00000000000..2f3c51761af --- /dev/null +++ b/apps/core/src/hooks/useFeatureEnabledByNetwork.ts @@ -0,0 +1,15 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { useFeature } from '@growthbook/growthbook-react'; +import type { Network } from '@iota/iota-sdk/client'; +import { Feature } from '../enums'; + +type NetworkBasedFeature = { + [key in Network]: boolean; +}; + +export function useFeatureEnabledByNetwork(feature: Feature, network: Network): boolean { + const featureFlag = useFeature(feature)?.value; + return featureFlag?.[network] ?? false; +} diff --git a/apps/explorer/src/pages/epochs/stats/EpochTopStats.tsx b/apps/explorer/src/pages/epochs/stats/EpochTopStats.tsx index c99f5a51c39..93d650863e1 100644 --- a/apps/explorer/src/pages/epochs/stats/EpochTopStats.tsx +++ b/apps/explorer/src/pages/epochs/stats/EpochTopStats.tsx @@ -5,11 +5,12 @@ import { ProgressBar } from '~/components'; import { EpochStatsGrid } from './EpochStats'; import { LabelText, LabelTextSize } from '@iota/apps-ui-kit'; -import { formatDate } from '@iota/core'; +import { Feature, formatDate, useFeatureEnabledByNetwork } from '@iota/core'; import { TokenStats } from './TokenStats'; import { getSupplyChangeAfterEpochEnd } from '~/lib'; import { useEpochProgress } from '../utils'; -import type { EndOfEpochInfo } from '@iota/iota-sdk/src/client'; +import type { Network, EndOfEpochInfo } from '@iota/iota-sdk/client'; +import { useNetworkContext } from '~/contexts'; interface EpochProgressProps { start: number; @@ -25,8 +26,15 @@ export function EpochTopStats({ endOfEpochInfo, }: EpochProgressProps): React.JSX.Element { const { progress, label } = useEpochProgress(); + const [network] = useNetworkContext(); + const endTime = inProgress ? label : end ? formatDate(end) : undefined; + const isBurntAndMintedTokensInEndedEpochsFeatureEnabled = useFeatureEnabledByNetwork( + Feature.BurntAndMintedTokensInEndedEpochs, + network as Network, + ); + return (
{inProgress ? : null} @@ -35,12 +43,30 @@ export function EpochTopStats({ {endTime ? : null} {endOfEpochInfo && ( - + <> + {isBurntAndMintedTokensInEndedEpochsFeatureEnabled && ( + <> + + + + )} + + )}