Skip to content

Commit

Permalink
feat: add epoch end time
Browse files Browse the repository at this point in the history
  • Loading branch information
mohandast52 committed Oct 2, 2024
1 parent 161b8ac commit cdf50a0
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 25 deletions.
9 changes: 5 additions & 4 deletions electron/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,8 @@ const HEIGHT = 700;
* Creates the main window
*/
const createMainWindow = async () => {
const width = isDev ? 840 : APP_WIDTH;
const width = APP_WIDTH;
// const width = isDev ? 840 : APP_WIDTH;
mainWindow = new BrowserWindow({
title: 'Pearl',
resizable: false,
Expand Down Expand Up @@ -209,9 +210,9 @@ const createMainWindow = async () => {
logger.electron('Store IPC failed:', JSON.stringify(e));
}

if (isDev) {
mainWindow.webContents.openDevTools();
}
// if (isDev) {
// mainWindow.webContents.openDevTools();
// }

if (isDev) {
mainWindow.loadURL(`http://localhost:${appConfig.ports.dev.next}`);
Expand Down
1 change: 1 addition & 0 deletions frontend/components/MainPage/header/AgentButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,7 @@ export const AgentButton = () => {
const { isEligibleForStaking, isAgentEvicted } = useStakingContractInfo();

return useMemo(() => {
return <CannotStartAgentPopover />;
if (!hasInitialLoaded) {
return <Button type="primary" size="large" disabled loading />;
}
Expand Down
2 changes: 1 addition & 1 deletion frontend/components/MainPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { KeepAgentRunningSection } from './sections/KeepAgentRunningSection';
import { MainNeedsFunds } from './sections/NeedsFundsSection';
import { NewStakingProgramAlertSection } from './sections/NewStakingProgramAlertSection';
import { MainOlasBalance } from './sections/OlasBalanceSection';
import { MainRewards } from './sections/RewardsSection';
import { MainRewards } from './sections/RewardsSection/RewardsSection';
import { StakingContractUpdate } from './sections/StakingContractUpdate';

export const Main = () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { InfoCircleOutlined, RightOutlined } from '@ant-design/icons';
import { Button, Flex, Modal, Skeleton, Tag, Tooltip, Typography } from 'antd';
import { Button, Flex, Modal, Popover, Skeleton, Tag, Typography } from 'antd';
import Image from 'next/image';
import { useCallback, useEffect, useRef, useState } from 'react';

Expand All @@ -10,11 +10,13 @@ import { usePageState } from '@/hooks/usePageState';
import { useReward } from '@/hooks/useReward';
import { useStore } from '@/hooks/useStore';
import { balanceFormat } from '@/utils/numberFormatters';
import { formatToTime } from '@/utils/time';

import { ConfettiAnimation } from '../../Confetti/ConfettiAnimation';
import { CardSection } from '../../styled/CardSection';
import { ConfettiAnimation } from '../../../Confetti/ConfettiAnimation';
import { CardSection } from '../../../styled/CardSection';
import { useEpochEndTime } from './useEpochEndTime';

const { Text, Title, Paragraph } = Typography;
const { Text, Title } = Typography;

const Loader = () => (
<Flex vertical gap={8}>
Expand All @@ -30,24 +32,29 @@ const DisplayRewards = () => {
const { availableRewardsForEpochEth, isEligibleForRewards } = useReward();
const { isBalanceLoaded } = useBalance();
const { goto } = usePageState();
const { data: epochEndTimeInMs } = useEpochEndTime();

const reward = getFormattedReward(availableRewardsForEpochEth);

return (
<CardSection vertical gap={8} padding="16px 24px" align="start">
<Text type="secondary">
Staking rewards this epoch&nbsp;
<Tooltip
<Popover
arrow={false}
title={
<Paragraph className="text-sm m-0">
The agent&apos;s working period lasts at least 24 hours, but its
start and end point may not be at the same time every day.
</Paragraph>
content={
<>
The epoch ends each day at ~{' '}
<Text className="text-sm" strong>
{epochEndTimeInMs
? `${formatToTime(epochEndTimeInMs * 1000)} (UTC)`
: '--'}
</Text>
</>
}
>
<InfoCircleOutlined />
</Tooltip>
</Popover>
</Text>

{isBalanceLoaded ? (
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { useQuery } from '@tanstack/react-query';
import { gql, request } from 'graphql-request';
import { useMemo } from 'react';
import { z } from 'zod';

import { SUBGRAPH_URL } from '@/constants/urls';
import { useStakingProgram } from '@/hooks/useStakingProgram';

const EpochTimeSchema = z.object({
epoch: z.string(),
epochLength: z.string(),
blockTimestamp: z.string(),
contractAddress: z.string(),
});
type EpochTime = z.infer<typeof EpochTimeSchema>;

export const useEpochEndTime = () => {
const { activeStakingProgramAddress } = useStakingProgram();
const fetchRewardsQuery = useMemo(() => {
return gql`
query {
checkpoints(
orderBy: epoch
orderDirection: desc
first: 1
where: {
contractAddress: "${activeStakingProgramAddress}"
}
) {
epoch
epochLength
blockTimestamp
contractAddress
}
}
`;
}, [activeStakingProgramAddress]);

const { data, isLoading } = useQuery({
queryKey: ['epochEndTime'],
queryFn: async () => {
const response = (await request(SUBGRAPH_URL, fetchRewardsQuery)) as {
checkpoints: EpochTime[];
};
return EpochTimeSchema.parse(response.checkpoints[0]);
},
select: (data) => {
// last epoch end time + epoch length
return Number(data.blockTimestamp) + Number(data.epochLength);
},
enabled: !!activeStakingProgramAddress,
});

return { data, isLoading };
};
4 changes: 1 addition & 3 deletions frontend/components/RewardsHistory/useRewardsHistory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { z } from 'zod';
import { Chain } from '@/client';
import { SERVICE_STAKING_TOKEN_MECH_USAGE_CONTRACT_ADDRESSES } from '@/constants/contractAddresses';
import { STAKING_PROGRAM_META } from '@/constants/stakingProgramMeta';
import { SUBGRAPH_URL } from '@/constants/urls';
import { StakingProgramId } from '@/enums/StakingProgram';
import { useServices } from '@/hooks/useServices';

Expand All @@ -30,9 +31,6 @@ const beta2Address =
SERVICE_STAKING_TOKEN_MECH_USAGE_CONTRACT_ADDRESSES[Chain.GNOSIS]
.pearl_beta_2;

const SUBGRAPH_URL =
'https://api.studio.thegraph.com/query/81855/pearl-staking-rewards-history/version/latest';

const fetchRewardsQuery = gql`
{
allRewards: checkpoints(orderBy: epoch, orderDirection: desc) {
Expand Down
3 changes: 3 additions & 0 deletions frontend/constants/urls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ export const COW_SWAP_GNOSIS_XDAI_OLAS_URL: string =
export const SUPPORT_URL =
'https://discord.com/channels/899649805582737479/1244588374736502847';
export const FAQ_URL = 'https://olas.network/operate#faq';

export const SUBGRAPH_URL =
'https://api.studio.thegraph.com/query/81855/pearl-staking-rewards-history/version/latest';
10 changes: 10 additions & 0 deletions frontend/hooks/useStakingProgram.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { useContext, useMemo } from 'react';

import { Chain } from '@/client';
import { SERVICE_STAKING_TOKEN_MECH_USAGE_CONTRACT_ADDRESSES } from '@/constants/contractAddresses';
import { STAKING_PROGRAM_META } from '@/constants/stakingProgramMeta';
import { StakingProgramContext } from '@/context/StakingProgramContext';

Expand Down Expand Up @@ -31,8 +33,16 @@ export const useStakingProgram = () => {
const defaultStakingProgramMeta =
STAKING_PROGRAM_META[defaultStakingProgramId];

const activeStakingProgramAddress = useMemo(() => {
if (!activeStakingProgramId) return undefined;
return SERVICE_STAKING_TOKEN_MECH_USAGE_CONTRACT_ADDRESSES[Chain.GNOSIS][
activeStakingProgramId
];
}, [activeStakingProgramId]);

return {
activeStakingProgramId,
activeStakingProgramAddress,
activeStakingProgramMeta,
defaultStakingProgramId,
defaultStakingProgramMeta,
Expand Down
26 changes: 20 additions & 6 deletions frontend/utils/time.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,36 @@ export const getTimeAgo = (timestampInSeconds: number) => {
* @returns formatted date in the format of 'MMM DD'
* @example 1626825600 => 'Jul 21'
*/
export const formatToMonthDay = (timeInSeconds: number) => {
if (!isNumber(timeInSeconds)) return '--';
return new Date(timeInSeconds).toLocaleDateString('en-US', {
export const formatToMonthDay = (timeInMs: number) => {
if (!isNumber(timeInMs)) return '--';
return new Date(timeInMs).toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
});
};

/**
* @returns formatted time in the format of 'HH:MM AM/PM'
* @example 1626825600 => '12:00 PM'
*/
export const formatToTime = (timeInMs: number) => {
if (!isNumber(timeInMs)) return '--';
return new Date(timeInMs).toLocaleTimeString('en-US', {
hour: 'numeric',
minute: 'numeric',
hour12: true,
timeZone: 'UTC',
});
};

/**
*
* @returns formatted date and time in the format of 'MMM DD, HH:MM AM/PM'
* @example 1626825600 => 'Jul 21, 12:00 PM'
*/
export const formatToShortDateTime = (timeInSeconds?: number) => {
if (!isNumber(timeInSeconds)) return '--';
return new Date(timeInSeconds).toLocaleDateString('en-US', {
export const formatToShortDateTime = (timeInMs?: number) => {
if (!isNumber(timeInMs)) return '--';
return new Date(timeInMs).toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
hour: 'numeric',
Expand Down

0 comments on commit cdf50a0

Please sign in to comment.