Skip to content

Commit

Permalink
Manual ispo claiming process (#926)
Browse files Browse the repository at this point in the history
* feat: add manual claims

* fix routing

* fix application routes

* fix: add navigation

* some fixes

---------

Co-authored-by: ridel1e <[email protected]>
  • Loading branch information
yasha-black and Ridel1e authored Oct 10, 2023
1 parent d7322e3 commit 7c65ddd
Show file tree
Hide file tree
Showing 7 changed files with 455 additions and 167 deletions.
13 changes: 12 additions & 1 deletion src/ApplicationRoutes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { useApplicationSettings } from './context';
import { AddLiquidity } from './pages/AddLiquidity/AddLiquidity';
import { CreatePool } from './pages/CreatePool/CreatePool';
import { Farms } from './pages/Farms/Farms';
import { IspoRewards } from './pages/IspoRewards/IspoRewards.tsx';
import { Liquidity } from './pages/Liquidity/Liquidity';
import { LockLiquidity } from './pages/LockLiquidity/LockLiquidity';
import { PoolOverview } from './pages/PoolOverview/PoolOverview';
Expand Down Expand Up @@ -111,7 +112,17 @@ export const routesConfig: RouteConfigExtended[] = [
{
title: 'Rewards',
path: 'rewards',
element: <Rewards />,
children: [
{
path: '',
element: <Rewards />,
},
{
title: 'ISPO Rewards',
path: 'ispo',
element: <IspoRewards />,
},
],
},
{
path: '*',
Expand Down
3 changes: 0 additions & 3 deletions src/createBrowserHistory.ts

This file was deleted.

20 changes: 20 additions & 0 deletions src/network/cardano/api/rewards/rewards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,3 +268,23 @@ export const rewards$ = getAddresses().pipe(
publishReplay(1),
refCount(),
);

export interface IspoRewardsData {
available: Currency;
received: Currency;
}

export const requestIspoRewards = (
address: string,
): Promise<IspoRewardsData> => {
return axios
.post('https://rewards.spectrum.fi/v1/rewards/ispo/data', address, {
headers: {
'Content-Type': 'application/json',
},
})
.then((res) => ({
available: new Currency(res.data.available.toString(), rewardAsset),
received: new Currency(res.data.received.toString(), rewardAsset),
}));
};
212 changes: 212 additions & 0 deletions src/pages/IspoRewards/IspoRewards.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
import {
Alert,
Box,
Button,
CopyOutlined,
Empty,
Flex,
Form,
Input,
message,
Typography,
useForm,
} from '@ergolabs/ui-kit';
import { t, Trans } from '@lingui/macro';
import { FC, useState } from 'react';
import CopyToClipboard from 'react-copy-to-clipboard';

import { AssetIcon } from '../../components/AssetIcon/AssetIcon.tsx';
import { Page } from '../../components/Page/Page.tsx';
import {
IspoRewardsData,
requestIspoRewards,
} from '../../network/cardano/api/rewards/rewards.ts';

const REWARDS_ADDRESS =
'addr1vx3vcluw7qtulynhzsy4prfdmnjth8w52ejg2qeclsz7argu26gcf';

interface IspoForm {
address?: string;
}

interface IspoRewardsViewProps {
data: IspoRewardsData;
}

const IspoRewardsView: FC<IspoRewardsViewProps> = ({ data }) => {
return (
<Box borderRadius="l" bordered padding={3}>
<Flex col>
<Flex.Item marginBottom={2} justify="space-between">
<Typography.Title level={5}>
<Trans>Available</Trans>
</Typography.Title>
<Flex align="center">
<Flex.Item marginRight={1}>
<AssetIcon asset={data.available.asset} />
</Flex.Item>

<Typography.Body size="large" strong>
{data.available.toString()} {data.available.asset.ticker}
</Typography.Body>
</Flex>
</Flex.Item>

<Flex.Item justify="space-between">
<Typography.Title level={5}>
<Trans>Claimed</Trans>
</Typography.Title>
<Flex align="center">
<Flex.Item marginRight={1}>
<AssetIcon asset={data.received.asset} />
</Flex.Item>

<Typography.Body size="large" strong>
{data.received.toString()} {data.received.asset.ticker}
</Typography.Body>
</Flex>
</Flex.Item>
</Flex>
</Box>
);
};

const ClaimIspoRewards: FC<{ data: IspoRewardsData }> = ({ data }) => {
return (
<Box borderRadius="l" bordered padding={3}>
<Flex col>
{data.available.amount > 0n ? (
<>
<Flex.Item marginBottom={2}>
<Typography.Body strong>
<Trans>
Complete the claiming process by sending{' '}
<span style={{ color: 'var(--spectrum-warning-color)' }}>
5 ADA
</span>{' '}
in ONE transaction to the address below:
</Trans>
</Typography.Body>
</Flex.Item>
<Flex.Item marginBottom={2}>
<CopyToClipboard
text={REWARDS_ADDRESS}
onCopy={() => message.success(t`Address copied!`)}
>
<Typography.Link onClick={(e) => e.stopPropagation()}>
<CopyOutlined style={{ marginRight: '4px' }} />
{REWARDS_ADDRESS}
</Typography.Link>
</CopyToClipboard>
</Flex.Item>
<Flex.Item marginBottom={2}>
<Alert
type="warning"
showIcon
message={t`Only send ADA from the wallet that owns the provided stake or payment address. Otherwise your request won't be processed. If you accidentally made something wrong, contact support`}
/>
</Flex.Item>
<Flex.Item>
<Alert
type="info"
showIcon
message={t`All ADA will be returned to you except ~0.4 ADA which will be spent on the network fee.`}
/>
</Flex.Item>
</>
) : (
<Flex.Item>
<Alert
type="info"
showIcon
message={t`No available rewards for now. Come back next epoch!`}
/>
</Flex.Item>
)}
</Flex>
</Box>
);
};

const renderRewards = (data?: IspoRewardsData) => {
if (!data) {
return <></>;
}

if (data.received.amount <= 0n && data.available.amount <= 0n) {
return (
<Flex col align="center">
<Empty />
<Typography.Body strong>
<Trans>No rewards found</Trans>
</Typography.Body>
</Flex>
);
}

return (
<>
<Flex.Item marginBottom={2}>
<IspoRewardsView data={data} />
</Flex.Item>
<Flex.Item>
<ClaimIspoRewards data={data} />
</Flex.Item>
</>
);
};

export const IspoRewards = () => {
const [data, setData] = useState<IspoRewardsData | undefined>(undefined);
const form = useForm<IspoForm>({
address: undefined,
});

return (
<Page
withBackButton
backTo="../../../rewards"
width={600}
title="Claim ISPO rewards"
>
<Flex col>
<Flex.Item marginBottom={data ? 2 : 0}>
<Form
form={form}
onSubmit={({ value: { address } }) => {
if (address) {
requestIspoRewards(address).then((data) => {
setData(data);
});
}
}}
>
<Form.Listener<IspoForm>>
{({ value }) => {
return (
<Input
size="middle"
placeholder={t`Enter your stake or payment address`}
value={value.address}
onChange={({ target }) => {
form.patchValue({ address: target.value });
}}
/>
);
}}
</Form.Listener>
<Button
style={{ marginTop: '8px' }}
htmlType="submit"
type="primary"
>
Check My Reward
</Button>
</Form>
</Flex.Item>

{renderRewards(data)}
</Flex>
</Page>
);
};
53 changes: 37 additions & 16 deletions src/pages/Rewards/Rewards.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
import { Trans } from '@lingui/macro';
import { ElementLocation, ElementName } from '@spectrumlabs/analytics';
import { FC } from 'react';
import { useNavigate } from 'react-router-dom';
import { filter } from 'rxjs';

import { applicationConfig } from '../../applicationConfig';
Expand All @@ -30,6 +31,8 @@ export const Rewards: FC = () => {
getAddresses().pipe(filter((addresses) => !!addresses?.length)),
);

const navigate = useNavigate();

return (
<Flex col align="center">
{applicationConfig.isRewardsAvailable && (
Expand Down Expand Up @@ -114,22 +117,40 @@ export const Rewards: FC = () => {
)}
</Flex.Item>
{applicationConfig.isRewardsAvailable ? (
<ConnectWalletButton
width="100%"
size="extra-large"
trace={{
element_location: ElementLocation.rewardsPage,
element_name: ElementName.connectWalletButton,
}}
>
{loading ? (
<Skeleton active />
) : rewardsData ? (
<RewardsDashboard rewardsData={rewardsData} />
) : (
<RewardsError />
)}
</ConnectWalletButton>
<Flex col align="center">
<Flex.Item width="100%" marginBottom={2}>
<ConnectWalletButton
width="100%"
size="extra-large"
trace={{
element_location: ElementLocation.rewardsPage,
element_name: ElementName.connectWalletButton,
}}
>
{loading ? (
<Skeleton active />
) : rewardsData ? (
<RewardsDashboard rewardsData={rewardsData} />
) : (
<RewardsError />
)}
</ConnectWalletButton>
</Flex.Item>
<Flex.Item align="center">
<Typography.Body secondary style={{ textAlign: 'center' }}>
If you would like to claim your ISPO rewards without
connecting your wallet, please click{' '}
<Typography.Link
onClick={() => {
navigate('ispo');
}}
>
here
</Typography.Link>
.
</Typography.Body>
</Flex.Item>
</Flex>
) : (
<RewardsBugFixing />
)}
Expand Down
Loading

0 comments on commit 7c65ddd

Please sign in to comment.