ci(release): publish latest release

parent 30f8553b
IPFS hash of the deployment:
- CIDv0: `QmWjdKVdC9JtozeVwHk1mC1NqZQFVaE67FUbiimYKFKXga`
- CIDv1: `bafybeid4ybefcxjobfsidxoodakcycwsqpigag7lo6nwiyshjqv3i3ai34`
- CIDv0: `QmaaNmJT3Bbm4i4ahXzABht6cZn6wp5F9GfY1U1YuhkDuL`
- CIDv1: `bafybeifv2bmhbxigtfs4j7mwgjfvcyiwjwfl644etbjc2mthilpckedwam`
The latest release is always mirrored at [app.uniswap.org](https://app.uniswap.org).
......@@ -10,10 +10,15 @@ You can also access the Uniswap Interface from an IPFS gateway.
Your Uniswap settings are never remembered across different URLs.
IPFS gateways:
- https://bafybeid4ybefcxjobfsidxoodakcycwsqpigag7lo6nwiyshjqv3i3ai34.ipfs.dweb.link/
- https://bafybeid4ybefcxjobfsidxoodakcycwsqpigag7lo6nwiyshjqv3i3ai34.ipfs.cf-ipfs.com/
- [ipfs://QmWjdKVdC9JtozeVwHk1mC1NqZQFVaE67FUbiimYKFKXga/](ipfs://QmWjdKVdC9JtozeVwHk1mC1NqZQFVaE67FUbiimYKFKXga/)
- https://bafybeifv2bmhbxigtfs4j7mwgjfvcyiwjwfl644etbjc2mthilpckedwam.ipfs.dweb.link/
- https://bafybeifv2bmhbxigtfs4j7mwgjfvcyiwjwfl644etbjc2mthilpckedwam.ipfs.cf-ipfs.com/
- [ipfs://QmaaNmJT3Bbm4i4ahXzABht6cZn6wp5F9GfY1U1YuhkDuL/](ipfs://QmaaNmJT3Bbm4i4ahXzABht6cZn6wp5F9GfY1U1YuhkDuL/)
### 5.22.1 (2024-04-02)
### 5.22.2 (2024-04-05)
### Bug Fixes
* **web:** fix limit price offline bug (#7325) 2247761
web/5.22.1
\ No newline at end of file
web/5.22.2
\ No newline at end of file
......@@ -3,9 +3,14 @@ import { parseUnits } from 'ethers/lib/utils'
import JSBI from 'jsbi'
import { useMemo } from 'react'
export enum LimitPriceErrorType {
CALCULATION_ERROR = 'CALCULATION_ERROR',
BELOW_MARKET = 'BELOW_MARKET',
}
type CurrentPriceAdjustmentResult =
| { currentPriceAdjustment: number; priceError: boolean }
| { currentPriceAdjustment: undefined; priceError: false }
| { currentPriceAdjustment: number; priceError?: LimitPriceErrorType.BELOW_MARKET }
| { currentPriceAdjustment: undefined; priceError: LimitPriceErrorType.CALCULATION_ERROR }
export function useCurrentPriceAdjustment({
parsedLimitPrice,
......@@ -28,7 +33,7 @@ export function useCurrentPriceAdjustment({
!quoteCurrency ||
!parsedLimitPrice.baseCurrency.equals(baseCurrency)
) {
return { currentPriceAdjustment: undefined, priceError: false }
return { currentPriceAdjustment: undefined, priceError: LimitPriceErrorType.CALCULATION_ERROR }
}
const oneUnitOfBaseCurrency = CurrencyAmount.fromRawAmount(
baseCurrency,
......@@ -46,9 +51,12 @@ export function useCurrentPriceAdjustment({
const percentageChange = new Fraction(difference, scaledMarketQuote)
const currentPriceAdjustment = Math.round(Number(percentageChange.multiply(100).toFixed(2)))
const priceBelowMarket = limitPriceInverted ? currentPriceAdjustment > 0 : currentPriceAdjustment < 0
return {
currentPriceAdjustment,
priceError: limitPriceInverted ? (currentPriceAdjustment ?? 0) > 0 : (currentPriceAdjustment ?? 0) < 0,
priceError: priceBelowMarket ? LimitPriceErrorType.BELOW_MARKET : undefined,
}
}, [parsedLimitPrice, marketPrice, baseCurrency, quoteCurrency, limitPriceInverted])
}
......@@ -37,7 +37,10 @@ import { maxAmountSpend } from 'utils/maxAmountSpend'
import { MenuState, miniPortfolioMenuStateAtom } from 'components/AccountDrawer/DefaultMenu'
import { OpenLimitOrdersButton } from 'components/AccountDrawer/MiniPortfolio/Limits/OpenLimitOrdersButton'
import { useCurrentPriceAdjustment } from 'components/CurrencyInputPanel/LimitPriceInputPanel/useCurrentPriceAdjustment'
import {
LimitPriceErrorType,
useCurrentPriceAdjustment,
} from 'components/CurrencyInputPanel/LimitPriceInputPanel/useCurrentPriceAdjustment'
import Row from 'components/Row'
import { CurrencySearchFilters } from 'components/SearchModal/CurrencySearch'
import { useAtom } from 'jotai'
......@@ -346,8 +349,9 @@ function LimitForm({ onCurrencyChange }: LimitFormProps) {
hasInsufficientFunds={hasInsufficientFunds}
limitPriceError={priceError}
/>
{priceError && inputCurrency && outputCurrency && limitOrderTrade && (
{!!priceError && inputCurrency && outputCurrency && limitOrderTrade && (
<LimitPriceError
priceError={priceError}
priceAdjustmentPercentage={currentPriceAdjustment}
inputCurrency={inputCurrency}
outputCurrency={outputCurrency}
......@@ -413,7 +417,7 @@ function SubmitOrderButton({
handleContinueToReview: () => void
inputCurrency?: Currency
hasInsufficientFunds: boolean
limitPriceError?: boolean
limitPriceError?: LimitPriceErrorType
}) {
const toggleWalletDrawer = useToggleAccountDrawer()
const { account } = useWeb3React()
......@@ -446,7 +450,7 @@ function SubmitOrderButton({
onClick={handleContinueToReview}
id="submit-order-button"
data-testid="submit-order-button"
disabled={!trade || limitPriceError}
disabled={!trade || !!limitPriceError}
>
<Text fontSize={20}>Confirm</Text>
</ButtonError>
......
import { LimitPriceErrorType } from 'components/CurrencyInputPanel/LimitPriceInputPanel/useCurrentPriceAdjustment'
import { DAI, USDC_MAINNET } from 'constants/tokens'
import { render } from 'test-utils/render'
import { LimitPriceError } from './LimitPriceError'
......@@ -15,6 +16,20 @@ describe('LimitPriceError', () => {
outputCurrency={USDC_MAINNET}
priceInverted={inverted}
priceAdjustmentPercentage={change}
priceError={LimitPriceErrorType.BELOW_MARKET}
/>
)
expect(container.firstChild).toMatchSnapshot()
})
it('renders the limit price error correctly when there is a calculation error', async () => {
const { container } = render(
<LimitPriceError
inputCurrency={DAI}
outputCurrency={USDC_MAINNET}
priceInverted={false}
priceAdjustmentPercentage={0}
priceError={LimitPriceErrorType.CALCULATION_ERROR}
/>
)
expect(container.firstChild).toMatchSnapshot()
......
import { Trans } from '@lingui/macro'
import { Currency } from '@uniswap/sdk-core'
import Column from 'components/Column'
import { LimitPriceErrorType } from 'components/CurrencyInputPanel/LimitPriceInputPanel/useCurrentPriceAdjustment'
import Row from 'components/Row'
import { ReactNode } from 'react'
import { AlertTriangle } from 'react-feather'
......@@ -28,29 +29,39 @@ const LogoContainer = styled.div`
`
interface LimitPriceErrorProps {
priceError: LimitPriceErrorType
inputCurrency: Currency
outputCurrency: Currency
priceInverted: boolean
priceAdjustmentPercentage: number
priceAdjustmentPercentage?: number
}
function getTitle({ inputCurrency, outputCurrency, priceInverted }: LimitPriceErrorProps): ReactNode {
if (priceInverted) {
function getTitle({ inputCurrency, outputCurrency, priceInverted, priceError }: LimitPriceErrorProps): ReactNode {
if (priceError === LimitPriceErrorType.CALCULATION_ERROR) {
return <Trans>Market price not available</Trans>
} else if (priceInverted) {
return <Trans>Buying {outputCurrency.symbol} above market price</Trans>
} else {
return <Trans>Selling {inputCurrency.symbol} below market price</Trans>
}
}
function getDescription({ priceInverted, priceAdjustmentPercentage }: LimitPriceErrorProps): ReactNode {
if (priceInverted) {
function getDescription({ priceInverted, priceAdjustmentPercentage, priceError }: LimitPriceErrorProps): ReactNode {
if (priceError === LimitPriceErrorType.CALCULATION_ERROR) {
return (
<Trans>
We are unable to calculate the current market price. To avoid submitting an order below market price, please
check your network connection and try again.
</Trans>
)
} else if (priceInverted && !!priceAdjustmentPercentage) {
return (
<Trans>
Your limit price is {Math.abs(priceAdjustmentPercentage)}% higher than market. Adjust your limit price to
proceed.
</Trans>
)
} else {
} else if (priceAdjustmentPercentage) {
return (
<Trans>
Your limit price is {Math.abs(priceAdjustmentPercentage)}% lower than market. Adjust your limit price to
......@@ -58,6 +69,7 @@ function getDescription({ priceInverted, priceAdjustmentPercentage }: LimitPrice
</Trans>
)
}
return null
}
export function LimitPriceError(props: LimitPriceErrorProps) {
......
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`LimitPriceError renders the limit price error correctly when there is a calculation error 1`] = `
.c1 {
box-sizing: border-box;
margin: 0;
min-width: 0;
}
.c2 {
width: 100%;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
padding: 0;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: start;
-webkit-justify-content: flex-start;
-ms-flex-pack: start;
justify-content: flex-start;
gap: 12px;
}
.c6 {
color: #222222;
-webkit-letter-spacing: -0.01em;
-moz-letter-spacing: -0.01em;
-ms-letter-spacing: -0.01em;
letter-spacing: -0.01em;
}
.c7 {
color: #7D7D7D;
-webkit-letter-spacing: -0.01em;
-moz-letter-spacing: -0.01em;
-ms-letter-spacing: -0.01em;
letter-spacing: -0.01em;
}
.c5 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
-webkit-box-pack: start;
-webkit-justify-content: flex-start;
-ms-flex-pack: start;
justify-content: flex-start;
}
.c0 {
-webkit-transition: display 125ms ease-in-out, -webkit-transform 125ms ease-in-out;
-webkit-transition: display 125ms ease-in-out, transform 125ms ease-in-out;
transition: display 125ms ease-in-out, transform 125ms ease-in-out;
-webkit-animation: gyvpAI 125ms ease-in-out forwards;
animation: gyvpAI 125ms ease-in-out forwards;
-webkit-animation-delay: 125ms;
animation-delay: 125ms;
opacity: 0;
-webkit-translate: translateY(10px);
translate: translateY(10px);
}
.c0.exiting {
-webkit-animation: dnSqss 125ms ease-in-out;
animation: dnSqss 125ms ease-in-out;
}
.c3 {
padding: 12px;
border: 1px solid #22222212;
border-radius: 16px;
margin-top: 4px;
}
.c4 {
height: 40px;
width: 40px;
position: relative;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: center;
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
border-radius: 12px;
background-color: #FFF2F1;
-webkit-flex-shrink: 0;
-ms-flex-negative: 0;
flex-shrink: 0;
}
<span
class=" _dsp_contents"
>
<span
class=" t_light _dsp_contents is_Theme"
>
<div
class="c0"
>
<div
class="c1 c2 c3"
>
<div
class="c4"
>
<svg
fill="none"
height="20px"
stroke="#FF5F52"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="1"
viewBox="0 0 24 24"
width="20px"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"
/>
<line
x1="12"
x2="12"
y1="9"
y2="13"
/>
<line
x1="12"
x2="12.01"
y1="17"
y2="17"
/>
</svg>
</div>
<div
class="c5"
>
<div
class="c6 css-n8z49y"
>
Market price not available
</div>
<div
class="c7 css-142zc9n"
>
We are unable to calculate the current market price. To avoid submitting an order below market price, please check your network connection and try again.
</div>
</div>
</div>
</div>
</span>
</span>
`;
exports[`LimitPriceError renders the limit price error correctly, inverted false change -10 1`] = `
.c1 {
box-sizing: border-box;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment