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.735.0 #8595

Merged
merged 14 commits into from
Jan 16, 2025
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
1 change: 1 addition & 0 deletions .env.base
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ REACT_APP_FEATURE_PHANTOM_WALLET=true
REACT_APP_FEATURE_THOR_FREE_FEES=true
REACT_APP_FEATURE_LIMIT_ORDERS=false
REACT_APP_FEATURE_NEW_TRADE_FLOW=true
REACT_APP_FEATURE_NEW_WALLET_FLOW=false

# absolute URL prefix
REACT_APP_ABSOLUTE_URL_PREFIX=https://app.shapeshift.com
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@
"@shapeshiftoss/utils": "workspace:^",
"@sniptt/monads": "^0.5.10",
"@tanstack/react-query": "^5.52.0",
"@tanstack/react-table": "^8.20.6",
"@tanstack/react-virtual": "^3.11.2",
"@uniswap/sdk": "^3.0.3",
"@uniswap/sdk-core": "^5.3.1",
"@uniswap/v3-sdk": "^3.13.1",
Expand Down
3 changes: 3 additions & 0 deletions packages/caip/src/adapters/coingecko/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
gnosisChainId,
optimismChainId,
polygonChainId,
solanaChainId,
thorchainChainId,
} from '../../constants'
import * as adapters from './generated'
Expand Down Expand Up @@ -141,6 +142,8 @@ export const coingeckoAssetPlatformToChainId = (
return cosmosChainId
case CoingeckoAssetPlatform.Thorchain:
return thorchainChainId
case CoingeckoAssetPlatform.Solana:
return solanaChainId
default:
return undefined
}
Expand Down
47 changes: 11 additions & 36 deletions packages/swapper/src/swappers/CowSwapper/endpoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,10 @@ import type {
TradeRate,
} from '../../types'
import { SwapperName } from '../../types'
import {
checkSafeTransactionStatus,
createDefaultStatusResponse,
getHopByIndex,
isExecutableTradeQuote,
} from '../../utils'
import { checkSafeTransactionStatus, getHopByIndex, isExecutableTradeQuote } from '../../utils'
import { getCowSwapTradeQuote } from './getCowSwapTradeQuote/getCowSwapTradeQuote'
import { getCowSwapTradeRate } from './getCowSwapTradeRate/getCowSwapTradeRate'
import type { CowSwapGetTradesResponse, CowSwapGetTransactionsResponse } from './types'
import type { CowSwapGetTradesResponse } from './types'
import { cowService } from './utils/cowService'
import { deductAffiliateFeesFromAmount, deductSlippageFromAmount } from './utils/helpers/helpers'

Expand Down Expand Up @@ -184,38 +179,18 @@ export const cowApi: SwapperApi = {
const { data: trades } = maybeTradesResponse.unwrap()
const buyTxHash = trades[0]?.txHash

if (!buyTxHash) return createDefaultStatusResponse(undefined)

const maybeGetOrdersResponse = await cowService.get<CowSwapGetTransactionsResponse>(
`${config.REACT_APP_COWSWAP_BASE_URL}/${network}/api/v1/transactions/${buyTxHash}/orders`,
)

if (maybeGetOrdersResponse.isErr()) throw maybeGetOrdersResponse.unwrapErr()

const {
data: [{ status: rawStatus }],
} = maybeGetOrdersResponse.unwrap()

// https://api.cow.fi/docs/#/default/get_api_v1_orders__UID_
const status = (() => {
switch (rawStatus) {
case 'fulfilled':
return TxStatus.Confirmed
case 'presignaturePending':
case 'open':
return TxStatus.Pending
case 'cancelled':
case 'expired':
return TxStatus.Failed
default:
return TxStatus.Unknown
if (buyTxHash) {
return {
status: TxStatus.Confirmed,
buyTxHash,
message: 'fulfilled',
}
})()
}

return {
status,
buyTxHash,
message: rawStatus,
status: TxStatus.Pending,
buyTxHash: undefined,
message: 'open',
}
},
}
7 changes: 5 additions & 2 deletions packages/swapper/src/swappers/LifiSwapper/endpoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,8 @@ export const lifiApi: SwapperApi = {

const statusResponse = await response.json()

const receiving: ExtendedTransactionInfo | undefined = statusResponse.receiving

const status = (() => {
switch (statusResponse.status) {
case 'DONE':
Expand All @@ -301,8 +303,9 @@ export const lifiApi: SwapperApi = {
})()

return {
status,
buyTxHash: (statusResponse.receiving as ExtendedTransactionInfo)?.txHash,
// We have an out Tx hash (either same or cross-chain) for this step, so we consider the Tx (effectively, the step) confirmed
status: receiving?.txHash ? TxStatus.Confirmed : status,
buyTxHash: receiving?.txHash,
message: statusResponse.substatusMessage,
}
},
Expand Down
13 changes: 8 additions & 5 deletions packages/swapper/src/swappers/ThorchainSwapper/endpoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -652,18 +652,21 @@ export const thorchainApi: SwapperApi = {

const buyTxHash = parseThorBuyTxHash(txHash, lastOutTx)

// If thornode says the tx is done, its done ;)
// We discard txData errors because we can derive the status before it returns a success response.
if (!('error' in txData) && txData.observed_tx?.status === 'done') {
const hasOutboundL1Tx = lastOutTx !== undefined && lastOutTx.chain !== 'THOR'
const hasOutboundRuneTx = lastOutTx !== undefined && lastOutTx.chain === 'THOR'

// We consider the transaction confirmed as soon as we have a buyTxHash
// For UTXOs, this means that the swap will be confirmed as soon as Txs hit the mempool
// Which is actually correct, as we update UTXO balances optimistically
if (!('error' in txData) && buyTxHash && (hasOutboundL1Tx || hasOutboundRuneTx)) {
return {
buyTxHash,
status: TxStatus.Confirmed,
message: undefined,
}
}

const hasOutboundTx = lastOutTx !== undefined && lastOutTx.chain !== 'THOR'
const message = getLatestThorTxStatusMessage(txStatusData, hasOutboundTx)
const message = getLatestThorTxStatusMessage(txStatusData, hasOutboundL1Tx)
return {
buyTxHash,
status: TxStatus.Pending,
Expand Down
5 changes: 4 additions & 1 deletion src/assets/translations/en/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"overview": "Overview",
"getStarted": "Get Started",
"connectWallet": "Connect Wallet",
"pairing": "Pairing",
"connectWalletToGetStartedWith": "Connect a wallet to get started with %{feature}",
"connectedWallet": "Connected Wallet",
"connectedWalletSettings": "Wallet Settings",
Expand Down Expand Up @@ -911,7 +912,9 @@
"gasFee": "This is the estimated gas fee to complete this trade.",
"slippageWithAmount": "If the price moves so that you will receive less than %{amount}, your transaction will be reverted. This is the minimum amount you are guaranteed to receive.",
"slippage": "Your transaction will revert if the price changes unfavorably by more than this percentage.",
"noRelatedAssets": "This asset is only available on %{chainDisplayName}"
"noRelatedAssets": "This asset is only available on %{chainDisplayName}",
"chainNotSupportedByWallet": "This chain is not supported by your wallet. Switch to a different wallet to trade this asset.",
"chainNotConnected": "This chain is not connected to your wallet. Connect %{chainDisplayName} to trade this asset."
},
"rates": {
"tags": {
Expand Down
3 changes: 1 addition & 2 deletions src/components/AssetHeader/AssetHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ type AssetHeaderProps = {
const externalLinkIcon = <ExternalLinkIcon />
const displayMdFlex = { base: 'none', md: 'flex' }
const fontSizeMd2xl = { base: 'xl', md: '2xl' }
const pairProps = { showFirst: true }

export const AssetHeader: React.FC<AssetHeaderProps> = ({ assetId, accountId }) => {
const translate = useTranslate()
Expand Down Expand Up @@ -90,7 +89,7 @@ export const AssetHeader: React.FC<AssetHeaderProps> = ({ assetId, accountId })
<PageHeader.Left>
<Display.Desktop>
<Flex alignItems='center' mr='auto' flex={1}>
<AssetIcon assetId={asset.assetId} pairProps={pairProps} />
<AssetIcon assetId={asset.assetId} />
<Flex ml={3} textAlign='left' gap={2} alignItems='center'>
<Heading fontSize={fontSizeMd2xl} lineHeight='shorter'>
{name} {`(${symbol}${asset.id ? ` ${middleEllipsis(asset.id)}` : ''})`}
Expand Down
42 changes: 34 additions & 8 deletions src/components/AssetIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ export const topClipPath =
'polygon( 89.786% 19.645%,89.786% 19.645%,86.937% 16.22%,83.793% 13.067%,80.377% 10.207%,76.708% 7.661%,72.807% 5.449%,68.695% 3.593%,64.394% 2.112%,59.922% 1.029%,55.303% 0.364%,50.555% 0.138%,50.555% 0.138%,49.786% 0.143%,49.019% 0.161%,48.256% 0.191%,47.495% 0.232%,46.738% 0.284%,45.984% 0.347%,45.233% 0.421%,44.485% 0.506%,43.742% 0.601%,43.001% 0.707%,43.001% 0.707%,41.981% 0.968%,41.073% 1.406%,40.279% 1.999%,39.6% 2.725%,39.04% 3.564%,38.599% 4.495%,38.281% 5.496%,38.087% 6.546%,38.018% 7.623%,38.078% 8.707%,38.078% 8.707%,38.109% 8.998%,38.137% 9.29%,38.162% 9.583%,38.184% 9.877%,38.203% 10.172%,38.219% 10.468%,38.231% 10.765%,38.24% 11.062%,38.246% 11.361%,38.247% 11.661%,38.247% 11.661%,37.915% 15.777%,36.953% 19.683%,35.413% 23.324%,33.348% 26.651%,30.811% 29.609%,27.853% 32.146%,24.527% 34.211%,20.885% 35.751%,16.979% 36.713%,12.863% 37.045%,12.863% 37.045%,12.563% 37.043%,12.265% 37.038%,11.967% 37.029%,11.67% 37.017%,11.374% 37.001%,11.079% 36.982%,10.785% 36.96%,10.492% 36.935%,10.2% 36.907%,9.909% 36.876%,9.909% 36.876%,8.825% 36.816%,7.748% 36.884%,6.698% 37.079%,5.697% 37.397%,4.767% 37.838%,3.927% 38.398%,3.201% 39.076%,2.608% 39.871%,2.17% 40.779%,1.909% 41.799%,1.909% 41.799%,1.8% 42.539%,1.702% 43.283%,1.616% 44.031%,1.542% 44.781%,1.48% 45.536%,1.429% 46.293%,1.39% 47.053%,1.362% 47.817%,1.345% 48.584%,1.34% 49.353%,1.34% 49.353%,1.566% 54.101%,2.231% 58.72%,3.315% 63.191%,4.795% 67.493%,6.651% 71.605%,8.863% 75.506%,11.41% 79.175%,14.27% 82.591%,17.423% 85.734%,20.847% 88.584%,20.847% 88.584%,21.163% 88.511%,21.474% 88.423%,21.778% 88.318%,22.075% 88.198%,22.365% 88.061%,22.645% 87.907%,22.916% 87.736%,23.176% 87.549%,23.426% 87.344%,23.663% 87.122%,56.001% 54.784%,88.34% 22.445%,88.34% 22.445%,88.562% 22.208%,88.767% 21.959%,88.954% 21.699%,89.125% 21.428%,89.278% 21.147%,89.415% 20.858%,89.536% 20.561%,89.64% 20.256%,89.729% 19.946%,89.801% 19.63%,89.801% 19.614%,89.786% 19.645% );'
export const squareClipPath =
'polygon( 7.504% 37.56%,7.504% 37.56%,6.521% 37.641%,5.589% 37.874%,4.719% 38.247%,3.925% 38.747%,3.219% 39.363%,2.613% 40.08%,2.12% 40.886%,1.753% 41.769%,1.523% 42.716%,1.444% 43.714%,1.444% 86.791%,1.444% 86.791%,1.602% 88.787%,2.062% 90.681%,2.797% 92.447%,3.782% 94.06%,4.994% 95.494%,6.406% 96.724%,7.994% 97.725%,9.734% 98.471%,11.599% 98.938%,13.565% 99.099%,86.292% 99.099%,86.292% 99.099%,88.258% 98.938%,90.123% 98.471%,91.863% 97.725%,93.451% 96.724%,94.863% 95.494%,96.075% 94.06%,97.06% 92.447%,97.795% 90.681%,98.255% 88.787%,98.413% 86.791%,98.413% 12.945%,98.413% 12.945%,98.255% 10.948%,97.795% 9.054%,97.06% 7.289%,96.075% 5.676%,94.863% 4.242%,93.451% 3.012%,91.863% 2.011%,90.123% 1.264%,88.258% 0.798%,86.292% 0.637%,43.868% 0.637%,43.868% 0.637%,42.885% 0.718%,41.952% 0.951%,41.083% 1.324%,40.289% 1.824%,39.582% 2.439%,38.977% 3.156%,38.484% 3.963%,38.116% 4.846%,37.887% 5.793%,37.807% 6.791%,37.807% 12.945%,37.807% 12.945%,37.49% 16.937%,36.571% 20.725%,35.101% 24.257%,33.13% 27.482%,30.707% 30.35%,27.882% 32.811%,24.706% 34.813%,21.227% 36.305%,17.497% 37.238%,13.565% 37.56%,7.504% 37.56% );'
export const pairIconsClipPath =
'polygon(83% 0%, 100% 0%, 100% 100%, 0% 112%, 0% 105%, 16% 100%, -8% 56%, 3% 28%, 2% 35%, 5% 37%, 6% 36%, 8% 37%, 8% 36%, 12% 34%, 14% 31%, 17% 25%, 20% 0%, 23% 0%, 26% 0%, 29% 0%, 32% 0%, 35% 0%, 37% 0%, 39% 0%, 40% 0%, 41% 0%, 42% 0%, 43% 0%, 43% 0%)'

export type AssetIconProps = {
// Show the network icon instead of the asset icon e.g OP icon instead of ETH for Optimism native asset
Expand Down Expand Up @@ -112,7 +114,9 @@ export const AssetIcon = memo(
asset: _asset,
showNetworkIcon,
src,
pairProps,
pairProps = {
showFirst: true,
},
...rest
}: AssetIconProps) => {
const asset = useAppSelector(state =>
Expand All @@ -129,6 +133,7 @@ export const AssetIcon = memo(
() => <FoxIcon boxSize='16px' color={assetIconColor} />,
[assetIconColor],
)
const feeAsset = useAppSelector(state => selectFeeAssetById(state, nativeAssetId ?? ''))

if (!asset) return <LazyLoadAvatar src={src} bg={assetIconBg} icon={foxIcon} {...rest} />

Expand All @@ -137,14 +142,35 @@ export const AssetIcon = memo(
}

if (asset.icons?.length) {
const showNetwork = feeAsset?.networkIcon || asset.assetId !== feeAsset?.assetId

return (
<PairIcons
icons={asset.icons}
iconSize={rest.size}
iconBoxSize={rest.boxSize}
{...pairProps}
{...rest}
/>
<Center>
<Center position={showNetwork && showNetworkIcon ? 'relative' : 'static'}>
{showNetwork && showNetworkIcon && (
<LazyLoadAvatar
position='absolute'
left='-8%'
top='-8%'
transform='scale(0.4)'
transformOrigin='top left'
icon={foxIcon}
fontSize='inherit'
src={feeAsset?.networkIcon ?? feeAsset?.icon}
size={rest.size}
zIndex={2}
/>
)}
<PairIcons
icons={asset.icons}
iconSize={rest.size}
iconBoxSize={rest.boxSize}
clipPath={showNetwork && showNetworkIcon ? pairIconsClipPath : ''}
{...pairProps}
{...rest}
/>
</Center>
</Center>
)
}

Expand Down
27 changes: 23 additions & 4 deletions src/components/AssetIconWithBadge.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import type { AvatarProps } from '@chakra-ui/react'
import { Box, Center, Image } from '@chakra-ui/react'
import type { AssetId } from '@shapeshiftoss/caip'
import type { Asset } from '@shapeshiftoss/types'
import type { TransferType } from '@shapeshiftoss/unchained-client'
import uniqBy from 'lodash/uniqBy'
import type { PropsWithChildren } from 'react'
import { useMemo } from 'react'
import { LuGlobe } from 'react-icons/lu'
import FlipShadow from 'assets/flip-shadow.svg'
import type { Transfer } from 'hooks/useTxDetails/useTxDetails'
import { selectAssetById } from 'state/slices/selectors'
import { useAppSelector } from 'state/store'

import {
AssetIcon,
Expand All @@ -17,6 +20,9 @@ import {
topClipPath,
} from './AssetIcon'

export const pairIconsBadgeClipPath =
'polygon(83% 0%, 100% 0%, 100% 100%, 0% 112%, 0% 105%, 16% 100%, -8% 56%, 3% 33%, 2% 36%, 5% 37%, 6% 36%, 8% 37%, 11% 45%, 11% 34%, 17% 38%, 18% 37%, 31% 33%, 34% 17%, 34% 0%, 23% 0%, 26% 0%, 29% 0%, 32% 0%, 35% 0%, 37% 0%, 39% 0%, 40% 0%, 41% 0%, 42% 0%, 43% 0%, 43% 0%)'

type AssetIconWithBadgeProps = {
size?: AvatarProps['size']
assetId?: AssetId
Expand Down Expand Up @@ -47,9 +53,18 @@ const useTransferData = (transfersByType?: Record<TransferType, Transfer[]>) =>
return { transfers, isNft }
}

const getClipPath = (index: number, totalTransfers: number, isNft: boolean) => {
const getClipPath = (
index: number,
totalTransfers: number,
isNft: boolean,
asset: Asset | undefined,
) => {
if (isNft) return squareClipPath
if (totalTransfers === 1) return defaultClipPath
if (totalTransfers === 1) {
if (asset?.icons && asset.icons.length > 1) return pairIconsBadgeClipPath

return defaultClipPath
}
if (index === 1) return bottomClipPath
return topClipPath
}
Expand All @@ -63,6 +78,7 @@ const TransferIcon: React.FC<{
}> = ({ transfer, index, totalTransfers, isNft, size }) => {
const isSecondTransfer = index === 1
const shouldShowShadow = isSecondTransfer && totalTransfers > 1
const asset = useAppSelector(state => selectAssetById(state, transfer.assetId))

if (totalTransfers > 2 && index === 2) return null // Skip third+ transfers

Expand All @@ -82,7 +98,7 @@ const TransferIcon: React.FC<{
<AssetIcon
showNetworkIcon={false}
assetId={transfer.assetId}
clipPath={getClipPath(index, totalTransfers, isNft)}
clipPath={getClipPath(index, totalTransfers, isNft, asset)}
name={transfer.asset.name}
size={size}
position={shouldShowShadow ? 'absolute' : 'static'}
Expand All @@ -104,6 +120,7 @@ export const AssetIconWithBadge: React.FC<AssetIconWithBadgeProps> = ({
}) => {
const { transfers, isNft } = useTransferData(transfersByType)
const webIcon = <LuGlobe />
const asset = useAppSelector(state => selectAssetById(state, assetId ?? ''))

const renderContent = () => {
if (assetId && secondaryAssetId) {
Expand Down Expand Up @@ -144,7 +161,9 @@ export const AssetIconWithBadge: React.FC<AssetIconWithBadgeProps> = ({
<AssetIcon
showNetworkIcon={false}
assetId={assetId}
clipPath={defaultClipPath}
clipPath={
asset?.icons && asset.icons.length > 1 ? pairIconsBadgeClipPath : defaultClipPath
}
size={size}
/>
)
Expand Down
Loading
Loading