Skip to content

Commit

Permalink
Merge branch 'develop' into tooling-epic/explorer-darkmode-support
Browse files Browse the repository at this point in the history
  • Loading branch information
evavirseda authored Nov 26, 2024
2 parents 7df5a90 + e9493e7 commit 24069d2
Show file tree
Hide file tree
Showing 51 changed files with 1,659 additions and 974 deletions.
10 changes: 6 additions & 4 deletions apps/core/src/components/Inputs/SendTokenFormInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export interface SendTokenInputProps {
onActionClick: () => Promise<void>;
isMaxActionDisabled?: boolean;
name: string;
isPayAllIota: boolean;
}

export function SendTokenFormInput({
Expand All @@ -30,6 +31,7 @@ export function SendTokenFormInput({
onActionClick,
isMaxActionDisabled,
name,
isPayAllIota,
}: SendTokenInputProps) {
const { values, setFieldValue, isSubmitting, validateField } = useFormikContext<TokenForm>();
const { data: gasBudgetEstimation } = useGasBudgetEstimation({
Expand All @@ -38,7 +40,7 @@ export function SendTokenFormInput({
activeAddress,
to: to,
amount: values.amount,
isPayAllIota: values.isPayAllIota,
isPayAllIota,
});
const [formattedGasBudgetEstimation, gasToken] = useFormatCoin(
gasBudgetEstimation,
Expand All @@ -61,8 +63,8 @@ export function SendTokenFormInput({

// gasBudgetEstimation should change when the amount above changes
useEffect(() => {
setFieldValue('gasBudgetEst', formattedGasBudgetEstimation, false);
}, [formattedGasBudgetEstimation, setFieldValue, values.amount]);
setFieldValue('gasBudgetEst', gasBudgetEstimation, false);
}, [gasBudgetEstimation, setFieldValue, values.amount]);

return (
<Input
Expand All @@ -74,7 +76,7 @@ export function SendTokenFormInput({
placeholder="0.00"
label="Send Amount"
suffix={` ${symbol}`}
prefix={values.isPayAllIota ? '~ ' : undefined}
prefix={isPayAllIota ? '~ ' : undefined}
allowNegative={false}
errorMessage={errorMessage}
amountCounter={!errorMessage ? (coins ? gasAmount : '--') : undefined}
Expand Down
3 changes: 1 addition & 2 deletions apps/core/src/components/coin/CoinIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@
// SPDX-License-Identifier: Apache-2.0

import React from 'react';
import { useCoinMetadata } from '../../hooks';
import { useCoinMetadata, ImageIcon, ImageIconSize } from '../../';
import { IotaLogoMark } from '@iota/ui-icons';
import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils';
import { ImageIcon, ImageIconSize } from '../icon';
import cx from 'clsx';

interface NonIotaCoinProps {
Expand Down
3 changes: 3 additions & 0 deletions apps/core/src/constants/staking.constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@ export const UNSTAKING_REQUEST_EVENT = '0x3::validator::UnstakingRequestEvent';

export const DELEGATED_STAKES_QUERY_STALE_TIME = 10_000;
export const DELEGATED_STAKES_QUERY_REFETCH_INTERVAL = 30_000;

export const NUM_OF_EPOCH_BEFORE_STAKING_REWARDS_REDEEMABLE = 2;
export const NUM_OF_EPOCH_BEFORE_STAKING_REWARDS_STARTS = 1;
1 change: 0 additions & 1 deletion apps/core/src/forms/token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,5 @@
export type TokenForm = {
amount: string;
to: string;
isPayAllIota: boolean;
gasBudgetEst: string;
};
2 changes: 2 additions & 0 deletions apps/core/src/hooks/stake/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@
export * from './useGetDelegatedStake';
export * from './useTotalDelegatedRewards';
export * from './useTotalDelegatedStake';
export * from './useValidatorInfo';
export * from './useStakeTxnInfo';
52 changes: 52 additions & 0 deletions apps/core/src/hooks/stake/useStakeTxnInfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright (c) 2024 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0
import {
useGetTimeBeforeEpochNumber,
useTimeAgo,
TimeUnit,
NUM_OF_EPOCH_BEFORE_STAKING_REWARDS_REDEEMABLE,
NUM_OF_EPOCH_BEFORE_STAKING_REWARDS_STARTS,
} from '../../';

export function useStakeTxnInfo(startEpoch?: string | number) {
const startEarningRewardsEpoch =
Number(startEpoch || 0) + NUM_OF_EPOCH_BEFORE_STAKING_REWARDS_STARTS;

const redeemableRewardsEpoch =
Number(startEpoch || 0) + NUM_OF_EPOCH_BEFORE_STAKING_REWARDS_REDEEMABLE;

const { data: timeBeforeStakeRewardsStarts } =
useGetTimeBeforeEpochNumber(startEarningRewardsEpoch);
const timeBeforeStakeRewardsStartsAgo = useTimeAgo({
timeFrom: timeBeforeStakeRewardsStarts,
shortedTimeLabel: false,
shouldEnd: true,
maxTimeUnit: TimeUnit.ONE_HOUR,
});
const stakedRewardsStartEpoch =
timeBeforeStakeRewardsStarts > 0
? `in ${timeBeforeStakeRewardsStartsAgo}`
: startEpoch
? `Epoch #${Number(startEarningRewardsEpoch)}`
: '--';

const { data: timeBeforeStakeRewardsRedeemable } =
useGetTimeBeforeEpochNumber(redeemableRewardsEpoch);
const timeBeforeStakeRewardsRedeemableAgo = useTimeAgo({
timeFrom: timeBeforeStakeRewardsRedeemable,
shortedTimeLabel: false,
shouldEnd: true,
maxTimeUnit: TimeUnit.ONE_HOUR,
});
const timeBeforeStakeRewardsRedeemableAgoDisplay =
timeBeforeStakeRewardsRedeemable > 0
? `in ${timeBeforeStakeRewardsRedeemableAgo}`
: startEpoch
? `Epoch #${Number(redeemableRewardsEpoch)}`
: '--';

return {
stakedRewardsStartEpoch,
timeBeforeStakeRewardsRedeemableAgoDisplay,
};
}
50 changes: 50 additions & 0 deletions apps/core/src/hooks/stake/useValidatorInfo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright (c) 2024 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0
import { useIotaClientQuery } from '@iota/dapp-kit';
import { useGetValidatorsApy } from '../';

export function useValidatorInfo({ validatorAddress }: { validatorAddress: string }) {
const {
data: system,
isPending: isPendingValidators,
isError: errorValidators,
} = useIotaClientQuery('getLatestIotaSystemState');
const { data: rollingAverageApys } = useGetValidatorsApy();

const validatorSummary =
system?.activeValidators.find((validator) => validator.iotaAddress === validatorAddress) ||
null;

const currentEpoch = Number(system?.epoch || 0);

const stakingPoolActivationEpoch = Number(validatorSummary?.stakingPoolActivationEpoch || 0);

// flag as new validator if the validator was activated in the last epoch
// for genesis validators, this will be false
const newValidator = currentEpoch - stakingPoolActivationEpoch <= 1 && currentEpoch !== 0;

// flag if the validator is at risk of being removed from the active set
const isAtRisk = system?.atRiskValidators.some((item) => item[0] === validatorAddress);

const { apy, isApyApproxZero } = rollingAverageApys?.[validatorAddress] ?? {
apy: null,
};

const commission = validatorSummary ? Number(validatorSummary.commissionRate) / 100 : 0;

return {
system,
isPendingValidators,
errorValidators,

currentEpoch,
validatorSummary,
name: validatorSummary?.name || '',
stakingPoolActivationEpoch,
commission,
newValidator,
isAtRisk,
apy,
isApyApproxZero,
};
}
1 change: 1 addition & 0 deletions apps/core/src/hooks/useGetStakingValidatorDetails.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ export function useGetStakingValidatorDetails({
return {
epoch: Number(system?.epoch) || 0,
totalStake: totalStakeFormatted,
totalStakeOriginal: totalStake,
totalValidatorsStake: totalValidatorsStakeFormatted,
totalStakePercentage,
validatorApy,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Modifications Copyright (c) 2024 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

import { CoinFormat, formatBalance } from '@iota/core';
import { CoinFormat, formatBalance } from '../../';
import BigNumber from 'bignumber.js';
import { mixed, object } from 'yup';

Expand Down
1 change: 1 addition & 0 deletions apps/core/src/utils/stake/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ export * from './formatDelegatedStake';
export * from './createStakeTransaction';
export * from './createTimelockedUnstakeTransaction';
export * from './createTimelockedStakeTransaction';
export * from './createValidationSchema';
35 changes: 24 additions & 11 deletions apps/explorer/src/components/owned-coins/OwnedCoins.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -153,12 +153,14 @@ export function OwnedCoins({ id }: OwnerCoinsProps): JSX.Element {
</div>
) : (
<div className="flex h-full flex-col">
<Title
title={coinBalanceHeader}
trailingElement={
hasCoinsBalance && <CoinsFilter filterOptions={filterOptions} />
}
/>
<div className="flex flex-col justify-center sm:min-h-[72px]">
<Title
title={coinBalanceHeader}
trailingElement={
hasCoinsBalance && <CoinsFilter filterOptions={filterOptions} />
}
/>
</div>
{hasCoinsBalance ? (
<>
<div className="relative overflow-y-auto p-sm--rs pt-0">
Expand Down Expand Up @@ -213,18 +215,29 @@ export function OwnedCoins({ id }: OwnerCoinsProps): JSX.Element {
)}
</>
) : (
<div className="flex h-20 items-center justify-center md:h-coinsAndAssetsContainer">
<span className="flex flex-row items-center gap-x-xs text-neutral-40 dark:text-neutral-60">
No Coins Owned
</span>
</div>
<NoObjectsOwnedMessage objectType="Coins" />
)}
</div>
)}
</div>
);
}

interface NoObjectsOwnedMessageProps {
objectType: string;
}
export function NoObjectsOwnedMessage({
objectType,
}: NoObjectsOwnedMessageProps): React.JSX.Element {
return (
<div className="flex h-full items-center justify-center md:h-coinsAndAssetsContainer">
<span className="flex flex-row items-center gap-x-xs text-neutral-40 dark:text-neutral-60">
No {objectType} Owned
</span>
</div>
);
}

interface FilterOption {
label: string;
isDisabled?: boolean;
Expand Down
Loading

0 comments on commit 24069d2

Please sign in to comment.