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

chore: release v1.648.0 #7431

Merged
merged 6 commits into from
Jul 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 2 additions & 3 deletions scripts/generateAssetData/bnbsmartchain/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@ import uniqBy from 'lodash/uniqBy'

import { bnbsmartchain } from '../baseAssets'
import * as coingecko from '../coingecko'
// import { getPortalTokens } from '../utils/portals'
import { getPortalTokens } from '../utils/portals'

export const getAssets = async (): Promise<Asset[]> => {
const results = await Promise.allSettled([
coingecko.getAssets(bscChainId),
// TODO(gomes): revert me back, there are 10k+ assets for BSC = problems
[], // getPortalTokens(bnbsmartchain),
getPortalTokens(bnbsmartchain),
])

const [assets, portalsAssets] = results.map(result => {
Expand Down
5 changes: 2 additions & 3 deletions scripts/generateAssetData/ethereum/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import uniqBy from 'lodash/uniqBy'
import { ethereum } from '../baseAssets'
import * as coingecko from '../coingecko'
import { generateTrustWalletUrl } from '../generateTrustWalletUrl/generateTrustWalletUrl'
// import { getPortalTokens } from '../utils/portals'
import { getPortalTokens } from '../utils/portals'
import { getIdleTokens } from './idleVaults'
import { getUniswapV2Pools } from './uniswapV2Pools'
// Yearn SDK is currently rugged upstream
Expand Down Expand Up @@ -40,8 +40,7 @@ export const getAssets = async (): Promise<Asset[]> => {
// getUnderlyingVaultTokens(),
getUniswapV2Pools(),
getIdleTokens(),
// TODO(gomes): revert me back, there are 10k+ assets for Ethereum = problems
[], // getPortalTokens(ethereum),
getPortalTokens(ethereum),
])

const [ethTokens, uniV2PoolTokens, idleTokens, portalsAssets] = results.map(result => {
Expand Down
6 changes: 5 additions & 1 deletion scripts/generateAssetData/utils/portals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ export const fetchPortalsTokens = async (

const params = {
limit: '250',
// Minimum 1000 bucks liquidity if asset is a LP token
minLiquidity: '1000',
// Minimum 1% APY if asset is a LP token
minApy: '1',
networks: [network],
page: page.toString(),
}
Expand Down Expand Up @@ -132,7 +136,7 @@ export const getPortalTokens = async (nativeAsset: Asset): Promise<Asset[]> => {
...explorerData,
color: colorMap[assetId] ?? '#FFFFFF',
icon: token.images?.[0],
icons: token.images,
...(token.images?.length && { icons: token.images }),
name: token.name,
precision: Number(token.decimals),
symbol: token.symbol,
Expand Down
3 changes: 2 additions & 1 deletion src/assets/translations/en/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -945,7 +945,7 @@
},
"approvalTitle": "Token allowance approval",
"resetTitle": "Token allowance reset",
"assetSummaryDescription": "%{amountFiatFormatted} on %{chainName}",
"fiatAmountOnChain": "%{amountFiatFormatted} on %{chainName}",
"quote": {
"cantSetSlippage": "We are unable to set a custom slippage (%{userSlippageFormatted}) for %{swapperName}",
"slippage": "Slippage: %{slippageFormatted}"
Expand Down Expand Up @@ -1776,6 +1776,7 @@
"SegwitNativeTooltip": "Recommended for most users. Only use the other addresses if you know what they are for",
"btcFormat": "BTC format",
"assetUnavailable": "Market data for this asset isn't available yet. We're working on it, hang tight!",
"customAsset": "This is a custom imported asset. Market data may not be accurate.",
"loading": "Fetching price history, hang tight...",
"maxTotalSupply": "Max Total Supply",
"availableSupply": "Available Supply",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ import { getChainAdapterManager } from 'context/PluginProvider/chainAdapterSingl
import { useLocaleFormatter } from 'hooks/useLocaleFormatter/useLocaleFormatter'
import { bn } from 'lib/bignumber/bignumber'
import { fromBaseUnit } from 'lib/math'
import { selectMarketDataUserCurrency } from 'state/slices/selectors'
import {
selectIsAssetWithoutMarketData,
selectMarketDataUserCurrency,
} from 'state/slices/selectors'
import { useAppSelector } from 'state/store'

import { StepperStep } from './StepperStep'
Expand All @@ -27,6 +30,9 @@ export const AssetSummaryStep = ({
number: { toCrypto, toFiat },
} = useLocaleFormatter()
const marketDataUserCurrency = useAppSelector(selectMarketDataUserCurrency)
const isAssetWithoutMarketData = useAppSelector(state =>
selectIsAssetWithoutMarketData(state, asset.assetId),
)

const sellAmountCryptoPrecision = useMemo(
() => fromBaseUnit(amountCryptoBaseUnit, asset.precision),
Expand All @@ -41,7 +47,7 @@ export const AssetSummaryStep = ({
const amountFiatFormatted = useMemo(() => {
const sellAssetRateUserCurrency = marketDataUserCurrency[asset.assetId]?.price ?? '0'
return toFiat(bn(sellAmountCryptoPrecision).times(sellAssetRateUserCurrency).toString())
}, [marketDataUserCurrency, sellAmountCryptoPrecision, toFiat, asset.assetId])
}, [marketDataUserCurrency, asset.assetId, toFiat, sellAmountCryptoPrecision])

const chainName = useMemo(() => {
const chainAdapterManager = getChainAdapterManager()
Expand All @@ -55,7 +61,11 @@ export const AssetSummaryStep = ({
return (
<StepperStep
title={amountCryptoFormatted}
description={translate('trade.assetSummaryDescription', { amountFiatFormatted, chainName })}
description={
isAssetWithoutMarketData
? undefined
: translate('trade.fiatAmountOnChain', { amountFiatFormatted, chainName })
}
stepIndicator={assetIcon}
isLastStep={isLastStep}
/>
Expand Down
13 changes: 10 additions & 3 deletions src/components/MultiHopTrade/components/TradeAmountInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ import { PercentOptionsButtonGroup } from 'components/DeFi/components/PercentOpt
import { useLocaleFormatter } from 'hooks/useLocaleFormatter/useLocaleFormatter'
import { bnOrZero } from 'lib/bignumber/bignumber'
import { allowedDecimalSeparators } from 'state/slices/preferencesSlice/preferencesSlice'
import { selectAssetById, selectMarketDataByAssetIdUserCurrency } from 'state/slices/selectors'
import {
selectAssetById,
selectIsAssetWithoutMarketData,
selectMarketDataByAssetIdUserCurrency,
} from 'state/slices/selectors'
import { useAppSelector } from 'state/store'
import { colors } from 'theme/colors'

Expand Down Expand Up @@ -170,6 +174,9 @@ export const TradeAmountInput: React.FC<TradeAmountInputProps> = memo(
const assetMarketDataUserCurrency = useAppSelector(state =>
selectMarketDataByAssetIdUserCurrency(state, assetId),
)
const isAssetWithoutMarketData = useAppSelector(state =>
selectIsAssetWithoutMarketData(state, assetId),
)

// Local controller in case consumers don't have a form context, which is the case for all current consumers currently except RFOX
const _methods = useForm<TradeAmountInputFormValues>({
Expand Down Expand Up @@ -348,7 +355,7 @@ export const TradeAmountInput: React.FC<TradeAmountInputProps> = memo(
/>
</Skeleton>
{RightComponent && <RightComponent assetId={assetId} />}
{layout === 'inline' && showFiatAmount && !hideAmounts && (
{layout === 'inline' && showFiatAmount && !isAssetWithoutMarketData && !hideAmounts && (
<Button
onClick={toggleIsFiat}
size='sm'
Expand All @@ -374,7 +381,7 @@ export const TradeAmountInput: React.FC<TradeAmountInputProps> = memo(
alignItems='center'
display={hideAmounts ? 'none' : 'flex'}
>
{showFiatAmount && (
{showFiatAmount && !isAssetWithoutMarketData && (
<Flex alignItems='center' gap={2}>
<Button
onClick={toggleIsFiat}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
selectInputBuyAsset,
selectInputSellAmountCryptoPrecision,
selectInputSellAsset,
selectIsAssetWithoutMarketData,
selectMarketDataByAssetIdUserCurrency,
selectMarketDataByFilter,
selectUserSlippagePercentageDecimal,
Expand Down Expand Up @@ -117,12 +118,22 @@ export const TradeQuote: FC<TradeQuoteProps> = memo(
[quote],
)

const isSellAssetWithoutMarketData = useAppSelector(state =>
selectIsAssetWithoutMarketData(state, sellAsset.assetId),
)
const isBuyAssetWithoutMarketData = useAppSelector(state =>
selectIsAssetWithoutMarketData(state, buyAsset.assetId),
)
const isTradingWithoutMarketData = isSellAssetWithoutMarketData || isBuyAssetWithoutMarketData

const totalReceiveAmountFiatPrecision = useMemo(
() =>
bn(totalReceiveAmountCryptoPrecision)
.times(buyAssetMarketData.price ?? 0)
.toString(),
[buyAssetMarketData.price, totalReceiveAmountCryptoPrecision],
isTradingWithoutMarketData
? undefined
: bn(totalReceiveAmountCryptoPrecision)
.times(buyAssetMarketData.price ?? 0)
.toString(),
[buyAssetMarketData.price, isTradingWithoutMarketData, totalReceiveAmountCryptoPrecision],
)

const handleQuoteSelection = useCallback(() => {
Expand Down Expand Up @@ -162,10 +173,10 @@ export const TradeQuote: FC<TradeQuoteProps> = memo(

const hasAmountWithPositiveReceive =
isAmountEntered &&
!hasNegativeRatio &&
(!hasNegativeRatio || isTradingWithoutMarketData) &&
bnOrZero(totalReceiveAmountCryptoPrecision).isGreaterThan(0)

const tag: JSX.Element = useMemo(() => {
const tag: JSX.Element | null = useMemo(() => {
const error = errors?.[0]
const defaultError = { error: TradeQuoteValidationError.UnknownError }

Expand All @@ -192,18 +203,13 @@ export const TradeQuote: FC<TradeQuoteProps> = memo(
</Tag>
)
default:
return (
return quoteOverallDifferenceDecimalPercentage !== undefined ? (
<Tooltip label={translate('trade.tooltip.overallPercentageDifference')}>
<Tag size='sm'>
{quoteOverallDifferenceDecimalPercentage !== undefined && (
<Amount.Percent
value={quoteOverallDifferenceDecimalPercentage ?? 0}
autoColor={false}
/>
)}
<Amount.Percent value={quoteOverallDifferenceDecimalPercentage} autoColor={false} />
</Tag>
</Tooltip>
)
) : null
}
}, [
errors,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export type TradeQuoteContentProps = {
buyAsset: Asset
isBest: boolean
numHops: number
totalReceiveAmountFiatPrecision: string
totalReceiveAmountFiatPrecision: string | undefined
hasAmountWithPositiveReceive: boolean
totalReceiveAmountCryptoPrecision: string
quoteDifferenceDecimalPercentage: number | undefined
Expand Down Expand Up @@ -128,12 +128,14 @@ export const TradeQuoteContent = ({
)}
</Flex>
<Skeleton isLoaded={!isLoading}>
<Amount.Fiat
color='text.subtle'
value={totalReceiveAmountFiatPrecision}
prefix='≈'
lineHeight={1}
/>
{totalReceiveAmountFiatPrecision ? (
<Amount.Fiat
color='text.subtle'
value={totalReceiveAmountFiatPrecision}
prefix='≈'
lineHeight={1}
/>
) : null}
</Skeleton>
</Flex>
</CardBody>
Expand Down
2 changes: 1 addition & 1 deletion src/components/TradeAssetSearch/TradeAssetSearch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ import {
} from 'state/slices/selectors'
import { useAppSelector } from 'state/store'

import { CustomAssetAcknowledgement } from './components/CustomAssetAcknowledgement'
import { DefaultAssetList } from './components/DefaultAssetList'
import { SearchTermAssetList } from './components/SearchTermAssetList'
import { CustomAssetAcknowledgement } from './hooks/CustomAssetAcknowledgement'
import { useGetPopularAssetsQuery } from './hooks/useGetPopularAssetsQuery'

const buttonProps = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { getMixPanel } from 'lib/mixpanel/mixPanelSingleton'
import { MixPanelEvent } from 'lib/mixpanel/types'
import { middleEllipsis } from 'lib/utils'
import { assets as assetsSlice } from 'state/slices/assetsSlice/assetsSlice'
import { marketData as marketDataSlice } from 'state/slices/marketDataSlice/marketDataSlice'
import { marketApi } from 'state/slices/marketDataSlice/marketDataSlice'
import { useAppDispatch } from 'state/store'

const externalLinkIcon = <ExternalLinkIcon paddingLeft={'4px'} />
Expand Down Expand Up @@ -74,14 +74,8 @@ export const CustomAssetAcknowledgement: React.FC<CustomAssetAcknowledgementProp

// Add asset to the store
dispatch(assetsSlice.actions.upsertAsset(asset))

// Add market data to the store
dispatch(
marketDataSlice.actions.setCryptoMarketData({
[asset.assetId]: { price: '0', marketCap: '0', volume: '0', changePercent24Hr: 0 },
}),
)

// Use the market API to get the market data for the custom asset
dispatch(marketApi.endpoints.findByAssetIds.initiate([asset.assetId]))
// Once the custom asset is in the store, proceed as if it was a normal asset
handleAssetClick(asset)
}, [dispatch, handleAssetClick, asset])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { isEvmChainId } from '@shapeshiftoss/chain-adapters'
import type { Asset } from '@shapeshiftoss/types'
import { makeAsset, type MinimalAsset } from '@shapeshiftoss/utils'
import { useMemo } from 'react'
import { ALCHEMY_SUPPORTED_CHAIN_IDS } from 'lib/alchemySdkInstance'
import { isSome } from 'lib/utils'
import {
selectAssetsSortedByName,
Expand All @@ -29,7 +30,7 @@ export const SearchTermAssetList = ({
activeChainId,
searchString,
allowWalletUnsupportedAssets,
onAssetClick,
onAssetClick: handleAssetClick,
onImportClick,
}: SearchTermAssetListProps) => {
const assets = useAppSelector(selectAssetsSortedByName)
Expand All @@ -40,9 +41,14 @@ export const SearchTermAssetList = ({
[activeChainId, walletConnectedChainIds],
)
const walletSupportedEvmChainIds = useMemo(() => chainIds.filter(isEvmChainId), [chainIds])
const customTokenSupportedChainIds = useMemo(
() =>
walletSupportedEvmChainIds.filter(chainId => ALCHEMY_SUPPORTED_CHAIN_IDS.includes(chainId)),
[walletSupportedEvmChainIds],
)
const { data: customTokens, isLoading: isLoadingCustomTokens } = useGetCustomTokensQuery({
contractAddress: searchString,
chainIds: walletSupportedEvmChainIds,
chainIds: customTokenSupportedChainIds,
})

const assetsForChain = useMemo(() => {
Expand All @@ -59,30 +65,28 @@ export const SearchTermAssetList = ({

const customAssets: Asset[] = useMemo(
() =>
customTokens
? customTokens
.filter(isSome)
.map(metaData => {
const { name, symbol, decimals, logo } = metaData
// If we can't get all the information we need to create an Asset, don't allow the custom token
if (!name || !symbol || !decimals) return null
const assetId = toAssetId({
chainId: metaData.chainId,
assetNamespace:
metaData.chainId === bscChainId ? ASSET_NAMESPACE.bep20 : ASSET_NAMESPACE.erc20,
assetReference: metaData.contractAddress,
})
const minimalAsset: MinimalAsset = {
assetId,
name,
symbol,
precision: decimals,
icon: logo ?? undefined,
}
return makeAsset(assetsById, minimalAsset)
})
.filter(isSome)
: [],
(customTokens ?? [])
.map(metaData => {
if (!metaData) return null
const { name, symbol, decimals, logo } = metaData
// If we can't get all the information we need to create an Asset, don't allow the custom token
if (!name || !symbol || !decimals) return null
const assetId = toAssetId({
chainId: metaData.chainId,
assetNamespace:
metaData.chainId === bscChainId ? ASSET_NAMESPACE.bep20 : ASSET_NAMESPACE.erc20,
assetReference: metaData.contractAddress,
})
const minimalAsset: MinimalAsset = {
assetId,
name,
symbol,
precision: decimals,
icon: logo ?? undefined,
}
return makeAsset(assetsById, minimalAsset)
})
.filter(isSome),
[assetsById, customTokens],
)

Expand Down Expand Up @@ -110,7 +114,7 @@ export const SearchTermAssetList = ({
groupCounts={groupCounts}
hideZeroBalanceAmounts={true}
groupIsLoading={groupIsLoading}
onAssetClick={onAssetClick}
onAssetClick={handleAssetClick}
onImportClick={onImportClick}
/>
)
Expand Down
Loading
Loading