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.671.0 #7684

Merged
merged 4 commits into from
Sep 4, 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
26 changes: 13 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,19 +91,19 @@
"@shapeshiftoss/caip": "workspace:^",
"@shapeshiftoss/chain-adapters": "workspace:^",
"@shapeshiftoss/errors": "workspace:^",
"@shapeshiftoss/hdwallet-coinbase": "1.54.1",
"@shapeshiftoss/hdwallet-core": "1.54.1",
"@shapeshiftoss/hdwallet-keepkey": "1.54.1",
"@shapeshiftoss/hdwallet-keepkey-webusb": "1.54.1",
"@shapeshiftoss/hdwallet-keplr": "1.54.1",
"@shapeshiftoss/hdwallet-ledger": "1.54.1",
"@shapeshiftoss/hdwallet-ledger-webusb": "1.54.1",
"@shapeshiftoss/hdwallet-metamask": "1.54.1",
"@shapeshiftoss/hdwallet-native": "1.54.1",
"@shapeshiftoss/hdwallet-native-vault": "1.54.1",
"@shapeshiftoss/hdwallet-shapeshift-multichain": "1.54.1",
"@shapeshiftoss/hdwallet-walletconnectv2": "1.54.1",
"@shapeshiftoss/hdwallet-xdefi": "1.54.1",
"@shapeshiftoss/hdwallet-coinbase": "1.54.2",
"@shapeshiftoss/hdwallet-core": "1.54.2",
"@shapeshiftoss/hdwallet-keepkey": "1.54.2",
"@shapeshiftoss/hdwallet-keepkey-webusb": "1.54.2",
"@shapeshiftoss/hdwallet-keplr": "1.54.2",
"@shapeshiftoss/hdwallet-ledger": "1.54.2",
"@shapeshiftoss/hdwallet-ledger-webusb": "1.54.2",
"@shapeshiftoss/hdwallet-metamask": "1.54.2",
"@shapeshiftoss/hdwallet-native": "1.54.2",
"@shapeshiftoss/hdwallet-native-vault": "1.54.2",
"@shapeshiftoss/hdwallet-shapeshift-multichain": "1.54.2",
"@shapeshiftoss/hdwallet-walletconnectv2": "1.54.2",
"@shapeshiftoss/hdwallet-xdefi": "1.54.2",
"@shapeshiftoss/swapper": "workspace:^",
"@shapeshiftoss/types": "workspace:^",
"@shapeshiftoss/unchained-client": "workspace:^",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
import { getRate, makeSwapErrorRight } from '../../../utils'
import { getTreasuryAddressFromChainId, isNativeEvmAsset } from '../../utils/helpers/helpers'
import { chainIdToPortalsNetwork } from '../constants'
import { fetchPortalsTradeOrder } from '../utils/fetchPortalsTradeOrder'
import { fetchPortalsTradeEstimate, fetchPortalsTradeOrder } from '../utils/fetchPortalsTradeOrder'
import { getDummyQuoteParams, isSupportedChainId } from '../utils/helpers'

export async function getPortalsTradeQuote(
Expand Down Expand Up @@ -120,10 +120,24 @@ export async function getPortalsTradeQuote(
validate: true,
swapperConfig,
}).catch(async e => {
// If validation fails, fire two more quotes:
// 1. a quote with validation enabled, but using a well-funded address to get a rough gasLimit estimate
// 2. another quote with validation disabled, to get an actual quote
// If validation fails, fire 3 more quotes:
// 1. a quote estimate (does not require approval) to get the optimal slippage tolerance
// 2. a quote with validation enabled, but using a well-funded address to get a rough gasLimit estimate
// 3. another quote with validation disabled, to get an actual quote (using the user slippage, or the optimal from the estimate)
console.info('failed to get Portals quote with validation enabled', e)

// Use the quote estimate endpoint to get the optimal slippage tolerance
const quoteEstimateResponse = await fetchPortalsTradeEstimate({
sender: sendAddress,
inputToken,
outputToken,
inputAmount: sellAmountIncludingProtocolFeesCryptoBaseUnit,
swapperConfig,
}).catch(e => {
console.info('failed to get Portals quote estimate', e)
return undefined
})

const dummyQuoteParams = getDummyQuoteParams(sellAsset.chainId)

const dummySellAssetAddress = fromAssetId(dummyQuoteParams.sellAssetId).assetReference
Expand All @@ -132,6 +146,7 @@ export async function getPortalsTradeQuote(
const dummyInputToken = `${portalsNetwork}:${dummySellAssetAddress}`
const dummyOutputToken = `${portalsNetwork}:${dummyBuyAssetAddress}`

// Use a dummy request to the portal endpoint to get a rough gasLimit estimate
const dummyOrderResponse = await fetchPortalsTradeOrder({
sender: dummyQuoteParams.accountAddress,
inputToken: dummyInputToken,
Expand All @@ -158,6 +173,7 @@ export async function getPortalsTradeQuote(
inputAmount: sellAmountIncludingProtocolFeesCryptoBaseUnit,
slippageTolerancePercentage:
userSlippageTolerancePercentageDecimalOrDefault ??
quoteEstimateResponse?.context.slippageTolerancePercentage ??
bnOrZero(getDefaultSlippageDecimalPercentageForSwapper(SwapperName.Portals))
.times(100)
.toNumber(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ type PortalsTradeOrderParams = {
swapperConfig: SwapperConfig
}

type PortalsTradeOrderEstimateParams = Omit<PortalsTradeOrderParams, 'partner' | 'validate'>

type PortalsTradeOrderResponse = {
context: {
orderId: string
Expand Down Expand Up @@ -50,6 +52,25 @@ type PortalsTradeOrderResponse = {
gasLimit: string
}
}

type PortalsTradeOrderEstimateResponse = {
outputAmount: string
minOutputAmount: string
outputToken: string
outputTokenDecimals: number
context: {
slippageTolerancePercentage: number
inputAmount: string
inputAmountUsd: number
inputToken: string
outputToken: string
outputAmount: string
outputAmountUsd: number
minOutputAmountUsd: number
sender?: string
}
}

export const fetchPortalsTradeOrder = async ({
sender,
inputToken,
Expand Down Expand Up @@ -90,3 +111,35 @@ export const fetchPortalsTradeOrder = async ({
throw error
}
}

export const fetchPortalsTradeEstimate = async ({
sender,
inputToken,
inputAmount,
outputToken,
slippageTolerancePercentage,
swapperConfig,
}: PortalsTradeOrderEstimateParams): Promise<PortalsTradeOrderEstimateResponse> => {
const url = `${swapperConfig.REACT_APP_PORTALS_BASE_URL}/v2/portal/estimate`

const params = new URLSearchParams({
sender,
inputToken,
inputAmount,
outputToken,
})

if (slippageTolerancePercentage !== undefined) {
params.append('slippageTolerancePercentage', slippageTolerancePercentage.toFixed(2)) // Portals API expects a string with at most 2 decimal places
}

try {
const response = await axios.get<PortalsTradeOrderEstimateResponse>(url, { params })
return response.data
} catch (error) {
if (axios.isAxiosError(error)) {
throw new Error(`Failed to fetch Portals trade estimate: ${error.message}`)
}
throw error
}
}
1 change: 1 addition & 0 deletions src/components/AccountDropdown/AccountSegement.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export const AccountSegment: FC<AccountGroupProps> = ({ title, subtitle }) => (
py={2}
color='text.subtle'
fontSize='sm'
alignItems='center'
justifyContent='space-between'
>
<RawText>{title}</RawText>
Expand Down
12 changes: 8 additions & 4 deletions src/components/InlineCopyButton.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { CheckIcon, CopyIcon } from '@chakra-ui/icons'
import { Flex, IconButton } from '@chakra-ui/react'
import type { PropsWithChildren } from 'react'
import type { MouseEvent, PropsWithChildren } from 'react'
import React, { useCallback } from 'react'
import { useTranslate } from 'react-polyglot'
import { useCopyToClipboard } from 'hooks/useCopyToClipboard'
Expand All @@ -23,9 +23,13 @@ export const InlineCopyButton: React.FC<InlineCopyButtonProps> = ({
const translate = useTranslate()
const { isCopied, copyToClipboard } = useCopyToClipboard({ timeout: 2000 })

const handleCopyClick = useCallback(() => {
copyToClipboard(value)
}, [copyToClipboard, value])
const handleCopyClick = useCallback(
(e: MouseEvent) => {
e.stopPropagation()
copyToClipboard(value)
},
[copyToClipboard, value],
)

// Hide the copy button if it is disabled
if (isDisabled) return <>{children}</>
Expand Down
43 changes: 23 additions & 20 deletions src/components/Modals/Nfts/components/NftOverview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { CopyButton } from 'plugins/walletConnectToDapps/components/modals/CopyB
import { useCallback } from 'react'
import { useTranslate } from 'react-polyglot'
import { AssetIcon } from 'components/AssetIcon'
import { InlineCopyButton } from 'components/InlineCopyButton'
import { MiddleEllipsis } from 'components/MiddleEllipsis/MiddleEllipsis'
import { Row } from 'components/Row/Row'
import { SanitizedHtml } from 'components/SanitizedHtml/SanitizedHtml'
Expand Down Expand Up @@ -66,26 +67,28 @@ export const NftOverview: React.FC<NftOverviewProps> = ({ nftItem }) => {
<Row>
<Row.Label>{translate('nft.address')}</Row.Label>
<Row.Value>
<Button
as={Link}
isExternal
href={maybeCollectionLink}
variant='ghost'
colorScheme='blue'
bg='transparent'
fontWeight='normal'
fontFamily='monospace'
onClick={handlellipsisAddressClick}
mt={1}
p={0}
height='auto'
fontSize='inherit'
_hover={ellipsisAddressHover}
display='flex'
alignItems='center'
>
<MiddleEllipsis value={address} />
</Button>
<InlineCopyButton value={address}>
<Button
as={Link}
isExternal
href={maybeCollectionLink}
variant='ghost'
colorScheme='blue'
bg='transparent'
fontWeight='normal'
fontFamily='monospace'
onClick={handlellipsisAddressClick}
mt={1}
p={0}
height='auto'
fontSize='inherit'
_hover={ellipsisAddressHover}
display='flex'
alignItems='center'
>
<MiddleEllipsis value={address} />
</Button>
</InlineCopyButton>
</Row.Value>
</Row>
)}
Expand Down
28 changes: 20 additions & 8 deletions src/components/Modals/Send/views/Confirm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
Stack,
useColorModeValue,
} from '@chakra-ui/react'
import { fromAccountId } from '@shapeshiftoss/caip'
import { fromAssetId } from '@shapeshiftoss/caip/dist/assetId/assetId'
import { CHAIN_NAMESPACE } from '@shapeshiftoss/caip/dist/constants'
import type { FeeDataKey } from '@shapeshiftoss/chain-adapters'
Expand All @@ -19,6 +20,7 @@ import { useTranslate } from 'react-polyglot'
import { useHistory } from 'react-router-dom'
import { AccountDropdown } from 'components/AccountDropdown/AccountDropdown'
import { Amount } from 'components/Amount/Amount'
import { InlineCopyButton } from 'components/InlineCopyButton'
import { MiddleEllipsis } from 'components/MiddleEllipsis/MiddleEllipsis'
import { DialogBackButton } from 'components/Modal/components/DialogBackButton'
import { DialogBody } from 'components/Modal/components/DialogBody'
Expand All @@ -30,6 +32,7 @@ import { SlideTransition } from 'components/SlideTransition'
import { RawText, Text } from 'components/Text'
import type { TextPropTypes } from 'components/Text/Text'
import { bnOrZero } from 'lib/bignumber/bignumber'
import { isUtxoAccountId } from 'lib/utils/utxo'
import { selectAssetById, selectFeeAssetById } from 'state/slices/selectors'
import { useAppSelector } from 'state/store'

Expand Down Expand Up @@ -142,20 +145,29 @@ export const Confirm = () => {
<Text translation='modals.send.confirm.sendFrom' />
</Row.Label>
<Row.Value display='flex' alignItems='center'>
<AccountDropdown
onChange={handleAccountChange}
assetId={asset.assetId}
defaultAccountId={accountId}
buttonProps={accountDropdownButtonProps}
disabled
/>
<InlineCopyButton
isDisabled={!accountId || isUtxoAccountId(accountId)}
value={fromAccountId(accountId ?? '').account}
>
<AccountDropdown
onChange={handleAccountChange}
assetId={asset.assetId}
defaultAccountId={accountId}
buttonProps={accountDropdownButtonProps}
disabled
/>
</InlineCopyButton>
</Row.Value>
</Row>
<Row>
<Row.Label>
<Text translation={'modals.send.confirm.sendTo'} />
</Row.Label>
<Row.Value>{vanityAddress ? vanityAddress : <MiddleEllipsis value={to} />}</Row.Value>
<Row.Value>
<InlineCopyButton value={to}>
{vanityAddress ? vanityAddress : <MiddleEllipsis value={to} />}
</InlineCopyButton>
</Row.Value>
</Row>
{allowCustomSendNonce && (
<Row>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
Tag,
useStyleConfig,
} from '@chakra-ui/react'
import { InlineCopyButton } from 'components/InlineCopyButton'
import { MiddleEllipsis } from 'components/MiddleEllipsis/MiddleEllipsis'
import { selectActiveQuote } from 'state/slices/tradeQuoteSlice/selectors'
import { useAppSelector } from 'state/store'
Expand Down Expand Up @@ -39,10 +40,13 @@ const LastStepTag = () => {

return (
<Tag size='md' colorScheme='blue'>
<MiddleEllipsis value={receiveAddress} />
<InlineCopyButton value={receiveAddress}>
<MiddleEllipsis value={receiveAddress} />
</InlineCopyButton>
</Tag>
)
}

export const StepperStep = ({
title,
stepIndicator,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Button, Link } from '@chakra-ui/react'
import { useCallback } from 'react'
import { InlineCopyButton } from 'components/InlineCopyButton'
import { MiddleEllipsis } from 'components/MiddleEllipsis/MiddleEllipsis'

const buttonHover = { bg: 'transparent' }
Expand All @@ -18,24 +19,28 @@ export const Address = ({
[],
)
return explorerAddressLink ? (
<Button
as={Link}
href={`${explorerAddressLink}${ens || address}`}
isExternal
bg='transparent'
variant='ghost'
colorScheme='blue'
fontWeight='normal'
p={0}
onClick={handleClick}
height='auto'
fontFamily='monospace'
_hover={buttonHover}
fontSize='inherit'
>
<MiddleEllipsis value={ens || address} />
</Button>
<InlineCopyButton value={address}>
<Button
as={Link}
href={`${explorerAddressLink}${ens || address}`}
isExternal
bg='transparent'
variant='ghost'
colorScheme='blue'
fontWeight='normal'
p={0}
onClick={handleClick}
height='auto'
fontFamily='monospace'
_hover={buttonHover}
fontSize='inherit'
>
<MiddleEllipsis value={ens || address} />
</Button>
</InlineCopyButton>
) : (
<MiddleEllipsis value={ens || address} />
<InlineCopyButton value={address}>
<MiddleEllipsis value={ens || address} />
</InlineCopyButton>
)
}
Loading
Loading