Skip to content

Commit

Permalink
v7.9.9
Browse files Browse the repository at this point in the history
v7.9.9
  • Loading branch information
platschi authored Oct 16, 2023
2 parents 7105713 + f34b38d commit 91efcb4
Show file tree
Hide file tree
Showing 19 changed files with 2,284 additions and 880 deletions.
13 changes: 12 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "kwenta",
"version": "7.9.8",
"version": "7.9.9",
"description": "Kwenta",
"main": "index.js",
"scripts": {
Expand Down Expand Up @@ -51,5 +51,16 @@
"lint-staged": "13.2.3",
"prettier": "2.8.8",
"typescript": "5.1.6"
},
"pnpm": {
"overrides": {
"got@<11.8.5": ">=11.8.5",
"@adobe/css-tools@<4.3.1": ">=4.3.1",
"semver@<5.7.2": ">=5.7.2",
"semver@>=7.0.0 <7.5.2": ">=7.5.2",
"get-func-name@<2.0.1": ">=2.0.1",
"zod@<=3.22.2": ">=3.22.3",
"postcss@<8.4.31": ">=8.4.31"
}
}
}
2 changes: 1 addition & 1 deletion packages/app/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@kwenta/app",
"version": "7.9.8",
"version": "7.9.9",
"scripts": {
"dev": "next",
"build": "next build",
Expand Down
3 changes: 0 additions & 3 deletions packages/app/src/constants/links.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@ export const EXTERNAL_LINKS = {
OneInchLink: (from: CurrencyKey, to: CurrencyKey) => `https://1inch.exchange/#/${from}/${to}`,
OptimismTokenBridge: 'https://gateway.optimism.io',
},
Options: {
Trade: 'https://options.kwenta.eth.limo/#/trade',
},
Synthetix: {
Home: 'https://www.synthetix.io',
Litepaper: 'https://docs.synthetix.io/litepaper/',
Expand Down
1 change: 1 addition & 0 deletions packages/app/src/constants/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export const ROUTES = {
Stake: normalizeRoute('/dashboard', 'staking', 'tab'),
Rewards: normalizeRoute('/dashboard', 'rewards', 'tab'),
Migrate: normalizeRoute('/dashboard', 'migrate', 'tab'),
Redeem: normalizeRoute('/dashboard', 'redeem', 'tab'),
TradingRewards: formatUrl('/dashboard/staking', { tab: 'trading-rewards' }),
},
Exchange: {
Expand Down
25 changes: 25 additions & 0 deletions packages/app/src/pages/dashboard/redeem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import Head from 'next/head'
import { FC, ReactNode } from 'react'
import { useTranslation } from 'react-i18next'

import DashboardLayout from 'sections/dashboard/DashboardLayout'
import RedemptionTab from 'sections/dashboard/RedemptionTab'

type RedemptionComponent = FC & { getLayout: (page: ReactNode) => JSX.Element }

const RedeemPage: RedemptionComponent = () => {
const { t } = useTranslation()

return (
<>
<Head>
<title>{t('dashboard-redeem.page-title')}</title>
</Head>
<RedemptionTab />
</>
)
}

RedeemPage.getLayout = (page) => <DashboardLayout>{page}</DashboardLayout>

export default RedeemPage
13 changes: 11 additions & 2 deletions packages/app/src/sections/dashboard/DashboardLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { EXTERNAL_LINKS } from 'constants/links'
import ROUTES from 'constants/routes'
import AppLayout from 'sections/shared/Layout/AppLayout'
import { useAppSelector } from 'state/hooks'
import { selectStakingMigrationRequired } from 'state/staking/selectors'
import { selectRedemptionRequired, selectStakingMigrationRequired } from 'state/staking/selectors'
import { selectStartMigration } from 'state/stakingMigration/selectors'
import { LeftSideContent, PageContent } from 'styles/common'

Expand All @@ -23,6 +23,7 @@ enum Tab {
Governance = 'governance',
Stake = 'staking',
Migrate = 'migrate',
Redeem = 'redeem',
}

const Tabs = Object.values(Tab)
Expand All @@ -32,6 +33,7 @@ const DashboardLayout: FC<{ children?: ReactNode }> = ({ children }) => {
const router = useRouter()
const stakingMigrationRequired = useAppSelector(selectStakingMigrationRequired)
const startMigration = useAppSelector(selectStartMigration)
const redemptionRequired = useAppSelector(selectRedemptionRequired)

const tabQuery = useMemo(() => {
if (router.pathname) {
Expand Down Expand Up @@ -79,6 +81,13 @@ const DashboardLayout: FC<{ children?: ReactNode }> = ({ children }) => {
href: ROUTES.Dashboard.Migrate,
hidden: !stakingMigrationRequired && !startMigration,
},
{
name: Tab.Redeem,
label: t('dashboard.tabs.redeem'),
active: activeTab === Tab.Redeem,
href: ROUTES.Dashboard.Redeem,
hidden: !redemptionRequired,
},
{
name: Tab.Governance,
label: t('dashboard.tabs.governance'),
Expand All @@ -87,7 +96,7 @@ const DashboardLayout: FC<{ children?: ReactNode }> = ({ children }) => {
external: true,
},
],
[t, activeTab, startMigration, stakingMigrationRequired]
[t, activeTab, startMigration, stakingMigrationRequired, redemptionRequired]
)

const visibleTabs = TABS.filter(({ hidden }) => !hidden)
Expand Down
49 changes: 49 additions & 0 deletions packages/app/src/sections/dashboard/RedemptionTab.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { useTranslation } from 'react-i18next'
import styled from 'styled-components'

import { FlexDivRowCentered } from 'components/layout/flex'
import { SplitContainer } from 'components/layout/grid'
import { Heading } from 'components/Text'
import media from 'styles/media'

import RedeemInputCard from './Stake/InputCards/RedeempInputCard'

const RedemptionTab = () => {
const { t } = useTranslation()

return (
<Container>
<TitleContainer>
<StyledHeading variant="h4">{t('dashboard.stake.tabs.redeem.title')}</StyledHeading>
</TitleContainer>
<SplitContainer>
<RedeemInputCard
inputLabel={t('dashboard.stake.tabs.stake-table.vkwenta-token')}
isVKwenta
/>
<RedeemInputCard
inputLabel={t('dashboard.stake.tabs.stake-table.vekwenta-token')}
isVKwenta={false}
/>
</SplitContainer>
</Container>
)
}

const StyledHeading = styled(Heading)`
font-weight: 400;
`

const TitleContainer = styled(FlexDivRowCentered)`
margin: 30px 0px;
column-gap: 10%;
`

const Container = styled.div`
${media.lessThan('lg')`
padding: 0px 15px;
`}
margin-top: 20px;
`

export default RedemptionTab
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import { truncateNumbers } from '@kwenta/sdk/utils'
import { FC, useCallback, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import styled from 'styled-components'

import Button from 'components/Button'
import ErrorView from 'components/ErrorView'
import { FlexDivRowCentered } from 'components/layout/flex'
import { StakingCard } from 'sections/dashboard/Stake/card'
import { useAppDispatch, useAppSelector } from 'state/hooks'
import { approveKwentaToken, redeemToken } from 'state/staking/actions'
import {
selectIsVeKwentaTokenApproved,
selectIsVKwentaTokenApproved,
selectVeKwentaBalance,
selectVKwentaBalance,
} from 'state/staking/selectors'
import { selectDisableRedeemEscrowKwenta } from 'state/stakingMigration/selectors'
import { numericValueCSS } from 'styles/common'

type RedeemInputCardProps = {
inputLabel: string
isVKwenta: boolean
}

const RedeemInputCard: FC<RedeemInputCardProps> = ({ inputLabel, isVKwenta }) => {
const { t } = useTranslation()
const dispatch = useAppDispatch()

const vKwentaBalance = useAppSelector(selectVKwentaBalance)
const veKwentaBalance = useAppSelector(selectVeKwentaBalance)
const isVKwentaApproved = useAppSelector(selectIsVKwentaTokenApproved)
const isVeKwentaApproved = useAppSelector(selectIsVeKwentaTokenApproved)
const VeKwentaDisableRedeem = useAppSelector(selectDisableRedeemEscrowKwenta)

const isApproved = useMemo(
() => (isVKwenta ? isVKwentaApproved : isVeKwentaApproved),
[isVKwenta, isVKwentaApproved, isVeKwentaApproved]
)

const balance = useMemo(
() => (isVKwenta ? vKwentaBalance : veKwentaBalance),
[isVKwenta, vKwentaBalance, veKwentaBalance]
)

const DisableRedeem = useMemo(
() => (isVKwenta ? false : VeKwentaDisableRedeem),
[isVKwenta, VeKwentaDisableRedeem]
)

const buttonLabel = useMemo(() => {
return isApproved
? t('dashboard.stake.tabs.stake-table.redeem')
: t('dashboard.stake.tabs.stake-table.approve')
}, [isApproved, t])

const submitRedeem = useCallback(() => {
const token = isVKwenta ? 'vKwenta' : 'veKwenta'

if (!isApproved) {
dispatch(approveKwentaToken(token))
} else {
dispatch(redeemToken(token))
}
}, [dispatch, isApproved, isVKwenta])

return (
<>
<StakingInputCardContainer>
<div>
<StakeInputHeader>
<div>{inputLabel}</div>
<StyledFlexDivRowCentered>
<div>{t('dashboard.stake.tabs.stake-table.balance')}</div>
<div className="max">{truncateNumbers(balance, 4)}</div>
</StyledFlexDivRowCentered>
</StakeInputHeader>
</div>
{DisableRedeem ? (
<ErrorView
messageType="warn"
message={t('dashboard.stake.tabs.redeem.warning')}
containerStyle={{
margin: '0',
marginTop: '25px',
padding: '10px 0',
}}
/>
) : (
<Button
fullWidth
variant="flat"
size="small"
disabled={balance.eq(0) || DisableRedeem}
onClick={submitRedeem}
>
{buttonLabel}
</Button>
)}
</StakingInputCardContainer>
</>
)
}

const StyledFlexDivRowCentered = styled(FlexDivRowCentered)`
column-gap: 5px;
`

const StakingInputCardContainer = styled(StakingCard)`
min-height: 125px;
max-height: 250px;
display: flex;
flex-direction: column;
justify-content: space-between;
`

const StakeInputHeader = styled.div`
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
color: ${(props) => props.theme.colors.selectedTheme.title};
font-size: 14px;
.max {
color: ${(props) => props.theme.colors.selectedTheme.button.text.primary};
${numericValueCSS};
}
`

export default RedeemInputCard
22 changes: 17 additions & 5 deletions packages/app/src/sections/futures/Trade/ShowPercentage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,15 @@ const ShowPercentage: React.FC<ShowPercentageProps> = ({
leverageWei,
sizeWei,
}) => {
const isLoss = useMemo(() => {
if (!targetPrice || !price || !leverageSide) return false

const targetPriceWei = wei(targetPrice)
const positiveDiff = targetPriceWei.gt(price)

return leverageSide === 'short' ? positiveDiff : !positiveDiff
}, [price, targetPrice, leverageSide])

const [calculatePercentage, calculatePL] = useMemo(() => {
if (!targetPrice || !price || !leverageSide || !sizeWei) return ''
const priceWei = wei(targetPrice)
Expand All @@ -39,21 +48,24 @@ const ShowPercentage: React.FC<ShowPercentageProps> = ({
const percentage = diff.div(price).mul(leverageWei)
const profitLoss = sizeWei.mul(percentage.div(leverageWei)).mul(isStopLoss ? -1 : 1)

return [formatPercent(percentage), formatDollars(profitLoss, { sign: isStopLoss ? '' : '+' })]
return [
formatPercent(percentage),
formatDollars(profitLoss, { sign: profitLoss.lt(0) ? '' : '+' }),
]
}, [price, isStopLoss, leverageSide, leverageWei, targetPrice, sizeWei])

return (
<Body size="large" mono>
<ProfitLoss isStopLoss={isStopLoss}>{calculatePL}</ProfitLoss>
<ProfitLoss isLoss={isLoss}>{calculatePL}</ProfitLoss>
{calculatePercentage}
</Body>
)
}

const ProfitLoss = styled.span<{ isStopLoss: boolean }>`
const ProfitLoss = styled.span<{ isLoss: boolean }>`
margin-right: 0.7rem;
color: ${({ theme, isStopLoss }) =>
isStopLoss
color: ${({ theme, isLoss }) =>
isLoss
? theme.colors.selectedTheme.newTheme.text.negative
: theme.colors.selectedTheme.newTheme.text.positive};
`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,6 @@ export const getMenuLinks = (isMobile: boolean): MenuLinks => [
i18nLabel: 'header.nav.referrals',
link: ROUTES.Referrals.Home,
},
{
i18nLabel: 'header.nav.options.title',
link: EXTERNAL_LINKS.Options.Trade,
},
]

export const DESKTOP_NAV_LINKS = getMenuLinks(false).filter((m) => !m.hidden)
Expand Down
3 changes: 1 addition & 2 deletions packages/app/src/state/futures/smartMargin/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -583,8 +583,7 @@ export const editClosePositionPrice =
(marketKey: FuturesMarketKey, price: string): AppThunk =>
(dispatch, getState) => {
const { nativeSizeDelta, orderType } = selectCloseSMPositionOrderInputs(getState())
const marketPrice = selectMarketIndexPrice(getState())
const { position } = selectEditPositionModalInfo(getState())
const { position, marketPrice } = selectEditPositionModalInfo(getState())
const closeTradeSide =
position?.activePosition.side === PositionSide.SHORT ? PositionSide.LONG : PositionSide.SHORT
const invalidLabel = orderPriceInvalidLabel(
Expand Down
8 changes: 8 additions & 0 deletions packages/app/src/state/staking/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,12 @@ export const fetchStakingData = createAsyncThunk<StakingAction, void, ThunkConfi
kwentaBalance,
weekCounter,
totalStakedBalance,
vKwentaBalance,
vKwentaAllowance,
kwentaAllowance,
epochPeriod,
veKwentaBalance,
veKwentaAllowance,
} = await sdk.kwentaToken.getStakingData()

return {
Expand All @@ -69,8 +73,12 @@ export const fetchStakingData = createAsyncThunk<StakingAction, void, ThunkConfi
kwentaBalance: kwentaBalance.toString(),
weekCounter,
totalStakedBalance: totalStakedBalance.toString(),
vKwentaBalance: vKwentaBalance.toString(),
vKwentaAllowance: vKwentaAllowance.toString(),
kwentaAllowance: kwentaAllowance.toString(),
epochPeriod,
veKwentaBalance: veKwentaBalance.toString(),
veKwentaAllowance: veKwentaAllowance.toString(),
}
} catch (err) {
logError(err)
Expand Down
Loading

1 comment on commit 91efcb4

@vercel
Copy link

@vercel vercel bot commented on 91efcb4 Oct 16, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

kwenta – ./packages/app

www.kwenta.io
kwenta-git-main-kwenta.vercel.app
kwenta.io
kwenta-kwenta.vercel.app

Please sign in to comment.