diff --git a/.env.example b/.env.example
index 25226c89..5c508803 100644
--- a/.env.example
+++ b/.env.example
@@ -4,8 +4,6 @@ NEXT_PUBLIC_CHAIN_ID=devnet
NEXT_PUBLIC_RPC=https://rpc.devnet.osmosis.zone/
NEXT_PUBLIC_GQL=https://devnet-osmosis-gql.marsprotocol.io/graphql
NEXT_PUBLIC_REST=https://lcd.devnet.osmosis.zone/
-NEXT_PUBLIC_ZAPPER=osmo1yhh8mhthj5jn5c6ty59z3tpsk554qxmlkrkcderw6jls0pcg8zxsdjdj94
-NEXT_PUBLIC_PARAMS=osmo1aye5qcer5n52crrkaf35jprsad2807q6kg3eeeu7k79h4slxfausfqhc9y
# MAINNET #
@@ -14,8 +12,6 @@ NEXT_PUBLIC_CHAIN_ID=osmosis-1
NEXT_PUBLIC_RPC=https://osmosis-node.marsprotocol.io/GGSFGSFGFG34/osmosis-rpc-front/
NEXT_PUBLIC_GQL=https://osmosis-node.marsprotocol.io/GGSFGSFGFG34/osmosis-hive-front/graphql
NEXT_PUBLIC_REST=https://osmosis-node.marsprotocol.io/GGSFGSFGFG34/osmosis-lcd-front/
-NEXT_PUBLIC_ZAPPER=osmo17qwvc70pzc9mudr8t02t3pl74hhqsgwnskl734p4hug3s8mkerdqzduf7c
-NEXT_PUBLIC_PARAMS=osmo1nlmdxt9ctql2jr47qd4fpgzg84cjswxyw6q99u4y4u4q6c2f5ksq7ysent
# COMMON #
@@ -28,6 +24,8 @@ NEXT_PUBLIC_CREDIT_MANAGER=osmo1f2m24wktq0sw3c0lexlg7fv4kngwyttvzws3a3r3al9ld2s2
NEXT_PUBLIC_INCENTIVES=osmo1nkahswfr8shg8rlxqwup0vgahp0dk4x8w6tkv3rra8rratnut36sk22vrm
NEXT_PUBLIC_SWAPPER=osmo1wee0z8c7tcawyl647eapqs4a88q8jpa7ddy6nn2nrs7t47p2zhxswetwla
NEXT_PUBLIC_PYTH=osmo13ge29x4e2s63a8ytz2px8gurtyznmue4a69n5275692v3qn3ks8q7cwck7
+NEXT_PUBLIC_ZAPPER=osmo17qwvc70pzc9mudr8t02t3pl74hhqsgwnskl734p4hug3s8mkerdqzduf7c
+NEXT_PUBLIC_PARAMS=osmo1nlmdxt9ctql2jr47qd4fpgzg84cjswxyw6q99u4y4u4q6c2f5ksq7ysent
NEXT_PUBLIC_PYTH_ENDPOINT=https://hermes.pyth.network/api
NEXT_PUBLIC_MAINNET_REST=https://osmosis-node.marsprotocol.io/GGSFGSFGFG34/osmosis-rpc-front/
NEXT_PUBLIC_CANDLES_ENDPOINT=https://osmosis-candles.marsprotocol.io/
diff --git a/src/components/Account/AccountBalancesTable/Columns/Apy.tsx b/src/components/Account/AccountBalancesTable/Columns/Apy.tsx
new file mode 100644
index 00000000..03321a6c
--- /dev/null
+++ b/src/components/Account/AccountBalancesTable/Columns/Apy.tsx
@@ -0,0 +1,28 @@
+import AssetRate from 'components/Asset/AssetRate'
+import { byDenom } from 'utils/array'
+
+export const APY_META = { accessorKey: 'apy', header: 'APY' }
+
+interface Props {
+ apy: number
+ markets: Market[]
+ denom: string
+ type: 'deposits' | 'borrowing' | 'lending' | 'vault'
+}
+
+export default function Apr(props: Props) {
+ const { markets, type, denom, apy } = props
+
+ if (type === 'deposits') return
–
+ const isEnabled = markets.find(byDenom(denom))?.borrowEnabled ?? false
+
+ return (
+
+ )
+}
diff --git a/src/components/Account/AccountBalancesTable/Columns/Asset.tsx b/src/components/Account/AccountBalancesTable/Columns/Asset.tsx
new file mode 100644
index 00000000..fc26c5a5
--- /dev/null
+++ b/src/components/Account/AccountBalancesTable/Columns/Asset.tsx
@@ -0,0 +1,22 @@
+import Text from 'components/Text'
+export const ASSET_META = { accessorKey: 'symbol', header: 'Asset', id: 'symbol' }
+
+interface Props {
+ symbol: string
+ type: 'deposits' | 'borrowing' | 'lending' | 'vault'
+}
+
+export const borderColor = (type: Props['type']): string =>
+ type === 'borrowing' ? 'border-loss' : 'border-profit'
+
+export default function Asset(props: Props) {
+ const { symbol, type } = props
+ return (
+
+ {symbol}
+ {type === 'borrowing' && (debt)}
+ {type === 'lending' && (lent)}
+ {type === 'vault' && (farm)}
+
+ )
+}
diff --git a/src/components/Account/AccountBalancesTable/Columns/Size.tsx b/src/components/Account/AccountBalancesTable/Columns/Size.tsx
new file mode 100644
index 00000000..cc65876e
--- /dev/null
+++ b/src/components/Account/AccountBalancesTable/Columns/Size.tsx
@@ -0,0 +1,60 @@
+import { Row } from '@tanstack/react-table'
+import classNames from 'classnames'
+
+import { getAmountChangeColor } from 'components/Account/AccountBalancesTable/functions'
+import { FormattedNumber } from 'components/FormattedNumber'
+import { MAX_AMOUNT_DECIMALS, MIN_AMOUNT } from 'constants/math'
+import { formatAmountToPrecision } from 'utils/formatters'
+
+export const SIZE_META = { accessorKey: 'size', header: 'Size' }
+
+interface Props {
+ size: number
+ amountChange: BigNumber
+ denom: string
+ type: 'deposits' | 'borrowing' | 'lending' | 'vault'
+}
+
+export const sizeSortingFn = (a: Row, b: Row): number => {
+ const isVaultA = a.original.type === 'vault'
+ const isVaultB = b.original.type === 'vault'
+
+ const sizeA = isVaultA ? 0 : a.original.size
+ const sizeB = isVaultB ? 0 : b.original.size
+
+ return sizeA - sizeB
+}
+
+export default function Size(props: Props) {
+ const { amountChange, type, size } = props
+
+ if (type === 'vault') return –
+
+ const color = getAmountChangeColor(type, amountChange)
+ const className = classNames('text-xs text-right', color)
+
+ if (size >= 1)
+ return (
+
+ )
+
+ const formattedAmount = formatAmountToPrecision(size, MAX_AMOUNT_DECIMALS)
+ const lowAmount = formattedAmount === 0 ? 0 : Math.max(formattedAmount, MIN_AMOUNT)
+ return (
+
+ )
+}
diff --git a/src/components/Account/AccountBalancesTable/Columns/Value.tsx b/src/components/Account/AccountBalancesTable/Columns/Value.tsx
new file mode 100644
index 00000000..54094b97
--- /dev/null
+++ b/src/components/Account/AccountBalancesTable/Columns/Value.tsx
@@ -0,0 +1,33 @@
+import { Row } from '@tanstack/react-table'
+import classNames from 'classnames'
+
+import { getAmountChangeColor } from 'components/Account/AccountBalancesTable/functions'
+import DisplayCurrency from 'components/DisplayCurrency'
+import { ORACLE_DENOM } from 'constants/oracle'
+import { BNCoin } from 'types/classes/BNCoin'
+import { BN } from 'utils/helpers'
+
+export const VALUE_META = { accessorKey: 'value', header: 'Value' }
+
+interface Props {
+ amountChange: BigNumber
+ value: string
+ type: 'deposits' | 'borrowing' | 'lending' | 'vault'
+}
+
+export const valueSortingFn = (a: Row, b: Row): number => {
+ const valueA = BN(a.original.value)
+ const valueB = BN(b.original.value)
+ return valueA.minus(valueB).toNumber()
+}
+
+export default function Value(props: Props) {
+ const { amountChange, type, value } = props
+ const color = getAmountChangeColor(type, amountChange)
+ const coin = new BNCoin({
+ denom: ORACLE_DENOM,
+ amount: value,
+ })
+
+ return
+}
diff --git a/src/components/Account/AccountBalancesTable/Columns/useAccountBalancesColumns.tsx b/src/components/Account/AccountBalancesTable/Columns/useAccountBalancesColumns.tsx
new file mode 100644
index 00000000..c8cfa9e3
--- /dev/null
+++ b/src/components/Account/AccountBalancesTable/Columns/useAccountBalancesColumns.tsx
@@ -0,0 +1,62 @@
+import { ColumnDef } from '@tanstack/react-table'
+import { useMemo } from 'react'
+
+import Apy, { APY_META } from 'components/Account/AccountBalancesTable/Columns/Apy'
+import Asset, { ASSET_META } from 'components/Account/AccountBalancesTable/Columns/Asset'
+import Size, {
+ SIZE_META,
+ sizeSortingFn,
+} from 'components/Account/AccountBalancesTable/Columns/Size'
+import Value, {
+ VALUE_META,
+ valueSortingFn,
+} from 'components/Account/AccountBalancesTable/Columns/Value'
+import useMarketAssets from 'hooks/useMarketAssets'
+
+export default function useAccountBalancesColumns() {
+ const { data: markets } = useMarketAssets()
+
+ return useMemo[]>(() => {
+ return [
+ {
+ ...ASSET_META,
+ cell: ({ row }) => ,
+ },
+ {
+ ...VALUE_META,
+ cell: ({ row }) => (
+
+ ),
+
+ sortingFn: valueSortingFn,
+ },
+ {
+ ...SIZE_META,
+ cell: ({ row }) => (
+
+ ),
+ sortingFn: sizeSortingFn,
+ },
+ {
+ ...APY_META,
+ cell: ({ row }) => (
+
+ ),
+ },
+ ]
+ }, [markets])
+}
diff --git a/src/components/Account/AccountBalancesTable/index.tsx b/src/components/Account/AccountBalancesTable/index.tsx
index 334e4d18..7c8d0916 100644
--- a/src/components/Account/AccountBalancesTable/index.tsx
+++ b/src/components/Account/AccountBalancesTable/index.tsx
@@ -1,51 +1,31 @@
-import {
- ColumnDef,
- flexRender,
- getCoreRowModel,
- getSortedRowModel,
- SortingState,
- useReactTable,
-} from '@tanstack/react-table'
import classNames from 'classnames'
-import { useMemo, useState } from 'react'
import { useLocation, useNavigate } from 'react-router-dom'
-import { getAmountChangeColor } from 'components/Account/AccountBalancesTable/functions'
+import useAccountBalancesColumns from 'components/Account/AccountBalancesTable/Columns/useAccountBalancesColumns'
import useAccountBalanceData from 'components/Account/AccountBalancesTable/useAccountBalanceData'
import AccountFundFullPage from 'components/Account/AccountFund/AccountFundFullPage'
-import AssetRate from 'components/Asset/AssetRate'
import ActionButton from 'components/Button/ActionButton'
-import DisplayCurrency from 'components/DisplayCurrency'
-import { FormattedNumber } from 'components/FormattedNumber'
-import { SortAsc, SortDesc, SortNone } from 'components/Icons'
-import Text from 'components/Text'
-import { ASSETS } from 'constants/assets'
-import { MAX_AMOUNT_DECIMALS, MIN_AMOUNT } from 'constants/math'
-import { ORACLE_DENOM } from 'constants/oracle'
+import Card from 'components/Card'
+import Table from 'components/Table'
+import ConditionalWrapper from 'hocs/ConditionalWrapper'
import useCurrentAccount from 'hooks/useCurrentAccount'
-import useMarketAssets from 'hooks/useMarketAssets'
import useStore from 'store'
-import { BNCoin } from 'types/classes/BNCoin'
-import { byDenom } from 'utils/array'
-import { getAssetByDenom } from 'utils/assets'
-import { demagnify, formatAmountToPrecision } from 'utils/formatters'
import { getPage, getRoute } from 'utils/route'
interface Props {
account: Account
lendingData: LendingMarketTableData[]
borrowingData: BorrowMarketTableData[]
+ hideCard?: boolean
tableBodyClassName?: string
}
-export default function Index(props: Props) {
- const { account, lendingData, borrowingData, tableBodyClassName } = props
- const { data: markets } = useMarketAssets()
+export default function AccountBalancesTable(props: Props) {
+ const { account, lendingData, borrowingData, tableBodyClassName, hideCard } = props
const currentAccount = useCurrentAccount()
const navigate = useNavigate()
const { pathname } = useLocation()
const address = useStore((s) => s.address)
- const [sorting, setSorting] = useState([])
const updatedAccount = useStore((s) => s.updatedAccount)
const accountBalanceData = useAccountBalanceData({
account,
@@ -54,206 +34,51 @@ export default function Index(props: Props) {
borrowingData,
})
- const columns = useMemo[]>(
- () => [
- {
- header: 'Asset',
- accessorKey: 'symbol',
- id: 'symbol',
- cell: ({ row }) => {
- return (
-
- {row.original.symbol}
- {row.original.type === 'borrowing' && (debt)}
- {row.original.type === 'lending' && (lent)}
- {row.original.type === 'vault' && (farm)}
-
- )
- },
- },
- {
- header: 'Value',
- accessorKey: 'value',
- id: 'value',
- cell: ({ row }) => {
- const color = getAmountChangeColor(row.original.type, row.original.amountChange)
- const coin = new BNCoin({
- denom: ORACLE_DENOM,
- amount: row.original.value.toString(),
- })
- return
- },
- },
- {
- id: 'size',
- accessorKey: 'size',
- header: 'Size',
- cell: ({ row }) => {
- const asset = getAssetByDenom(row.original.denom)
-
- if (row.original.type === 'vault' || !asset)
- return –
-
- const color = getAmountChangeColor(row.original.type, row.original.amountChange)
- const className = classNames('text-xs text-right', color)
- const amount = demagnify(
- row.original.amount,
- getAssetByDenom(row.original.denom) ?? ASSETS[0],
- )
- if (amount >= 1)
- return (
-
- )
-
- const formattedAmount = formatAmountToPrecision(amount, MAX_AMOUNT_DECIMALS)
- const lowAmount = formattedAmount === 0 ? 0 : Math.max(formattedAmount, MIN_AMOUNT)
- return (
-
- )
- },
- },
- {
- id: 'apy',
- accessorKey: 'apy',
- header: 'APY',
- cell: ({ row }) => {
- if (row.original.type === 'deposits')
- return –
- const isEnabled = markets.find(byDenom(row.original.denom))?.borrowEnabled ?? false
- return (
-
- )
- },
- },
- ],
- [markets],
- )
-
- const table = useReactTable({
- data: accountBalanceData,
- columns,
- state: {
- sorting,
- },
- onSortingChange: setSorting,
- getCoreRowModel: getCoreRowModel(),
- getSortedRowModel: getSortedRowModel(),
- })
+ const columns = useAccountBalancesColumns()
if (accountBalanceData.length === 0)
return (
-
-
{
- if (currentAccount?.id !== account.id) {
- navigate(getRoute(getPage(pathname), address, account.id))
- }
- useStore.setState({
- focusComponent: {
- component: ,
- onClose: () => {
- useStore.setState({ getStartedModal: true })
+ (
+
+ {children}
+
+ )}
+ >
+
+
{
+ if (currentAccount?.id !== account.id) {
+ navigate(getRoute(getPage(pathname), address, account.id))
+ }
+ useStore.setState({
+ focusComponent: {
+ component: ,
+ onClose: () => {
+ useStore.setState({ getStartedModal: true })
+ },
},
- },
- })
- }}
- />
-
+ })
+ }}
+ />
+
+
)
return (
-
-
- {table.getHeaderGroups().map((headerGroup) => (
-
- {headerGroup.headers.map((header) => {
- return (
-
-
-
- {header.column.getCanSort()
- ? {
- asc: ,
- desc: ,
- false: ,
- }[header.column.getIsSorted() as string] ?? null
- : null}
-
-
- {flexRender(header.column.columnDef.header, header.getContext())}
-
-
- |
- )
- })}
-
- ))}
-
-
- {table.getRowModel().rows.map((row) => {
- return (
-
- {row.getVisibleCells().map((cell) => {
- const borderClass =
- cell.row.original.type === 'borrowing' ? 'border-loss' : 'border-profit'
- return (
-
- {flexRender(cell.column.columnDef.cell, cell.getContext())}
- |
- )
- })}
-
- )
- })}
-
-
+
)
}
diff --git a/src/components/Account/AccountDetails/index.tsx b/src/components/Account/AccountDetails/index.tsx
index 8ef7122a..f4a26cd9 100644
--- a/src/components/Account/AccountDetails/index.tsx
+++ b/src/components/Account/AccountDetails/index.tsx
@@ -180,6 +180,7 @@ function AccountDetails(props: Props) {
account={account}
borrowingData={borrowAssetsData}
lendingData={lendingAssetsData}
+ hideCard
/>
diff --git a/src/components/Account/AccountSummary.tsx b/src/components/Account/AccountSummary.tsx
index 048ba2b1..57983300 100644
--- a/src/components/Account/AccountSummary.tsx
+++ b/src/components/Account/AccountSummary.tsx
@@ -130,6 +130,7 @@ export default function AccountSummary(props: Props) {
account={props.account}
borrowingData={borrowAssetsData}
lendingData={lendingAssetsData}
+ hideCard
/>
) : null,
isOpen: accountSummaryTabs[1],
diff --git a/src/components/Earn/Farm/Table/Columns/useAvailableColumns.tsx b/src/components/Earn/Farm/Table/Columns/useAvailableColumns.tsx
index 132ab70d..dc81f9cc 100644
--- a/src/components/Earn/Farm/Table/Columns/useAvailableColumns.tsx
+++ b/src/components/Earn/Farm/Table/Columns/useAvailableColumns.tsx
@@ -10,8 +10,7 @@ import DepositCap, {
import MaxLTV, { LTV_MAX_META } from 'components/Earn/Farm/Table/Columns/MaxLTV'
import Name, { NAME_META } from 'components/Earn/Farm/Table/Columns/Name'
import TVL, { TVL_META } from 'components/Earn/Farm/Table/Columns/TVL'
-
-import { DETAILS_META } from './Details'
+import { DETAILS_META } from 'components/Earn/Farm/Table/Columns/Details'
interface Props {
isLoading: boolean
diff --git a/src/components/HLS/Farm/AvailableHLSVaults.tsx b/src/components/HLS/Farm/AvailableHLSVaults.tsx
index 6ab4036d..59800e8b 100644
--- a/src/components/HLS/Farm/AvailableHLSVaults.tsx
+++ b/src/components/HLS/Farm/AvailableHLSVaults.tsx
@@ -1,6 +1,7 @@
import { Suspense, useMemo } from 'react'
import { NAME_META } from 'components/Earn/Farm/Table/Columns/Name'
+import useAvailableColumns from 'components/Earn/Farm/Table/Columns/useAvailableColumns'
import Table from 'components/Table'
import { ENV } from 'constants/env'
import { BN_ZERO } from 'constants/math'
@@ -8,8 +9,6 @@ import { TESTNET_VAULTS_META_DATA, VAULTS_META_DATA } from 'constants/vaults'
import useVaults from 'hooks/useVaults'
import { NETWORK } from 'types/enums/network'
-import useAvailableColumns from './Table/Columns/useAvailableColumns'
-
const title = 'Available HLS Vaults'
function Content() {
diff --git a/src/components/Portfolio/Account/Balances.tsx b/src/components/Portfolio/Account/Balances.tsx
index e02be24a..755ec53c 100644
--- a/src/components/Portfolio/Account/Balances.tsx
+++ b/src/components/Portfolio/Account/Balances.tsx
@@ -29,6 +29,7 @@ function Content(props: Props) {
account={account}
borrowingData={borrowAssets}
lendingData={lendingAssets}
+ hideCard
/>
)
diff --git a/src/components/Table/Row.tsx b/src/components/Table/Row.tsx
index f7220281..0138f9e4 100644
--- a/src/components/Table/Row.tsx
+++ b/src/components/Table/Row.tsx
@@ -7,6 +7,12 @@ interface Props {
renderExpanded?: (row: TanstackRow, table: TanstackTable) => JSX.Element
rowClassName?: string
rowClickHandler?: () => void
+ spacingClassName?: string
+ isBalancesTable?: boolean
+}
+
+function getBorderColor(row: AccountBalanceRow) {
+ return row.type === 'borrowing' ? 'border-loss' : 'border-profit'
}
export default function Row(props: Props) {
@@ -27,8 +33,20 @@ export default function Row(props: Props) {
}}
>
{props.row.getVisibleCells().map((cell) => {
+ const isSymbolOrName = cell.column.id === 'symbol' || cell.column.id === 'name'
+ const borderClasses =
+ props.isBalancesTable && isSymbolOrName
+ ? classNames('border-l', getBorderColor(cell.row.original as AccountBalanceRow))
+ : ''
return (
-
+ |
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
)
diff --git a/src/components/Table/index.tsx b/src/components/Table/index.tsx
index 99145ecc..62aa21ca 100644
--- a/src/components/Table/index.tsx
+++ b/src/components/Table/index.tsx
@@ -15,6 +15,7 @@ import Card from 'components/Card'
import { SortAsc, SortDesc, SortNone } from 'components/Icons'
import Row from 'components/Table/Row'
import Text from 'components/Text'
+import ConditionalWrapper from 'hocs/ConditionalWrapper'
interface Props {
title: string
@@ -22,6 +23,10 @@ interface Props {
data: T[]
initialSorting: SortingState
renderExpanded?: (row: TanstackRow, table: TanstackTable) => JSX.Element
+ tableBodyClassName?: string
+ spacingClassName?: string
+ isBalancesTable?: boolean
+ hideCard?: boolean
}
export default function Table(props: Props) {
@@ -39,9 +44,19 @@ export default function Table(props: Props) {
})
return (
-
-
-
+ (
+
+ {children}
+
+ )}
+ >
+
+
{table.getHeaderGroups().map((headerGroup) => (
{headerGroup.headers.map((header) => {
@@ -50,7 +65,7 @@ export default function Table(props: Props) {
key={header.id}
onClick={header.column.getToggleSortingHandler()}
className={classNames(
- 'px-4 py-3',
+ props.spacingClassName ?? 'px-4 py-3',
header.column.getCanSort() && 'hover:cursor-pointer',
header.id === 'symbol' || header.id === 'name' ? 'text-left' : 'text-right',
)}
@@ -75,8 +90,8 @@ export default function Table(props: Props) {
{flexRender(header.column.columnDef.header, header.getContext())}
@@ -89,10 +104,17 @@ export default function Table(props: Props) {
{table.getRowModel().rows.map((row) => (
-
+
))}
-
+
)
}
diff --git a/src/components/Trade/AccountDetailsCard.tsx b/src/components/Trade/AccountDetailsCard.tsx
index 8a6d6831..b091a11c 100644
--- a/src/components/Trade/AccountDetailsCard.tsx
+++ b/src/components/Trade/AccountDetailsCard.tsx
@@ -1,7 +1,6 @@
import { useMemo } from 'react'
import AccountBalancesTable from 'components/Account/AccountBalancesTable'
-import Card from 'components/Card'
import useBorrowMarketAssetsTableData from 'hooks/useBorrowMarketAssetsTableData'
import useCurrentAccount from 'hooks/useCurrentAccount'
import useLendingMarketAssetsTableData from 'hooks/useLendingMarketAssetsTableData'
@@ -19,13 +18,11 @@ export default function AccountDetailsCard() {
if (account)
return (
-
-
-
+
)
}
diff --git a/src/utils/accounts.ts b/src/utils/accounts.ts
index c129fb4a..e576ada4 100644
--- a/src/utils/accounts.ts
+++ b/src/utils/accounts.ts
@@ -10,8 +10,7 @@ import {
import { byDenom } from 'utils/array'
import { getAssetByDenom } from 'utils/assets'
import { BN } from 'utils/helpers'
-
-import { convertApyToApr } from './parsers'
+import { convertApyToApr } from 'utils/parsers'
export const calculateAccountBalanceValue = (
account: Account | AccountChange,