Skip to content

Commit

Permalink
Merge pull request #58 from OriginProtocol/feat/activity-center
Browse files Browse the repository at this point in the history
[TAS-320] Feat/activity center
  • Loading branch information
toniocodo committed Oct 5, 2023
2 parents 0a06772 + e8f872e commit 2d5b2fd
Show file tree
Hide file tree
Showing 54 changed files with 1,591 additions and 987 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
node_modules
dist
*.generated.ts
1 change: 0 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
"@nx/enforce-module-boundaries": [
"error",
{
"enforceBuildableLibDependency": true,
"allow": [],
"depConstraints": [
{
Expand Down
12 changes: 11 additions & 1 deletion apps/oeth/src/components/Topnav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
useMediaQuery,
useTheme,
} from '@mui/material';
import { AccountPopover } from '@origin/oeth/shared';
import { AccountPopover, ActivityButton } from '@origin/oeth/shared';
import { OpenAccountModalButton } from '@origin/shared/providers';
import { useIntl } from 'react-intl';
import { Link, useLocation, useNavigate } from 'react-router-dom';
Expand Down Expand Up @@ -198,6 +198,16 @@ export function Topnav(props: BoxProps) {
anchor={accountModalAnchor}
setAnchor={setAccountModalAnchor}
/>
<ActivityButton
sx={{
width: { xs: 36, md: 44 },
height: { xs: 36, md: 44 },
padding: {
xs: 0.75,
md: 1,
},
}}
/>
</Box>
<Divider
sx={{
Expand Down
8 changes: 7 additions & 1 deletion apps/oeth/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ import { StrictMode } from 'react';
import * as ReactDOM from 'react-dom/client';

import { Experimental_CssVarsProvider as CssVarsProvider } from '@mui/material';
import { chains, queryClient, wagmiConfig } from '@origin/oeth/shared';
import {
ActivityProvider,
chains,
queryClient,
wagmiConfig,
} from '@origin/oeth/shared';
import {
CurveProvider,
GeoFenceProvider,
Expand Down Expand Up @@ -43,6 +48,7 @@ root.render(
[RainbowKitProvider, { chains: chains, theme: darkTheme() }],
[CurveProvider],
[NotificationsProvider],
[ActivityProvider],
[GeoFenceProvider],
],
<RouterProvider router={createHashRouter(routes)} />,
Expand Down
117 changes: 41 additions & 76 deletions libs/oeth/history/src/queries.generated.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,21 @@
import { graphqlClient } from '@origin/oeth/shared';
import { useQuery } from '@tanstack/react-query';
import * as Types from '@origin/oeth/shared';

import type * as Types from '@origin/oeth/shared';
import type { UseQueryOptions } from '@tanstack/react-query';
import { useQuery, UseQueryOptions } from '@tanstack/react-query';
import { graphqlClient } from '@origin/oeth/shared';
export type HistoryPageQueryVariables = Types.Exact<{
address: Types.Scalars['String']['input'];
offset: Types.Scalars['Int']['input'];
filters?: Types.InputMaybe<Array<Types.HistoryType> | Types.HistoryType>;
}>;

export type HistoryPageQuery = {
__typename?: 'Query';
addresses: Array<{
__typename?: 'Address';
balance: string;
earned: string;
isContract: boolean;
rebasingOption: Types.RebasingOption;
lastUpdated: string;
history: Array<{
__typename?: 'History';
type: Types.HistoryType;
value: string;
txHash: string;
timestamp: string;
balance: string;
}>;
}>;
};

export type HistoryApyQueryVariables = Types.Exact<{ [key: string]: never }>;
export type HistoryPageQuery = { __typename?: 'Query', addresses: Array<{ __typename?: 'Address', balance: string, earned: string, isContract: boolean, rebasingOption: Types.RebasingOption, lastUpdated: string, history: Array<{ __typename?: 'History', type: Types.HistoryType, value: string, txHash: string, timestamp: string, balance: string }> }> };

export type HistoryApyQueryVariables = Types.Exact<{ [key: string]: never; }>;


export type HistoryApyQuery = { __typename?: 'Query', apies: Array<{ __typename?: 'APY', apy7DayAvg: number, apy30DayAvg: number }> };

export type HistoryApyQuery = {
__typename?: 'Query';
apies: Array<{ __typename?: 'APY'; apy7DayAvg: number; apy30DayAvg: number }>;
};

export const HistoryPageDocument = `
query HistoryPage($address: String!, $offset: Int!, $filters: [HistoryType!]) {
Expand All @@ -59,32 +40,23 @@ export const HistoryPageDocument = `
}
}
`;
export const useHistoryPageQuery = <TData = HistoryPageQuery, TError = unknown>(
variables: HistoryPageQueryVariables,
options?: UseQueryOptions<HistoryPageQuery, TError, TData>,
) =>
useQuery<HistoryPageQuery, TError, TData>(
['HistoryPage', variables],
graphqlClient<HistoryPageQuery, HistoryPageQueryVariables>(
HistoryPageDocument,
variables,
),
options,
);
export const useHistoryPageQuery = <
TData = HistoryPageQuery,
TError = unknown
>(
variables: HistoryPageQueryVariables,
options?: UseQueryOptions<HistoryPageQuery, TError, TData>
) =>
useQuery<HistoryPageQuery, TError, TData>(
['HistoryPage', variables],
graphqlClient<HistoryPageQuery, HistoryPageQueryVariables>(HistoryPageDocument, variables),
options
);

useHistoryPageQuery.getKey = (variables: HistoryPageQueryVariables) => ['HistoryPage', variables];
;

useHistoryPageQuery.getKey = (variables: HistoryPageQueryVariables) => [
'HistoryPage',
variables,
];
useHistoryPageQuery.fetcher = (
variables: HistoryPageQueryVariables,
options?: RequestInit['headers'],
) =>
graphqlClient<HistoryPageQuery, HistoryPageQueryVariables>(
HistoryPageDocument,
variables,
options,
);
useHistoryPageQuery.fetcher = (variables: HistoryPageQueryVariables, options?: RequestInit['headers']) => graphqlClient<HistoryPageQuery, HistoryPageQueryVariables>(HistoryPageDocument, variables, options);
export const HistoryApyDocument = `
query HistoryApy {
apies(limit: 1, orderBy: timestamp_DESC) {
Expand All @@ -93,27 +65,20 @@ export const HistoryApyDocument = `
}
}
`;
export const useHistoryApyQuery = <TData = HistoryApyQuery, TError = unknown>(
variables?: HistoryApyQueryVariables,
options?: UseQueryOptions<HistoryApyQuery, TError, TData>,
) =>
useQuery<HistoryApyQuery, TError, TData>(
variables === undefined ? ['HistoryApy'] : ['HistoryApy', variables],
graphqlClient<HistoryApyQuery, HistoryApyQueryVariables>(
HistoryApyDocument,
variables,
),
options,
);
export const useHistoryApyQuery = <
TData = HistoryApyQuery,
TError = unknown
>(
variables?: HistoryApyQueryVariables,
options?: UseQueryOptions<HistoryApyQuery, TError, TData>
) =>
useQuery<HistoryApyQuery, TError, TData>(
variables === undefined ? ['HistoryApy'] : ['HistoryApy', variables],
graphqlClient<HistoryApyQuery, HistoryApyQueryVariables>(HistoryApyDocument, variables),
options
);

useHistoryApyQuery.getKey = (variables?: HistoryApyQueryVariables) => variables === undefined ? ['HistoryApy'] : ['HistoryApy', variables];
;

useHistoryApyQuery.getKey = (variables?: HistoryApyQueryVariables) =>
variables === undefined ? ['HistoryApy'] : ['HistoryApy', variables];
useHistoryApyQuery.fetcher = (
variables?: HistoryApyQueryVariables,
options?: RequestInit['headers'],
) =>
graphqlClient<HistoryApyQuery, HistoryApyQueryVariables>(
HistoryApyDocument,
variables,
options,
);
useHistoryApyQuery.fetcher = (variables?: HistoryApyQueryVariables, options?: RequestInit['headers']) => graphqlClient<HistoryApyQuery, HistoryApyQueryVariables>(HistoryApyDocument, variables, options);
104 changes: 72 additions & 32 deletions libs/oeth/redeem/src/hooks.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import { useCallback } from 'react';

import { contracts } from '@origin/shared/contracts';
import { Box } from '@mui/material';
import {
BlockExplorerLink,
usePushNotification,
useSlippage,
} from '@origin/shared/providers';
import { isNilOrEmpty } from '@origin/shared/utils';
RedeemNotification,
useDeleteActivity,
usePushActivity,
useUpdateActivity,
} from '@origin/oeth/shared';
import { NotificationSnack } from '@origin/shared/components';
import { contracts, tokens } from '@origin/shared/contracts';
import { usePushNotification, useSlippage } from '@origin/shared/providers';
import { isNilOrEmpty, isUserRejected } from '@origin/shared/utils';
import {
prepareWriteContract,
waitForTransaction,
Expand Down Expand Up @@ -40,6 +44,9 @@ export const useHandleRedeem = () => {
const intl = useIntl();
const { value: slippage } = useSlippage();
const pushNotification = usePushNotification();
const pushActivity = usePushActivity();
const updateActivity = useUpdateActivity();
const deleteActivity = useDeleteActivity();
const { address } = useAccount();
const [{ amountIn, amountOut }, setRedeemState] = useRedeemState();
const wagmiClient = useQueryClient();
Expand All @@ -49,65 +56,98 @@ export const useHandleRedeem = () => {
return;
}

const minAmountOut = parseUnits(
(
+formatUnits(amountOut, MIX_TOKEN.decimals) -
+formatUnits(amountOut, MIX_TOKEN.decimals) * slippage
).toString(),
MIX_TOKEN.decimals,
);

const activity = pushActivity({
type: 'redeem',
status: 'pending',
tokenIn: tokens.mainnet.OETH,
tokenOut: MIX_TOKEN,
amountIn,
amountOut,
});

setRedeemState(
produce((draft) => {
draft.isRedeemLoading = true;
}),
);

try {
const minAmountOut = parseUnits(
(
+formatUnits(amountOut, MIX_TOKEN.decimals) -
+formatUnits(amountOut, MIX_TOKEN.decimals) * slippage
).toString(),
MIX_TOKEN.decimals,
);

const { request } = await prepareWriteContract({
address: contracts.mainnet.OETHVaultCore.address,
abi: contracts.mainnet.OETHVaultCore.abi,
functionName: 'redeem',
args: [amountIn, minAmountOut],
});
const { hash } = await writeContract(request);
setRedeemState(
produce((draft) => {
draft.isRedeemLoading = false;
}),
);
const txReceipt = await waitForTransaction({ hash });

console.log('redeem vault done!');
wagmiClient.invalidateQueries({ queryKey: ['redeem_balance'] });
updateActivity({ ...activity, status: 'success', txReceipt });
pushNotification({
title: intl.formatMessage({ defaultMessage: 'Redeem complete' }),
severity: 'success',
content: <BlockExplorerLink hash={txReceipt.hash} />,
content: (
<RedeemNotification
{...activity}
status="success"
txReceipt={txReceipt}
/>
),
});
} catch (e) {
console.error(`redeem vault error!\n${e.message}`);
if (e?.code === 'ACTION_REJECTED') {
} catch (error) {
if (isUserRejected(error)) {
deleteActivity(activity.id);
pushNotification({
title: intl.formatMessage({ defaultMessage: 'Redeem vault' }),
severity: 'info',
content: (
<NotificationSnack
icon={<Box component="img" src="/images/warn.png" />}
title={intl.formatMessage({
defaultMessage: 'Operation Cancelled',
})}
subtitle={intl.formatMessage({
defaultMessage: 'User rejected operation',
})}
/>
),
});
} else {
updateActivity({
...activity,
status: 'error',
error: error?.shortMessage ?? error.message,
});
pushNotification({
title: intl.formatMessage({ defaultMessage: 'Redeem vault' }),
severity: 'error',
content: (
<RedeemNotification
{...activity}
status="error"
error={error?.shortMessage ?? error.message}
/>
),
});
}
}

setRedeemState(
produce((draft) => {
draft.isRedeemLoading = false;
}),
);
}, [
address,
amountIn,
amountOut,
deleteActivity,
intl,
pushActivity,
pushNotification,
setRedeemState,
slippage,
updateActivity,
wagmiClient,
]);
};

0 comments on commit 2d5b2fd

Please sign in to comment.