Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b964953daf | ||
|
|
649fd9c845 | ||
|
|
6347e63a15 | ||
|
|
bdcb9a8a0a | ||
|
|
8d90bb7a39 | ||
|
|
d70b456855 | ||
|
|
fbb797fa54 | ||
|
|
8ace518311 | ||
|
|
67c776c995 | ||
|
|
719754c46c | ||
|
|
9170af888e | ||
|
|
b258f557d1 | ||
|
|
9d8c7f8e12 | ||
|
|
9c44e61e23 | ||
|
|
71db11b6ac | ||
|
|
db3328c8d9 | ||
|
|
34dfb41a1e |
3
.env
3
.env
@@ -1,2 +1,3 @@
|
|||||||
REACT_APP_CHAIN_ID="1"
|
REACT_APP_CHAIN_ID="1"
|
||||||
REACT_APP_NETWORK_URL="https://mainnet.infura.io/v3/4bf032f2d38a4ed6bb975b80d6340847"
|
REACT_APP_NETWORK_URL="https://mainnet.infura.io/v3/4bf032f2d38a4ed6bb975b80d6340847"
|
||||||
|
REACT_APP_WALLETCONNECT_BRIDGE_URL="https://uniswap.bridge.walletconnect.org"
|
||||||
8
.github/workflows/release.yaml
vendored
8
.github/workflows/release.yaml
vendored
@@ -54,6 +54,14 @@ jobs:
|
|||||||
pinata-api-key: ${{ secrets.PINATA_API_KEY }}
|
pinata-api-key: ${{ secrets.PINATA_API_KEY }}
|
||||||
pinata-secret-api-key: ${{ secrets.PINATA_API_SECRET_KEY }}
|
pinata-secret-api-key: ${{ secrets.PINATA_API_SECRET_KEY }}
|
||||||
|
|
||||||
|
- name: Pin to Crust
|
||||||
|
uses: crustio/ipfs-crust-action@v1.0.8
|
||||||
|
continue-on-error: true
|
||||||
|
timeout-minutes: 2
|
||||||
|
with:
|
||||||
|
cid: ${{ steps.upload.outputs.hash }}
|
||||||
|
seeds: ${{ secrets.CRUST_SEEDS }}
|
||||||
|
|
||||||
- name: Convert CIDv0 to CIDv1
|
- name: Convert CIDv0 to CIDv1
|
||||||
id: convert_cidv0
|
id: convert_cidv0
|
||||||
uses: uniswap/convert-cidv0-cidv1@v1.0.0
|
uses: uniswap/convert-cidv0-cidv1@v1.0.0
|
||||||
|
|||||||
10
package.json
10
package.json
@@ -82,18 +82,24 @@
|
|||||||
"react-window": "^1.8.5",
|
"react-window": "^1.8.5",
|
||||||
"rebass": "^4.0.7",
|
"rebass": "^4.0.7",
|
||||||
"redux-localstorage-simple": "^2.3.1",
|
"redux-localstorage-simple": "^2.3.1",
|
||||||
"serve": "^11.3.0",
|
"serve": "^11.3.2",
|
||||||
"start-server-and-test": "^1.11.0",
|
"start-server-and-test": "^1.11.0",
|
||||||
"styled-components": "^4.2.0",
|
"styled-components": "^4.2.0",
|
||||||
"typescript": "^3.8.3",
|
"typescript": "^3.8.3",
|
||||||
"use-count-up": "^2.2.5",
|
"use-count-up": "^2.2.5",
|
||||||
"wcag-contrast": "^3.0.0"
|
"wcag-contrast": "^3.0.0",
|
||||||
|
"workbox-core": "^6.1.0",
|
||||||
|
"workbox-expiration": "^6.1.0",
|
||||||
|
"workbox-precaching": "^6.1.0",
|
||||||
|
"workbox-routing": "^6.1.0",
|
||||||
|
"workbox-strategies": "^6.1.0"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
"@walletconnect/web3-provider": "1.1.1-alpha.0"
|
"@walletconnect/web3-provider": "1.1.1-alpha.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "react-scripts start",
|
"start": "react-scripts start",
|
||||||
|
"start:service-worker": "yarn build && yarn serve -s build",
|
||||||
"build": "react-scripts build",
|
"build": "react-scripts build",
|
||||||
"test": "react-scripts test --env=jsdom",
|
"test": "react-scripts test --env=jsdom",
|
||||||
"eject": "react-scripts eject",
|
"eject": "react-scripts eject",
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"short_name": "Uniswap",
|
"background_color": "#fff",
|
||||||
"name": "Uniswap",
|
"display": "standalone",
|
||||||
|
"homepage_url": "https://app.uniswap.org",
|
||||||
"icons": [
|
"icons": [
|
||||||
{
|
{
|
||||||
"src": "./images/192x192_App_Icon.png",
|
"src": "./images/192x192_App_Icon.png",
|
||||||
@@ -16,7 +17,8 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"orientation": "portrait",
|
"orientation": "portrait",
|
||||||
"display": "standalone",
|
"name": "Uniswap",
|
||||||
"theme_color": "#ff007a",
|
"short_name": "Uniswap",
|
||||||
"background_color": "#fff"
|
"start_url": ".",
|
||||||
|
"theme_color": "#ff007a"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,7 +115,13 @@ export default function Modal({
|
|||||||
{fadeTransition.map(
|
{fadeTransition.map(
|
||||||
({ item, key, props }) =>
|
({ item, key, props }) =>
|
||||||
item && (
|
item && (
|
||||||
<StyledDialogOverlay key={key} style={props} onDismiss={onDismiss} initialFocusRef={initialFocusRef}>
|
<StyledDialogOverlay
|
||||||
|
key={key}
|
||||||
|
style={props}
|
||||||
|
onDismiss={onDismiss}
|
||||||
|
initialFocusRef={initialFocusRef}
|
||||||
|
unstable_lockFocusAcrossFrames={false}
|
||||||
|
>
|
||||||
<StyledDialogContent
|
<StyledDialogContent
|
||||||
{...(isMobile
|
{...(isMobile
|
||||||
? {
|
? {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import React, { useContext, useRef, useState } from 'react'
|
import React, { useContext, useRef, useState } from 'react'
|
||||||
import { Settings, X } from 'react-feather'
|
import { Settings, X } from 'react-feather'
|
||||||
|
import ReactGA from 'react-ga'
|
||||||
import { Text } from 'rebass'
|
import { Text } from 'rebass'
|
||||||
import styled, { ThemeContext } from 'styled-components'
|
import styled, { ThemeContext } from 'styled-components'
|
||||||
import { useOnClickOutside } from '../../hooks/useOnClickOutside'
|
import { useOnClickOutside } from '../../hooks/useOnClickOutside'
|
||||||
@@ -236,7 +237,13 @@ export default function SettingsTab() {
|
|||||||
<Toggle
|
<Toggle
|
||||||
id="toggle-disable-multihop-button"
|
id="toggle-disable-multihop-button"
|
||||||
isActive={singleHopOnly}
|
isActive={singleHopOnly}
|
||||||
toggle={() => (singleHopOnly ? setSingleHopOnly(false) : setSingleHopOnly(true))}
|
toggle={() => {
|
||||||
|
ReactGA.event({
|
||||||
|
category: 'Routing',
|
||||||
|
action: singleHopOnly ? 'disable single hop' : 'enable single hop'
|
||||||
|
})
|
||||||
|
setSingleHopOnly(!singleHopOnly)
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</RowBetween>
|
</RowBetween>
|
||||||
</AutoColumn>
|
</AutoColumn>
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
import { Token } from '@uniswap/sdk'
|
import { Token } from '@uniswap/sdk'
|
||||||
import React, { useCallback } from 'react'
|
import React from 'react'
|
||||||
import Modal from '../Modal'
|
import Modal from '../Modal'
|
||||||
import { ImportToken } from 'components/SearchModal/ImportToken'
|
import { ImportToken } from 'components/SearchModal/ImportToken'
|
||||||
|
|
||||||
export default function TokenWarningModal({
|
export default function TokenWarningModal({
|
||||||
isOpen,
|
isOpen,
|
||||||
tokens,
|
tokens,
|
||||||
onConfirm
|
onConfirm,
|
||||||
|
onDismiss
|
||||||
}: {
|
}: {
|
||||||
isOpen: boolean
|
isOpen: boolean
|
||||||
tokens: Token[]
|
tokens: Token[]
|
||||||
onConfirm: () => void
|
onConfirm: () => void
|
||||||
|
onDismiss: () => void
|
||||||
}) {
|
}) {
|
||||||
const handleDismiss = useCallback(() => null, [])
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal isOpen={isOpen} onDismiss={handleDismiss} maxHeight={90}>
|
<Modal isOpen={isOpen} onDismiss={onDismiss} maxHeight={100}>
|
||||||
<ImportToken tokens={tokens} handleCurrencySelect={onConfirm} />
|
<ImportToken tokens={tokens} handleCurrencySelect={onConfirm} />
|
||||||
</Modal>
|
</Modal>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ export function AdvancedSwapDetails({ trade }: AdvancedSwapDetailsProps) {
|
|||||||
{!showRoute && (
|
{!showRoute && (
|
||||||
<AutoColumn style={{ padding: '12px 16px 0 16px' }}>
|
<AutoColumn style={{ padding: '12px 16px 0 16px' }}>
|
||||||
<InfoLink
|
<InfoLink
|
||||||
href={'https://uniswap.info/pair/' + trade.route.pairs[0].liquidityToken.address}
|
href={'https://info.uniswap.org/pair/' + trade.route.pairs[0].liquidityToken.address}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
View pair analytics ↗
|
View pair analytics ↗
|
||||||
|
|||||||
@@ -64,7 +64,6 @@ export default function UnsupportedCurrencyFooter({
|
|||||||
<AutoColumn gap="lg">
|
<AutoColumn gap="lg">
|
||||||
<RowBetween>
|
<RowBetween>
|
||||||
<TYPE.mediumHeader>Unsupported Assets</TYPE.mediumHeader>
|
<TYPE.mediumHeader>Unsupported Assets</TYPE.mediumHeader>
|
||||||
|
|
||||||
<CloseIcon onClick={() => setShowDetails(false)} />
|
<CloseIcon onClick={() => setShowDetails(false)} />
|
||||||
</RowBetween>
|
</RowBetween>
|
||||||
{tokens.map(token => {
|
{tokens.map(token => {
|
||||||
|
|||||||
@@ -6,10 +6,12 @@ import { PortisConnector } from '@web3-react/portis-connector'
|
|||||||
|
|
||||||
import { FortmaticConnector } from './Fortmatic'
|
import { FortmaticConnector } from './Fortmatic'
|
||||||
import { NetworkConnector } from './NetworkConnector'
|
import { NetworkConnector } from './NetworkConnector'
|
||||||
|
import UNISWAP_LOGO_URL from '../assets/svg/logo.svg'
|
||||||
|
|
||||||
const NETWORK_URL = process.env.REACT_APP_NETWORK_URL
|
const NETWORK_URL = process.env.REACT_APP_NETWORK_URL
|
||||||
const FORMATIC_KEY = process.env.REACT_APP_FORTMATIC_KEY
|
const FORMATIC_KEY = process.env.REACT_APP_FORTMATIC_KEY
|
||||||
const PORTIS_ID = process.env.REACT_APP_PORTIS_ID
|
const PORTIS_ID = process.env.REACT_APP_PORTIS_ID
|
||||||
|
const WALLETCONNECT_BRIDGE_URL = process.env.REACT_APP_WALLETCONNECT_BRIDGE_URL
|
||||||
|
|
||||||
export const NETWORK_CHAIN_ID: number = parseInt(process.env.REACT_APP_CHAIN_ID ?? '1')
|
export const NETWORK_CHAIN_ID: number = parseInt(process.env.REACT_APP_CHAIN_ID ?? '1')
|
||||||
|
|
||||||
@@ -33,7 +35,7 @@ export const injected = new InjectedConnector({
|
|||||||
// mainnet only
|
// mainnet only
|
||||||
export const walletconnect = new WalletConnectConnector({
|
export const walletconnect = new WalletConnectConnector({
|
||||||
rpc: { 1: NETWORK_URL },
|
rpc: { 1: NETWORK_URL },
|
||||||
bridge: 'https://bridge.walletconnect.org',
|
bridge: WALLETCONNECT_BRIDGE_URL,
|
||||||
qrcode: true,
|
qrcode: true,
|
||||||
pollingInterval: 15000
|
pollingInterval: 15000
|
||||||
})
|
})
|
||||||
@@ -54,6 +56,5 @@ export const portis = new PortisConnector({
|
|||||||
export const walletlink = new WalletLinkConnector({
|
export const walletlink = new WalletLinkConnector({
|
||||||
url: NETWORK_URL,
|
url: NETWORK_URL,
|
||||||
appName: 'Uniswap',
|
appName: 'Uniswap',
|
||||||
appLogoUrl:
|
appLogoUrl: UNISWAP_LOGO_URL
|
||||||
'https://mpng.pngfly.com/20181202/bex/kisspng-emoji-domain-unicorn-pin-badges-sticker-unicorn-tumblr-emoji-unicorn-iphoneemoji-5c046729264a77.5671679315437924251569.jpg'
|
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,8 +1,4 @@
|
|||||||
// used to mark unsupported tokens, these are hosted lists of unsupported tokens
|
// used to mark unsupported tokens, these are hosted lists of unsupported tokens
|
||||||
/**
|
|
||||||
* @TODO add list from blockchain association
|
|
||||||
*/
|
|
||||||
export const UNSUPPORTED_LIST_URLS: string[] = []
|
|
||||||
|
|
||||||
const COMPOUND_LIST = 'https://raw.githubusercontent.com/compound-finance/token-list/master/compound.tokenlist.json'
|
const COMPOUND_LIST = 'https://raw.githubusercontent.com/compound-finance/token-list/master/compound.tokenlist.json'
|
||||||
const UMA_LIST = 'https://umaproject.org/uma.tokenlist.json'
|
const UMA_LIST = 'https://umaproject.org/uma.tokenlist.json'
|
||||||
@@ -17,6 +13,9 @@ const CMC_ALL_LIST = 'defi.cmc.eth'
|
|||||||
const CMC_STABLECOIN = 'stablecoin.cmc.eth'
|
const CMC_STABLECOIN = 'stablecoin.cmc.eth'
|
||||||
const KLEROS_LIST = 't2crtokens.eth'
|
const KLEROS_LIST = 't2crtokens.eth'
|
||||||
const GEMINI_LIST = 'https://www.gemini.com/uniswap/manifest.json'
|
const GEMINI_LIST = 'https://www.gemini.com/uniswap/manifest.json'
|
||||||
|
const BA_LIST = 'https://raw.githubusercontent.com/The-Blockchain-Association/sec-notice-list/master/ba-sec-list.json'
|
||||||
|
|
||||||
|
export const UNSUPPORTED_LIST_URLS: string[] = [BA_LIST]
|
||||||
|
|
||||||
// lower index == higher priority for token import
|
// lower index == higher priority for token import
|
||||||
export const DEFAULT_LIST_OF_LISTS: string[] = [
|
export const DEFAULT_LIST_OF_LISTS: string[] = [
|
||||||
|
|||||||
@@ -17,6 +17,14 @@
|
|||||||
"decimals": 6,
|
"decimals": 6,
|
||||||
"chainId": 1,
|
"chainId": 1,
|
||||||
"logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x4922a015c4407F87432B179bb209e125432E4a2A/logo.png"
|
"logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x4922a015c4407F87432B179bb209e125432E4a2A/logo.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Grump Cat",
|
||||||
|
"address": "0x93B2FfF814FCaEFFB01406e80B4Ecd89Ca6A021b",
|
||||||
|
"symbol": "GRUMPY",
|
||||||
|
"decimals": 9,
|
||||||
|
"chainId": 1,
|
||||||
|
"logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x4922a015c4407F87432B179bb209e125432E4a2A/logo.png"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -150,18 +150,18 @@ export function useTradeExactOut(currencyIn?: Currency, currencyAmountOut?: Curr
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function useIsTransactionUnsupported(currencyIn?: Currency, currencyOut?: Currency): boolean {
|
export function useIsTransactionUnsupported(currencyIn?: Currency, currencyOut?: Currency): boolean {
|
||||||
const unsupportedToken: { [address: string]: Token } = useUnsupportedTokens()
|
const unsupportedTokens: { [address: string]: Token } = useUnsupportedTokens()
|
||||||
const { chainId } = useActiveWeb3React()
|
const { chainId } = useActiveWeb3React()
|
||||||
|
|
||||||
const tokenIn = wrappedCurrency(currencyIn, chainId)
|
const tokenIn = wrappedCurrency(currencyIn, chainId)
|
||||||
const tokenOut = wrappedCurrency(currencyOut, chainId)
|
const tokenOut = wrappedCurrency(currencyOut, chainId)
|
||||||
|
|
||||||
// if unsupported list loaded & either token on list, mark as unsupported
|
// if unsupported list loaded & either token on list, mark as unsupported
|
||||||
if (unsupportedToken) {
|
if (unsupportedTokens) {
|
||||||
if (tokenIn && Object.keys(unsupportedToken).includes(tokenIn.address)) {
|
if (tokenIn && Object.keys(unsupportedTokens).includes(tokenIn.address)) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if (tokenOut && Object.keys(unsupportedToken).includes(tokenOut.address)) {
|
if (tokenOut && Object.keys(unsupportedTokens).includes(tokenOut.address)) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import { NetworkContextName } from './constants'
|
|||||||
import './i18n'
|
import './i18n'
|
||||||
import App from './pages/App'
|
import App from './pages/App'
|
||||||
import store from './state'
|
import store from './state'
|
||||||
|
import * as serviceWorkerRegistration from './serviceWorkerRegistration'
|
||||||
import ApplicationUpdater from './state/application/updater'
|
import ApplicationUpdater from './state/application/updater'
|
||||||
import ListsUpdater from './state/lists/updater'
|
import ListsUpdater from './state/lists/updater'
|
||||||
import MulticallUpdater from './state/multicall/updater'
|
import MulticallUpdater from './state/multicall/updater'
|
||||||
@@ -27,8 +28,14 @@ if (!!window.ethereum) {
|
|||||||
|
|
||||||
const GOOGLE_ANALYTICS_ID: string | undefined = process.env.REACT_APP_GOOGLE_ANALYTICS_ID
|
const GOOGLE_ANALYTICS_ID: string | undefined = process.env.REACT_APP_GOOGLE_ANALYTICS_ID
|
||||||
if (typeof GOOGLE_ANALYTICS_ID === 'string') {
|
if (typeof GOOGLE_ANALYTICS_ID === 'string') {
|
||||||
ReactGA.initialize(GOOGLE_ANALYTICS_ID)
|
ReactGA.initialize(GOOGLE_ANALYTICS_ID, {
|
||||||
|
gaOptions: {
|
||||||
|
storage: 'none',
|
||||||
|
storeGac: false
|
||||||
|
}
|
||||||
|
})
|
||||||
ReactGA.set({
|
ReactGA.set({
|
||||||
|
anonymizeIp: true,
|
||||||
customBrowserType: !isMobile ? 'desktop' : 'web3' in window || 'ethereum' in window ? 'mobileWeb3' : 'mobileRegular'
|
customBrowserType: !isMobile ? 'desktop' : 'web3' in window || 'ethereum' in window ? 'mobileWeb3' : 'mobileRegular'
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
@@ -75,3 +82,5 @@ ReactDOM.render(
|
|||||||
</StrictMode>,
|
</StrictMode>,
|
||||||
document.getElementById('root')
|
document.getElementById('root')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
serviceWorkerRegistration.unregister()
|
||||||
|
|||||||
@@ -48,8 +48,9 @@ import Loader from '../../components/Loader'
|
|||||||
import { useIsTransactionUnsupported } from 'hooks/Trades'
|
import { useIsTransactionUnsupported } from 'hooks/Trades'
|
||||||
import UnsupportedCurrencyFooter from 'components/swap/UnsupportedCurrencyFooter'
|
import UnsupportedCurrencyFooter from 'components/swap/UnsupportedCurrencyFooter'
|
||||||
import { isTradeBetter } from 'utils/trades'
|
import { isTradeBetter } from 'utils/trades'
|
||||||
|
import { RouteComponentProps } from 'react-router-dom'
|
||||||
|
|
||||||
export default function Swap() {
|
export default function Swap({ history }: RouteComponentProps) {
|
||||||
const loadedUrlParams = useDefaultsFromURLSearch()
|
const loadedUrlParams = useDefaultsFromURLSearch()
|
||||||
|
|
||||||
// token warning stuff
|
// token warning stuff
|
||||||
@@ -97,6 +98,7 @@ export default function Swap() {
|
|||||||
currencies,
|
currencies,
|
||||||
inputError: swapInputError
|
inputError: swapInputError
|
||||||
} = useDerivedSwapInfo()
|
} = useDerivedSwapInfo()
|
||||||
|
|
||||||
const { wrapType, execute: onWrap, inputError: wrapInputError } = useWrapCallback(
|
const { wrapType, execute: onWrap, inputError: wrapInputError } = useWrapCallback(
|
||||||
currencies[Field.INPUT],
|
currencies[Field.INPUT],
|
||||||
currencies[Field.OUTPUT],
|
currencies[Field.OUTPUT],
|
||||||
@@ -142,6 +144,12 @@ export default function Swap() {
|
|||||||
[onUserInput]
|
[onUserInput]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// reset if they close warning without tokens in params
|
||||||
|
const handleDismissTokenWarning = useCallback(() => {
|
||||||
|
setDismissTokenWarning(true)
|
||||||
|
history.push('/swap/')
|
||||||
|
}, [history])
|
||||||
|
|
||||||
// modal and loading
|
// modal and loading
|
||||||
const [{ showConfirm, tradeToConfirm, swapErrorMessage, attemptingTxn, txHash }, setSwapState] = useState<{
|
const [{ showConfirm, tradeToConfirm, swapErrorMessage, attemptingTxn, txHash }, setSwapState] = useState<{
|
||||||
showConfirm: boolean
|
showConfirm: boolean
|
||||||
@@ -297,6 +305,7 @@ export default function Swap() {
|
|||||||
isOpen={importTokensNotInDefault.length > 0 && !dismissTokenWarning}
|
isOpen={importTokensNotInDefault.length > 0 && !dismissTokenWarning}
|
||||||
tokens={importTokensNotInDefault}
|
tokens={importTokensNotInDefault}
|
||||||
onConfirm={handleConfirmTokenWarning}
|
onConfirm={handleConfirmTokenWarning}
|
||||||
|
onDismiss={handleDismissTokenWarning}
|
||||||
/>
|
/>
|
||||||
<SwapPoolTabs active={'swap'} />
|
<SwapPoolTabs active={'swap'} />
|
||||||
<AppBody>
|
<AppBody>
|
||||||
|
|||||||
80
src/service-worker.ts
Normal file
80
src/service-worker.ts
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
/// <reference lib="webworker" />
|
||||||
|
/* eslint-disable no-restricted-globals */
|
||||||
|
|
||||||
|
// This service worker can be customized!
|
||||||
|
// See https://developers.google.com/web/tools/workbox/modules
|
||||||
|
// for the list of available Workbox modules, or add any other
|
||||||
|
// code you'd like.
|
||||||
|
// You can also remove this file if you'd prefer not to use a
|
||||||
|
// service worker, and the Workbox build step will be skipped.
|
||||||
|
|
||||||
|
import { clientsClaim } from 'workbox-core'
|
||||||
|
import { ExpirationPlugin } from 'workbox-expiration'
|
||||||
|
import { createHandlerBoundToURL, precacheAndRoute } from 'workbox-precaching'
|
||||||
|
import { registerRoute } from 'workbox-routing'
|
||||||
|
import { StaleWhileRevalidate } from 'workbox-strategies'
|
||||||
|
|
||||||
|
declare const self: ServiceWorkerGlobalScope
|
||||||
|
|
||||||
|
clientsClaim()
|
||||||
|
|
||||||
|
// Precache all of the assets generated by your build process.
|
||||||
|
// Their URLs are injected into the manifest variable below.
|
||||||
|
// This variable must be present somewhere in your service worker file,
|
||||||
|
// even if you decide not to use precaching. See https://cra.link/PWA
|
||||||
|
precacheAndRoute(self.__WB_MANIFEST)
|
||||||
|
|
||||||
|
// Set up App Shell-style routing, so that all navigation requests
|
||||||
|
// are fulfilled with your index.html shell. Learn more at
|
||||||
|
// https://developers.google.com/web/fundamentals/architecture/app-shell
|
||||||
|
const fileExtensionRegexp = new RegExp('/[^/?]+\\.[^/]+$')
|
||||||
|
registerRoute(
|
||||||
|
// Return false to exempt requests from being fulfilled by index.html.
|
||||||
|
({ request, url }: { request: Request; url: URL }) => {
|
||||||
|
// If this isn't a navigation, skip.
|
||||||
|
if (request.mode !== 'navigate') {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this is a URL that starts with /_, skip.
|
||||||
|
if (url.pathname.startsWith('/_')) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this looks like a URL for a resource, because it contains
|
||||||
|
// a file extension, skip.
|
||||||
|
if (url.pathname.match(fileExtensionRegexp)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return true to signal that we want to use the handler.
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
createHandlerBoundToURL(process.env.PUBLIC_URL + '/index.html')
|
||||||
|
)
|
||||||
|
|
||||||
|
// An example runtime caching route for requests that aren't handled by the
|
||||||
|
// precache, in this case same-origin .png requests like those from in public/
|
||||||
|
registerRoute(
|
||||||
|
// Add in any other file extensions or routing criteria as needed.
|
||||||
|
({ url }) => url.origin === self.location.origin && url.pathname.endsWith('.png'),
|
||||||
|
// Customize this strategy as needed, e.g., by changing to CacheFirst.
|
||||||
|
new StaleWhileRevalidate({
|
||||||
|
cacheName: 'images',
|
||||||
|
plugins: [
|
||||||
|
// Ensure that once this runtime cache reaches a maximum size the
|
||||||
|
// least-recently used images are removed.
|
||||||
|
new ExpirationPlugin({ maxEntries: 50 })
|
||||||
|
]
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
// This allows the web app to trigger skipWaiting via
|
||||||
|
// registration.waiting.postMessage({type: 'SKIP_WAITING'})
|
||||||
|
self.addEventListener('message', event => {
|
||||||
|
if (event.data && event.data.type === 'SKIP_WAITING') {
|
||||||
|
self.skipWaiting()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// Any other custom service worker logic can go here.
|
||||||
139
src/serviceWorkerRegistration.ts
Normal file
139
src/serviceWorkerRegistration.ts
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
// This optional code is used to register a service worker.
|
||||||
|
// register() is not called by default.
|
||||||
|
|
||||||
|
// This lets the app load faster on subsequent visits in production, and gives
|
||||||
|
// it offline capabilities. However, it also means that developers (and users)
|
||||||
|
// will only see deployed updates on subsequent visits to a page, after all the
|
||||||
|
// existing tabs open on the page have been closed, since previously cached
|
||||||
|
// resources are updated in the background.
|
||||||
|
|
||||||
|
// To learn more about the benefits of this model and instructions on how to
|
||||||
|
// opt-in, read https://cra.link/PWA
|
||||||
|
|
||||||
|
const isLocalhost = Boolean(
|
||||||
|
window.location.hostname === 'localhost' ||
|
||||||
|
// [::1] is the IPv6 localhost address.
|
||||||
|
window.location.hostname === '[::1]' ||
|
||||||
|
// 127.0.0.0/8 are considered localhost for IPv4.
|
||||||
|
window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/)
|
||||||
|
)
|
||||||
|
|
||||||
|
type Config = {
|
||||||
|
onSuccess?: (registration: ServiceWorkerRegistration) => void
|
||||||
|
onUpdate?: (registration: ServiceWorkerRegistration) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
function registerValidSW(swUrl: string, config?: Config) {
|
||||||
|
navigator.serviceWorker
|
||||||
|
.register(swUrl)
|
||||||
|
.then(registration => {
|
||||||
|
registration.onupdatefound = () => {
|
||||||
|
const installingWorker = registration.installing
|
||||||
|
if (installingWorker == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
installingWorker.onstatechange = () => {
|
||||||
|
if (installingWorker.state === 'installed') {
|
||||||
|
if (navigator.serviceWorker.controller) {
|
||||||
|
// At this point, the updated precached content has been fetched,
|
||||||
|
// but the previous service worker will still serve the older
|
||||||
|
// content until all client tabs are closed.
|
||||||
|
console.log(
|
||||||
|
'New content is available and will be used when all ' +
|
||||||
|
'tabs for this page are closed. See https://cra.link/PWA.'
|
||||||
|
)
|
||||||
|
|
||||||
|
// Execute callback
|
||||||
|
if (config && config.onUpdate) {
|
||||||
|
config.onUpdate(registration)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// At this point, everything has been precached.
|
||||||
|
// It's the perfect time to display a
|
||||||
|
// "Content is cached for offline use." message.
|
||||||
|
console.log('Content is cached for offline use.')
|
||||||
|
|
||||||
|
// Execute callback
|
||||||
|
if (config && config.onSuccess) {
|
||||||
|
config.onSuccess(registration)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error during service worker registration:', error)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkValidServiceWorker(swUrl: string, config?: Config) {
|
||||||
|
// Check if the service worker can be found. If it can't reload the page.
|
||||||
|
fetch(swUrl, {
|
||||||
|
headers: { 'Service-Worker': 'script' }
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
// Ensure service worker exists, and that we really are getting a JS file.
|
||||||
|
const contentType = response.headers.get('content-type')
|
||||||
|
if (response.status === 404 || (contentType != null && contentType.indexOf('javascript') === -1)) {
|
||||||
|
// No service worker found. Probably a different app. Reload the page.
|
||||||
|
navigator.serviceWorker.ready.then(registration => {
|
||||||
|
registration.unregister().then(() => {
|
||||||
|
window.location.reload()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// Service worker found. Proceed as normal.
|
||||||
|
registerValidSW(swUrl, config)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
console.log('No internet connection found. App is running in offline mode.')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function register(config?: Config) {
|
||||||
|
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
|
||||||
|
// The URL constructor is available in all browsers that support SW.
|
||||||
|
const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href)
|
||||||
|
if (publicUrl.origin !== window.location.origin) {
|
||||||
|
// Our service worker won't work if PUBLIC_URL is on a different origin
|
||||||
|
// from what our page is served on. This might happen if a CDN is used to
|
||||||
|
// serve assets; see https://github.com/facebook/create-react-app/issues/2374
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('load', () => {
|
||||||
|
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`
|
||||||
|
|
||||||
|
if (isLocalhost) {
|
||||||
|
// This is running on localhost. Let's check if a service worker still exists or not.
|
||||||
|
checkValidServiceWorker(swUrl, config)
|
||||||
|
|
||||||
|
// Add some additional logging to localhost, pointing developers to the
|
||||||
|
// service worker/PWA documentation.
|
||||||
|
navigator.serviceWorker.ready.then(() => {
|
||||||
|
console.log(
|
||||||
|
'This web app is being served cache-first by a service ' +
|
||||||
|
'worker. To learn more, visit https://cra.link/PWA'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// Is not localhost. Just register service worker
|
||||||
|
registerValidSW(swUrl, config)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function unregister() {
|
||||||
|
if ('serviceWorker' in navigator) {
|
||||||
|
navigator.serviceWorker.ready
|
||||||
|
.then(registration => {
|
||||||
|
registration.unregister()
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error(error.message)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -29,18 +29,16 @@ function fetchClaim(account: string, chainId: ChainId): Promise<UserClaimData |
|
|||||||
|
|
||||||
return (CLAIM_PROMISES[key] =
|
return (CLAIM_PROMISES[key] =
|
||||||
CLAIM_PROMISES[key] ??
|
CLAIM_PROMISES[key] ??
|
||||||
fetch(`https://gentle-frost-9e74.uniswap.workers.dev/${chainId}/${formatted}`)
|
fetch('https://merkle-drop-1.uniswap.workers.dev/', {
|
||||||
.then(res => {
|
body: JSON.stringify({ chainId, address: formatted }),
|
||||||
if (res.status === 200) {
|
headers: {
|
||||||
return res.json()
|
'Content-Type': 'application/json',
|
||||||
} else {
|
'Referrer-Policy': 'no-referrer'
|
||||||
console.debug(`No claim for account ${formatted} on chain ID ${chainId}`)
|
},
|
||||||
return null
|
method: 'POST'
|
||||||
}
|
})
|
||||||
})
|
.then(res => (res.ok ? res.json() : console.log(`No claim for account ${formatted} on chain ID ${chainId}`)))
|
||||||
.catch(error => {
|
.catch(error => console.error('Failed to get claim data', error)))
|
||||||
console.error('Failed to get claim data', error)
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse distributorContract blob and detect if user has claim data
|
// parse distributorContract blob and detect if user has claim data
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { DEFAULT_ACTIVE_LIST_URLS } from './../../constants/lists'
|
import { DEFAULT_ACTIVE_LIST_URLS, UNSUPPORTED_LIST_URLS } from './../../constants/lists'
|
||||||
import { createReducer } from '@reduxjs/toolkit'
|
import { createReducer } from '@reduxjs/toolkit'
|
||||||
import { getVersionUpgrade, VersionUpgrade } from '@uniswap/token-lists'
|
import { getVersionUpgrade, VersionUpgrade } from '@uniswap/token-lists'
|
||||||
import { TokenList } from '@uniswap/token-lists/dist/types'
|
import { TokenList } from '@uniswap/token-lists/dist/types'
|
||||||
@@ -36,7 +36,7 @@ type Mutable<T> = { -readonly [P in keyof T]: T[P] extends ReadonlyArray<infer U
|
|||||||
const initialState: ListsState = {
|
const initialState: ListsState = {
|
||||||
lastInitializedDefaultListOfLists: DEFAULT_LIST_OF_LISTS,
|
lastInitializedDefaultListOfLists: DEFAULT_LIST_OF_LISTS,
|
||||||
byUrl: {
|
byUrl: {
|
||||||
...DEFAULT_LIST_OF_LISTS.reduce<Mutable<ListsState['byUrl']>>((memo, listUrl) => {
|
...DEFAULT_LIST_OF_LISTS.concat(...UNSUPPORTED_LIST_URLS).reduce<Mutable<ListsState['byUrl']>>((memo, listUrl) => {
|
||||||
memo[listUrl] = NEW_LIST_STATE
|
memo[listUrl] = NEW_LIST_STATE
|
||||||
return memo
|
return memo
|
||||||
}, {})
|
}, {})
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import { AppDispatch } from '../index'
|
|||||||
import { acceptListUpdate } from './actions'
|
import { acceptListUpdate } from './actions'
|
||||||
import { useActiveListUrls } from './hooks'
|
import { useActiveListUrls } from './hooks'
|
||||||
import { useAllInactiveTokens } from 'hooks/Tokens'
|
import { useAllInactiveTokens } from 'hooks/Tokens'
|
||||||
|
import { UNSUPPORTED_LIST_URLS } from 'constants/lists'
|
||||||
|
|
||||||
export default function Updater(): null {
|
export default function Updater(): null {
|
||||||
const { library } = useActiveWeb3React()
|
const { library } = useActiveWeb3React()
|
||||||
@@ -44,6 +45,16 @@ export default function Updater(): null {
|
|||||||
})
|
})
|
||||||
}, [dispatch, fetchList, library, lists])
|
}, [dispatch, fetchList, library, lists])
|
||||||
|
|
||||||
|
// if any lists from unsupported lists are loaded, check them too (in case new updates since last visit)
|
||||||
|
useEffect(() => {
|
||||||
|
Object.keys(UNSUPPORTED_LIST_URLS).forEach(listUrl => {
|
||||||
|
const list = lists[listUrl]
|
||||||
|
if (!list || (!list.current && !list.loadingRequestId && !list.error)) {
|
||||||
|
fetchList(listUrl).catch(error => console.debug('list added fetching error', error))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}, [dispatch, fetchList, library, lists])
|
||||||
|
|
||||||
// automatically update lists if versions are minor/patch
|
// automatically update lists if versions are minor/patch
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
Object.keys(lists).forEach(listUrl => {
|
Object.keys(lists).forEach(listUrl => {
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { ChainId, Pair, Token } from '@uniswap/sdk'
|
import { ChainId, Pair, Token } from '@uniswap/sdk'
|
||||||
import flatMap from 'lodash.flatmap'
|
import flatMap from 'lodash.flatmap'
|
||||||
import ReactGA from 'react-ga'
|
|
||||||
import { useCallback, useMemo } from 'react'
|
import { useCallback, useMemo } from 'react'
|
||||||
import { shallowEqual, useDispatch, useSelector } from 'react-redux'
|
import { shallowEqual, useDispatch, useSelector } from 'react-redux'
|
||||||
import { BASES_TO_TRACK_LIQUIDITY_FOR, PINNED_PAIRS } from '../../constants'
|
import { BASES_TO_TRACK_LIQUIDITY_FOR, PINNED_PAIRS } from '../../constants'
|
||||||
@@ -92,10 +91,6 @@ export function useUserSingleHopOnly(): [boolean, (newSingleHopOnly: boolean) =>
|
|||||||
|
|
||||||
const setSingleHopOnly = useCallback(
|
const setSingleHopOnly = useCallback(
|
||||||
(newSingleHopOnly: boolean) => {
|
(newSingleHopOnly: boolean) => {
|
||||||
ReactGA.event({
|
|
||||||
category: 'Routing',
|
|
||||||
action: newSingleHopOnly ? 'enable single hop' : 'disable single hop'
|
|
||||||
})
|
|
||||||
dispatch(updateUserSingleHopOnly({ userSingleHopOnly: newSingleHopOnly }))
|
dispatch(updateUserSingleHopOnly({ userSingleHopOnly: newSingleHopOnly }))
|
||||||
},
|
},
|
||||||
[dispatch]
|
[dispatch]
|
||||||
@@ -162,7 +157,7 @@ export function useUserAddedTokens(): Token[] {
|
|||||||
|
|
||||||
return useMemo(() => {
|
return useMemo(() => {
|
||||||
if (!chainId) return []
|
if (!chainId) return []
|
||||||
return Object.values(serializedTokensMap[chainId as ChainId] ?? {}).map(deserializeToken)
|
return Object.values(serializedTokensMap?.[chainId as ChainId] ?? {}).map(deserializeToken)
|
||||||
}, [serializedTokensMap, chainId])
|
}, [serializedTokensMap, chainId])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -111,11 +111,17 @@ export default createReducer(initialState, builder =>
|
|||||||
state.userSingleHopOnly = action.payload.userSingleHopOnly
|
state.userSingleHopOnly = action.payload.userSingleHopOnly
|
||||||
})
|
})
|
||||||
.addCase(addSerializedToken, (state, { payload: { serializedToken } }) => {
|
.addCase(addSerializedToken, (state, { payload: { serializedToken } }) => {
|
||||||
|
if (!state.tokens) {
|
||||||
|
state.tokens = {}
|
||||||
|
}
|
||||||
state.tokens[serializedToken.chainId] = state.tokens[serializedToken.chainId] || {}
|
state.tokens[serializedToken.chainId] = state.tokens[serializedToken.chainId] || {}
|
||||||
state.tokens[serializedToken.chainId][serializedToken.address] = serializedToken
|
state.tokens[serializedToken.chainId][serializedToken.address] = serializedToken
|
||||||
state.timestamp = currentTimestamp()
|
state.timestamp = currentTimestamp()
|
||||||
})
|
})
|
||||||
.addCase(removeSerializedToken, (state, { payload: { address, chainId } }) => {
|
.addCase(removeSerializedToken, (state, { payload: { address, chainId } }) => {
|
||||||
|
if (!state.tokens) {
|
||||||
|
state.tokens = {}
|
||||||
|
}
|
||||||
state.tokens[chainId] = state.tokens[chainId] || {}
|
state.tokens[chainId] = state.tokens[chainId] || {}
|
||||||
delete state.tokens[chainId][address]
|
delete state.tokens[chainId][address]
|
||||||
state.timestamp = currentTimestamp()
|
state.timestamp = currentTimestamp()
|
||||||
|
|||||||
37
yarn.lock
37
yarn.lock
@@ -13762,7 +13762,7 @@ serve-static@1.14.1:
|
|||||||
parseurl "~1.3.3"
|
parseurl "~1.3.3"
|
||||||
send "0.17.1"
|
send "0.17.1"
|
||||||
|
|
||||||
serve@^11.3.0:
|
serve@^11.3.2:
|
||||||
version "11.3.2"
|
version "11.3.2"
|
||||||
resolved "https://registry.yarnpkg.com/serve/-/serve-11.3.2.tgz#b905e980616feecd170e51c8f979a7b2374098f5"
|
resolved "https://registry.yarnpkg.com/serve/-/serve-11.3.2.tgz#b905e980616feecd170e51c8f979a7b2374098f5"
|
||||||
integrity sha512-yKWQfI3xbj/f7X1lTBg91fXBP0FqjJ4TEi+ilES5yzH0iKJpN5LjNb1YzIfQg9Rqn4ECUS2SOf2+Kmepogoa5w==
|
integrity sha512-yKWQfI3xbj/f7X1lTBg91fXBP0FqjJ4TEi+ilES5yzH0iKJpN5LjNb1YzIfQg9Rqn4ECUS2SOf2+Kmepogoa5w==
|
||||||
@@ -15655,6 +15655,11 @@ workbox-core@^4.3.1:
|
|||||||
resolved "https://registry.yarnpkg.com/workbox-core/-/workbox-core-4.3.1.tgz#005d2c6a06a171437afd6ca2904a5727ecd73be6"
|
resolved "https://registry.yarnpkg.com/workbox-core/-/workbox-core-4.3.1.tgz#005d2c6a06a171437afd6ca2904a5727ecd73be6"
|
||||||
integrity sha512-I3C9jlLmMKPxAC1t0ExCq+QoAMd0vAAHULEgRZ7kieCdUd919n53WC0AfvokHNwqRhGn+tIIj7vcb5duCjs2Kg==
|
integrity sha512-I3C9jlLmMKPxAC1t0ExCq+QoAMd0vAAHULEgRZ7kieCdUd919n53WC0AfvokHNwqRhGn+tIIj7vcb5duCjs2Kg==
|
||||||
|
|
||||||
|
workbox-core@^6.1.0:
|
||||||
|
version "6.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/workbox-core/-/workbox-core-6.1.0.tgz#2671b64f76550e83a4c2202676b67ce372e10881"
|
||||||
|
integrity sha512-s3KqTJfBreO4xCZpR2LB5p/EknAx8eg0QumKiIgxM4hRO0RtwS2pJvTieNEM23X3RqxRhqweriLD8To19KUvjg==
|
||||||
|
|
||||||
workbox-expiration@^4.3.1:
|
workbox-expiration@^4.3.1:
|
||||||
version "4.3.1"
|
version "4.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/workbox-expiration/-/workbox-expiration-4.3.1.tgz#d790433562029e56837f341d7f553c4a78ebe921"
|
resolved "https://registry.yarnpkg.com/workbox-expiration/-/workbox-expiration-4.3.1.tgz#d790433562029e56837f341d7f553c4a78ebe921"
|
||||||
@@ -15662,6 +15667,13 @@ workbox-expiration@^4.3.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
workbox-core "^4.3.1"
|
workbox-core "^4.3.1"
|
||||||
|
|
||||||
|
workbox-expiration@^6.1.0:
|
||||||
|
version "6.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/workbox-expiration/-/workbox-expiration-6.1.0.tgz#cf6bb384e49d0c92b79233c46671d9c6d82478a2"
|
||||||
|
integrity sha512-jp2xGk+LC4AhCoOxO/bC06GQkq/oVp0ZIf1zXLQh6OD2fWZPkXNjLLSuDnjXoGGPibYrq7gEE/xjAdYGjNWl1A==
|
||||||
|
dependencies:
|
||||||
|
workbox-core "^6.1.0"
|
||||||
|
|
||||||
workbox-google-analytics@^4.3.1:
|
workbox-google-analytics@^4.3.1:
|
||||||
version "4.3.1"
|
version "4.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/workbox-google-analytics/-/workbox-google-analytics-4.3.1.tgz#9eda0183b103890b5c256e6f4ea15a1f1548519a"
|
resolved "https://registry.yarnpkg.com/workbox-google-analytics/-/workbox-google-analytics-4.3.1.tgz#9eda0183b103890b5c256e6f4ea15a1f1548519a"
|
||||||
@@ -15686,6 +15698,15 @@ workbox-precaching@^4.3.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
workbox-core "^4.3.1"
|
workbox-core "^4.3.1"
|
||||||
|
|
||||||
|
workbox-precaching@^6.1.0:
|
||||||
|
version "6.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/workbox-precaching/-/workbox-precaching-6.1.0.tgz#9ee3d28f27cd78daa62f5bd6a0d33f5682ac97a7"
|
||||||
|
integrity sha512-zjye8MVzieBVJ3sS0hFcbKLp7pTHMfJM17YqxCxB0KykXWnxLOpYnStQ9M+bjWJsKJOQvbkPqvq5u9+mtA923g==
|
||||||
|
dependencies:
|
||||||
|
workbox-core "^6.1.0"
|
||||||
|
workbox-routing "^6.1.0"
|
||||||
|
workbox-strategies "^6.1.0"
|
||||||
|
|
||||||
workbox-range-requests@^4.3.1:
|
workbox-range-requests@^4.3.1:
|
||||||
version "4.3.1"
|
version "4.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/workbox-range-requests/-/workbox-range-requests-4.3.1.tgz#f8a470188922145cbf0c09a9a2d5e35645244e74"
|
resolved "https://registry.yarnpkg.com/workbox-range-requests/-/workbox-range-requests-4.3.1.tgz#f8a470188922145cbf0c09a9a2d5e35645244e74"
|
||||||
@@ -15700,6 +15721,13 @@ workbox-routing@^4.3.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
workbox-core "^4.3.1"
|
workbox-core "^4.3.1"
|
||||||
|
|
||||||
|
workbox-routing@^6.1.0:
|
||||||
|
version "6.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/workbox-routing/-/workbox-routing-6.1.0.tgz#f885cb7801e2c9c5678f197656cf27a2b649c1d5"
|
||||||
|
integrity sha512-FXQ5cwb6Mk90fC0rfQLX0pN+r/N4eBafwkh/QanJUq0e6jMPdDFLrlsikZL/0LcXEx+yAkWLytoiS+d2HOEBOw==
|
||||||
|
dependencies:
|
||||||
|
workbox-core "^6.1.0"
|
||||||
|
|
||||||
workbox-strategies@^4.3.1:
|
workbox-strategies@^4.3.1:
|
||||||
version "4.3.1"
|
version "4.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/workbox-strategies/-/workbox-strategies-4.3.1.tgz#d2be03c4ef214c115e1ab29c9c759c9fe3e9e646"
|
resolved "https://registry.yarnpkg.com/workbox-strategies/-/workbox-strategies-4.3.1.tgz#d2be03c4ef214c115e1ab29c9c759c9fe3e9e646"
|
||||||
@@ -15707,6 +15735,13 @@ workbox-strategies@^4.3.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
workbox-core "^4.3.1"
|
workbox-core "^4.3.1"
|
||||||
|
|
||||||
|
workbox-strategies@^6.1.0:
|
||||||
|
version "6.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/workbox-strategies/-/workbox-strategies-6.1.0.tgz#9ddcee44408d2fb403f22a7989803b5c58560590"
|
||||||
|
integrity sha512-HvUknzJdZWeV3x7Eq33a7TGAv9/r1TEiQK6kQ1QNzN+IKiqhIjnhKFHmMxb5hK1Gw9/aDSJTLNPDaLPfIJRQFQ==
|
||||||
|
dependencies:
|
||||||
|
workbox-core "^6.1.0"
|
||||||
|
|
||||||
workbox-streams@^4.3.1:
|
workbox-streams@^4.3.1:
|
||||||
version "4.3.1"
|
version "4.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/workbox-streams/-/workbox-streams-4.3.1.tgz#0b57da70e982572de09c8742dd0cb40a6b7c2cc3"
|
resolved "https://registry.yarnpkg.com/workbox-streams/-/workbox-streams-4.3.1.tgz#0b57da70e982572de09c8742dd0cb40a6b7c2cc3"
|
||||||
|
|||||||
Reference in New Issue
Block a user