Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(synapse-interface): portfolio gas tokens #2401

Merged
merged 53 commits into from
Apr 17, 2024
Merged
Show file tree
Hide file tree
Changes from 36 commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
73a15b1
Construct `GasToken` type, add initial few gas tokens to test portfol…
bigboydiamonds Mar 28, 2024
bc13ced
Fetching for native gas token works when creating new Token constant
bigboydiamonds Mar 28, 2024
5c144ad
Implement GasToken type
bigboydiamonds Mar 28, 2024
f1ef57a
Create GasToken constants
bigboydiamonds Mar 29, 2024
a1c9092
Gas tokens showing with icons
bigboydiamonds Mar 29, 2024
60c60b6
Filter out gas tokens from portfolio tokens
bigboydiamonds Mar 29, 2024
40c9a7d
Account for chains that do not have gas tokens
bigboydiamonds Mar 29, 2024
e06fe7e
Create gas token component that is not clickable
bigboydiamonds Mar 29, 2024
c9cf3e8
Fix undefined filter issue
bigboydiamonds Mar 29, 2024
32bf18d
Account for when tokens or gasTokens do not exist
bigboydiamonds Mar 29, 2024
6a3f653
GasTokenAsset'
bigboydiamonds Mar 29, 2024
678525f
Remove extraneous props from GasTokenAsset
bigboydiamonds Mar 29, 2024
748d688
Add remaining gas tokens
bigboydiamonds Mar 29, 2024
3551516
Add gas token asset descriptor text
bigboydiamonds Apr 1, 2024
d6554ed
Add gas token dtext for bridgeable gas tokens
bigboydiamonds Apr 1, 2024
66e9130
Text color
bigboydiamonds Apr 1, 2024
cedbc82
Fix spelling
bigboydiamonds Apr 1, 2024
0ac45f1
Add Gas Icon
bigboydiamonds Apr 1, 2024
711a8b1
Add hover tooltip for Gas Icon
bigboydiamonds Apr 1, 2024
b7b02b7
Refactor: HoverTooltip
bigboydiamonds Apr 1, 2024
017797a
Clean
bigboydiamonds Apr 1, 2024
f141b5b
Add padding to gas icon top
bigboydiamonds Apr 1, 2024
23a3f33
Update gas icon size
bigboydiamonds Apr 2, 2024
a5f573f
Prevent colliding tooltips
bigboydiamonds Apr 2, 2024
093aaba
Center justify tooltip
bigboydiamonds Apr 2, 2024
375309a
Clean
bigboydiamonds Apr 2, 2024
877fdc0
Catch any errors for single network portfolio fetch so rest return
bigboydiamonds Apr 2, 2024
952d8c5
Apply changes to GasTokenAsset
bigboydiamonds Apr 2, 2024
a37ed97
Replace balance title with tooltip
bigboydiamonds Apr 2, 2024
6a31c29
Use HoverTooltip in portfolio network header
bigboydiamonds Apr 2, 2024
e55c1e5
Merge branch 'master' into fe/portfolio-gas-tokens
abtestingalpha Apr 3, 2024
a1bf4cb
Clean
bigboydiamonds Apr 8, 2024
601ea4d
Merge branch 'fe/portfolio-gas-tokens' of https://github.com/synapsec…
bigboydiamonds Apr 8, 2024
1bee10d
Merge branch 'master' into fe/portfolio-gas-tokens
bigboydiamonds Apr 9, 2024
4ae15d7
Move getParsedBalance to utils
bigboydiamonds Apr 9, 2024
f3a0df1
Use CHAINS constant to consruct GasToken data
bigboydiamonds Apr 9, 2024
04f400e
Fix Canto gas token error
bigboydiamonds Apr 10, 2024
354d36a
Update nativeCurrency fields to include gas token properties
bigboydiamonds Apr 10, 2024
77e6d38
Update getGasTokens() util function for updated type
bigboydiamonds Apr 10, 2024
93f6ec7
Allow nativeCurrency fields to be undefined if not bridgeable
bigboydiamonds Apr 10, 2024
3117294
Successfully filter for gas tokens in new approach
bigboydiamonds Apr 10, 2024
fe08d75
Clean
bigboydiamonds Apr 10, 2024
711216e
Optimize mapping for gas tokens
bigboydiamonds Apr 10, 2024
094ca55
Update fetchPortfolioBalances to account for new shape in nativeCurrency
bigboydiamonds Apr 10, 2024
ea57c76
Implement new NON_BRIDGEABLE_GAS_TOKEN constant
bigboydiamonds Apr 10, 2024
be13154
Update fetch functions for type
bigboydiamonds Apr 10, 2024
592fd72
Remove undefined prop types
bigboydiamonds Apr 10, 2024
e5ba641
Clean
bigboydiamonds Apr 10, 2024
d39cb85
Merge pull request #2480 from synapsecns/fe/chain-native-currency
bigboydiamonds Apr 17, 2024
b3a272c
Merge branch 'master' into fe/portfolio-gas-tokens
abtestingalpha Apr 17, 2024
20e2152
Merge branch 'master' into fe/portfolio-gas-tokens
bigboydiamonds Apr 17, 2024
605551e
Merge branch 'fe/portfolio-gas-tokens' of https://github.com/synapsec…
bigboydiamonds Apr 17, 2024
cbfcb6c
GasTokensByChain naming convention
bigboydiamonds Apr 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import React from 'react'
import Image from 'next/image'
import { Token } from '@/utils/types'
import { getParsedBalance } from '@/utils/getParsedBalance'
import { HoverTooltip } from './HoverTooltip'
import GasIcon from '@/components/icons/GasIcon'

export const GasTokenAsset = ({
token,
balance,
}: {
token: Token
balance: bigint
}) => {
const { icon, symbol, decimals } = token
const parsedBalance = getParsedBalance(balance, decimals as number, 3)
const parsedBalanceLong = getParsedBalance(balance, decimals as number, 8)

return (
<div
id="gas-token-asset"
className={`
p-2 flex items-center border-y text-white
justify-between last:rounded-b-md border-transparent
`}
>
<div className="relative flex items-center gap-2 py-2 pl-2 pr-4 rounded">
<Image
loading="lazy"
alt={`${symbol} img`}
className="w-6 h-6 rounded-md"
src={icon}
/>
<HoverTooltip
hoverContent={
<div className="whitespace-nowrap">
{parsedBalanceLong} {symbol}
</div>
}
>
<div>
{parsedBalance} {symbol}
</div>
</HoverTooltip>
<HoverTooltip
hoverContent={<div className="whitespace-nowrap">Gas token</div>}
>
<GasIcon className="pt-0.5 m-auto fill-secondary" />
</HoverTooltip>
</div>

<div className="p-2 text-sm opacity-70">Not bridgeable</div>
</div>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React, { useState } from 'react'

export const HoverTooltip = ({ children, hoverContent }) => {
const [showTooltip, setShowTooltip] = useState(false)

const activateTooltip = () => setShowTooltip(true)
const hideTooltip = () => setShowTooltip(false)

return (
<div
onMouseEnter={activateTooltip}
onMouseLeave={hideTooltip}
className="relative"
>
{children}
<Tooltip isHovered={showTooltip}>{hoverContent}</Tooltip>
</div>
)
}

const Tooltip = ({
isHovered,
children,
}: {
isHovered: boolean
children: React.ReactNode
}) => {
if (isHovered) {
return (
<div
className={`
absolute left-1/2 bottom-full translate-x-[-50%]
z-50 hover-content px-2 py-1 text-white mb-1
border border-solid border-[#252537]
bg-[#101018] rounded-md text-left text-sm
`}
>
<data>{children}</data>
</div>
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ import {
updateFromValue,
} from '@/slices/bridge/reducer'
import { Token } from '@/utils/types'
import { formatBigIntToString } from '@/utils/bigint/format'
import { inputRef } from '../../StateManagedBridge/InputContainer'
import Image from 'next/image'
import { useBridgeState } from '@/slices/bridge/hooks'
import { hasOnlyZeroes } from '@/utils/hasOnlyZeroes'
import { PortfolioAssetActionButton } from './PortfolioAssetActionButton'
import { trimTrailingZeroesAfterDecimal } from '@/utils/trimTrailingZeroesAfterDecimal'
import { zeroAddress } from 'viem'
import GasIcon from '@/components/icons/GasIcon'
import { HoverTooltip } from './HoverTooltip'
import { getParsedBalance } from '@/utils/getParsedBalance'

const handleFocusOnBridgeInput = () => {
inputRef.current?.focus()
Expand All @@ -34,7 +36,7 @@ export const PortfolioTokenAsset = ({
}: PortfolioTokenAssetProps) => {
const dispatch = useAppDispatch()
const { fromChainId, fromToken } = useBridgeState()
const { icon, symbol, decimals } = token
const { icon, symbol, decimals, addresses } = token

const tokenDecimals = _.isNumber(decimals)
? decimals
Expand All @@ -58,6 +60,8 @@ export const PortfolioTokenAsset = ({
)
}, [token, balance, portfolioChainId])

const isBridgeableGasToken = addresses[portfolioChainId] === zeroAddress

return (
<div
id="portfolio-token-asset"
Expand All @@ -73,15 +77,32 @@ export const PortfolioTokenAsset = ({
pl-2 pr-4 py-2 cursor-pointer rounded
hover:bg-surface active:opacity-70
`}
title={`${parsedBalanceLong} ${symbol}`}
>
<Image
loading="lazy"
alt={`${symbol} img`}
className="w-6 h-6 rounded-md"
src={icon}
/>
{parsedBalance} {symbol}
<HoverTooltip
hoverContent={
<div className="whitespace-nowrap">
{parsedBalanceLong} {symbol}
</div>
}
>
<div>
{parsedBalance} {symbol}
</div>
</HoverTooltip>

{isBridgeableGasToken ? (
<HoverTooltip
hoverContent={<div className="whitespace-nowrap">Gas token</div>}
>
<GasIcon className="pt-0.5 m-auto fill-secondary" />
</HoverTooltip>
) : null}
</div>
<PortfolioAssetActionButton
selectCallback={handleFromSelectionCallback}
Expand All @@ -91,14 +112,3 @@ export const PortfolioTokenAsset = ({
</div>
)
}

const getParsedBalance = (
balance: bigint,
decimals: number,
places?: number
) => {
const formattedBalance = formatBigIntToString(balance, decimals, places)
const verySmallBalance = balance > 0n && hasOnlyZeroes(formattedBalance)

return verySmallBalance ? '< 0.001' : formattedBalance
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
import { useState } from 'react'
import Image from 'next/image'
import { TokenAndBalance } from '@/utils/actions/fetchPortfolioBalances'
import { HoverTooltip } from './HoverTooltip'

export const PortfolioTokenVisualizer = ({
portfolioTokens,
}: {
portfolioTokens: TokenAndBalance[]
}) => {
const [isT1Hovered, setIsT1Hovered] = useState<boolean>(false)
const [isT2Hovered, setIsT2Hovered] = useState<boolean>(false)
const [isT3Hovered, setIsT3Hovered] = useState<boolean>(false)

const hasNoTokens: boolean =
!portfolioTokens || (portfolioTokens && portfolioTokens.length === 0)
const hasOneToken: boolean = portfolioTokens && portfolioTokens.length > 0
Expand Down Expand Up @@ -39,95 +35,71 @@ export const PortfolioTokenVisualizer = ({
>
{hasOneToken && (
<div>
<Image
loading="lazy"
className="w-6 h-6 rounded-md"
alt={`${portfolioTokens[0].token.symbol} img`}
src={portfolioTokens[0].token.icon}
onMouseEnter={() => setIsT1Hovered(true)}
onMouseLeave={() => setIsT1Hovered(false)}
/>
<div className="relative">
<HoverContent isHovered={isT1Hovered}>
<HoverTooltip
hoverContent={
<div className="whitespace-nowrap">
{portfolioTokens[0]?.parsedBalance}{' '}
{portfolioTokens[0]?.token.symbol}
</div>
</HoverContent>
</div>
}
>
<Image
loading="lazy"
className="w-6 h-6 rounded-md"
alt={`${portfolioTokens[0].token.symbol} img`}
src={portfolioTokens[0].token.icon}
/>
</HoverTooltip>
</div>
)}

{hasOnlyOneToken && (
<div className="text-white whitespace-nowrap">
{portfolioTokens[0].parsedBalance} {portfolioTokens[0].token.symbol}
</div>
)}

{hasTwoTokens && (
<div>
<Image
loading="lazy"
className="w-6 h-6 rounded-md"
alt={`${portfolioTokens[1].token.symbol} img`}
src={portfolioTokens[1].token.icon}
onMouseEnter={() => setIsT2Hovered(true)}
onMouseLeave={() => setIsT2Hovered(false)}
/>
<div className="relative">
<HoverContent isHovered={isT2Hovered}>
<HoverTooltip
hoverContent={
<div className="whitespace-nowrap">
{portfolioTokens[1]?.parsedBalance}{' '}
{portfolioTokens[1]?.token.symbol}
</div>
</HoverContent>
</div>
}
>
<Image
loading="lazy"
className="w-6 h-6 rounded-md"
alt={`${portfolioTokens[1].token.symbol} img`}
src={portfolioTokens[1].token.icon}
/>
</HoverTooltip>
</div>
)}

{numOverTwoTokens > 0 && (
<div
className="text-white"
onMouseEnter={() => setIsT3Hovered(true)}
onMouseLeave={() => setIsT3Hovered(false)}
>
+ {numOverTwoTokens}
<div className="relative inline-block">
<HoverTooltip
hoverContent={portfolioTokens?.map(
(token: TokenAndBalance, key: number) => {
if (key > 1) {
const tokenSymbol = token.token.symbol
const balance = token.parsedBalance
return (
<div className="whitespace-nowrap" key={key}>
{balance} {tokenSymbol}
</div>
)
}
}
)}
>
<div className="text-white">+ {numOverTwoTokens}</div>
</HoverTooltip>
</div>
)}
<div className="relative inline-block">
<HoverContent isHovered={isT3Hovered}>
{portfolioTokens?.map((token: TokenAndBalance, key: number) => {
if (key > 1) {
const tokenSymbol = token.token.symbol
const balance = token.parsedBalance
return (
<div className="whitespace-nowrap" key={key}>
{balance} {tokenSymbol}
</div>
)
}
})}
</HoverContent>
</div>
</div>
)
}

export const HoverContent = ({
isHovered,
children,
}: {
isHovered: boolean
children: React.ReactNode
}) => {
if (isHovered) {
return (
<div
className={`
absolute z-50 hover-content p-2 text-white
border border-solid border-[#252537]
bg-[#101018] rounded-md text-left
`}
>
{children}
</div>
)
}
}
Loading
Loading