From 9d94828aace704fdbcefcf4baaf2ea4651a66a5f Mon Sep 17 00:00:00 2001 From: saml33 Date: Fri, 13 Jan 2023 11:16:10 +1100 Subject: [PATCH 01/17] paginate trade history --- components/account/ActivityFeedTable.tsx | 13 +- components/trade/TradeHistory.tsx | 254 ++++++++++++++--------- store/mangoStore.ts | 48 ++--- utils/constants.ts | 2 + 4 files changed, 185 insertions(+), 132 deletions(-) diff --git a/components/account/ActivityFeedTable.tsx b/components/account/ActivityFeedTable.tsx index 34d3a5b7..4b07283d 100644 --- a/components/account/ActivityFeedTable.tsx +++ b/components/account/ActivityFeedTable.tsx @@ -17,7 +17,7 @@ import { useViewport } from 'hooks/useViewport' import { useTranslation } from 'next-i18next' import Image from 'next/legacy/image' import { Fragment, useCallback, useState } from 'react' -import { PREFERRED_EXPLORER_KEY } from 'utils/constants' +import { PAGINATION_PAGE_LENGTH, PREFERRED_EXPLORER_KEY } from 'utils/constants' import { formatDecimal, formatFixedDecimals } from 'utils/numbers' import { breakpoints } from 'utils/theme' @@ -55,8 +55,12 @@ const ActivityFeedTable = ({ s.activityFeed.loading = true }) if (!mangoAccountAddress) return - setOffset(offset + 25) - actions.fetchActivityFeed(mangoAccountAddress, offset + 25, params) + setOffset(offset + PAGINATION_PAGE_LENGTH) + actions.fetchActivityFeed( + mangoAccountAddress, + offset + PAGINATION_PAGE_LENGTH, + params + ) }, [actions, offset, params, mangoAccountAddress]) const getCreditAndDebit = (activity: any) => { @@ -316,7 +320,8 @@ const ActivityFeedTable = ({ ))} ) : null} - {activityFeed.length && activityFeed.length % 25 === 0 ? ( + {activityFeed.length && + activityFeed.length % PAGINATION_PAGE_LENGTH === 0 ? (
Show More
diff --git a/components/trade/TradeHistory.tsx b/components/trade/TradeHistory.tsx index 8262dd7c..9f01a0c6 100644 --- a/components/trade/TradeHistory.tsx +++ b/components/trade/TradeHistory.tsx @@ -1,4 +1,6 @@ import { I80F48, PerpMarket } from '@blockworks-foundation/mango-v4' +import { LinkButton } from '@components/shared/Button' +import SheenLoader from '@components/shared/SheenLoader' import SideBadge from '@components/shared/SideBadge' import { Table, @@ -14,7 +16,9 @@ import mangoStore from '@store/mangoStore' import useMangoAccount from 'hooks/useMangoAccount' import useSelectedMarket from 'hooks/useSelectedMarket' import { useViewport } from 'hooks/useViewport' -import { useMemo } from 'react' +import { useTranslation } from 'next-i18next' +import { useCallback, useMemo, useState } from 'react' +import { PAGINATION_PAGE_LENGTH } from 'utils/constants' import { formatDecimal, formatFixedDecimals } from 'utils/numbers' import { breakpoints } from 'utils/theme' import TableMarketName from './TableMarketName' @@ -86,11 +90,17 @@ const formatTradeHistory = ( } const TradeHistory = () => { + const { t } = useTranslation(['common', 'trade']) const group = mangoStore.getState().group const { selectedMarket } = useSelectedMarket() const { mangoAccount, mangoAccountAddress } = useMangoAccount() + const actions = mangoStore((s) => s.actions) const fills = mangoStore((s) => s.selectedMarket.fills) - const tradeHistory = mangoStore((s) => s.mangoAccount.tradeHistory) + const tradeHistory = mangoStore((s) => s.mangoAccount.tradeHistory.data) + const loadingTradeHistory = mangoStore( + (s) => s.mangoAccount.tradeHistory.loading + ) + const [offset, setOffset] = useState(0) const { width } = useViewport() const showTableView = width ? width > breakpoints.md : false @@ -151,81 +161,129 @@ const TradeHistory = () => { return [...newFills, ...tradeHistory] }, [eventQueueFillsForAccount, tradeHistory]) - console.log('trade history', tradeHistory) + const handleShowMore = useCallback(() => { + const set = mangoStore.getState().set + set((s) => { + s.mangoAccount.tradeHistory.loading = true + }) + setOffset(offset + PAGINATION_PAGE_LENGTH) + actions.fetchTradeHistory(offset + PAGINATION_PAGE_LENGTH) + }, [actions, offset]) if (!selectedMarket || !group) return null - return mangoAccount && combinedTradeHistory.length ? ( - showTableView ? ( -
- - - - - - - - - - - - - - {combinedTradeHistory.map((trade: any) => { - let market - if ('market' in trade) { - market = group.getSerum3MarketByExternalMarket( - new PublicKey(trade.market) - ) - } else if ('perp_market' in trade) { - market = group.getPerpMarketByName(trade.perp_market) - } else { - market = selectedMarket - } - let makerTaker = trade.liquidity - if ('maker' in trade) { - makerTaker = trade.maker ? 'Maker' : 'Taker' - if (trade.taker === mangoAccount.publicKey.toString()) { - makerTaker = 'Taker' + return mangoAccount && + (combinedTradeHistory.length || loadingTradeHistory) ? ( + <> + {showTableView ? ( +
+
MarketSideSizePriceValueFeeTime
+ + + + + + + + + + + + + {combinedTradeHistory.map((trade: any, index: number) => { + let market + if ('market' in trade) { + market = group.getSerum3MarketByExternalMarket( + new PublicKey(trade.market) + ) + } else if ('perp_market' in trade) { + market = group.getPerpMarketByName(trade.perp_market) + } else { + market = selectedMarket + } + let makerTaker = trade.liquidity + if ('maker' in trade) { + makerTaker = trade.maker ? 'Maker' : 'Taker' + if (trade.taker === mangoAccount.publicKey.toString()) { + makerTaker = 'Taker' + } + } + const size = trade.size || trade.quantity + let fee + if (trade.fee_cost || trade.feeCost) { + fee = trade.fee_cost || trade.feeCost + } else { + fee = + trade.maker === mangoAccount.publicKey.toString() + ? trade.maker_fee + : trade.taker_fee } - } - const size = trade.size || trade.quantity - let fee - if (trade.fee_cost || trade.feeCost) { - fee = trade.fee_cost || trade.feeCost - } else { - fee = - trade.maker === mangoAccount.publicKey.toString() - ? trade.maker_fee - : trade.taker_fee - } - return ( - - - + + + + + + + + + ) + })} + +
{t('market')}{t('trade:side')}{t('trade:size')}{t('price')}{t('value')}{t('fee')}{t('date')}
- - + return ( + + + + + + {size} + {formatDecimal(trade.price)} + + {formatFixedDecimals(trade.price * size, true, true)} + + {formatDecimal(fee)} +

+ {makerTaker} +

+
+ {trade.block_datetime ? ( + + ) : ( + 'Recent' + )} +
+
+ ) : ( +
+ {combinedTradeHistory.map((trade: any, index: number) => { + const size = trade.size || trade.quantity + return ( +
+
+ +
- - {size} - - {formatDecimal(trade.price)} - - - {formatFixedDecimals(trade.price * size)} - - - {formatDecimal(fee)} -

- {makerTaker} +

+ {size} + {' for '} + + {formatDecimal(trade.price)} +

- - - +
+
+
+ {trade.block_datetime ? ( { ) : ( 'Recent' )} - - - ) - })} - - -
- ) : ( -
- {eventQueueFillsForAccount.map((trade: any) => { - return ( -
-
- -
- -

- - {trade.size} - - {' for '} - - {formatDecimal(trade.price)} - + +

+ {formatFixedDecimals(trade.price * size, true, true)}

-

${trade.value.toFixed(2)}

-
- ) - })} -
- ) + ) + })} +
+ )} + {loadingTradeHistory ? ( +
+ {[...Array(4)].map((x, i) => ( + +
+ + ))} +
+ ) : null} + {combinedTradeHistory.length && + combinedTradeHistory.length % PAGINATION_PAGE_LENGTH === 0 ? ( +
+ Show More +
+ ) : null} + ) : (
diff --git a/store/mangoStore.ts b/store/mangoStore.ts index e9e2f0bb..9bd61c9c 100644 --- a/store/mangoStore.ts +++ b/store/mangoStore.ts @@ -34,6 +34,7 @@ import { INPUT_TOKEN_DEFAULT, LAST_ACCOUNT_KEY, OUTPUT_TOKEN_DEFAULT, + PAGINATION_PAGE_LENGTH, RPC_PROVIDER_KEY, } from '../utils/constants' import { OrderbookL2, SpotBalances, SpotTradeHistory } from 'types' @@ -246,7 +247,7 @@ export type MangoStore = { initialLoad: boolean } } - tradeHistory: SpotTradeHistory[] + tradeHistory: { data: SpotTradeHistory[]; loading: boolean } } mangoAccounts: MangoAccount[] markets: Serum3Market[] | undefined @@ -330,7 +331,7 @@ export type MangoStore = { ) => Promise fetchTokenStats: () => void fetchTourSettings: (walletPk: string) => void - fetchTradeHistory: () => Promise + fetchTradeHistory: (offset?: number) => Promise fetchWalletTokens: (wallet: Wallet) => Promise connectMangoClientWithWallet: (wallet: WalletAdapter) => Promise loadMarketFills: () => Promise @@ -383,7 +384,7 @@ const mangoStore = create()( performance: { data: [], loading: false }, swapHistory: { data: [], initialLoad: false }, }, - tradeHistory: [], + tradeHistory: { data: [], loading: true }, }, mangoAccounts: [], markets: undefined, @@ -539,7 +540,7 @@ const mangoStore = create()( try { const response = await fetch( - `https://mango-transaction-log.herokuapp.com/v4/stats/activity-feed?mango-account=${mangoAccountPk}&offset=${offset}&limit=25${ + `https://mango-transaction-log.herokuapp.com/v4/stats/activity-feed?mango-account=${mangoAccountPk}&offset=${offset}&limit=${PAGINATION_PAGE_LENGTH}${ params ? params : '' }` ) @@ -1007,36 +1008,33 @@ const mangoStore = create()( console.log('Error fetching fills:', err) } }, - async fetchTradeHistory() { + async fetchTradeHistory(offset = 0) { const set = get().set - const mangoAccount = get().mangoAccount.current + const mangoAccountPk = + get().mangoAccount?.current?.publicKey.toString() + const loadedHistory = + mangoStore.getState().mangoAccount.tradeHistory.data try { - const [spotRes, perpRes] = await Promise.all([ - fetch( - `https://mango-transaction-log.herokuapp.com/v4/stats/openbook-trades?address=${mangoAccount?.publicKey.toString()}&address-type=mango-account` - ), - fetch( - `https://mango-transaction-log.herokuapp.com/v4/stats/perp-trade-history?mango-account=${mangoAccount?.publicKey.toString()}&limit=1000` - ), - ]) - const spotHistory = await spotRes.json() - const perpHistory = await perpRes.json() - console.log('th', spotHistory, perpHistory) - let tradeHistory: any[] = [] - if (spotHistory?.length) { - tradeHistory = tradeHistory.concat(spotHistory) - } - if (perpHistory?.length) { - tradeHistory = tradeHistory.concat(perpHistory) - } + const response = await fetch( + `https://mango-transaction-log.herokuapp.com/v4/stats/trade-history?mango-account=${mangoAccountPk}&limit=${PAGINATION_PAGE_LENGTH}&offset=${offset}` + ) + const parsedHistory = await response.json() + const newHistory = parsedHistory.map((h: any) => h.activity_details) + + const history = + offset !== 0 ? loadedHistory.concat(newHistory) : newHistory set((s) => { - s.mangoAccount.tradeHistory = tradeHistory.sort( + s.mangoAccount.tradeHistory.data = history?.sort( (x: any) => x.block_datetime ) }) } catch (e) { console.error('Unable to fetch trade history', e) + } finally { + set((s) => { + s.mangoAccount.tradeHistory.loading = false + }) } }, updateConnection(endpointUrl) { diff --git a/utils/constants.ts b/utils/constants.ts index 36bf95da..53af4d46 100644 --- a/utils/constants.ts +++ b/utils/constants.ts @@ -65,3 +65,5 @@ export const MIN_SOL_BALANCE = 0.001 export const ACCOUNT_ACTION_MODAL_HEIGHT = '506px' export const ACCOUNT_ACTION_MODAL_INNER_HEIGHT = '444px' + +export const PAGINATION_PAGE_LENGTH = 25 From 297f653e0fcf3e254678ec622f2ab5f5d4897413 Mon Sep 17 00:00:00 2001 From: saml33 Date: Fri, 13 Jan 2023 12:34:21 +1100 Subject: [PATCH 02/17] add trade history to account tabs --- components/account/AccountTabs.tsx | 16 ++++++++++------ components/trade/TradeHistory.tsx | 2 +- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/components/account/AccountTabs.tsx b/components/account/AccountTabs.tsx index 595bc979..345f161d 100644 --- a/components/account/AccountTabs.tsx +++ b/components/account/AccountTabs.tsx @@ -8,6 +8,7 @@ import { useUnsettledSpotBalances } from 'hooks/useUnsettledSpotBalances' import { useViewport } from 'hooks/useViewport' import { breakpoints } from 'utils/theme' import useUnsettledPerpPositions from 'hooks/useUnsettledPerpPositions' +import TradeHistory from '@components/trade/TradeHistory' const AccountTabs = () => { const [activeTab, setActiveTab] = useState('balances') @@ -23,15 +24,16 @@ const AccountTabs = () => { return [ ['balances', 0], + ['trade:unsettled', unsettledTradeCount], ['activity:activity', 0], ['swap:swap-history', 0], - ['trade:unsettled', unsettledTradeCount], + ['trade-history', 0], ] }, [unsettledPerpPositions, unsettledSpotBalances]) return ( <> -
+
setActiveTab(v)} @@ -51,10 +53,6 @@ const TabContent = ({ activeTab }: { activeTab: string }) => { switch (activeTab) { case 'balances': return - case 'activity:activity': - return - case 'swap:swap-history': - return case 'trade:unsettled': return ( { unsettledPerpPositions={unsettledPerpPositions} /> ) + case 'activity:activity': + return + case 'swap:swap-history': + return + case 'trade-history': + return default: return } diff --git a/components/trade/TradeHistory.tsx b/components/trade/TradeHistory.tsx index 9f01a0c6..9d6065e2 100644 --- a/components/trade/TradeHistory.tsx +++ b/components/trade/TradeHistory.tsx @@ -319,7 +319,7 @@ const TradeHistory = () => { ) : null} ) : ( -
+

No trade history

From cb96bb1823a25d7c68b1c09d94cdef01cedf67b6 Mon Sep 17 00:00:00 2001 From: saml33 Date: Fri, 13 Jan 2023 12:43:20 +1100 Subject: [PATCH 03/17] allow tables to scroll horizontally --- components/shared/TableElements.tsx | 6 +- components/trade/TradeHistory.tsx | 164 ++++++++++++++-------------- 2 files changed, 86 insertions(+), 84 deletions(-) diff --git a/components/shared/TableElements.tsx b/components/shared/TableElements.tsx index f4856774..b10b91d7 100644 --- a/components/shared/TableElements.tsx +++ b/components/shared/TableElements.tsx @@ -7,7 +7,11 @@ export const Table = ({ }: { children: ReactNode className?: string -}) => {children}
+}) => ( +
+ {children}
+
+) export const TrHead = ({ children, diff --git a/components/trade/TradeHistory.tsx b/components/trade/TradeHistory.tsx index 9d6065e2..2e69833f 100644 --- a/components/trade/TradeHistory.tsx +++ b/components/trade/TradeHistory.tsx @@ -176,90 +176,88 @@ const TradeHistory = () => { (combinedTradeHistory.length || loadingTradeHistory) ? ( <> {showTableView ? ( -
- - - - - - - - - - - - - - {combinedTradeHistory.map((trade: any, index: number) => { - let market - if ('market' in trade) { - market = group.getSerum3MarketByExternalMarket( - new PublicKey(trade.market) - ) - } else if ('perp_market' in trade) { - market = group.getPerpMarketByName(trade.perp_market) - } else { - market = selectedMarket - } - let makerTaker = trade.liquidity - if ('maker' in trade) { - makerTaker = trade.maker ? 'Maker' : 'Taker' - if (trade.taker === mangoAccount.publicKey.toString()) { - makerTaker = 'Taker' - } - } - const size = trade.size || trade.quantity - let fee - if (trade.fee_cost || trade.feeCost) { - fee = trade.fee_cost || trade.feeCost - } else { - fee = - trade.maker === mangoAccount.publicKey.toString() - ? trade.maker_fee - : trade.taker_fee - } - - return ( - - - - - - - - - - +
{t('market')}{t('trade:side')}{t('trade:size')}{t('price')}{t('value')}{t('fee')}{t('date')}
- - - - {size} - {formatDecimal(trade.price)} - - {formatFixedDecimals(trade.price * size, true, true)} - - {formatDecimal(fee)} -

- {makerTaker} -

-
- {trade.block_datetime ? ( - - ) : ( - 'Recent' - )} -
+ + + + + + + + + + + + + {combinedTradeHistory.map((trade: any, index: number) => { + let market + if ('market' in trade) { + market = group.getSerum3MarketByExternalMarket( + new PublicKey(trade.market) ) - })} - -
{t('market')}{t('trade:side')}{t('trade:size')}{t('price')}{t('value')}{t('fee')}{t('date')}
-
+ } else if ('perp_market' in trade) { + market = group.getPerpMarketByName(trade.perp_market) + } else { + market = selectedMarket + } + let makerTaker = trade.liquidity + if ('maker' in trade) { + makerTaker = trade.maker ? 'Maker' : 'Taker' + if (trade.taker === mangoAccount.publicKey.toString()) { + makerTaker = 'Taker' + } + } + const size = trade.size || trade.quantity + let fee + if (trade.fee_cost || trade.feeCost) { + fee = trade.fee_cost || trade.feeCost + } else { + fee = + trade.maker === mangoAccount.publicKey.toString() + ? trade.maker_fee + : trade.taker_fee + } + + return ( + + + + + + + + {size} + + {formatDecimal(trade.price)} + + + {formatFixedDecimals(trade.price * size, true, true)} + + + {formatDecimal(fee)} +

+ {makerTaker} +

+ + + + {trade.block_datetime ? ( + + ) : ( + 'Recent' + )} + +
+ ) + })} + + ) : (
{combinedTradeHistory.map((trade: any, index: number) => { From 2c12f5c5ea71f777a72dcd5570a49035892b8277 Mon Sep 17 00:00:00 2001 From: saml33 Date: Mon, 16 Jan 2023 16:13:34 +1100 Subject: [PATCH 04/17] add daily pnl history --- components/TokenList.tsx | 4 +- components/account/AccountChart.tsx | 27 ++++++- components/account/AccountPage.tsx | 99 +++++++++++++++--------- components/modals/PnlHistoryModal.tsx | 93 ++++++++++++++++++++++ components/shared/DirectionTriangles.tsx | 4 +- components/swap/SwapHistoryTable.tsx | 6 +- components/wallet/ConnectedMenu.tsx | 8 +- store/mangoStore.ts | 59 +++++++------- 8 files changed, 220 insertions(+), 80 deletions(-) create mode 100644 components/modals/PnlHistoryModal.tsx diff --git a/components/TokenList.tsx b/components/TokenList.tsx index 257baadc..cbf36ef3 100644 --- a/components/TokenList.tsx +++ b/components/TokenList.tsx @@ -46,7 +46,7 @@ const TokenList = () => { const { group } = useMangoGroup() const { mangoTokens } = useJupiterMints() const totalInterestData = mangoStore( - (s) => s.mangoAccount.stats.interestTotals.data + (s) => s.mangoAccount.interestTotals.data ) const { width } = useViewport() const showTableView = width ? width > breakpoints.md : false @@ -304,7 +304,7 @@ const MobileTokenListItem = ({ bank }: { bank: Bank }) => { const spotBalances = mangoStore((s) => s.mangoAccount.spotBalances) const { mangoAccount } = useMangoAccount() const totalInterestData = mangoStore( - (s) => s.mangoAccount.stats.interestTotals.data + (s) => s.mangoAccount.interestTotals.data ) const symbol = bank.name const oraclePrice = bank.uiPrice diff --git a/components/account/AccountChart.tsx b/components/account/AccountChart.tsx index e2aee2e3..1e370efc 100644 --- a/components/account/AccountChart.tsx +++ b/components/account/AccountChart.tsx @@ -1,6 +1,6 @@ import { toUiDecimalsForQuote } from '@blockworks-foundation/mango-v4' import { useTranslation } from 'next-i18next' -import { useMemo, useState } from 'react' +import { useEffect, useMemo, useState } from 'react' import mangoStore from '@store/mangoStore' import dynamic from 'next/dynamic' import { numberCompacter } from 'utils/numbers' @@ -11,19 +11,38 @@ const DetailedAreaChart = dynamic( const AccountChart = ({ chartToShow, - data, hideChart, + mangoAccountAddress, yKey, }: { chartToShow: string - data: Array hideChart: () => void + mangoAccountAddress: string yKey: string }) => { const { t } = useTranslation('common') const actions = mangoStore.getState().actions const [daysToShow, setDaysToShow] = useState('1') - const loading = mangoStore((s) => s.mangoAccount.stats.performance.loading) + const loading = mangoStore((s) => s.mangoAccount.performance.loading) + const performanceData = mangoStore((s) => s.mangoAccount.performance.data) + + useEffect(() => { + if (mangoAccountAddress) { + actions.fetchAccountPerformance(mangoAccountAddress, 1) + } + }, [actions, mangoAccountAddress]) + + const data: any = useMemo(() => { + if (!performanceData.length) return [] + if (chartToShow === 'cumulative-interest-value') { + performanceData.map((d) => ({ + interest_value: + d.borrow_interest_cumulative_usd + d.deposit_interest_cumulative_usd, + time: d.time, + })) + } + return performanceData + }, [performanceData]) const handleDaysToShow = async (days: string) => { const mangoAccount = mangoStore.getState().mangoAccount.current diff --git a/components/account/AccountPage.tsx b/components/account/AccountPage.tsx index 5962c765..c8041d5d 100644 --- a/components/account/AccountPage.tsx +++ b/components/account/AccountPage.tsx @@ -19,7 +19,9 @@ import { useTheme } from 'next-themes' import { IconButton } from '../shared/Button' import { ArrowsPointingOutIcon, + ChartBarIcon, ChevronRightIcon, + ClockIcon, } from '@heroicons/react/20/solid' import { Transition } from '@headlessui/react' import AccountTabs from './AccountTabs' @@ -40,6 +42,7 @@ import { INITIAL_ANIMATION_SETTINGS } from '@components/settings/AnimationSettin import { useViewport } from 'hooks/useViewport' import { breakpoints } from 'utils/theme' import useMangoGroup from 'hooks/useMangoGroup' +import PnlHistoryModal from '@components/modals/PnlHistoryModal' export async function getStaticProps({ locale }: { locale: string }) { return { @@ -60,13 +63,14 @@ const AccountPage = () => { const { mangoAccount, mangoAccountAddress } = useMangoAccount() const actions = mangoStore.getState().actions const loadPerformanceData = mangoStore( - (s) => s.mangoAccount.stats.performance.loading + (s) => s.mangoAccount.performance.loading ) - const performanceData = mangoStore( - (s) => s.mangoAccount.stats.performance.data + const performanceInitialLoad = mangoStore( + (s) => s.mangoAccount.performance.initialLoad ) + const performanceData = mangoStore((s) => s.mangoAccount.performance.data) const totalInterestData = mangoStore( - (s) => s.mangoAccount.stats.interestTotals.data + (s) => s.mangoAccount.interestTotals.data ) const [chartToShow, setChartToShow] = useState< 'account-value' | 'cumulative-interest-value' | 'pnl' | '' @@ -75,6 +79,7 @@ const AccountPage = () => { PerformanceDataItem[] >([]) const [showExpandChart, setShowExpandChart] = useState(false) + const [showPnlHistory, setShowPnlHistory] = useState(false) const { theme } = useTheme() const { width } = useViewport() const isMobile = width ? width < breakpoints.md : false @@ -93,10 +98,10 @@ const AccountPage = () => { }, [actions, mangoAccountAddress]) useEffect(() => { - if (mangoAccount && performanceData.length && !chartToShow) { + if (performanceInitialLoad) { setOneDayPerformanceData(performanceData) } - }, [mangoAccount, performanceData, chartToShow]) + }, [performanceInitialLoad]) const onHoverMenu = (open: boolean, action: string) => { if ( @@ -115,7 +120,7 @@ const AccountPage = () => { const handleHideChart = () => { const set = mangoStore.getState().set set((s) => { - s.mangoAccount.stats.performance.data = oneDayPerformanceData + s.mangoAccount.performance.data = oneDayPerformanceData }) setChartToShow('') } @@ -151,7 +156,9 @@ const AccountPage = () => { const oneDayPnlChange = useMemo(() => { if (accountPnl && oneDayPerformanceData.length) { const startDayPnl = oneDayPerformanceData[0].pnl - return accountPnl - startDayPnl + const endDayPnl = + oneDayPerformanceData[oneDayPerformanceData.length - 1].pnl + return endDayPnl - startDayPnl } return 0.0 }, [accountPnl, oneDayPerformanceData]) @@ -431,24 +438,43 @@ const AccountPage = () => {

- +
- {!loadPerformanceData ? ( - mangoAccount && performanceData.length ? ( + {performanceInitialLoad ? ( + oneDayPerformanceData.length ? (
@@ -290,7 +299,7 @@ const AccountPage = () => { ? COLORS.UP[theme] : COLORS.DOWN[theme] } - data={performanceData.concat(latestAccountData)} + data={oneDayPerformanceData.concat(latestAccountData)} name="accountValue" xKey="time" yKey="account_equity" @@ -316,11 +325,11 @@ const AccountPage = () => {
) : null - ) : ( + ) : mangoAccountAddress ? (
- )} + ) : null}
@@ -442,7 +451,7 @@ const AccountPage = () => {
@@ -453,7 +462,7 @@ const AccountPage = () => { {mangoAccountAddress ? (
{performanceData.length > 4 ? ( - + { ) : null} - + {
- +
{/* {!tourSettings?.account_tour_seen && isOnBoarded && connected ? ( @@ -524,7 +538,7 @@ const AccountPage = () => { setShowPnlHistory(false)} + onClose={handleCloseDailyPnlModal} /> ) : null} diff --git a/components/modals/PnlHistoryModal.tsx b/components/modals/PnlHistoryModal.tsx index 3016052e..b5cae654 100644 --- a/components/modals/PnlHistoryModal.tsx +++ b/components/modals/PnlHistoryModal.tsx @@ -3,10 +3,11 @@ import Modal from '../shared/Modal' import mangoStore, { PerformanceDataItem } from '@store/mangoStore' // import { useTranslation } from 'next-i18next' import { useEffect, useMemo } from 'react' -import BounceLoader from '../shared/BounceLoader' import useMangoAccount from 'hooks/useMangoAccount' import dayjs from 'dayjs' import Change from '@components/shared/Change' +import SheenLoader from '@components/shared/SheenLoader' +import { NoSymbolIcon } from '@heroicons/react/20/solid' interface PnlHistoryModalProps { pnlChangeToday: number @@ -61,30 +62,37 @@ const PnlHistoryModal = ({ return (
- {loading ? ( - - ) : ( -
-

Daily PnL

- {dailyValues?.length ? ( -
-
- {dailyValues.map((v: any) => ( -
-

{dayjs(v.time).format('YYYY-MM-DD')}

- -
- ))} -
+
+

Daily PnL

+ {loading ? ( +
+ {[...Array(4)].map((x, i) => ( + +
+ + ))} +
+ ) : dailyValues?.length ? ( +
+
+ {dailyValues.map((v: any) => ( +
+

{dayjs(v.time).format('YYYY-MM-DD')}

+ +
+ ))}
- ) : ( -

No daily history

- )} -
- )} +
+ ) : ( +
+ +

No PnL History

+
+ )} +
) From 9716c5f7755acf9c8a956b9515c5d3b1cfa77927 Mon Sep 17 00:00:00 2001 From: saml33 Date: Tue, 17 Jan 2023 12:26:31 +1100 Subject: [PATCH 06/17] add pnl for current week --- components/account/AccountPage.tsx | 2 +- components/modals/PnlHistoryModal.tsx | 73 ++++++++++++++++++++------- 2 files changed, 55 insertions(+), 20 deletions(-) diff --git a/components/account/AccountPage.tsx b/components/account/AccountPage.tsx index d92b75d8..8a9a7752 100644 --- a/components/account/AccountPage.tsx +++ b/components/account/AccountPage.tsx @@ -472,7 +472,7 @@ const AccountPage = () => { ) : null} - + { + const dailyValues: PnlChange[] = useMemo(() => { if (!performanceData.length) return [] const dailyPnl = performanceData.filter((d: PerformanceDataItem) => { @@ -48,22 +53,43 @@ const PnlHistoryModal = ({ time: d.time, pnlChange: dailyPnl[index + 1].pnl - d.pnl, } + } else { + return { + time: performanceData[performanceData.length - 1].time, + pnlChange: pnlChangeToday, + } } }) - .slice(0, -1) - .concat({ - time: performanceData[performanceData.length - 1].time, - pnlChange: pnlChangeToday, - }) .reverse() : [] }, [performanceData]) + const pnlThisWeek = useMemo(() => { + if (dailyValues.length) { + const saturdayIndex = dailyValues.findIndex((d) => { + const day = new Date(d.time).getDay() + return day === 6 + }) + if (saturdayIndex !== -1) { + return dailyValues + .slice(0, saturdayIndex) + .reduce((a, c) => a + c.pnlChange, 0) + } else { + return dailyValues.reduce((a, c) => a + c.pnlChange, 0) + } + } + return 0 + }, [dailyValues]) + + const getLastSunday = (d: Date) => { + return d.setDate(d.getDate() - d.getDay()) + } + return (
-

Daily PnL

+

PnL History

{loading ? (
{[...Array(4)].map((x, i) => ( @@ -73,19 +99,28 @@ const PnlHistoryModal = ({ ))}
) : dailyValues?.length ? ( -
-
- {dailyValues.map((v: any) => ( -
-

{dayjs(v.time).format('YYYY-MM-DD')}

- -
- ))} + <> +
+
+ {dailyValues.map((v: any) => ( +
+

{dayjs(v.time).format('YYYY-MM-DD')}

+ +
+ ))} +
-
+ +
+

{`Week starting ${dayjs(getLastSunday(new Date())).format( + 'MM-DD' + )}`}

+ +
+ ) : (
From 46d9c54ef3dec3492719b72bf9440f5c1df4e862 Mon Sep 17 00:00:00 2001 From: saml33 Date: Tue, 17 Jan 2023 15:59:51 +1100 Subject: [PATCH 07/17] add translation vars --- components/account/AccountPage.tsx | 31 ++++++++------------------- components/modals/PnlHistoryModal.tsx | 16 ++++++++------ pages/index.tsx | 1 + public/locales/en/account.json | 11 ++++++++++ public/locales/en/common.json | 1 + public/locales/es/account.json | 11 ++++++++++ public/locales/es/common.json | 1 + public/locales/ru/account.json | 11 ++++++++++ public/locales/ru/common.json | 1 + public/locales/zh/account.json | 11 ++++++++++ public/locales/zh/common.json | 1 + public/locales/zh_tw/account.json | 11 ++++++++++ public/locales/zh_tw/common.json | 1 + 13 files changed, 79 insertions(+), 29 deletions(-) create mode 100644 public/locales/en/account.json create mode 100644 public/locales/es/account.json create mode 100644 public/locales/ru/account.json create mode 100644 public/locales/zh/account.json create mode 100644 public/locales/zh_tw/account.json diff --git a/components/account/AccountPage.tsx b/components/account/AccountPage.tsx index 8a9a7752..2d749f66 100644 --- a/components/account/AccountPage.tsx +++ b/components/account/AccountPage.tsx @@ -3,7 +3,6 @@ import { toUiDecimalsForQuote, } from '@blockworks-foundation/mango-v4' import { useTranslation } from 'next-i18next' -import { serverSideTranslations } from 'next-i18next/serverSideTranslations' import { useEffect, useMemo, useState } from 'react' import AccountActions from './AccountActions' import mangoStore, { PerformanceDataItem } from '@store/mangoStore' @@ -43,20 +42,8 @@ import { breakpoints } from 'utils/theme' import useMangoGroup from 'hooks/useMangoGroup' import PnlHistoryModal from '@components/modals/PnlHistoryModal' -export async function getStaticProps({ locale }: { locale: string }) { - return { - props: { - ...(await serverSideTranslations(locale, [ - 'common', - 'close-account', - 'trade', - ])), - }, - } -} - const AccountPage = () => { - const { t } = useTranslation('common') + const { t } = useTranslation(['common', 'account']) // const { connected } = useWallet() const { group } = useMangoGroup() const { mangoAccount, mangoAccountAddress } = useMangoAccount() @@ -385,7 +372,7 @@ const AccountPage = () => {
{

- Total: + {t('total')}: {group && mangoAccount ? formatFixedDecimals( @@ -433,7 +420,7 @@ const AccountPage = () => {
{
@@ -462,7 +449,7 @@ const AccountPage = () => { {mangoAccountAddress ? (
{performanceData.length > 4 ? ( - + { ) : null} - + {
{ - // const { t } = useTranslation('common') + const { t } = useTranslation('account') const { mangoAccountAddress } = useMangoAccount() const actions = mangoStore.getState().actions const loading = mangoStore((s) => s.mangoAccount.performance.loading) @@ -89,7 +89,7 @@ const PnlHistoryModal = ({
-

PnL History

+

{t('pnl-history')}

{loading ? (
{[...Array(4)].map((x, i) => ( @@ -115,16 +115,18 @@ const PnlHistoryModal = ({
-

{`Week starting ${dayjs(getLastSunday(new Date())).format( - 'MM-DD' - )}`}

+

+ {t('week-starting', { + week: dayjs(getLastSunday(new Date())).format('MM-DD'), + })} +

) : (
-

No PnL History

+

{t('no-pnl-history')}

)}
diff --git a/pages/index.tsx b/pages/index.tsx index b216e035..ead15c41 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -6,6 +6,7 @@ export async function getStaticProps({ locale }: { locale: string }) { return { props: { ...(await serverSideTranslations(locale, [ + 'account', 'activity', 'common', 'onboarding', diff --git a/public/locales/en/account.json b/public/locales/en/account.json new file mode 100644 index 00000000..28d4646c --- /dev/null +++ b/public/locales/en/account.json @@ -0,0 +1,11 @@ +{ + "no-pnl-history": "No PnL History", + "pnl-chart": "PnL Chart", + "pnl-history": "PnL History", + "tooltip-free-collateral": "The amount of capital you have to use for trades and loans. When your free collateral reaches $0 you won't be able to trade, borrow or withdraw", + "tooltip-leverage": "Total assets value divided by account equity value", + "tooltip-pnl": "The amount your account has profited or lost", + "tooltip-total-collateral": "Total value of collateral for trading and borrowing (including unsettled PnL)", + "tooltip-total-interest": "The value of interest earned (deposits) minus interest paid (borrows)", + "week-starting": "Week starting {{week}}" +} \ No newline at end of file diff --git a/public/locales/en/common.json b/public/locales/en/common.json index 3f6b6386..ddd3cedd 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -121,6 +121,7 @@ "token-collateral-multiplier": "{{token}} Collateral Multiplier", "tooltip-borrow-rate": "The variable interest rate you'll pay on your borrowed balance", "tooltip-collateral-value": "The USD amount you can trade or borrow against", + "total": "Total", "total-borrows": "Total Borrows", "total-borrow-value": "Total Borrow Value", "total-collateral": "Total Collateral", diff --git a/public/locales/es/account.json b/public/locales/es/account.json new file mode 100644 index 00000000..28d4646c --- /dev/null +++ b/public/locales/es/account.json @@ -0,0 +1,11 @@ +{ + "no-pnl-history": "No PnL History", + "pnl-chart": "PnL Chart", + "pnl-history": "PnL History", + "tooltip-free-collateral": "The amount of capital you have to use for trades and loans. When your free collateral reaches $0 you won't be able to trade, borrow or withdraw", + "tooltip-leverage": "Total assets value divided by account equity value", + "tooltip-pnl": "The amount your account has profited or lost", + "tooltip-total-collateral": "Total value of collateral for trading and borrowing (including unsettled PnL)", + "tooltip-total-interest": "The value of interest earned (deposits) minus interest paid (borrows)", + "week-starting": "Week starting {{week}}" +} \ No newline at end of file diff --git a/public/locales/es/common.json b/public/locales/es/common.json index 3f6b6386..ddd3cedd 100644 --- a/public/locales/es/common.json +++ b/public/locales/es/common.json @@ -121,6 +121,7 @@ "token-collateral-multiplier": "{{token}} Collateral Multiplier", "tooltip-borrow-rate": "The variable interest rate you'll pay on your borrowed balance", "tooltip-collateral-value": "The USD amount you can trade or borrow against", + "total": "Total", "total-borrows": "Total Borrows", "total-borrow-value": "Total Borrow Value", "total-collateral": "Total Collateral", diff --git a/public/locales/ru/account.json b/public/locales/ru/account.json new file mode 100644 index 00000000..28d4646c --- /dev/null +++ b/public/locales/ru/account.json @@ -0,0 +1,11 @@ +{ + "no-pnl-history": "No PnL History", + "pnl-chart": "PnL Chart", + "pnl-history": "PnL History", + "tooltip-free-collateral": "The amount of capital you have to use for trades and loans. When your free collateral reaches $0 you won't be able to trade, borrow or withdraw", + "tooltip-leverage": "Total assets value divided by account equity value", + "tooltip-pnl": "The amount your account has profited or lost", + "tooltip-total-collateral": "Total value of collateral for trading and borrowing (including unsettled PnL)", + "tooltip-total-interest": "The value of interest earned (deposits) minus interest paid (borrows)", + "week-starting": "Week starting {{week}}" +} \ No newline at end of file diff --git a/public/locales/ru/common.json b/public/locales/ru/common.json index 3f6b6386..ddd3cedd 100644 --- a/public/locales/ru/common.json +++ b/public/locales/ru/common.json @@ -121,6 +121,7 @@ "token-collateral-multiplier": "{{token}} Collateral Multiplier", "tooltip-borrow-rate": "The variable interest rate you'll pay on your borrowed balance", "tooltip-collateral-value": "The USD amount you can trade or borrow against", + "total": "Total", "total-borrows": "Total Borrows", "total-borrow-value": "Total Borrow Value", "total-collateral": "Total Collateral", diff --git a/public/locales/zh/account.json b/public/locales/zh/account.json new file mode 100644 index 00000000..28d4646c --- /dev/null +++ b/public/locales/zh/account.json @@ -0,0 +1,11 @@ +{ + "no-pnl-history": "No PnL History", + "pnl-chart": "PnL Chart", + "pnl-history": "PnL History", + "tooltip-free-collateral": "The amount of capital you have to use for trades and loans. When your free collateral reaches $0 you won't be able to trade, borrow or withdraw", + "tooltip-leverage": "Total assets value divided by account equity value", + "tooltip-pnl": "The amount your account has profited or lost", + "tooltip-total-collateral": "Total value of collateral for trading and borrowing (including unsettled PnL)", + "tooltip-total-interest": "The value of interest earned (deposits) minus interest paid (borrows)", + "week-starting": "Week starting {{week}}" +} \ No newline at end of file diff --git a/public/locales/zh/common.json b/public/locales/zh/common.json index 3f6b6386..ddd3cedd 100644 --- a/public/locales/zh/common.json +++ b/public/locales/zh/common.json @@ -121,6 +121,7 @@ "token-collateral-multiplier": "{{token}} Collateral Multiplier", "tooltip-borrow-rate": "The variable interest rate you'll pay on your borrowed balance", "tooltip-collateral-value": "The USD amount you can trade or borrow against", + "total": "Total", "total-borrows": "Total Borrows", "total-borrow-value": "Total Borrow Value", "total-collateral": "Total Collateral", diff --git a/public/locales/zh_tw/account.json b/public/locales/zh_tw/account.json new file mode 100644 index 00000000..28d4646c --- /dev/null +++ b/public/locales/zh_tw/account.json @@ -0,0 +1,11 @@ +{ + "no-pnl-history": "No PnL History", + "pnl-chart": "PnL Chart", + "pnl-history": "PnL History", + "tooltip-free-collateral": "The amount of capital you have to use for trades and loans. When your free collateral reaches $0 you won't be able to trade, borrow or withdraw", + "tooltip-leverage": "Total assets value divided by account equity value", + "tooltip-pnl": "The amount your account has profited or lost", + "tooltip-total-collateral": "Total value of collateral for trading and borrowing (including unsettled PnL)", + "tooltip-total-interest": "The value of interest earned (deposits) minus interest paid (borrows)", + "week-starting": "Week starting {{week}}" +} \ No newline at end of file diff --git a/public/locales/zh_tw/common.json b/public/locales/zh_tw/common.json index 3f6b6386..ddd3cedd 100644 --- a/public/locales/zh_tw/common.json +++ b/public/locales/zh_tw/common.json @@ -121,6 +121,7 @@ "token-collateral-multiplier": "{{token}} Collateral Multiplier", "tooltip-borrow-rate": "The variable interest rate you'll pay on your borrowed balance", "tooltip-collateral-value": "The USD amount you can trade or borrow against", + "total": "Total", "total-borrows": "Total Borrows", "total-borrow-value": "Total Borrow Value", "total-collateral": "Total Collateral", From 4d5230cf05b98ccbf649bc7c6cb7c592b99fedd9 Mon Sep 17 00:00:00 2001 From: Riordan Panayides Date: Wed, 18 Jan 2023 13:13:29 +0000 Subject: [PATCH 08/17] Replace references to mango-transaction-log --- components/profile/EditNftProfilePic.tsx | 5 +++-- components/profile/EditProfileForm.tsx | 5 +++-- components/tours/CustomTooltip.tsx | 3 ++- components/trade/PerpFundingRate.tsx | 3 ++- store/mangoStore.ts | 21 +++++++++++---------- utils/constants.ts | 2 ++ 6 files changed, 23 insertions(+), 16 deletions(-) diff --git a/components/profile/EditNftProfilePic.tsx b/components/profile/EditNftProfilePic.tsx index b711d950..0a11b390 100644 --- a/components/profile/EditNftProfilePic.tsx +++ b/components/profile/EditNftProfilePic.tsx @@ -6,6 +6,7 @@ import { useTranslation } from 'next-i18next' import Button, { LinkButton } from '../shared/Button' import { bs58 } from '@project-serum/anchor/dist/cjs/utils/bytes' import { notify } from 'utils/notifications' +import { MANGO_DATA_API_URL } from 'utils/constants' const ImgWithLoader = (props: any) => { const [isLoading, setIsLoading] = useState(true) @@ -67,7 +68,7 @@ const EditNftProfilePic = ({ onClose }: { onClose: () => void }) => { }), } const response = await fetch( - 'https://mango-transaction-log.herokuapp.com/v4/user-data/profile-details', + `${MANGO_DATA_API_URL}/user-data/profile-details`, requestOptions ) if (response.status === 200) { @@ -113,7 +114,7 @@ const EditNftProfilePic = ({ onClose }: { onClose: () => void }) => { }), } const response = await fetch( - 'https://mango-transaction-log.herokuapp.com/v4/user-data/profile-details', + `${MANGO_DATA_API_URL}/user-data/profile-details`, requestOptions ) if (response.status === 200) { diff --git a/components/profile/EditProfileForm.tsx b/components/profile/EditProfileForm.tsx index 6d238d91..5d268824 100644 --- a/components/profile/EditProfileForm.tsx +++ b/components/profile/EditProfileForm.tsx @@ -14,6 +14,7 @@ import mangoStore from '@store/mangoStore' import startCase from 'lodash/startCase' import { useTranslation } from 'next-i18next' import { ChangeEvent, useState } from 'react' +import { MANGO_DATA_API_URL } from 'utils/constants' import { notify } from 'utils/notifications' import ProfileImage from './ProfileImage' @@ -42,7 +43,7 @@ const EditProfileForm = ({ try { setLoadUniquenessCheck(true) const response = await fetch( - `https://mango-transaction-log.herokuapp.com/v4/user-data/check-profile-name-unique?profile-name=${name}` + `${MANGO_DATA_API_URL}/user-data/check-profile-name-unique?profile-name=${name}` ) const uniquenessCheck = await response.json() @@ -103,7 +104,7 @@ const EditProfileForm = ({ }), } const response = await fetch( - 'https://mango-transaction-log.herokuapp.com/v4/user-data/profile-details', + `${MANGO_DATA_API_URL}/user-data/profile-details`, requestOptions ) if (response.status === 200) { diff --git a/components/tours/CustomTooltip.tsx b/components/tours/CustomTooltip.tsx index cf5313f0..d35b433a 100644 --- a/components/tours/CustomTooltip.tsx +++ b/components/tours/CustomTooltip.tsx @@ -3,6 +3,7 @@ import { XMarkIcon } from '@heroicons/react/20/solid' import { useWallet } from '@solana/wallet-adapter-react' import mangoStore from '@store/mangoStore' import { useState } from 'react' +import { MANGO_DATA_API_URL } from 'utils/constants' import { WalktourLogic } from 'walktour' const CustomTooltip = ({ @@ -37,7 +38,7 @@ const CustomTooltip = ({ body: message, } const response = await fetch( - 'https://mango-transaction-log.herokuapp.com/v4/user-data/settings-unsigned', + `${MANGO_DATA_API_URL}/user-data/settings-unsigned`, requestOptions ) if (response.status === 200) { diff --git a/components/trade/PerpFundingRate.tsx b/components/trade/PerpFundingRate.tsx index 13a8fb5e..4cf18363 100644 --- a/components/trade/PerpFundingRate.tsx +++ b/components/trade/PerpFundingRate.tsx @@ -5,10 +5,11 @@ import { useQuery } from '@tanstack/react-query' import useMangoGroup from 'hooks/useMangoGroup' import useSelectedMarket from 'hooks/useSelectedMarket' import { useMemo } from 'react' +import { MANGO_DATA_API_URL } from 'utils/constants' const fetchFundingRate = async (groupPk: string | undefined) => { const res = await fetch( - `https://mango-transaction-log.herokuapp.com/v4/one-hour-funding-rate?mango-group=${groupPk}` + `${MANGO_DATA_API_URL}/one-hour-funding-rate?mango-group=${groupPk}` ) return await res.json() } diff --git a/store/mangoStore.ts b/store/mangoStore.ts index f8c13c4a..22bfc3d8 100644 --- a/store/mangoStore.ts +++ b/store/mangoStore.ts @@ -33,6 +33,7 @@ import { DEFAULT_MARKET_NAME, INPUT_TOKEN_DEFAULT, LAST_ACCOUNT_KEY, + MANGO_DATA_API_URL, OUTPUT_TOKEN_DEFAULT, RPC_PROVIDER_KEY, } from '../utils/constants' @@ -461,7 +462,7 @@ const mangoStore = create()( }) try { const response = await fetch( - `https://mango-transaction-log.herokuapp.com/v4/stats/interest-account-total?mango-account=${mangoAccountPk}` + `${MANGO_DATA_API_URL}/stats/interest-account-total?mango-account=${mangoAccountPk}` ) const parsedResponse = await response.json() const entries: any = Object.entries(parsedResponse).sort((a, b) => @@ -498,7 +499,7 @@ const mangoStore = create()( }) try { const response = await fetch( - `https://mango-transaction-log.herokuapp.com/v4/stats/performance_account?mango-account=${mangoAccountPk}&start-date=${dayjs() + `${MANGO_DATA_API_URL}/stats/performance_account?mango-account=${mangoAccountPk}&start-date=${dayjs() .subtract(range, 'day') .format('YYYY-MM-DD')}` ) @@ -541,7 +542,7 @@ const mangoStore = create()( try { const response = await fetch( - `https://mango-transaction-log.herokuapp.com/v4/stats/activity-feed?mango-account=${mangoAccountPk}&offset=${offset}&limit=25${ + `${MANGO_DATA_API_URL}/stats/activity-feed?mango-account=${mangoAccountPk}&offset=${offset}&limit=25${ params ? params : '' }` ) @@ -817,7 +818,7 @@ const mangoStore = create()( }) try { const response = await fetch( - `https://mango-transaction-log.herokuapp.com/v4/perp-historical-stats?mango-group=${group?.publicKey.toString()}` + `${MANGO_DATA_API_URL}/perp-historical-stats?mango-group=${group?.publicKey.toString()}` ) const data = await response.json() @@ -840,7 +841,7 @@ const mangoStore = create()( setTimeout(async () => { try { const history = await fetch( - `https://mango-transaction-log.herokuapp.com/v4/stats/swap-history?mango-account=${mangoAccountPk}` + `${MANGO_DATA_API_URL}/stats/swap-history?mango-account=${mangoAccountPk}` ) const parsedHistory = await history.json() const sortedHistory = @@ -876,7 +877,7 @@ const mangoStore = create()( }) try { const response = await fetch( - `https://mango-transaction-log.herokuapp.com/v4/token-historical-stats?mango-group=${group?.publicKey.toString()}` + `${MANGO_DATA_API_URL}/token-historical-stats?mango-group=${group?.publicKey.toString()}` ) const data = await response.json() @@ -945,7 +946,7 @@ const mangoStore = create()( }) try { const response = await fetch( - `https://mango-transaction-log.herokuapp.com/v4/user-data/profile-details?wallet-pk=${walletPk}` + `${MANGO_DATA_API_URL}/user-data/profile-details?wallet-pk=${walletPk}` ) const data = await response.json() set((state) => { @@ -967,7 +968,7 @@ const mangoStore = create()( }) try { const response = await fetch( - `https://mango-transaction-log.herokuapp.com/v4/user-data/settings-unsigned?wallet-pk=${walletPk}` + `${MANGO_DATA_API_URL}/user-data/settings-unsigned?wallet-pk=${walletPk}` ) const data = await response.json() set((state) => { @@ -1021,10 +1022,10 @@ const mangoStore = create()( try { const [spotRes, perpRes] = await Promise.all([ fetch( - `https://mango-transaction-log.herokuapp.com/v4/stats/openbook-trades?address=${mangoAccount?.publicKey.toString()}&address-type=mango-account` + `${MANGO_DATA_API_URL}/stats/openbook-trades?address=${mangoAccount?.publicKey.toString()}&address-type=mango-account` ), fetch( - `https://mango-transaction-log.herokuapp.com/v4/stats/perp-trade-history?mango-account=${mangoAccount?.publicKey.toString()}&limit=1000` + `${MANGO_DATA_API_URL}/stats/perp-trade-history?mango-account=${mangoAccount?.publicKey.toString()}&limit=1000` ), ]) const spotHistory = await spotRes.json() diff --git a/utils/constants.ts b/utils/constants.ts index 1a19ddab..13421363 100644 --- a/utils/constants.ts +++ b/utils/constants.ts @@ -60,6 +60,8 @@ export const CHART_DATA_FEED = `https://dry-ravine-67635.herokuapp.com/tv` export const MANGO_ROUTER_API_URL = 'https://api.mngo.cloud/router/v1' +export const MANGO_DATA_API_URL = 'https://api.mngo.cloud/data/v4' + export const DEFAULT_MARKET_NAME = 'SOL/USDC' export const MIN_SOL_BALANCE = 0.001 From b470d03adf2ba30802991f883d9bf38384210ba9 Mon Sep 17 00:00:00 2001 From: Riordan Panayides Date: Wed, 18 Jan 2023 18:00:27 +0000 Subject: [PATCH 09/17] Fix mango-v4 dependency --- yarn.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarn.lock b/yarn.lock index 624ae37c..95df898e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -52,7 +52,7 @@ "@blockworks-foundation/mango-v4@https://github.com/blockworks-foundation/mango-v4.git#ts-client": version "0.0.1-beta.6" - resolved "https://github.com/blockworks-foundation/mango-v4.git#adc9140ad2a3c2e9c3b425b8804d9415f2a05067" + resolved "https://github.com/blockworks-foundation/mango-v4.git#1ca560c007081127ac31486a96a3729da22f99fb" dependencies: "@project-serum/anchor" "^0.25.0" "@project-serum/serum" "^0.13.65" From 79821f52165b33884793a4d579c0e0d8ce2776e7 Mon Sep 17 00:00:00 2001 From: Riordan Panayides Date: Wed, 18 Jan 2023 18:41:42 +0000 Subject: [PATCH 10/17] Fix side badge for combinedTradeHistory trades --- components/trade/TradeHistory.tsx | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/components/trade/TradeHistory.tsx b/components/trade/TradeHistory.tsx index aeccc5b4..91f207bf 100644 --- a/components/trade/TradeHistory.tsx +++ b/components/trade/TradeHistory.tsx @@ -189,6 +189,17 @@ const TradeHistory = () => { makerTaker = 'Taker' } } + let side = trade.side + if ('perp_market' in trade) { + const sideObj: any = {} + if (makerTaker == 'Taker') { + sideObj[trade.taker_side] = 1 + } else { + sideObj[trade.taker_side == 'bid' ? 'ask' : 'bid'] = 1 + } + side = sideObj + } + const size = trade.size || trade.quantity let fee if (trade.fee_cost || trade.feeCost) { @@ -209,14 +220,14 @@ const TradeHistory = () => { - + {size} {formatDecimal(trade.price)} - {formatFixedDecimals(trade.price * size)} + ${formatFixedDecimals(trade.price * size)} {formatDecimal(fee)} From 193d2a16fe5ab894525be10dfc4d4e5cc7f25000 Mon Sep 17 00:00:00 2001 From: saml33 Date: Thu, 19 Jan 2023 10:50:55 +1100 Subject: [PATCH 11/17] fix connect wallet button for long wallet names --- components/wallet/ConnectWalletButton.tsx | 38 +++++++++++++---------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/components/wallet/ConnectWalletButton.tsx b/components/wallet/ConnectWalletButton.tsx index 0c49a624..bbc15b80 100644 --- a/components/wallet/ConnectWalletButton.tsx +++ b/components/wallet/ConnectWalletButton.tsx @@ -29,24 +29,28 @@ export const ConnectWalletButton: React.FC = () => { >
-
- {`${wallet?.adapter.name} -
+ {connecting ? ( + + ) : ( +
+ {`${wallet?.adapter.name} +
+ )}
-
- {connecting ? : t('connect')} +
+ {t('connect')}
From b8ca0a40c73aa2fbc6f0d3e7278629dd3fd16abc Mon Sep 17 00:00:00 2001 From: tjs Date: Wed, 18 Jan 2023 19:19:46 -0500 Subject: [PATCH 12/17] fix type error from merge --- store/mangoStore.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/store/mangoStore.ts b/store/mangoStore.ts index d38444bb..a781ffb0 100644 --- a/store/mangoStore.ts +++ b/store/mangoStore.ts @@ -384,11 +384,9 @@ const mangoStore = create()( openOrders: {}, perpPositions: [], spotBalances: {}, - stats: { - interestTotals: { data: [], loading: false }, - performance: { data: [], loading: false }, - swapHistory: { data: [], initialLoad: false }, - }, + interestTotals: { data: [], loading: false }, + performance: { data: [], loading: false, initialLoad: false }, + swapHistory: { data: [], initialLoad: false }, tradeHistory: { data: [], loading: true }, }, mangoAccounts: [], From 8ffe2eb19540e949e52de8eedd1ad6e386b71a8c Mon Sep 17 00:00:00 2001 From: tjs Date: Wed, 18 Jan 2023 19:21:02 -0500 Subject: [PATCH 13/17] add quiet flag to husky check --- .husky/pre-commit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.husky/pre-commit b/.husky/pre-commit index f3a559de..c8cc17a7 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,4 +1,4 @@ #!/usr/bin/env sh . "$(dirname -- "$0")/_/husky.sh" -yarn typecheck && yarn lint +yarn typecheck && yarn lint --quiet From 270c74b9db35c1556f71908f18686c6cae1b8d26 Mon Sep 17 00:00:00 2001 From: saml33 Date: Thu, 19 Jan 2023 13:42:29 +1100 Subject: [PATCH 14/17] toggle tradingview on mobile --- components/trade/AdvancedMarketHeader.tsx | 71 +++++++++++++------- components/trade/MobileTradeAdvancedPage.tsx | 15 +++-- components/trade/TradingChartContainer.tsx | 4 +- components/trade/TradingViewChartKline.tsx | 4 +- 4 files changed, 62 insertions(+), 32 deletions(-) diff --git a/components/trade/AdvancedMarketHeader.tsx b/components/trade/AdvancedMarketHeader.tsx index 81220542..825c7c74 100644 --- a/components/trade/AdvancedMarketHeader.tsx +++ b/components/trade/AdvancedMarketHeader.tsx @@ -1,5 +1,7 @@ import { PerpMarket } from '@blockworks-foundation/mango-v4' +import { IconButton } from '@components/shared/Button' import Change from '@components/shared/Change' +import { ChartBarIcon } from '@heroicons/react/20/solid' import { useCoingecko } from 'hooks/useCoingecko' import useSelectedMarket from 'hooks/useSelectedMarket' import { useTranslation } from 'next-i18next' @@ -8,7 +10,13 @@ import { getDecimalCount } from 'utils/numbers' import MarketSelectDropdown from './MarketSelectDropdown' import PerpFundingRate from './PerpFundingRate' -const AdvancedMarketHeader = () => { +const AdvancedMarketHeader = ({ + showChart, + setShowChart, +}: { + showChart?: boolean + setShowChart?: (x: boolean) => void +}) => { const { t } = useTranslation(['common', 'trade']) const { serumOrPerpMarket, baseSymbol, price } = useSelectedMarket() const { data: tokenPrices } = useCoingecko() @@ -35,31 +43,46 @@ const AdvancedMarketHeader = () => {
-
-
-
{t('trade:oracle-price')}
-
- {price ? ( - `$${price.toFixed( - getDecimalCount(serumOrPerpMarket?.tickSize || 0.01) - )}` - ) : ( - - )} -
-
-
-
{t('rolling-change')}
- -
- {serumOrPerpMarket instanceof PerpMarket ? ( -
-
- {t('trade:funding-rate')} +
+
+
+
+
+ {t('trade:oracle-price')} +
+
+ {price ? ( + `$${price.toFixed( + getDecimalCount(serumOrPerpMarket?.tickSize || 0.01) + )}` + ) : ( + + )} +
- +
+
{t('rolling-change')}
+ +
+ {serumOrPerpMarket instanceof PerpMarket ? ( +
+
+ {t('trade:funding-rate')} +
+ +
+ ) : null}
- ) : null} + {setShowChart ? ( + setShowChart(!showChart)} + hideBg + > + + + ) : null} +
) diff --git a/components/trade/MobileTradeAdvancedPage.tsx b/components/trade/MobileTradeAdvancedPage.tsx index d22bce4d..2eb744e5 100644 --- a/components/trade/MobileTradeAdvancedPage.tsx +++ b/components/trade/MobileTradeAdvancedPage.tsx @@ -6,17 +6,24 @@ import TradeInfoTabs from './TradeInfoTabs' import TabButtons from '@components/shared/TabButtons' import { TABS } from './OrderbookAndTrades' import RecentTrades from './RecentTrades' +import TradingChartContainer from './TradingChartContainer' const MobileTradeAdvancedPage = () => { const [activeTab, setActiveTab] = useState('trade:book') + const [showChart, setShowChart] = useState(false) return (
- +
- {/*
- -
*/} + {showChart ? ( +
+ +
+ ) : null}
diff --git a/components/trade/TradingChartContainer.tsx b/components/trade/TradingChartContainer.tsx index 2776e877..7392fd8a 100644 --- a/components/trade/TradingChartContainer.tsx +++ b/components/trade/TradingChartContainer.tsx @@ -17,9 +17,9 @@ const TradingChartContainer = () => { const [tradingChart] = useLocalStorageState(TRADE_CHART_UI_KEY) const isTradingChart = tradingChart === 'custom' return !isTradingChart ? ( - + ) : ( - + ) } diff --git a/components/trade/TradingViewChartKline.tsx b/components/trade/TradingViewChartKline.tsx index 8c90ec64..0241e279 100644 --- a/components/trade/TradingViewChartKline.tsx +++ b/components/trade/TradingViewChartKline.tsx @@ -405,9 +405,9 @@ const TradingViewChartKline = ({ setIsFullView, isFullView }: Props) => { return (
From 4ce190161d4098165b53562905bdf46d52218cbe Mon Sep 17 00:00:00 2001 From: saml33 Date: Thu, 19 Jan 2023 14:38:06 +1100 Subject: [PATCH 15/17] round pnl history --- components/modals/PnlHistoryModal.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/components/modals/PnlHistoryModal.tsx b/components/modals/PnlHistoryModal.tsx index 272b201d..4638603a 100644 --- a/components/modals/PnlHistoryModal.tsx +++ b/components/modals/PnlHistoryModal.tsx @@ -8,6 +8,7 @@ import dayjs from 'dayjs' import Change from '@components/shared/Change' import SheenLoader from '@components/shared/SheenLoader' import { NoSymbolIcon } from '@heroicons/react/20/solid' +import { formatDecimal } from 'utils/numbers' interface PnlChange { time: string @@ -49,9 +50,10 @@ const PnlHistoryModal = ({ ? dailyPnl .map((d: PerformanceDataItem, index: number) => { if (index < dailyPnl.length - 1) { + const change = dailyPnl[index + 1].pnl - d.pnl return { time: d.time, - pnlChange: dailyPnl[index + 1].pnl - d.pnl, + pnlChange: change, } } else { return { @@ -108,7 +110,10 @@ const PnlHistoryModal = ({ key={v.time + v.pnlChange} >

{dayjs(v.time).format('YYYY-MM-DD')}

- +
))}
From 235f3cde9d06fbc3b73f68a53b67da984f8350bb Mon Sep 17 00:00:00 2001 From: saml33 Date: Thu, 19 Jan 2023 15:16:43 +1100 Subject: [PATCH 16/17] fix account performance data when changing accounts --- components/account/AccountPage.tsx | 41 ++++++++++++++++-------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/components/account/AccountPage.tsx b/components/account/AccountPage.tsx index 2d749f66..dc7c74dc 100644 --- a/components/account/AccountPage.tsx +++ b/components/account/AccountPage.tsx @@ -75,16 +75,25 @@ const AccountPage = () => { useEffect(() => { if (mangoAccountAddress) { + const set = mangoStore.getState().set + set((s) => { + s.mangoAccount.performance.initialLoad = false + }) + setOneDayPerformanceData([]) actions.fetchAccountPerformance(mangoAccountAddress, 1) actions.fetchAccountInterestTotals(mangoAccountAddress) } }, [actions, mangoAccountAddress]) useEffect(() => { - if (performanceInitialLoad && !oneDayPerformanceData.length) { + if ( + performanceData.length && + performanceInitialLoad && + !oneDayPerformanceData.length + ) { setOneDayPerformanceData(performanceData) } - }, [performanceInitialLoad, oneDayPerformanceData]) + }, [performanceInitialLoad, oneDayPerformanceData, performanceData]) const onHoverMenu = (open: boolean, action: string) => { if ( @@ -134,30 +143,24 @@ const AccountPage = () => { } }, [mangoAccount, group, accountValue]) - const { accountPnl, accountValueChange } = useMemo(() => { + const [accountPnl, accountValueChange, oneDayPnlChange] = useMemo(() => { if ( accountValue && oneDayPerformanceData.length && performanceData.length ) { - return { - accountPnl: performanceData[performanceData.length - 1].pnl, - accountValueChange: - accountValue - oneDayPerformanceData[0].account_equity, - } - } - return { accountPnl: 0, accountValueChange: 0 } - }, [accountValue, oneDayPerformanceData, performanceData]) - - const oneDayPnlChange = useMemo(() => { - if (accountPnl && oneDayPerformanceData.length) { + const accountPnl = performanceData[performanceData.length - 1].pnl + const accountValueChange = + accountValue - oneDayPerformanceData[0].account_equity const startDayPnl = oneDayPerformanceData[0].pnl const endDayPnl = oneDayPerformanceData[oneDayPerformanceData.length - 1].pnl - return endDayPnl - startDayPnl + const oneDayPnlChange = endDayPnl - startDayPnl + + return [accountPnl, accountValueChange, oneDayPnlChange] } - return 0.0 - }, [accountPnl, oneDayPerformanceData]) + return [0, 0, 0] + }, [accountValue, oneDayPerformanceData, performanceData]) const interestTotalValue = useMemo(() => { if (totalInterestData.length) { @@ -170,7 +173,7 @@ const AccountPage = () => { }, [totalInterestData]) const oneDayInterestChange = useMemo(() => { - if (oneDayPerformanceData.length && mangoAccount) { + if (oneDayPerformanceData.length) { const startDayInterest = oneDayPerformanceData[0].borrow_interest_cumulative_usd + oneDayPerformanceData[0].deposit_interest_cumulative_usd @@ -184,7 +187,7 @@ const AccountPage = () => { return endDayInterest - startDayInterest } return 0.0 - }, [oneDayPerformanceData, mangoAccount]) + }, [oneDayPerformanceData]) const maintHealth = useMemo(() => { return group && mangoAccount From cf7cf1c037eba01a84b1dedf5e4e00722292781f Mon Sep 17 00:00:00 2001 From: saml33 Date: Thu, 19 Jan 2023 15:22:16 +1100 Subject: [PATCH 17/17] round account page change components --- components/account/AccountPage.tsx | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/components/account/AccountPage.tsx b/components/account/AccountPage.tsx index dc7c74dc..99a06c4e 100644 --- a/components/account/AccountPage.tsx +++ b/components/account/AccountPage.tsx @@ -6,7 +6,7 @@ import { useTranslation } from 'next-i18next' import { useEffect, useMemo, useState } from 'react' import AccountActions from './AccountActions' import mangoStore, { PerformanceDataItem } from '@store/mangoStore' -import { formatFixedDecimals } from '../../utils/numbers' +import { formatDecimal, formatFixedDecimals } from '../../utils/numbers' import FlipNumbers from 'react-flip-numbers' import dynamic from 'next/dynamic' const SimpleAreaChart = dynamic( @@ -268,7 +268,10 @@ const AccountPage = () => { )}
- +

{t('today')}

@@ -478,7 +481,11 @@ const AccountPage = () => { {formatFixedDecimals(accountPnl, true, true)}

- +

{t('today')}

@@ -514,7 +521,11 @@ const AccountPage = () => { {formatFixedDecimals(interestTotalValue, true, true)}

- +

{t('today')}