Skip to content

Commit

Permalink
feat(evm): improve stake page (#335)
Browse files Browse the repository at this point in the history
  • Loading branch information
danielsimao authored Jan 16, 2025
1 parent 676e335 commit 197f08a
Show file tree
Hide file tree
Showing 70 changed files with 2,842 additions and 1,599 deletions.
2 changes: 1 addition & 1 deletion apps/evm/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
},
"dependencies": {
"@binance/w3w-wagmi-connector-v2": "1.2.4-alpha.0",
"@gobob/bob-sdk": "^3.1.0",
"@gobob/bob-sdk": "^3.1.1",
"@gobob/chains": "workspace:^",
"@gobob/currency": "workspace:^",
"@gobob/hooks": "workspace:^",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export const seTokenAbi = [
export const erc20WithUnderlying = [
{
inputs: [],
stateMutability: 'nonpayable',
Expand Down
1 change: 0 additions & 1 deletion apps/evm/src/app/[lang]/(bridge)/bridge/Bridge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,6 @@ const Bridge = ({ searchParams }: Props) => {
data={transactions}
isInitialLoading={isTransactionsInitialLoading}
txPendingUserAction={txPendingUserAction}
type='bridge'
onProveSuccess={refetch.bridge}
onRelaySuccess={refetch.bridge}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,10 @@ const GatewayTransactionDetails = ({
{!query.liquidity.isPending && query.liquidity.data && !query.liquidity.data.hasLiquidity && (
<Alert status='warning'>
<P size='s'>
{type === 'stake' ? (
<Trans>Cannot stake into {assetName} due to insufficient liquidity.</Trans>
{type === GatewayTransactionType.STRATEGY ? (
<Trans>Currently, there is no available liquidity for this strategy.</Trans>
) : (
<Trans>There is currently no available liquidity to onramp BTC into {assetName}.</Trans>
<Trans>Currently, there is no available liquidity to onramp BTC into {assetName}.</Trans>
)}
</P>
</Alert>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { CardProps, Divider, Flex, H2, Link, P, Spinner } from '@gobob/ui';
import { Trans, t } from '@lingui/macro';
import { useLingui } from '@lingui/react';
import { Trans } from '@lingui/macro';
import { useVirtualizer } from '@tanstack/react-virtual';
import { useMemo, useRef } from 'react';
import { useIsClient } from 'usehooks-ts';
import { useAccount } from 'wagmi';
import { useVirtualizer } from '@tanstack/react-virtual';

import { TransactionItem } from './TransactionItem';
import {
Expand All @@ -22,7 +21,6 @@ import { chainL2 } from '@/constants';
import { Transaction } from '@/types';

type Props = {
type: 'bridge' | 'stake';
isInitialLoading?: boolean;
data?: Transaction[];
onProveSuccess?: () => void;
Expand All @@ -35,15 +33,13 @@ type InheritAttrs = Omit<CardProps, keyof Props>;
type TransactionListProps = Props & InheritAttrs;

const TransactionList = ({
type,
isInitialLoading,
data,
onProveSuccess,
onRelaySuccess,
txPendingUserAction,
...props
}: TransactionListProps): JSX.Element => {
const { i18n } = useLingui();
const isClient = useIsClient();
// The scrollable element for your list
const parentRef = useRef(null);
Expand Down Expand Up @@ -80,7 +76,6 @@ const TransactionList = ({

const txsUrl = address ? `${explorerUrl}/address/${address}` : `${explorerUrl}`;
const hasData = !!data?.length;
const txType = type === 'bridge' ? t(i18n)`bridging` : t(i18n)`staking`;

return (
<StyledSection gap='xl' paddingX='4xl' paddingY='3xl' {...props}>
Expand All @@ -97,7 +92,7 @@ const TransactionList = ({
<Flex alignItems='center' gap='md' justifyContent='center' style={{ height: '100%' }}>
<Spinner size='16' thickness={2} />
<P align='center' size='xs'>
<Trans>Fetching {txType} operations...</Trans>
<Trans>Fetching operations...</Trans>
</P>
</Flex>
) : (
Expand Down Expand Up @@ -125,7 +120,7 @@ const TransactionList = ({
) : (
<Flex alignItems='center' gap='md' justifyContent='center' style={{ height: '100%' }}>
<P align='center' size='xs'>
<Trans>No {txType} operations found</Trans>
<Trans>No operations found</Trans>
</P>
</Flex>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ const GatewayTransactionModal = ({ data, onClose, ...props }: GatewayTransaction
<Trans>
Your assets will be delivered once your BTC transactions receive at least 3 confirmations and the
processing finishes on our L2 chain. We will provide you with updates accordingly. You can monitor the
progress on your bridge page. It will be marked as complete once the process has concluded.
progress on the &quot;Activity&quot; section. It will be marked as complete once the process has
concluded.
</Trans>
</P>
</Flex>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ describe('useGateway', () => {
const { result } = renderHook(
() =>
useGateway({
params: { type: GatewayTransactionType.STAKE, assetName: 'BTC' }
params: { type: GatewayTransactionType.STRATEGY, assetName: 'BTC' }
}),
{
wrapper
Expand All @@ -54,7 +54,7 @@ describe('useGateway', () => {
const { result } = renderHook(
() =>
useGateway({
params: { type: GatewayTransactionType.STAKE, assetName: 'BTC' }
params: { type: GatewayTransactionType.STRATEGY, assetName: 'BTC' }
}),
{
wrapper
Expand All @@ -72,7 +72,7 @@ describe('useGateway', () => {
const { result } = renderHook(
() =>
useGateway({
params: { type: GatewayTransactionType.STAKE, assetName: 'BTC' }
params: { type: GatewayTransactionType.STRATEGY, assetName: 'BTC' }
}),
{
wrapper
Expand All @@ -94,7 +94,7 @@ describe('useGateway', () => {
const { result } = renderHook(
() =>
useGateway({
params: { type: GatewayTransactionType.STAKE, assetName: 'BTC' },
params: { type: GatewayTransactionType.STRATEGY, assetName: 'BTC' },
onError: mockFeeEstimateQueryResult
}),
{
Expand Down
16 changes: 8 additions & 8 deletions apps/evm/src/app/[lang]/(bridge)/hooks/useGateway.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,8 @@ type UseGatewayQueryDataReturnType = {
balance: { data: CurrencyAmount<Bitcoin>; isPending: boolean };
};

type StakeParams = {
type: GatewayTransactionType.STAKE;
type StrategyParams = {
type: GatewayTransactionType.STRATEGY;
assetName?: string;
} & Partial<Pick<GatewayQuoteParams, 'toChain' | 'toToken' | 'strategyAddress'>>;

Expand All @@ -122,7 +122,7 @@ type BridgeParams = {
} & Partial<Pick<GatewayQuoteParams, 'toChain' | 'toToken'>>;

type UseGatewayLiquidityProps = {
params: BridgeParams | StakeParams;
params: BridgeParams | StrategyParams;
isDisabled?: boolean;
onMutate?: (data: Optional<InitGatewayTransaction, 'amount'>) => void;
onSuccess?: (data: InitGatewayTransaction) => void;
Expand Down Expand Up @@ -183,13 +183,13 @@ const useGateway = ({
const isTapRootAddress = btcAddressType === BtcAddressType.p2tr;

const liquidityQueryEnabled = Boolean(
params.toChain && params.toToken && params.type === GatewayTransactionType.STAKE ? params.strategyAddress : true
params.toChain && params.toToken && params.type === GatewayTransactionType.STRATEGY ? params.strategyAddress : true
);

const liquidityQueryKey = bridgeKeys.btcQuote(
params.toToken,
params.toChain,
(params as StakeParams)?.strategyAddress,
(params as StrategyParams)?.strategyAddress,
'liquidity-check'
);

Expand All @@ -208,7 +208,7 @@ const useGateway = ({
...DEFAULT_GATEWAY_QUOTE_PARAMS,
toChain,
toToken,
strategyAddress: params.type === GatewayTransactionType.STAKE ? params.strategyAddress : undefined,
strategyAddress: params.type === GatewayTransactionType.STRATEGY ? params.strategyAddress : undefined,
amount: undefined
});

Expand Down Expand Up @@ -268,7 +268,7 @@ const useGateway = ({
const quoteQueryKey = bridgeKeys.btcQuote(
params.toToken,
params.toChain,
(params as StakeParams)?.strategyAddress,
(params as StrategyParams)?.strategyAddress,
rawAmount,
isTopUpEnabled
);
Expand All @@ -292,7 +292,7 @@ const useGateway = ({
gasRefill: isTopUpEnabled ? GAS_REFILL : 0,
toChain,
toToken,
strategyAddress: params.type === GatewayTransactionType.STAKE ? params.strategyAddress : undefined
strategyAddress: params.type === GatewayTransactionType.STRATEGY ? params.strategyAddress : undefined
});

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ const getGatewayTransactions = async (address: Address): Promise<GatewayTransact
totalConfirmations: order.txProofDifficultyFactor,
status,
type: TransactionType.Gateway,
subType: order.strategyAddress ? GatewayTransactionType.STAKE : GatewayTransactionType.BRIDGE,
subType: order.strategyAddress ? GatewayTransactionType.STRATEGY : GatewayTransactionType.BRIDGE,
isPending,
order
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
'use client';

import { Flex } from '@gobob/ui';
import { useStore } from '@tanstack/react-store';
import { watchAccount } from '@wagmi/core';
import { useEffect, useRef } from 'react';
import { useConfig } from 'wagmi';
import { Flex } from '@gobob/ui';

import { Layout, TransactionList } from '../components';
import { GetGatewayTransactionsReturnType, useGetGatewayTransactions } from '../hooks';

import { StakeTable } from './components';
import { StrategiesTable } from './components';

import { PageLangParam } from '@/i18n/withLigui';
import { store } from '@/lib/store';
Expand All @@ -20,16 +20,12 @@ type Props = PageLangParam & {
};

const select = (data: GetGatewayTransactionsReturnType) =>
data.filter((item) => item.subType === GatewayTransactionType.STAKE);
data.filter((item) => item.subType === GatewayTransactionType.STRATEGY);

function Stake({ searchParams }: Props) {
function Strategies({ searchParams }: Props) {
const config = useConfig();

const {
data: transactions,
isLoading: isLoadingTransactions,
refetch: refetchTransactions
} = useGetGatewayTransactions({
const { data: transactions, isLoading: isLoadingTransactions } = useGetGatewayTransactions({
query: { select }
});

Expand All @@ -43,7 +39,7 @@ function Stake({ searchParams }: Props) {
if (account.address) {
store.setState((state) => ({
...state,
stake: { ...state.stake, transactions: { ...state.stake.transactions, isInitialLoading: true } }
stake: { ...state.strategies, transactions: { ...state.strategies.transactions, isInitialLoading: true } }
}));
}
}
Expand All @@ -64,12 +60,12 @@ function Stake({ searchParams }: Props) {

return (
<Layout>
<Flex direction='column' gap='xl' marginTop='xl'>
<StakeTable searchParams={searchParams} onStakeSuccess={refetchTransactions} />
<TransactionList data={transactions} isInitialLoading={isInitialLoading} type='stake' />
<Flex direction='column' gap='xl' marginTop='2xl'>
<StrategiesTable searchParams={searchParams} />
<TransactionList data={transactions} isInitialLoading={isInitialLoading} />
</Flex>
</Layout>
);
}

export { Stake };
export { Strategies };
104 changes: 104 additions & 0 deletions apps/evm/src/app/[lang]/(bridge)/stake/[slug]/Strategy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
'use client';

import { Alert, ArrowLeft, Avatar, Button, Card, Flex, H1, H2, Link, P, Skeleton, Tabs, TabsItem } from '@gobob/ui';
import { Trans } from '@lingui/macro';
import { useState } from 'react';

import { useGetGatewayTransactions } from '../../hooks';
import { StrategyDetails, StrategyForm } from '../components';
import { useGetStrategies } from '../hooks';

import { Layout, Main } from '@/components';
import { RoutesPath } from '@/constants';
import { PageLangParam } from '@/i18n/withLigui';

type Props = PageLangParam & {
params: { slug: string };
};

enum Tab {
Deposit = 'deposit',
Withdraw = 'withdraw'
}

function Strategy({ params }: Props) {
const { refetch: refetchTransactions } = useGetGatewayTransactions({});
const [tab, setTab] = useState<Tab>(Tab.Deposit);

const { data: strategies = [] } = useGetStrategies();

const strategy = strategies.find((strategy) => strategy.meta.slug === params.slug);

const isLending = strategy?.meta.type === 'lending';

const action = isLending ? <Trans>withdraw</Trans> : <Trans>unstake</Trans>;
const depositTitle = isLending ? <Trans>Supply</Trans> : <Trans>Stake</Trans>;
const withdrawTitle = isLending ? <Trans>Withdraw</Trans> : <Trans>Unstake</Trans>;

return (
<Layout>
<Main maxWidth='5xl' padding='lg'>
<Link href={RoutesPath.STRATEGIES}>
<Flex alignItems='center' gap='s'>
<ArrowLeft size='xs' />
<Trans>Back</Trans>
</Flex>
</Link>
<Flex alignItems='center' gap='lg' marginTop='4xl'>
{strategy ? (
<Avatar size='4xl' src={strategy.info.logoUrl || strategy.meta.logo} />
) : (
<Skeleton height='4xl' rounded='full' width='4xl' />
)}

<Flex alignItems='flex-start' direction='column'>
<H1 size='lg'>{strategy ? strategy.info.name : <Skeleton height='xl' width='12rem' />}</H1>
<H2 color='grey-50' size='md' weight='medium'>
{strategy ? strategy.info.protocol : <Skeleton height='xl' width='8rem' />}
</H2>
</Flex>
</Flex>
{strategy?.info?.warningMessage && (
<Alert status='warning' style={{ marginTop: '1rem' }} variant='outlined'>
{strategy?.info.warningMessage}
</Alert>
)}
<Flex direction={{ base: 'column', md: 'row' }} gap='xl' marginTop='3xl' style={{ width: '100%' }}>
<Card flex='1 0 0%' style={{ height: 'max-content' }}>
<Tabs fullWidth selectedKey={tab} size='lg' onSelectionChange={(key) => setTab(key as Tab)}>
<TabsItem key={Tab.Deposit} title={strategy ? depositTitle : <Skeleton height='xl' width='6rem' />}>
<StrategyForm isLending={isLending} strategy={strategy} onSuccess={refetchTransactions} />
</TabsItem>
<TabsItem key={Tab.Withdraw} title={strategy ? withdrawTitle : <Skeleton height='xl' width='6rem' />}>
<Flex
alignItems='center'
direction='column'
flex={1}
gap='xl'
justifyContent='center'
marginTop='md'
paddingX='md'
style={{ height: '100%', minHeight: '25rem' }}
>
<P align='center' color='grey-50' size='s'>
<Trans>
Complete your {action} by accessing {strategy?.info.protocol} Dapp using the button bellow
</Trans>
</P>
<Button asChild color='primary'>
<Link external href={strategy?.info.links.manage}>
Go to {strategy?.info.protocol} Dapp
</Link>
</Button>
</Flex>
</TabsItem>
</Tabs>
</Card>
<StrategyDetails isLending={isLending} strategy={strategy} />
</Flex>
</Main>
</Layout>
);
}

export { Strategy };
Loading

0 comments on commit 197f08a

Please sign in to comment.