Skip to content

Commit

Permalink
ci(release): publish latest release
Browse files Browse the repository at this point in the history
  • Loading branch information
hello-happy-puppy committed Dec 11, 2024
1 parent e989b6d commit ae7781f
Show file tree
Hide file tree
Showing 352 changed files with 18,919 additions and 9,587 deletions.
5 changes: 5 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ types

apps/mobile/ios
apps/mobile/android
apps/mobile/.storybook/storybook.requires.ts

# extension

Expand All @@ -42,3 +43,7 @@ packages/uniswap/codegen.ts
# eslint partials

packages/eslint-config/restrictedImports.js

# generated

packages/uniswap/src/data/rest/conversionTracking/api
1 change: 1 addition & 0 deletions CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* @uniswap/web-admins
73 changes: 66 additions & 7 deletions RELEASE
Original file line number Diff line number Diff line change
@@ -1,10 +1,69 @@
We are back with some new updates! Here’s the latest:
IPFS hash of the deployment:
- CIDv0: `QmUKDwf73MabW8XFc1EBM7rPqxs9p7sCAPaznFgrLpSJ6S`
- CIDv1: `bafybeicyzcey52u465bnzqnoat6g6itt7tjmkc47mmssyzge2xif2iihc4`

Token Warnings: See more information about the tokens you’re attempting to swap, enriched with data from Blockaid.
The latest release is always mirrored at [app.uniswap.org](https://app.uniswap.org).

You can also access the Uniswap Interface from an IPFS gateway.
**BEWARE**: The Uniswap interface uses [`localStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) to remember your settings, such as which tokens you have imported.
**You should always use an IPFS gateway that enforces origin separation**, or our hosted deployment of the latest release at [app.uniswap.org](https://app.uniswap.org).
Your Uniswap settings are never remembered across different URLs.

IPFS gateways:
- https://bafybeicyzcey52u465bnzqnoat6g6itt7tjmkc47mmssyzge2xif2iihc4.ipfs.dweb.link/
- https://bafybeicyzcey52u465bnzqnoat6g6itt7tjmkc47mmssyzge2xif2iihc4.ipfs.cf-ipfs.com/
- [ipfs://QmUKDwf73MabW8XFc1EBM7rPqxs9p7sCAPaznFgrLpSJ6S/](ipfs://QmUKDwf73MabW8XFc1EBM7rPqxs9p7sCAPaznFgrLpSJ6S/)

## 5.62.0 (2024-12-11)


### Features

* **web:** add modification check to on chain tx (#14083) 964cb1e
* **web:** add network cost to create flow (#14224) 9e280d9
* **web:** add platform id tracking (#13780) 186a9e0
* **web:** only show token warning on swap button click for prefilled (#14118) 068dd89
* **web:** price range input tick tooltips (#14129) 3c66f56
* **web:** show usd values in current tick tooltip for price range input (#14157) 7ecd409
* **web:** wiring up conversion proxy service (#13935) 6759787


### Bug Fixes

* **web:** [3/n] remove react-spring (SwapLineItem) (#13914) 991557e
* **web:** android keyboard issue (#14262) 1042833
* **web:** block lvmh nfts (#14233) dbbb92d
* **web:** cherrypick of price inversion issue (#14479) 75092f6
* **web:** delay main API call until approvals are calculated (#14302) af8185b
* **web:** downgrade react-native-web to 0.19.10 (#14474) 206c46f
* **web:** enforce privacy opt out choices (#14486) f8c43ad
* **web:** fix broken link for providing lps (#14372) (#14412) 71a95cc
* **web:** fix crash with v2 pair where there is a pool but no liquidity (#14186) cd0fd54
* **web:** fix max button functionality on deposit form (#14285) 1de6b4b
* **web:** hide un-owned positions (#14448) 280514a
* **web:** improve x-y positioning of liquidity chart and brush in range input (#14128) e50620d
* **web:** landing page modal diet - part ii (#14409) d1bd48c
* **web:** landing page modal diet (#14349) 6547912
* **web:** move input token warning to post-swap button (#14077) 823bef9
* **web:** op usdc sends (#14189) 24d41ea
* **web:** prevent crash when sending on bnb chain (#14359) 496ab28
* **web:** prevent flash of old swap flow (#14335) de64de2
* **web:** price range input grab (#14127) b1046cf
* **web:** remove nondefault list tokens from common bases (#14187) 2c9db40
* **web:** remove react-spring from NFT pages (#13923) 6045f3c
* **web:** rename swap settings context to tx settings context (#14276) 87fa4f6
* **web:** resizing resets flow (#14232) d442d98
* **web:** skip trading api calls when the form is not filled out (#14245) 389413d
* **web:** update support articles for v4 and lp redesign (#14248) a109d09
* **web:** update the claim flow to use the saga to deal with switching chains (#14346) 23246e9
* **web:** update the create flow to get data from the sdk instead of … (#14427) 94999a8
* **web:** v4 blocking fixes (#14178) 873bce1
* **web:** wrap positions in multichain context (#14467) 1d9f25d
* **web:** zora zk v2 lp fix staging (#14485) 4490890


### Continuous Integration

* **web:** update sitemaps b5a5370

Other changes:

- Increased manual slippage tolerance up to 50%
- Support for toggling between fiat and token input for fiat onramp
- Better dapp signing support
- Various bug fixes and performance improvements
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
extension/1.11.0
web/5.62.0
8 changes: 4 additions & 4 deletions apps/extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
"@svgr/webpack": "8.0.1",
"@tamagui/core": "1.114.4",
"@types/uuid": "9.0.1",
"@uniswap/analytics-events": "2.39.0",
"@uniswap/analytics-events": "2.40.0",
"@uniswap/uniswapx-sdk": "2.1.0-beta.18",
"@uniswap/universal-router-sdk": "4.5.2",
"@uniswap/v3-sdk": "3.18.1",
"@uniswap/v4-sdk": "1.10.3",
"@uniswap/universal-router-sdk": "4.7.0",
"@uniswap/v3-sdk": "3.19.0",
"@uniswap/v4-sdk": "1.12.0",
"dotenv-webpack": "8.0.1",
"ethers": "5.7.2",
"eventemitter3": "5.0.1",
Expand Down
13 changes: 2 additions & 11 deletions apps/extension/src/app/features/accounts/AccountSwitcherScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { ScreenHeader } from 'src/app/components/layout/ScreenHeader'
import { AccountItem } from 'src/app/features/accounts/AccountItem'
import { CreateWalletModal } from 'src/app/features/accounts/CreateWalletModal'
import { EditLabelModal } from 'src/app/features/accounts/EditLabelModal'
import { useSortedAccountList } from 'src/app/features/accounts/useSortedAccountList'
import { useDappContext } from 'src/app/features/dapp/DappContext'
import { updateDappConnectedAddressFromExtension } from 'src/app/features/dapp/actions'
import { useDappConnectedAccounts } from 'src/app/features/dapp/hooks'
Expand Down Expand Up @@ -33,7 +34,6 @@ import { AddressDisplay } from 'wallet/src/components/accounts/AddressDisplay'
import { PlusCircle } from 'wallet/src/components/icons/PlusCircle'
import { MenuContent } from 'wallet/src/components/menu/MenuContent'
import { MenuContentItem } from 'wallet/src/components/menu/types'
import { useAccountList } from 'wallet/src/features/accounts/hooks'
import { createOnboardingAccount } from 'wallet/src/features/onboarding/createOnboardingAccount'
import { BackupType, SignerMnemonicAccount } from 'wallet/src/features/wallet/accounts/types'
import { createAccountsActions } from 'wallet/src/features/wallet/create/createAccountsSaga'
Expand Down Expand Up @@ -148,17 +148,8 @@ export function AccountSwitcherScreen(): JSX.Element {
onPress: (): void => setShowRemoveWalletModal(true),
},
]
const { data: accountBalanceData } = useAccountList({
addresses: accountAddresses,
notifyOnNetworkStatusChange: true,
})

const sortedAddressesByBalance = accountAddresses
.map((address) => {
const wallet = accountBalanceData?.portfolios?.find((portfolio) => portfolio?.ownerAddress === address)
return { address, balance: wallet?.tokensTotalDenominatedValue?.value }
})
.sort((a, b) => (b.balance ?? 0) - (a.balance ?? 0))
const sortedAddressesByBalance = useSortedAccountList(accountAddresses)

const contentShadowProps = {
shadowColor: colors.shadowColor.val,
Expand Down
127 changes: 127 additions & 0 deletions apps/extension/src/app/features/accounts/useSortedAccountList.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import { useSortedAccountList } from 'src/app/features/accounts/useSortedAccountList'
import { act, renderHook } from 'src/test/test-utils'
import { useAccountList } from 'wallet/src/features/accounts/hooks'

jest.mock('wallet/src/features/accounts/hooks')
const mockUseAccountList = useAccountList as jest.MockedFunction<typeof useAccountList>

describe('useSortedAccountList', () => {
beforeEach(() => {
jest.clearAllMocks()
})

it('should sort addresses by balance in descending order', () => {
mockAccountList([mockPortfolio('address1', 100), mockPortfolio('address2', 200), mockPortfolio('address3', 150)])

const addresses = ['address1', 'address2', 'address3']
const { result } = renderHook(() => useSortedAccountList(addresses))

expect(result.current).toEqual([
{ address: 'address2', balance: 200 },
{ address: 'address3', balance: 150 },
{ address: 'address1', balance: 100 },
])
})

it('should handle undefined portfolios', () => {
mockAccountList(undefined)

const addresses = ['address1', 'address2']
const { result } = renderHook(() => useSortedAccountList(addresses))

expect(result.current).toEqual([
{ address: 'address1', balance: 0 },
{ address: 'address2', balance: 0 },
])
})

it('should use previous data during balance updates', () => {
mockAccountList([mockPortfolio('address1', 100), mockPortfolio('address2', 200)])

const addresses = ['address1', 'address2']
const { result, rerender } = renderHook((props) => useSortedAccountList(props), { initialProps: addresses })

expect(result.current).toEqual([
{ address: 'address2', balance: 200 },
{ address: 'address1', balance: 100 },
])

mockAccountList([mockPortfolio('address1', 100)], true)
rerender(['address1'])

expect(result.current).toEqual([{ address: 'address1', balance: 100 }])
})

it('should keep list order when an account is removed', async () => {
mockAccountList([mockPortfolio('address1', 100), mockPortfolio('address2', 200), mockPortfolio('address3', 300)])

const addresses = ['address1', 'address2', 'address3']
const { result, rerender } = renderHook((props) => useSortedAccountList(props), { initialProps: addresses })

expect(result.current).toEqual([
{ address: 'address3', balance: 300 },
{ address: 'address2', balance: 200 },
{ address: 'address1', balance: 100 },
])

mockAccountListUndefined()

await act(async () => {
rerender(['address1', 'address2'])
await new Promise((resolve) => setTimeout(resolve, 100))
})

expect(result.current).toEqual([
{ address: 'address2', balance: 200 },
{ address: 'address1', balance: 100 },
])

mockAccountList([mockPortfolio('address1', 100), mockPortfolio('address2', 200)])

await act(async () => {
rerender(['address1', 'address2'])
})

expect(result.current).toEqual([
{ address: 'address2', balance: 200 },
{ address: 'address1', balance: 100 },
])
})
})

function mockPortfolio(
ownerAddress: Address,
balance: number,
): {
id: string
ownerAddress: Address
tokensTotalDenominatedValue: { __typename?: 'Amount'; value: number }
} {
return {
id: ownerAddress,
ownerAddress,
tokensTotalDenominatedValue: { __typename: 'Amount', value: balance },
}
}

function mockAccountList(portfolios: ReturnType<typeof mockPortfolio>[] | undefined, loading = false): void {
mockUseAccountList.mockReturnValue({
data: { portfolios },
loading,
networkStatus: 7,
refetch: jest.fn(),
startPolling: jest.fn(),
stopPolling: jest.fn(),
})
}

function mockAccountListUndefined(): void {
mockUseAccountList.mockReturnValue({
data: undefined,
loading: true,
networkStatus: 7,
refetch: jest.fn(),
startPolling: jest.fn(),
stopPolling: jest.fn(),
})
}
47 changes: 47 additions & 0 deletions apps/extension/src/app/features/accounts/useSortedAccountList.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { useMemo } from 'react'
import { usePrevious } from 'utilities/src/react/hooks'
import { useAccountList } from 'wallet/src/features/accounts/hooks'

interface AddressWithBalance {
address: Address
balance: number
}

export function useSortedAccountList(addresses: Address[]): AddressWithBalance[] {
const { data: accountBalanceData } = useAccountList({
addresses,
})

/*
Why are we using previousAccountBalanceData?
This is a workaround for a data fetching inefficiency. When removing an address, we send a new query
with the updated address array, causing Apollo to refetch ALL balances. During this refetch, balances
temporarily show as 0, causing the list to re-sort momentarily.
We use previousAccountBalanceData to maintain the last known good balances during this refetch. The balances
will be updated once the new query completes.
*/
const previousAccountBalanceData = usePrevious(accountBalanceData)

const balanceRecord: Record<Address, number> = useMemo(() => {
const data = accountBalanceData || previousAccountBalanceData
if (!data?.portfolios) {
return {}
}
return Object.fromEntries(
data.portfolios
.filter((portfolio): portfolio is NonNullable<typeof portfolio> => Boolean(portfolio))
.map((portfolio) => [portfolio.ownerAddress, portfolio.tokensTotalDenominatedValue?.value ?? 0]),
)
}, [accountBalanceData, previousAccountBalanceData])

return useMemo(() => {
return addresses
.map((address) => ({
address,
balance: balanceRecord[address] ?? 0,
}))
.sort((a, b) => b.balance - a.balance)
}, [addresses, balanceRecord])
}
Loading

0 comments on commit ae7781f

Please sign in to comment.