Compare commits

..

136 Commits

Author SHA1 Message Date
Jordan Frankfurt
707abd0071 feat(widgets): ensure passed locale is supported (#3245)
* ensure passed locale is supported

* warn on locale mismatch

* export SUPPORTED_LOCALES
2022-02-07 19:57:26 -06:00
Jordan Frankfurt
2efc1fb372 fix(widgets): convert widget colors from hex to hsl (#3239)
* convert widget colors from hex to hsl

* nits
2022-02-07 17:15:24 -06:00
Jordan Frankfurt
55b37825f3 fix(widgets): white accentText color on some buttons (#3238)
* white accentText color on some buttons

* put color calculations in useMemo, change accentText name, make hsl hex

* onAccent -> onAccentText
2022-02-07 16:56:10 -06:00
Ian Lapham
bb27b7a2ef feat: widget loading animations polish (#3232)
* create use best trade hook for widgets

* update comment in hook file

* add loading states to input / output fields

* update to not use imports from app

* remove custom loading component

* update var name and syncing detection logic

* fix USD div type

* simplify loading css, small changes
2022-02-07 14:38:07 -08:00
Zach Pomerantz
c595ba951b fix: isolate infura (#3241)
* fix: rm infura urls from lib

* fix: use passed providers for client SOR

* fix: clean up supported chain ids

* nit: rename params with specificity

* fix: use public rpc urls for l2

* fix: special-case rpc urls
2022-02-07 10:12:45 -08:00
Zach Pomerantz
96a122d7b8 chore: rename web3-react-alpha (#3243)
Renames widgets-web3-react/* to @widgets/web3-react/*.
npm treats nested packages as scoped, and requires scoped packages to begin with @.
2022-02-07 08:50:01 -08:00
Zach Pomerantz
610f7d3581 fix: named imports (webpack 5 compat) (#3242)
* fix: avoid json named imports

This is required by webpack 5, and is done to keep the widgets library compatible.
See https://webpack.js.org/migrate/5/#using-named-exports-from-json-modules

Note that this must be done upstream as well, in @uniswap/v3-sdk and @uniswap/router-sdk.

* chore: bump v3-sdk to avoid json named imports
2022-02-07 08:49:48 -08:00
Zach Pomerantz
781e774ce7 fix: set dialog wrapper with callback (#3240) 2022-02-04 16:08:50 -08:00
Ian Lapham
2aa1e40481 feat: create use best trade hook for widgets (#3226)
* create use best trade hook for widgets

* update comment in hook file

* refactor loading state conditional

* update logic in use best trade

* clean code in best trade hook
2022-02-04 18:38:27 -05:00
Zach Pomerantz
1c278d5012 fix: close summary after confirmation (#3233) 2022-02-03 15:04:11 -08:00
Jordan Frankfurt
a323a5c48b feat(widgets): convenience fee (#3231)
* feat(widgets): support convenience fee in trades (#3219)

* feat(widgets): support convenience fee in trades

* update call signature

* pr feedback

* set default convenience fee to undefined

* pr feedback
2022-02-03 14:48:30 -06:00
Zach Pomerantz
43931dd689 feat: chain-specific ttls (#3228) 2022-02-03 11:30:50 -08:00
Zach Pomerantz
efa3d5529c fix: only show max where appropriate (#3229) 2022-02-03 11:30:24 -08:00
Zach Pomerantz
5c0246cfc6 feat: outline tooltips (#3230) 2022-02-03 11:30:05 -08:00
Jordan Frankfurt
ee32418ff8 Revert "feat(widgets): support convenience fee in trades (#3219)" (#3224)
This reverts commit 8064dd8ede.
2022-02-03 10:46:18 -06:00
Zach Pomerantz
6e22389791 fix: slippage and price impact ux (#3222) 2022-02-03 08:23:27 -08:00
Jordan Frankfurt
8064dd8ede feat(widgets): support convenience fee in trades (#3219)
* feat(widgets): support convenience fee in trades

* update call signature

* pr feedback
2022-02-03 09:38:42 -06:00
Crowdin Bot
921310ef52 chore(i18n): synchronize translations from crowdin [skip ci] 2022-02-03 08:06:38 +00:00
Ian Lapham
7b90fe137e update list component (#3221) 2022-02-02 17:52:38 -05:00
Ian Lapham
05b2711a8a feat: update widget with client side SOR (#3210)
* start SOR by creating custom widget hook

* update best trade hook to use SOR in widget

* update organization for client side SOR logic

* fix auto router chain id import

* remove dependency on react GA for widget

* update dependencies for SOr

* remove new useBestTrade.ts

* update loading logic for fetching hook

* update dependencies with import from ethersproject

* update import version

* add try catch on SOR usage

* code cleanup, nit fixes
2022-02-02 17:47:49 -05:00
Crowdin Bot
d060782242 chore(i18n): synchronize translations from crowdin [skip ci] 2022-02-02 22:07:03 +00:00
Zach Pomerantz
e19e8492c9 feat: ux warnings (#3220)
* chore: mv Toolbar to a directory

* refactor: clean up Toolbar

* refactor: simplify Toolbar Caption

* feat: warn on price impact in Summary

* refactor: add computeRealizedPriceImpact util
2022-02-02 13:55:36 -08:00
Ian Lapham
800b5e0bda fix: fix pricing displays (#3214)
* fix pricing displays

* update rate logic, code clean
2022-02-02 13:43:12 -05:00
Ian Lapham
fc637071f9 update deadline signature data (#3215) 2022-02-02 12:33:00 -05:00
Moody Salem
1b78ceec10 chore: lockfile update only from the walletlink connector update 2022-02-02 00:13:29 -05:00
Moody Salem
e5be3ebf8f chore: put back the integrity hashes that were removed by the walletlink change 2022-02-02 00:12:59 -05:00
Brendan Weinstein
1c73719766 fix: update walletlink-connector to 6.2.11 (#3213) 2022-02-02 00:10:01 -05:00
Crowdin Bot
14c91f9bba chore(i18n): synchronize translations from crowdin [skip ci] 2022-02-02 00:13:11 +00:00
Zach Pomerantz
4b762ef5c9 feat: slippage warning ux (#3211)
* feat: setting input spacings

* feat: popover icon props

* fix: slippage input border

* feat: slippage input warning ux

* feat: slippage summary warning ux

* fix: summary layout

* fix: large icon compatibility

* fix: input option style

* fix: large icon compatibility

* fix: popover dimensions

* feat: tooltip hook

* fix: better max slippage popovers

* feat: error color input on invalid slippage

* fix: use default tx ttl

* fix: type userDeadline
2022-02-01 15:03:55 -08:00
Zach Pomerantz
c82b4fae64 fix: branded footer nits (#3209)
* chore: export brand color

* fix: target only children for extracted color transitions

* fix: branded footer nits
2022-01-31 14:08:39 -06:00
Zach Pomerantz
ab8c1e3e90 fix: input/output value/balance styles (#3207)
* fix: right-align balance

* fix: set min-height on text
2022-01-31 10:46:10 -08:00
Ian Lapham
7055d60406 remove survey (#3206) 2022-01-31 13:17:51 -05:00
Ian Lapham
c641cec651 update button color (#3205) 2022-01-31 13:02:58 -05:00
Brendan Weinstein
b6a47c734f fix: support networks other than ethereum mainnet for walletlink/coinbase wallet (#3202) 2022-01-31 12:03:00 -05:00
Crowdin Bot
7aecf5d398 chore(i18n): synchronize translations from crowdin [skip ci] 2022-01-28 20:07:31 +00:00
Crowdin Bot
5bf2b81743 chore(i18n): synchronize translations from crowdin [skip ci] 2022-01-28 18:07:13 +00:00
Ian Lapham
ed247065a7 feat: format usd prices, add loading states (#3196)
* format usd prices, add loading states

* remove tildes, collapse details by default

* update swap deadline to use seconds

* update syntax for loading states
2022-01-28 12:59:23 -05:00
Crowdin Bot
0d0ad633fb chore(i18n): synchronize translations from crowdin [skip ci] 2022-01-28 17:10:31 +00:00
Jordan Frankfurt
4a8f1d9b96 feat(widgets): move uniswap protocol branding from header to bottom of output (#3194)
* move branding from header to bottom of output

* remove old prop

* BrandingFooter component

* pr feedback
2022-01-28 10:45:35 -06:00
Zach Pomerantz
043fb95d22 chore: no default color extraction (#3192) 2022-01-27 13:24:50 -08:00
Zach Pomerantz
06536bc925 chore: comment out routing tooltip (#3191) 2022-01-27 13:24:39 -08:00
Ian Lapham
a598a15799 feat: Make pending txn status functional (#3193)
* update swap hooks to add swap txn confirmations

* fix: remove uneeded comments

* update with latest

* update utils to separate swap callback hooks

* create generic swap callabck to be used by both app and widget

* update app swap callback to use logic from lib

* update big number import

* add swap txn to state on submit

* remove redundant  fields in txn interfaces

* consolidate trade type logic
2022-01-27 13:38:35 -05:00
Crowdin Bot
b0265c081e chore(i18n): synchronize translations from crowdin [skip ci] 2022-01-27 01:28:46 +00:00
Zach Pomerantz
47aff6ff74 feat: max slippage ui (#3190)
* style: input padding

* feat: expand Row grow

* style: polish max slippage
2022-01-26 16:44:21 -08:00
Zach Pomerantz
56717005e6 feat: pending tx state (#3189)
* refactor: state cleanup

* feat: add pending tx hash to swap state

* fix: update name to display tx hash
2022-01-26 16:39:10 -08:00
Ian Lapham
b50d10cbb2 feat: update swap hooks and add swap txn submission (#3187)
* update swap hooks to add swap txn confirmations

* fix: remove uneeded comments

* update with latest

* update utils to separate swap callback hooks

* create generic swap callabck to be used by both app and widget

* update app swap callback to use logic from lib

* update big number import
2022-01-26 19:21:10 -05:00
Jordan Frankfurt
ce96873a72 feat(widgets): use default input/output (#3161)
* feat: use default input/output on chain switch

* feat(widgets): ErrorGenerator -> PropValidator

* default prop validation

* useDefaults hook

* pr feedback

* fix cosmos

* drop token map changes

* add default inputs to cosmos fixture

* set up different validation layers for widget and swap

* split widget/swap prop types

* cleanup

* pr feedback

* clear defaults when they're no longer valid on the current chain

* remove state checks on validators

* stop using address in cosmos fixture

* pr feedback

* useMemo on useSwapDefaults args

* tell the user what they gave to error'd props

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2022-01-26 12:14:18 -06:00
Tina
779625a04e fix: chain parameter should be able to switch chains on initial load (#3180)
* fix switch network on load

* dont run useeffect when chainId isnt defined yet

* remove newline
2022-01-26 10:03:48 -08:00
Crowdin Bot
d1e0812684 chore(i18n): synchronize translations from crowdin [skip ci] 2022-01-26 03:53:51 +00:00
Zach Pomerantz
98e62b4f93 Revert "chore(i18n): synchronize translations from crowdin [skip ci]"
This reverts commit 9fb0d424c2.
2022-01-25 19:46:36 -08:00
Crowdin Bot
9fb0d424c2 chore(i18n): synchronize translations from crowdin [skip ci] 2022-01-26 01:31:09 +00:00
Zach Pomerantz
8d145b908e feat: pending approval ui (#3186)
* feat: track approval txs

* refactor: update transactions

* feat: pending approval ui

* chore: fix pending approval doc

* fix: clarify optimized trade

* fix: use relative path for data uri assets
2022-01-25 16:24:36 -08:00
Zach Pomerantz
c7633d910b refactor: track txs (#3185)
* feat: track approval txs

* refactor: update transactions

* chore: add ms to deps

* test: rm stale test

* fix: comment usage of trade for optimized trade
2022-01-25 18:55:27 -05:00
Crowdin Bot
1f89a46a3f chore(i18n): synchronize translations from crowdin [skip ci] 2022-01-25 20:07:16 +00:00
Crowdin Bot
8d54b01878 chore(i18n): synchronize translations from crowdin [skip ci] 2022-01-25 19:07:17 +00:00
Zach Pomerantz
ffe334ccbf feat: update summary view with real values (#3179)
* refactor: isolate approval callback hooks

* fix: use approval callback from trade

* chore: pass optimized trade to summary

* start review screen UI updates

* chore: pass optimized trade to summary

* fix: pass Trade to summary

* remove uneeded value type

* remove uneeded styling

* code cleanup

* code styling, update props

* fix fixture bug, code style updates

* bug fix in details array

* update logic in details

Co-authored-by: ianlapham <ianlapham@gmail.com>
2022-01-25 13:48:52 -05:00
Zach Pomerantz
ffe2bd315e fix: track swap approvals (#3183)
* fix: track swap approvals

* fix: type ambiguous return value
2022-01-24 17:52:45 -08:00
Zach Pomerantz
cee4b8c77a fix: disable swap button w/o account (#3177)
* fix: disable swap button w/o account

* nit: indent less
2022-01-24 15:28:48 -08:00
Tina
3153db9f73 feat: add chainId (network) as url parameter (#3057)
* read from query param and change networks if necessary

* dont open network selector menu on url param change

* prompt network change when url changes

* keep url, network in sync

* use chain name instead of id in url param

* only prompt network switch if url chain doesnt match
2022-01-24 15:23:34 -08:00
Ian Lapham
bbdb5f3f56 feat: update slippage tolerance to use auto or custom (#3166)
* update slippage tolerance to use auto or custom

* remove attempted styling for other PR

* back out UI changes, small naming updates

* remove UI work

* small code style changes, fix typo

* update comment to doc comment
2022-01-24 17:56:12 -05:00
Crowdin Bot
7f9c56b68c chore(i18n): synchronize translations from crowdin [skip ci] 2022-01-24 20:08:12 +00:00
Crowdin Bot
2b69974fdc chore(i18n): synchronize translations from crowdin [skip ci] 2022-01-24 19:06:44 +00:00
Zach Pomerantz
5236065769 refactor: isolate approval callback hooks (#3172)
* refactor: isolate approval callback hooks

* fix: use approval callback from trade
2022-01-24 10:56:24 -08:00
Justin Domingue
52128a2dcd chore: reset local tick data state on input change (#3176) 2022-01-24 11:10:33 -05:00
Justin Domingue
c9642c6cd0 feat: use TickLens on chains where subgraph is not functional (#3149) 2022-01-24 09:12:07 -05:00
Crowdin Bot
b878d764e5 chore(i18n): synchronize translations from crowdin [skip ci] 2022-01-23 18:09:33 +00:00
Will Hennessy
6a4f067ac0 Display message if not mainnet (#3151) 2022-01-23 12:31:40 -05:00
Crowdin Bot
e9407bb6bd chore(i18n): synchronize translations from crowdin [skip ci] 2022-01-22 15:07:19 +00:00
Crowdin Bot
8d822fd0e0 chore(i18n): synchronize translations from crowdin [skip ci] 2022-01-22 10:08:02 +00:00
Zach Pomerantz
6404ee6e0b fix: default tokens on chainId change only (#3169) 2022-01-21 13:14:50 -08:00
Crowdin Bot
8ac3ed1128 chore(i18n): synchronize translations from crowdin [skip ci] 2022-01-21 10:07:23 +00:00
Zach Pomerantz
b501974a76 feat: polish select (#3160)
* feat: filter selected currency from select

* test: use infura urls

* fix: load native with chain

* fix: use currencyId for key

* feat: switch currencies when selecting other

* fix: resolve merge conflict name
2022-01-20 16:15:23 -08:00
Zach Pomerantz
567fb0181c fix: chain mismatched currencies (#3163) 2022-01-20 16:12:42 -08:00
Crowdin Bot
8a37c427e6 chore(i18n): synchronize translations from crowdin [skip ci] 2022-01-21 00:11:38 +00:00
Ian Lapham
034b3e3e58 feat: Update swap state structure and attach to UI (#3155)
* refactor: mv settings state to own file

* chore: add default exports

* refactor: update swap state to match biz logic

* feat: copy biz logic to widgets

* Hook up UI to updated swap state

* fix: decimal inputs

* fix max slippage

* fix error in settings

* fix: typing errors

* revert: useBestTrade changes

* fix: use client side trade for widgets

* fix: exhaustive deps

* chore: add router-sdk

* fix: gate old web3 on widget env

* fix building errors

* update trade imports

* update hook naming for swap amount and currencies

* small changes

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2022-01-20 18:51:45 -05:00
Ian Lapham
053000e5fc fix: update address listt (#3159) 2022-01-20 14:50:27 -05:00
Crowdin Bot
b77e7deb49 chore(i18n): synchronize translations from crowdin [skip ci] 2022-01-20 03:06:53 +00:00
Crowdin Bot
c3321ae793 chore(i18n): synchronize translations from crowdin [skip ci] 2022-01-19 22:06:45 +00:00
Jordan Frankfurt
5dec0cf72b show wrong chain message instead of throwing on incorrect chain connection (#3153) 2022-01-19 15:52:41 -06:00
Zach Pomerantz
1efda07e7a refactor: mv try parse currency amount to lib utils (#3152) 2022-01-19 14:34:01 -05:00
Crowdin Bot
fd819260f9 chore(i18n): synchronize translations from crowdin [skip ci] 2022-01-19 16:11:52 +00:00
Jordan Frankfurt
8e3b2cb4b8 feat(widgets): add error reporting component, INTEGRATION ERROR type, and Missing provider error (#3110)
* add error reporting component, INTEGRATION ERROR type, and Missing provider error

* rename reporter to generator

* pr feedback

* refactor provider check

* add chainId, convenienceFee, and width errors

* pr feedback and convenienceFeeRecipient address enforcement

* fix imports for utils
2022-01-19 09:38:21 -06:00
Zach Pomerantz
d54783a324 fix: memoize more swap (#2950)
* fix: memoize derived swap info

* fix: memoize current block timestamp

* fix: memoize price impact

* fix: memoize debounced value updates

* fix: nits
2022-01-18 18:40:23 -05:00
Zach Pomerantz
850a20f6ad feat: include native currency in widget select (#3124)
* fix: token image for chains / natives

* feat: include native currency in select

- Updates widgets swap state to use Currency (and deals with downstream updates)
- Refactors logoURI code to a new lib/hooks/useCurrencyLogoURIs
- Adds native currency to useQueryTokenList

NB: This does not build because tests must be updated to use Currency (they currently use mock tokens)

* test: update fixtures to use real currency

* fix: data uri color extraction

* fix: token img state

* fix: use new array
2022-01-18 12:11:22 -08:00
Zach Pomerantz
99f681818f refactor: mv token hooks to lib (#3122)
* refactor: mv useNativeCurrency to lib/hooks

* refactor: mv useCurrency logic to lib/hooks
2022-01-14 11:30:04 -08:00
Crowdin Bot
1127e74357 chore(i18n): synchronize translations from crowdin [skip ci] 2022-01-14 19:07:20 +00:00
Ian Lapham
27843f6189 update end timestamp for survey (#3121) 2022-01-14 11:46:13 -07:00
Ian Lapham
1b10c88c51 feat: add survey popup for survey monkey (#3116)
* add survey popup for survey monkey

* update useEffect and add 24 hour window

* upate % logic

* update logic to show after duration

* update timestamp conditional

* small changes
2022-01-14 11:33:31 -07:00
Crowdin Bot
5d97cbf6ad chore(i18n): synchronize translations from crowdin [skip ci] 2022-01-14 08:11:26 +00:00
Crowdin Bot
064a73ca1b chore(i18n): synchronize translations from crowdin [skip ci] 2022-01-14 07:07:17 +00:00
Zach Pomerantz
e5a1cb4276 chore: replace microbundle with rollup (#3115)
* refactor: mv gas estimate chains out of component

* chore: replace microbundle with rollup

* chore: use ts rollup config

* chore: rename lib to widgets

* chore: add rollup doc comment

* feat: rollup typings

* fix: retain tsconfig decl dir
2022-01-13 17:11:27 -08:00
Zach Pomerantz
e68e1afd9d feat: sort the widget token select (#3114)
* refactor: mv token list utils to lib

* refactor: mv balance hooks to lib

* feat: interactive token select
2022-01-13 14:37:47 -08:00
Zach Pomerantz
8784a761d6 feat: add multicall to widget (#3112)
* feat: mv block number to atom

* fix: add block updater

* fix: fast forward dep

* refactor: mv multicall to lib

* feat: add multicall to widget

* chore: update widget deps

* nit: pluralize updaters

* chore: minimize deps
2022-01-13 08:54:08 -08:00
Zach Pomerantz
7aa0f500d6 feat: mv block number to atom (#3108)
* feat: mv block number to atom

* fix: add block updater

* fix: fast forward dep
2022-01-12 19:36:08 -08:00
Jordan Frankfurt
06a8151ede Revert "add error reporting component, INTEGRATION ERROR type, and Missing provider error (#3107)" (#3109)
This reverts commit ac2642fedc.
2022-01-12 14:24:23 -06:00
Jordan Frankfurt
ac2642fedc add error reporting component, INTEGRATION ERROR type, and Missing provider error (#3107) 2022-01-12 13:29:59 -06:00
Zach Pomerantz
ac962fb00d refactor: separate useActiveWeb3React (#3106) 2022-01-12 11:18:11 -08:00
Zach Pomerantz
f3bcf64144 refactor: split chain info from chains (#3105) 2022-01-12 10:46:41 -08:00
Zach Pomerantz
711b2ca85c chore: import @ethersprojects directly (#3104)
* Revert "chore: import from ethers"

This reverts commit 6d9c0855d2.

* Revert "fix: use provider JsonRpcProvider"

This reverts commit dcbbab5e4d.

* chore: depend on @ethersprojects directly
2022-01-12 10:06:22 -08:00
willpote
aa97ec01d3 chore: bump sor to 2.5.10 (#3091) 2022-01-11 17:26:42 -05:00
Crowdin Bot
83b70f3aa6 chore(i18n): synchronize translations from crowdin [skip ci] 2022-01-11 21:06:53 +00:00
Noah Zinsmeister
e37dd77680 Revert "bump to beta (#3090)"
This reverts commit aa37b23126.
2022-01-11 16:00:52 -05:00
Noah Zinsmeister
aa37b23126 bump to beta (#3090) 2022-01-11 15:30:45 -05:00
Jordan Frankfurt
5a90f13a03 chore(deps): bump walletconnect (#3097) 2022-01-11 14:16:35 -06:00
Will Hennessy
8c213f9001 Update wrong network message (#3089)
fixes https://github.com/Uniswap/interface/issues/2740
2022-01-11 14:16:19 -06:00
Jordan Frankfurt
5722902f96 add polygon to supported walletlink chainIds (#3096) 2022-01-11 14:15:09 -06:00
Zach Pomerantz
27412e49d5 chore: import from ethers (#3094)
* chore: rm lodash

* chore: improve styled-components lint

* chore: import from ethers

* fix: use provider JsonRpcProvider
2022-01-11 11:32:20 -08:00
Zach Pomerantz
90dfdc6bef feat: populate the widget token selector (#3080)
* feat: swap defaults

* refactor: mv token list utils to lib

* feat: expand fetchTokenList to include inlined

* feat: simple widget token list

* fix: token img props

* feat: use token list in selector

* fix: update useColor for optional logoURI

* fix: avoid leaking deps

* chore: add state to lib build

* chore: mv devDeps to deps for lib

* fix: microbundle css import

* fix: match ethers versions

* fix: use color callback

* chore: clean up token info type

* chore: widget type simplification

* refactor: share token map code

* test: include list in token select fixture

* fix: no tokens without chain id
2022-01-11 09:28:02 -08:00
Jordan Frankfurt
4f896361be fix(widgets): correctly position the arrows (#3083)
* correctly position the arrows

* update reverse button css and remove popover logic

* px->em
2022-01-11 09:50:39 -06:00
yj
c9bc166c1a fix: Add {id} replacement for ERC-1155 (#3068)
* Add `{id}` replacement for ERC-1155

For issue #3010

* Update useENSAvatar.ts

Add leading zero pad to 64 hex chars

* Update useENSAvatar.ts

Following review comments
2022-01-10 23:20:04 -05:00
Noah Zinsmeister
cecbf770c6 w3r version bumps (#3086) 2022-01-10 14:43:17 -05:00
Jordan Frankfurt
a7041ea700 undo accidental package version reversion (#3084) 2022-01-10 12:17:56 -06:00
Ian Lapham
5413303d24 update addresses (#3082) 2022-01-08 17:36:18 -05:00
dependabot[bot]
103e18496f chore(deps-dev): bump @uniswap/default-token-list from 2.2.0 to 3.0.0 (#3076)
Bumps [@uniswap/default-token-list](https://github.com/Uniswap/default-token-list) from 2.2.0 to 3.0.0.
- [Release notes](https://github.com/Uniswap/default-token-list/releases)
- [Commits](https://github.com/Uniswap/default-token-list/compare/v2.2.0...v3.0.0)

---
updated-dependencies:
- dependency-name: "@uniswap/default-token-list"
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-07 11:13:41 -05:00
Crowdin Bot
0e678465cb chore(i18n): synchronize translations from crowdin [skip ci] 2022-01-06 11:07:11 +00:00
Crowdin Bot
6b68baaa4d chore(i18n): synchronize translations from crowdin [skip ci] 2022-01-06 10:06:28 +00:00
Crowdin Bot
3c5e3744f1 chore(i18n): synchronize translations from crowdin [skip ci] 2022-01-06 05:09:06 +00:00
Crowdin Bot
d93b6f795e chore(i18n): synchronize translations from crowdin [skip ci] 2022-01-06 04:07:29 +00:00
Jordan Frankfurt
f145a56f4a fix: web3-react-fixes (#3066) (#3075)
* add empty connector

add url connector

* naming

Co-authored-by: Noah Zinsmeister <noahwz@gmail.com>
2022-01-05 20:48:33 -06:00
Ian Lapham
7622290557 update state org and get latest (#3073) 2022-01-05 16:17:13 -05:00
Crowdin Bot
226544402a chore(i18n): synchronize translations from crowdin [skip ci] 2022-01-05 20:06:38 +00:00
Ian Lapham
49fee909bc update unsupported list (#3071) 2022-01-05 14:07:01 -05:00
Crowdin Bot
f458ec8e12 chore(i18n): synchronize translations from crowdin [skip ci] 2022-01-05 19:05:50 +00:00
Jordan Frankfurt
f9fc506db4 chore: merge widgets work into main (#3065)
* feat: design system (#2622)

* refactor: mv setInterval to lib (#2621)

* chore: widget tooling (#2620)

* chore: remove global styles from cosmos viewer

* chore: add generated svgs to bundle

* chore: alias lib within lib

* feat: widgets swap settings and arch (#2629)

* style: update theme

* feat: grid-based row/column

* feat: widget/modal arch

* feat: tooltip arch

* feat: atoms arch

* feat: swap settings

* chore: update deps

* fix: input width

* refactor: modularize Tooltip

* feat: add grow to Row

* style: true prop

* refactor: clean NumericInput

* fix: customizable data structure

* chore: sort styled-components

* fix: import ReactNode

* fix: svgr index generation

* chore: run tests on widgets (#2635)

* chore: widgets nits (#2636)

* fix: restrict type color to theme

* feat: add types

* fix: input width

* fix: header divider

* fix: eslint

* fix: color name

* fix: use inputs for a11y (#2646)

* fix: clearable customizable

* feat: accent hovered select option

* feat: custom slippage color

* fix: use buttons for a11y

* fix: widgets styles (#2654)

* style: add body1

* refactor: modularize theme/components

* refactor: modularize all text Input

* fix: toggle opacity

* test: fixture arch

* feat: rm gas price select

* fix: toggle styles/strings

* feat: mock toggle

* fix: dialog overflow clipping

* fix: mix-blend-mode for safari

* fix: clip-path for safari svg

* fix: mock toggle content

* fix: input margin

* fix: input and cursor

* fix: validate . input

* fix: unused useMemo

* feat: widgets empty state (#2657)

* refactor: TextButton

* feat: inline icons

* feat: swap empty state

* feat: define TokenSelect

* fix: always inline icons

* feat: recent transactions (#2661)

* feat: wallet button

* fix: tx deps

* feat: widgets token select (#2685)

* fix: line height of 1

* fix: button margin

* fix: update styles

* feat: token select

* refactor: mocks and types

* feat: close dialog on esc

* feat: focus input on token select

* refactor: layer swap elements

* feat: use token color

* fix: widget theme

* fix: use vibrant

* chore: lodash types

* fix: fixture props

* feat: smoother color extraction

* fix: vibrant dep

* perf: extract input token color too

* feat: eased token background

* feat: token color prefetching

* chore: mv polished to deps

* chore: package management

* fix: token background transition

* fix: better color transitions

* feat: widgets UI (#2742)

* feat: add swap states

* fix: widget-global box-sizing

* feat: desaturate and opacity on token approval

* feat: red balance on balance insufficient

* fix: states

* feat: action button

* refactor: action button

* feat: loading spinner border

* fix: typescript errors

* fix: token color transition

* fix: unused typings

* feat: swap summary sans tooltip

* refactor: swap state

* feat: swap summary

* refactor: simpler swap names

* fix: cutoffs around footer

* refactor: recent txs

* refactor: buttons

* feat: tx status

* fix: consistent formatting

* feat: tx error

* test: tx error

* test: widget decorator

* style: theming

* fix: clean up dialogs

* fix: clean up swap

* fix: clean up overlays

* fix: action button text on hover

* fix: pickAtom

* fix: pickAtom typings

* fix: smoother error transition

* feat: enter for toggle

* fix: select tabbing

* refactor: simplify dialogs

* feat: widgets polish (#2757)

* fix: loading spinner fallback for safari

* fix: use border for focus

* refactor: token options

* fix: use react toggle event

* fix: token select

* fix: inert content when modal

* fix: windowed token select

* chore: mv windowing utils to deps

* fix: windowing with no rerender

* feat: widget i18n (#2765)

* feat: configure widget i18n

* i18n: wrap translatable strings in macros

* fix: rm lib/locales

* refactor: t to trans

* feat: cosmos locale selector

* chore: widgets nits (#2786)

* fix: tooltip color

* fix: tx ttl tooltip

* fix: tooltip positioning

* fix: token list padding top

* style: responsive tx

* nit: fix summary copy

* chore: change byline

* feat(widgets): add new @web3-react cosmos decorator (#2799)

 add new @web3-react cosmos decorator and provider api to widget

* feat: token color mock (#2878)

* chore: merge main into widgets (#2893)

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix: center focused outline card (#2625)

* fix: add usdc to arbitrum/optimism common bases (#2641)

* remove WETH from optimism bases (#2640)

* use l2 logos in base pairs (#2634)

* fix: split calls into more chunks if they fail due to out of gas errors (#2630)

* fix: split calls into more chunks if they fail due to out of gas errors

* set to 100m gas

* back to 25m so we batch fewer calls

* do not pass through gas limit, some simplification of the code

* unused import

* fix: restrict @davatar usage to avoid 3p fetches (#2649)

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix(L2): ensure chainIds match before fetching pool data (#2652)

* ensure chainIds match before fetching pool data

* debounce both input currencies, and only look for pairs on currencies that share a chainId

* pr feedback

* fix: use optional operator for chainId (#2666)

* chore: update token list (#2670)

* update token list

* Fix code style issues with ESLint

Co-authored-by: Lint Action <lint-action@samuelmeuli.com>

* fix: update token list (#2671)

* update token list

* Fix code style issues with ESLint

Co-authored-by: Lint Action <lint-action@samuelmeuli.com>

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* feat: extend privacy and terms (#2623)

* initial iteration

* add logging

* added hook

* polish

* remove unused import

* add hash

* addressed pr feedback

* remove autorouter icon

* use firebase store

* style

* adjust recat ga

* log remove liquidity

* update copy

* addressed pr feedback

* addressed pr feedback

* prevent privacy content from dismissing modal

* make top-level key origin

* use hostname

* restore trm

* chore(i18n): synchronize translations from crowdin [skip ci]

* log full signed tx (#2681)

* refactor monitoring (#2682)

* chore: set final privacy learn more link' (#2684)

* add learn more button

* add final link

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix: back arrow bug in wallet modal and fill tx for wallet (#2687)

* add tx to wallet connect

* remove id from env

* restore env

* block import of unsupported tokens (#2673)

generalize custom import token block ui

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(deps-dev): bump @uniswap/token-lists (#2699)

* chore(i18n): synchronize translations from crowdin [skip ci]

* try out 'dimension1' (#2704)

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix: walletconnect modal re-open after user rejection (#2693)

Co-authored-by: M0kY <moky@example.com>

* chore: update unsupported token list (#2689)

* chore: update unsupported token list

* Fix code style issues with ESLint

Co-authored-by: Lint Action <lint-action@samuelmeuli.com>

* fix: memoize the list stuff so the tokens are consistently clickable (#2724)

* chore(i18n): synchronize translations from crowdin [skip ci]

* feat: update cmc list link (#2710)

* update cmc lists

* update CMC url

* add token to unsupported list (#2732)

* don't overwrite localstorage lists when fetch throws (#2723)

* try cd1 for custom dimension (#2734)

* fix: Update walletlink-connector to 6.2.8 (#2655)

* Update walletlink-connector to 6.2.5 which has a walletlink update to support addEthereumChain+switchEthereumChain requests

* Update walletlink-connector to 6.2.7

* Update walletlink-connector to 6.2.8

* fix: Parse latest proposal description correctly

* add proposal start time (#2738)

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix: #2741 Increase liquidity form off center (#2746)

* fix: bump to latest token list including ENS token

* fix: remove deprecated optimism status url (#2771)

* feat: Menu update. Add help center & feature requests. Remove analytics & github. (#2709)

* Add help center, remove analytics from menu

* Add canny feature requests link, remove github link

* add coffee icon

* no unused imports eslint rule (#2773)

* chore(i18n): synchronize translations from crowdin [skip ci]

* add protocols param to quote endpoint (#2774)

* add protocols param to quote endpoint

* Fix code style issues with ESLint

Co-authored-by: Lint Action <lint-action@samuelmeuli.com>

* fix: lint error (#2775)

* fix(optimism): Optimism regenesis support (#2703)

* feat(optimism): optimistic kovan local regenesis changes

* use the regenesis version of the sdk

* remove the override no longer necessary

* diff rpc url

* back to kovan url

* lint error

* Optimism mainnet regenesis test (#2695)

* remove the optimism mainnet specific code and point to the mainnet regenesis rpc url

* point at the old mainnet multicall address

* bump the sdk version

* copy the list

* multicall address regenesis change

* revert the gas limit special casing for optimism

* bump the sdk version

* remove a couple other temporary edits

* unused test case

* specific version of v3-sdk

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* feat: add support for 0.01% tier (#2769)

* chore: add support for 0.01% tier

* only show 1bps on mainnet

* rename VERY_LOW to LOWEST

* upgrade to v3-sdk 3.7.0

* add snapshot testing for lowest tier

* fix integration test

* fix integration test

* use ALL_SUPPORTED_CHAIN_IDS over string all

* consider 0.01% tier in pool (#2770)

* merge main and only consider lowest tier for mainnet

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix(L2): update block warning updater to check most recent block timestamp (#2777)

* update block warning updater to check most recent block timestamp

* stop doing dumb state manipulation

* fix: copy in network alert

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix(L2): remove redux from chain connectivity (#2781)

* remove redux from chain connectivity

* useMachineTimeMs instead of Date.now to force updates, useCurrentBlockTimestamp

* use useInterval

* change not created font size to 10 (#2785)

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix: format date using Date.toLocaleString (#2459)

* fix: format date using Date.toLocaleString

Fixes #2458

* fix: date typings

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix: broken link to docs (#2816)

* chore: fix typo in useAllCurrencyCombinations.ts (#2778)

occurence -> occurrence

* chore: update typechain scripts for Windows (#2707)

There are two errors when deploying on Windows system:
1. Using single quotes in path argument doesn't seem to be accepted in typechain command
2. `?(v3-core|v3-periphery)` operator doesn't work

Here are fixes/workarounds.

* perf: lazy load vote related routes (#2468)

* perf: lazy load vote related routes

* wrap Switch in Suspense

* remove exact to match nested routes

* fix nested routes

* split Landing

* fix

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix: Enable 3085 requests for coinbase wallet (#2753)

enable 3085 requests for coinbase wallet

* feat: set the auto slippage tolerance by the dollar value of gas (#2815)

* feat: set the auto slippage tolerance by the dollar value of gas

* comments

* min/max at 0.5% to 25%

* oops on constant

* address review feedback

* Fixing #2818 (#2820)

* Fix code style issues with ESLint

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix: fix #2818

* chore(i18n): synchronize translations from crowdin [skip ci]

* log an event on max click (#2827)

* Add trailing slash to L2 info links (#2696)

Some links were broken. For example on /pools/ page click the 'Top Pools' CTA. It would mistakenly direct you to info.uniswap.org/optimismpools instead of optimism/pools

* fix(L2): block L2 tokens explicitly linked to L1 tokens that are blocked (#2721)

* block L2 tokens explicitly linked to L1 tokens that are blocked

* Fix code style issues with ESLint

* check for support on all connectors, and disable when the connector (or lack thereof) no longer supports 3085 (#2824)

* feat: display an ENS avatar (#2806)

* feat: ens avatar resolution

* chore: uninstall @davatar/react

* fix: add avatar alt

* feat: support data uris

* feat: support arweave uris

* feat: support erc721 avatars

* feat: support erc1155 avatars

* fix: jazzicon integration

* fix: clean usage of status icon

* fix: fix jazzicon svg offset

* refactor: share status icon component

* fix: pass memoized args to multicall

* Update locales.ts (#2825)

update Finnish from person (Suomalainen) to language (suomi)

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore: fix the build blocking linter error

* chore: run linters with auto_fix = false for forks (#2852)

* fix: do not show urls if issue is not occurring on app.uniswap.org (#2855)

* fix: do not show urls if issue is not occurring on app.uniswap.org

fixes https://github.com/Uniswap/interface/issues/2572

* address comment

* fix: remove orphaned node (#2863)

* fix: remove orphaned node

* fix: react cleanup

* refactor: use ref for jazzicon (#2874)

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(deps): bump ws from 5.2.2 to 5.2.3 (#2759)

Bumps [ws](https://github.com/websockets/ws) from 5.2.2 to 5.2.3.
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/5.2.2...5.2.3)

---
updated-dependencies:
- dependency-name: ws
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps): bump url-parse from 1.5.1 to 1.5.3 (#2504)

Bumps [url-parse](https://github.com/unshiftio/url-parse) from 1.5.1 to 1.5.3.
- [Release notes](https://github.com/unshiftio/url-parse/releases)
- [Commits](https://github.com/unshiftio/url-parse/compare/1.5.1...1.5.3)

---
updated-dependencies:
- dependency-name: url-parse
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* add more tests for tryParseTick (#2110)

* fix(lint): clean up the eslint config (#2886)

* fix(lint): clean up the eslint config

* Fix code style issues with ESLint

* fix the linter errors that arose from using the proper config

* clean up the rebass text renames

* fix if statement, use the config

* use the same name prefix for both steps

* `TextPreset` -> `ThemedText`

Co-authored-by: Lint Action <lint-action@samuelmeuli.com>

* fix: Add routes for stakewise tokens (#2832)

* Add additional routes for stakewise tokens

* Reference StakeWise addresses with sdk tokens

* Sort token imports

* chore: yarn-deduplicate

* chore: lint widgets

* fix: use lib useInterval

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: Micael Rodrigues <micaelr95@outlook.pt>
Co-authored-by: Justin Domingue <judo@uniswap.org>
Co-authored-by: Moody Salem <moodysalem@users.noreply.github.com>
Co-authored-by: Jordan Frankfurt <jordanwfrankfurt@gmail.com>
Co-authored-by: Ian Lapham <ian@uniswap.org>
Co-authored-by: Lint Action <lint-action@samuelmeuli.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: M0kY <46133205+M0kY@users.noreply.github.com>
Co-authored-by: M0kY <moky@example.com>
Co-authored-by: Will Hennessy <hennessywill@gmail.com>
Co-authored-by: Brendan Weinstein <65564422+brendanww@users.noreply.github.com>
Co-authored-by: Noah Zinsmeister <noahwz@gmail.com>
Co-authored-by: Ben Krochta <35636764+bkrochta@users.noreply.github.com>
Co-authored-by: Moody Salem <moody.salem@gmail.com>
Co-authored-by: Raj <sukhrajghuman@live.com>
Co-authored-by: Ikko Ashimine <eltociear@gmail.com>
Co-authored-by: Matthew Salamon <35425388+Matthews3301@users.noreply.github.com>
Co-authored-by: Sam Chen <chenxsan@gmail.com>
Co-authored-by: Ali Eray Kısabacak <eraykisabacak@hotmail.com>
Co-authored-by: Kimmo S <kkpsiren@gmail.com>
Co-authored-by: Dmitri Tsumak <tsumak.dmitri@gmail.com>

* chore: merge main into widgets (#2923)

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix: center focused outline card (#2625)

* fix: add usdc to arbitrum/optimism common bases (#2641)

* remove WETH from optimism bases (#2640)

* use l2 logos in base pairs (#2634)

* fix: split calls into more chunks if they fail due to out of gas errors (#2630)

* fix: split calls into more chunks if they fail due to out of gas errors

* set to 100m gas

* back to 25m so we batch fewer calls

* do not pass through gas limit, some simplification of the code

* unused import

* fix: restrict @davatar usage to avoid 3p fetches (#2649)

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix(L2): ensure chainIds match before fetching pool data (#2652)

* ensure chainIds match before fetching pool data

* debounce both input currencies, and only look for pairs on currencies that share a chainId

* pr feedback

* fix: use optional operator for chainId (#2666)

* chore: update token list (#2670)

* update token list

* Fix code style issues with ESLint

Co-authored-by: Lint Action <lint-action@samuelmeuli.com>

* fix: update token list (#2671)

* update token list

* Fix code style issues with ESLint

Co-authored-by: Lint Action <lint-action@samuelmeuli.com>

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* feat: extend privacy and terms (#2623)

* initial iteration

* add logging

* added hook

* polish

* remove unused import

* add hash

* addressed pr feedback

* remove autorouter icon

* use firebase store

* style

* adjust recat ga

* log remove liquidity

* update copy

* addressed pr feedback

* addressed pr feedback

* prevent privacy content from dismissing modal

* make top-level key origin

* use hostname

* restore trm

* chore(i18n): synchronize translations from crowdin [skip ci]

* log full signed tx (#2681)

* refactor monitoring (#2682)

* chore: set final privacy learn more link' (#2684)

* add learn more button

* add final link

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix: back arrow bug in wallet modal and fill tx for wallet (#2687)

* add tx to wallet connect

* remove id from env

* restore env

* block import of unsupported tokens (#2673)

generalize custom import token block ui

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(deps-dev): bump @uniswap/token-lists (#2699)

* chore(i18n): synchronize translations from crowdin [skip ci]

* try out 'dimension1' (#2704)

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix: walletconnect modal re-open after user rejection (#2693)

Co-authored-by: M0kY <moky@example.com>

* chore: update unsupported token list (#2689)

* chore: update unsupported token list

* Fix code style issues with ESLint

Co-authored-by: Lint Action <lint-action@samuelmeuli.com>

* fix: memoize the list stuff so the tokens are consistently clickable (#2724)

* chore(i18n): synchronize translations from crowdin [skip ci]

* feat: update cmc list link (#2710)

* update cmc lists

* update CMC url

* add token to unsupported list (#2732)

* don't overwrite localstorage lists when fetch throws (#2723)

* try cd1 for custom dimension (#2734)

* fix: Update walletlink-connector to 6.2.8 (#2655)

* Update walletlink-connector to 6.2.5 which has a walletlink update to support addEthereumChain+switchEthereumChain requests

* Update walletlink-connector to 6.2.7

* Update walletlink-connector to 6.2.8

* fix: Parse latest proposal description correctly

* add proposal start time (#2738)

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix: #2741 Increase liquidity form off center (#2746)

* fix: bump to latest token list including ENS token

* fix: remove deprecated optimism status url (#2771)

* feat: Menu update. Add help center & feature requests. Remove analytics & github. (#2709)

* Add help center, remove analytics from menu

* Add canny feature requests link, remove github link

* add coffee icon

* no unused imports eslint rule (#2773)

* chore(i18n): synchronize translations from crowdin [skip ci]

* add protocols param to quote endpoint (#2774)

* add protocols param to quote endpoint

* Fix code style issues with ESLint

Co-authored-by: Lint Action <lint-action@samuelmeuli.com>

* fix: lint error (#2775)

* fix(optimism): Optimism regenesis support (#2703)

* feat(optimism): optimistic kovan local regenesis changes

* use the regenesis version of the sdk

* remove the override no longer necessary

* diff rpc url

* back to kovan url

* lint error

* Optimism mainnet regenesis test (#2695)

* remove the optimism mainnet specific code and point to the mainnet regenesis rpc url

* point at the old mainnet multicall address

* bump the sdk version

* copy the list

* multicall address regenesis change

* revert the gas limit special casing for optimism

* bump the sdk version

* remove a couple other temporary edits

* unused test case

* specific version of v3-sdk

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* feat: add support for 0.01% tier (#2769)

* chore: add support for 0.01% tier

* only show 1bps on mainnet

* rename VERY_LOW to LOWEST

* upgrade to v3-sdk 3.7.0

* add snapshot testing for lowest tier

* fix integration test

* fix integration test

* use ALL_SUPPORTED_CHAIN_IDS over string all

* consider 0.01% tier in pool (#2770)

* merge main and only consider lowest tier for mainnet

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix(L2): update block warning updater to check most recent block timestamp (#2777)

* update block warning updater to check most recent block timestamp

* stop doing dumb state manipulation

* fix: copy in network alert

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix(L2): remove redux from chain connectivity (#2781)

* remove redux from chain connectivity

* useMachineTimeMs instead of Date.now to force updates, useCurrentBlockTimestamp

* use useInterval

* change not created font size to 10 (#2785)

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix: format date using Date.toLocaleString (#2459)

* fix: format date using Date.toLocaleString

Fixes #2458

* fix: date typings

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix: broken link to docs (#2816)

* chore: fix typo in useAllCurrencyCombinations.ts (#2778)

occurence -> occurrence

* chore: update typechain scripts for Windows (#2707)

There are two errors when deploying on Windows system:
1. Using single quotes in path argument doesn't seem to be accepted in typechain command
2. `?(v3-core|v3-periphery)` operator doesn't work

Here are fixes/workarounds.

* perf: lazy load vote related routes (#2468)

* perf: lazy load vote related routes

* wrap Switch in Suspense

* remove exact to match nested routes

* fix nested routes

* split Landing

* fix

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix: Enable 3085 requests for coinbase wallet (#2753)

enable 3085 requests for coinbase wallet

* feat: set the auto slippage tolerance by the dollar value of gas (#2815)

* feat: set the auto slippage tolerance by the dollar value of gas

* comments

* min/max at 0.5% to 25%

* oops on constant

* address review feedback

* Fixing #2818 (#2820)

* Fix code style issues with ESLint

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix: fix #2818

* chore(i18n): synchronize translations from crowdin [skip ci]

* log an event on max click (#2827)

* Add trailing slash to L2 info links (#2696)

Some links were broken. For example on /pools/ page click the 'Top Pools' CTA. It would mistakenly direct you to info.uniswap.org/optimismpools instead of optimism/pools

* fix(L2): block L2 tokens explicitly linked to L1 tokens that are blocked (#2721)

* block L2 tokens explicitly linked to L1 tokens that are blocked

* Fix code style issues with ESLint

* check for support on all connectors, and disable when the connector (or lack thereof) no longer supports 3085 (#2824)

* feat: display an ENS avatar (#2806)

* feat: ens avatar resolution

* chore: uninstall @davatar/react

* fix: add avatar alt

* feat: support data uris

* feat: support arweave uris

* feat: support erc721 avatars

* feat: support erc1155 avatars

* fix: jazzicon integration

* fix: clean usage of status icon

* fix: fix jazzicon svg offset

* refactor: share status icon component

* fix: pass memoized args to multicall

* Update locales.ts (#2825)

update Finnish from person (Suomalainen) to language (suomi)

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore: fix the build blocking linter error

* chore: run linters with auto_fix = false for forks (#2852)

* fix: do not show urls if issue is not occurring on app.uniswap.org (#2855)

* fix: do not show urls if issue is not occurring on app.uniswap.org

fixes https://github.com/Uniswap/interface/issues/2572

* address comment

* fix: remove orphaned node (#2863)

* fix: remove orphaned node

* fix: react cleanup

* refactor: use ref for jazzicon (#2874)

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(deps): bump ws from 5.2.2 to 5.2.3 (#2759)

Bumps [ws](https://github.com/websockets/ws) from 5.2.2 to 5.2.3.
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/5.2.2...5.2.3)

---
updated-dependencies:
- dependency-name: ws
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps): bump url-parse from 1.5.1 to 1.5.3 (#2504)

Bumps [url-parse](https://github.com/unshiftio/url-parse) from 1.5.1 to 1.5.3.
- [Release notes](https://github.com/unshiftio/url-parse/releases)
- [Commits](https://github.com/unshiftio/url-parse/compare/1.5.1...1.5.3)

---
updated-dependencies:
- dependency-name: url-parse
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* add more tests for tryParseTick (#2110)

* fix(lint): clean up the eslint config (#2886)

* fix(lint): clean up the eslint config

* Fix code style issues with ESLint

* fix the linter errors that arose from using the proper config

* clean up the rebass text renames

* fix if statement, use the config

* use the same name prefix for both steps

* `TextPreset` -> `ThemedText`

Co-authored-by: Lint Action <lint-action@samuelmeuli.com>

* fix: Add routes for stakewise tokens (#2832)

* Add additional routes for stakewise tokens

* Reference StakeWise addresses with sdk tokens

* Sort token imports

* fix: fix layout of proposal list items on the vote page on mobile (#2898)

* fix: fixing layout from using grid to flexbox

* fix: setting WrapSmall to nowrap due to layout issue on mobile

* fix: using width auto instead of disabling flex wrap

Co-authored-by: Julian Anderson <juliancanderson@gmail.com>

* fix: typo in arweave URI recognition (#2901)

* deleted files

* Revert "Merge branch 'main' of https://github.com/Uniswap/interface" (#2912)

This reverts commit bf7a40be7a, reversing
changes made to 097b8361d4.

* fix: inadvertent merges/reverts (#2915)

* Revert "Revert "Merge branch 'main' of https://github.com/Uniswap/interface" (#2912)"

This reverts commit 7d343dcfbd.

* Revert "deleted files"

This reverts commit 097b8361d4.

* refactor: Replace multicall implementation with library (#2768)

- Replace the local implementation of multicall with the new redux-multicall lib
- Create wrappers for redux-multicall hooks to inject block number and chainId

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: Micael Rodrigues <micaelr95@outlook.pt>
Co-authored-by: Justin Domingue <judo@uniswap.org>
Co-authored-by: Moody Salem <moodysalem@users.noreply.github.com>
Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
Co-authored-by: Ian Lapham <ian@uniswap.org>
Co-authored-by: Lint Action <lint-action@samuelmeuli.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: M0kY <46133205+M0kY@users.noreply.github.com>
Co-authored-by: M0kY <moky@example.com>
Co-authored-by: Will Hennessy <hennessywill@gmail.com>
Co-authored-by: Brendan Weinstein <65564422+brendanww@users.noreply.github.com>
Co-authored-by: Noah Zinsmeister <noahwz@gmail.com>
Co-authored-by: Ben Krochta <35636764+bkrochta@users.noreply.github.com>
Co-authored-by: Moody Salem <moody.salem@gmail.com>
Co-authored-by: Raj <sukhrajghuman@live.com>
Co-authored-by: Ikko Ashimine <eltociear@gmail.com>
Co-authored-by: Matthew Salamon <35425388+Matthews3301@users.noreply.github.com>
Co-authored-by: Sam Chen <chenxsan@gmail.com>
Co-authored-by: Ali Eray Kısabacak <eraykisabacak@hotmail.com>
Co-authored-by: Kimmo S <kkpsiren@gmail.com>
Co-authored-by: Dmitri Tsumak <tsumak.dmitri@gmail.com>
Co-authored-by: Julian Anderson <juliancanderson@gmail.com>
Co-authored-by: Carlos Diaz-Padron <carlosdiazpadron@gmail.com>
Co-authored-by: J M Rossy <jm.rossy@gmail.com>

* feat: Multicall lib integration for widgets (#2946)

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix: center focused outline card (#2625)

* fix: add usdc to arbitrum/optimism common bases (#2641)

* remove WETH from optimism bases (#2640)

* use l2 logos in base pairs (#2634)

* fix: split calls into more chunks if they fail due to out of gas errors (#2630)

* fix: split calls into more chunks if they fail due to out of gas errors

* set to 100m gas

* back to 25m so we batch fewer calls

* do not pass through gas limit, some simplification of the code

* unused import

* fix: restrict @davatar usage to avoid 3p fetches (#2649)

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix(L2): ensure chainIds match before fetching pool data (#2652)

* ensure chainIds match before fetching pool data

* debounce both input currencies, and only look for pairs on currencies that share a chainId

* pr feedback

* fix: use optional operator for chainId (#2666)

* chore: update token list (#2670)

* update token list

* Fix code style issues with ESLint

Co-authored-by: Lint Action <lint-action@samuelmeuli.com>

* fix: update token list (#2671)

* update token list

* Fix code style issues with ESLint

Co-authored-by: Lint Action <lint-action@samuelmeuli.com>

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* feat: extend privacy and terms (#2623)

* initial iteration

* add logging

* added hook

* polish

* remove unused import

* add hash

* addressed pr feedback

* remove autorouter icon

* use firebase store

* style

* adjust recat ga

* log remove liquidity

* update copy

* addressed pr feedback

* addressed pr feedback

* prevent privacy content from dismissing modal

* make top-level key origin

* use hostname

* restore trm

* chore(i18n): synchronize translations from crowdin [skip ci]

* log full signed tx (#2681)

* refactor monitoring (#2682)

* chore: set final privacy learn more link' (#2684)

* add learn more button

* add final link

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix: back arrow bug in wallet modal and fill tx for wallet (#2687)

* add tx to wallet connect

* remove id from env

* restore env

* block import of unsupported tokens (#2673)

generalize custom import token block ui

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(deps-dev): bump @uniswap/token-lists (#2699)

* chore(i18n): synchronize translations from crowdin [skip ci]

* try out 'dimension1' (#2704)

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix: walletconnect modal re-open after user rejection (#2693)

Co-authored-by: M0kY <moky@example.com>

* chore: update unsupported token list (#2689)

* chore: update unsupported token list

* Fix code style issues with ESLint

Co-authored-by: Lint Action <lint-action@samuelmeuli.com>

* fix: memoize the list stuff so the tokens are consistently clickable (#2724)

* chore(i18n): synchronize translations from crowdin [skip ci]

* feat: update cmc list link (#2710)

* update cmc lists

* update CMC url

* add token to unsupported list (#2732)

* don't overwrite localstorage lists when fetch throws (#2723)

* try cd1 for custom dimension (#2734)

* fix: Update walletlink-connector to 6.2.8 (#2655)

* Update walletlink-connector to 6.2.5 which has a walletlink update to support addEthereumChain+switchEthereumChain requests

* Update walletlink-connector to 6.2.7

* Update walletlink-connector to 6.2.8

* fix: Parse latest proposal description correctly

* add proposal start time (#2738)

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix: #2741 Increase liquidity form off center (#2746)

* fix: bump to latest token list including ENS token

* fix: remove deprecated optimism status url (#2771)

* feat: Menu update. Add help center & feature requests. Remove analytics & github. (#2709)

* Add help center, remove analytics from menu

* Add canny feature requests link, remove github link

* add coffee icon

* no unused imports eslint rule (#2773)

* chore(i18n): synchronize translations from crowdin [skip ci]

* add protocols param to quote endpoint (#2774)

* add protocols param to quote endpoint

* Fix code style issues with ESLint

Co-authored-by: Lint Action <lint-action@samuelmeuli.com>

* fix: lint error (#2775)

* fix(optimism): Optimism regenesis support (#2703)

* feat(optimism): optimistic kovan local regenesis changes

* use the regenesis version of the sdk

* remove the override no longer necessary

* diff rpc url

* back to kovan url

* lint error

* Optimism mainnet regenesis test (#2695)

* remove the optimism mainnet specific code and point to the mainnet regenesis rpc url

* point at the old mainnet multicall address

* bump the sdk version

* copy the list

* multicall address regenesis change

* revert the gas limit special casing for optimism

* bump the sdk version

* remove a couple other temporary edits

* unused test case

* specific version of v3-sdk

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* feat: add support for 0.01% tier (#2769)

* chore: add support for 0.01% tier

* only show 1bps on mainnet

* rename VERY_LOW to LOWEST

* upgrade to v3-sdk 3.7.0

* add snapshot testing for lowest tier

* fix integration test

* fix integration test

* use ALL_SUPPORTED_CHAIN_IDS over string all

* consider 0.01% tier in pool (#2770)

* merge main and only consider lowest tier for mainnet

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix(L2): update block warning updater to check most recent block timestamp (#2777)

* update block warning updater to check most recent block timestamp

* stop doing dumb state manipulation

* fix: copy in network alert

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix(L2): remove redux from chain connectivity (#2781)

* remove redux from chain connectivity

* useMachineTimeMs instead of Date.now to force updates, useCurrentBlockTimestamp

* use useInterval

* change not created font size to 10 (#2785)

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix: format date using Date.toLocaleString (#2459)

* fix: format date using Date.toLocaleString

Fixes #2458

* fix: date typings

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix: broken link to docs (#2816)

* chore: fix typo in useAllCurrencyCombinations.ts (#2778)

occurence -> occurrence

* chore: update typechain scripts for Windows (#2707)

There are two errors when deploying on Windows system:
1. Using single quotes in path argument doesn't seem to be accepted in typechain command
2. `?(v3-core|v3-periphery)` operator doesn't work

Here are fixes/workarounds.

* perf: lazy load vote related routes (#2468)

* perf: lazy load vote related routes

* wrap Switch in Suspense

* remove exact to match nested routes

* fix nested routes

* split Landing

* fix

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix: Enable 3085 requests for coinbase wallet (#2753)

enable 3085 requests for coinbase wallet

* feat: set the auto slippage tolerance by the dollar value of gas (#2815)

* feat: set the auto slippage tolerance by the dollar value of gas

* comments

* min/max at 0.5% to 25%

* oops on constant

* address review feedback

* Fixing #2818 (#2820)

* Fix code style issues with ESLint

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix: fix #2818

* chore(i18n): synchronize translations from crowdin [skip ci]

* log an event on max click (#2827)

* Add trailing slash to L2 info links (#2696)

Some links were broken. For example on /pools/ page click the 'Top Pools' CTA. It would mistakenly direct you to info.uniswap.org/optimismpools instead of optimism/pools

* fix(L2): block L2 tokens explicitly linked to L1 tokens that are blocked (#2721)

* block L2 tokens explicitly linked to L1 tokens that are blocked

* Fix code style issues with ESLint

* check for support on all connectors, and disable when the connector (or lack thereof) no longer supports 3085 (#2824)

* feat: display an ENS avatar (#2806)

* feat: ens avatar resolution

* chore: uninstall @davatar/react

* fix: add avatar alt

* feat: support data uris

* feat: support arweave uris

* feat: support erc721 avatars

* feat: support erc1155 avatars

* fix: jazzicon integration

* fix: clean usage of status icon

* fix: fix jazzicon svg offset

* refactor: share status icon component

* fix: pass memoized args to multicall

* Update locales.ts (#2825)

update Finnish from person (Suomalainen) to language (suomi)

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore: fix the build blocking linter error

* chore: run linters with auto_fix = false for forks (#2852)

* fix: do not show urls if issue is not occurring on app.uniswap.org (#2855)

* fix: do not show urls if issue is not occurring on app.uniswap.org

fixes https://github.com/Uniswap/interface/issues/2572

* address comment

* fix: remove orphaned node (#2863)

* fix: remove orphaned node

* fix: react cleanup

* refactor: use ref for jazzicon (#2874)

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(deps): bump ws from 5.2.2 to 5.2.3 (#2759)

Bumps [ws](https://github.com/websockets/ws) from 5.2.2 to 5.2.3.
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/5.2.2...5.2.3)

---
updated-dependencies:
- dependency-name: ws
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps): bump url-parse from 1.5.1 to 1.5.3 (#2504)

Bumps [url-parse](https://github.com/unshiftio/url-parse) from 1.5.1 to 1.5.3.
- [Release notes](https://github.com/unshiftio/url-parse/releases)
- [Commits](https://github.com/unshiftio/url-parse/compare/1.5.1...1.5.3)

---
updated-dependencies:
- dependency-name: url-parse
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* add more tests for tryParseTick (#2110)

* fix(lint): clean up the eslint config (#2886)

* fix(lint): clean up the eslint config

* Fix code style issues with ESLint

* fix the linter errors that arose from using the proper config

* clean up the rebass text renames

* fix if statement, use the config

* use the same name prefix for both steps

* `TextPreset` -> `ThemedText`

Co-authored-by: Lint Action <lint-action@samuelmeuli.com>

* fix: Add routes for stakewise tokens (#2832)

* Add additional routes for stakewise tokens

* Reference StakeWise addresses with sdk tokens

* Sort token imports

* fix: fix layout of proposal list items on the vote page on mobile (#2898)

* fix: fixing layout from using grid to flexbox

* fix: setting WrapSmall to nowrap due to layout issue on mobile

* fix: using width auto instead of disabling flex wrap

Co-authored-by: Julian Anderson <juliancanderson@gmail.com>

* fix: typo in arweave URI recognition (#2901)

* deleted files

* Revert "Merge branch 'main' of https://github.com/Uniswap/interface" (#2912)

This reverts commit bf7a40be7a, reversing
changes made to 097b8361d4.

* fix: inadvertent merges/reverts (#2915)

* Revert "Revert "Merge branch 'main' of https://github.com/Uniswap/interface" (#2912)"

This reverts commit 7d343dcfbd.

* Revert "deleted files"

This reverts commit 097b8361d4.

* refactor: Replace multicall implementation with library (#2768)

- Replace the local implementation of multicall with the new redux-multicall lib
- Create wrappers for redux-multicall hooks to inject block number and chainId

* package.json tweaks

* add multicall lib and some basic provider things

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: Micael Rodrigues <micaelr95@outlook.pt>
Co-authored-by: Justin Domingue <judo@uniswap.org>
Co-authored-by: Moody Salem <moodysalem@users.noreply.github.com>
Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
Co-authored-by: Ian Lapham <ian@uniswap.org>
Co-authored-by: Lint Action <lint-action@samuelmeuli.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: M0kY <46133205+M0kY@users.noreply.github.com>
Co-authored-by: M0kY <moky@example.com>
Co-authored-by: Will Hennessy <hennessywill@gmail.com>
Co-authored-by: Brendan Weinstein <65564422+brendanww@users.noreply.github.com>
Co-authored-by: Noah Zinsmeister <noahwz@gmail.com>
Co-authored-by: Ben Krochta <35636764+bkrochta@users.noreply.github.com>
Co-authored-by: Moody Salem <moody.salem@gmail.com>
Co-authored-by: Raj <sukhrajghuman@live.com>
Co-authored-by: Ikko Ashimine <eltociear@gmail.com>
Co-authored-by: Matthew Salamon <35425388+Matthews3301@users.noreply.github.com>
Co-authored-by: Sam Chen <chenxsan@gmail.com>
Co-authored-by: Ali Eray Kısabacak <eraykisabacak@hotmail.com>
Co-authored-by: Kimmo S <kkpsiren@gmail.com>
Co-authored-by: Dmitri Tsumak <tsumak.dmitri@gmail.com>
Co-authored-by: Julian Anderson <juliancanderson@gmail.com>
Co-authored-by: Carlos Diaz-Padron <carlosdiazpadron@gmail.com>
Co-authored-by: J M Rossy <jm.rossy@gmail.com>

* feat: widgets style update (#2939)

* feat: widgets empty state (#2951)

* chore: mv onHover to computed theme; reduce to 0.16

* chore: transparentize primary on hover

* chore: transparentize dynamic primary on hover

* style: restrict icon usage

Restricts icons to lib/icons. This ensures that icons are loaded as singletons outside of the React lifecycle. Doing otherwise hinders performance.

* fix: logo mix-blend-mode

* wip: empty states

* fix: accent/active colors

* wip: empty states

* fix: input hover states

* nit: specific user select

* nit: button transition

* nit: no button transition

* chore: better cosmos toggles

* chore: load inter

* make cosmos work with new required widget props (#2956)

* separate connector atoms (#2959)

* fix: widgets nits sans summary/status (#2960)

* fix: dynamic scrollbar

* feat: system theme hook

* nit: settings

* nit: large settings icons

* fix: accessible color computation

* fix: ignore status scroll for now

* fix: ignore txs scroll for now

* feat: widgets summary (#2980)

* fix: output first in toolbar

* fix: widget height

* feat: token color extraction toggle

* fix: header sizing

* fix: height nits

* chore: re-arch sub pages

* nit: height

* feat: border radius as range

* fix: exclude cosmos setter from hook deps

* feat: default width to 360

* feat: type classes

* fix: header height

* fix: default cosmos width to 360

* refactor: icon button

* wip: summary

* fix: scrollbar

* feat: summary

* fix: summary expando

* fix: widgets transitions (#2983)

* fix: action button height

* fix: summary scrollbar fading

* fix: summary fixture

* fix: action button transitions

* feat: widgets status (#2987)

* fix: action button height

* fix: summary scrollbar fading

* fix: summary fixture

* fix: action button transitions

* refactor: commit spinner as svg asset

* feat: status dialog

* fix: spinner rounding

* feat: widgets fonts and transitions (#2998)

* feat: fonts using @fontsource

* feat: dialog transitions

* fix: swap transitions

* Refactor use active web3 react (#3002)

* separate connector atoms

* refactor cosmos and set up widgets env var

* fix: cosmos modularization (#3014)

* fix: cosmos modularization

* fix: web3 in atom provider

* feat: make connectors resettable

* drop empty test (#3022)

* Revert "feat: make connectors resettable"

This reverts commit db5af68b9b.

* undo dumb open reorder

* bump widget web3-react versions

* bump to fix tests

Co-authored-by: Jordan Frankfurt <jordanwfrankfurt@gmail.com>
Co-authored-by: Noah Zinsmeister <noahwz@gmail.com>

* chore(widgets): Merge main into widgets (#3013)

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix: center focused outline card (#2625)

* fix: add usdc to arbitrum/optimism common bases (#2641)

* remove WETH from optimism bases (#2640)

* use l2 logos in base pairs (#2634)

* fix: split calls into more chunks if they fail due to out of gas errors (#2630)

* fix: split calls into more chunks if they fail due to out of gas errors

* set to 100m gas

* back to 25m so we batch fewer calls

* do not pass through gas limit, some simplification of the code

* unused import

* fix: restrict @davatar usage to avoid 3p fetches (#2649)

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix(L2): ensure chainIds match before fetching pool data (#2652)

* ensure chainIds match before fetching pool data

* debounce both input currencies, and only look for pairs on currencies that share a chainId

* pr feedback

* fix: use optional operator for chainId (#2666)

* chore: update token list (#2670)

* update token list

* Fix code style issues with ESLint

Co-authored-by: Lint Action <lint-action@samuelmeuli.com>

* fix: update token list (#2671)

* update token list

* Fix code style issues with ESLint

Co-authored-by: Lint Action <lint-action@samuelmeuli.com>

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* feat: extend privacy and terms (#2623)

* initial iteration

* add logging

* added hook

* polish

* remove unused import

* add hash

* addressed pr feedback

* remove autorouter icon

* use firebase store

* style

* adjust recat ga

* log remove liquidity

* update copy

* addressed pr feedback

* addressed pr feedback

* prevent privacy content from dismissing modal

* make top-level key origin

* use hostname

* restore trm

* chore(i18n): synchronize translations from crowdin [skip ci]

* log full signed tx (#2681)

* refactor monitoring (#2682)

* chore: set final privacy learn more link' (#2684)

* add learn more button

* add final link

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix: back arrow bug in wallet modal and fill tx for wallet (#2687)

* add tx to wallet connect

* remove id from env

* restore env

* block import of unsupported tokens (#2673)

generalize custom import token block ui

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(deps-dev): bump @uniswap/token-lists (#2699)

* chore(i18n): synchronize translations from crowdin [skip ci]

* try out 'dimension1' (#2704)

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix: walletconnect modal re-open after user rejection (#2693)

Co-authored-by: M0kY <moky@example.com>

* chore: update unsupported token list (#2689)

* chore: update unsupported token list

* Fix code style issues with ESLint

Co-authored-by: Lint Action <lint-action@samuelmeuli.com>

* fix: memoize the list stuff so the tokens are consistently clickable (#2724)

* chore(i18n): synchronize translations from crowdin [skip ci]

* feat: update cmc list link (#2710)

* update cmc lists

* update CMC url

* add token to unsupported list (#2732)

* don't overwrite localstorage lists when fetch throws (#2723)

* try cd1 for custom dimension (#2734)

* fix: Update walletlink-connector to 6.2.8 (#2655)

* Update walletlink-connector to 6.2.5 which has a walletlink update to support addEthereumChain+switchEthereumChain requests

* Update walletlink-connector to 6.2.7

* Update walletlink-connector to 6.2.8

* fix: Parse latest proposal description correctly

* add proposal start time (#2738)

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix: #2741 Increase liquidity form off center (#2746)

* fix: bump to latest token list including ENS token

* fix: remove deprecated optimism status url (#2771)

* feat: Menu update. Add help center & feature requests. Remove analytics & github. (#2709)

* Add help center, remove analytics from menu

* Add canny feature requests link, remove github link

* add coffee icon

* no unused imports eslint rule (#2773)

* chore(i18n): synchronize translations from crowdin [skip ci]

* add protocols param to quote endpoint (#2774)

* add protocols param to quote endpoint

* Fix code style issues with ESLint

Co-authored-by: Lint Action <lint-action@samuelmeuli.com>

* fix: lint error (#2775)

* fix(optimism): Optimism regenesis support (#2703)

* feat(optimism): optimistic kovan local regenesis changes

* use the regenesis version of the sdk

* remove the override no longer necessary

* diff rpc url

* back to kovan url

* lint error

* Optimism mainnet regenesis test (#2695)

* remove the optimism mainnet specific code and point to the mainnet regenesis rpc url

* point at the old mainnet multicall address

* bump the sdk version

* copy the list

* multicall address regenesis change

* revert the gas limit special casing for optimism

* bump the sdk version

* remove a couple other temporary edits

* unused test case

* specific version of v3-sdk

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(i18n): synchronize translations from crowdin [skip ci]

* feat: add support for 0.01% tier (#2769)

* chore: add support for 0.01% tier

* only show 1bps on mainnet

* rename VERY_LOW to LOWEST

* upgrade to v3-sdk 3.7.0

* add snapshot testing for lowest tier

* fix integration test

* fix integration test

* use ALL_SUPPORTED_CHAIN_IDS over string all

* consider 0.01% tier in pool (#2770)

* merge main and only consider lowest tier for mainnet

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix(L2): update block warning updater to check most recent block timestamp (#2777)

* update block warning updater to check most recent block timestamp

* stop doing dumb state manipulation

* fix: copy in network alert

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix(L2): remove redux from chain connectivity (#2781)

* remove redux from chain connectivity

* useMachineTimeMs instead of Date.now to force updates, useCurrentBlockTimestamp

* use useInterval

* change not created font size to 10 (#2785)

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix: format date using Date.toLocaleString (#2459)

* fix: format date using Date.toLocaleString

Fixes #2458

* fix: date typings

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix: broken link to docs (#2816)

* chore: fix typo in useAllCurrencyCombinations.ts (#2778)

occurence -> occurrence

* chore: update typechain scripts for Windows (#2707)

There are two errors when deploying on Windows system:
1. Using single quotes in path argument doesn't seem to be accepted in typechain command
2. `?(v3-core|v3-periphery)` operator doesn't work

Here are fixes/workarounds.

* perf: lazy load vote related routes (#2468)

* perf: lazy load vote related routes

* wrap Switch in Suspense

* remove exact to match nested routes

* fix nested routes

* split Landing

* fix

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix: Enable 3085 requests for coinbase wallet (#2753)

enable 3085 requests for coinbase wallet

* feat: set the auto slippage tolerance by the dollar value of gas (#2815)

* feat: set the auto slippage tolerance by the dollar value of gas

* comments

* min/max at 0.5% to 25%

* oops on constant

* address review feedback

* Fixing #2818 (#2820)

* Fix code style issues with ESLint

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix: fix #2818

* chore(i18n): synchronize translations from crowdin [skip ci]

* log an event on max click (#2827)

* Add trailing slash to L2 info links (#2696)

Some links were broken. For example on /pools/ page click the 'Top Pools' CTA. It would mistakenly direct you to info.uniswap.org/optimismpools instead of optimism/pools

* fix(L2): block L2 tokens explicitly linked to L1 tokens that are blocked (#2721)

* block L2 tokens explicitly linked to L1 tokens that are blocked

* Fix code style issues with ESLint

* check for support on all connectors, and disable when the connector (or lack thereof) no longer supports 3085 (#2824)

* feat: display an ENS avatar (#2806)

* feat: ens avatar resolution

* chore: uninstall @davatar/react

* fix: add avatar alt

* feat: support data uris

* feat: support arweave uris

* feat: support erc721 avatars

* feat: support erc1155 avatars

* fix: jazzicon integration

* fix: clean usage of status icon

* fix: fix jazzicon svg offset

* refactor: share status icon component

* fix: pass memoized args to multicall

* Update locales.ts (#2825)

update Finnish from person (Suomalainen) to language (suomi)

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore: fix the build blocking linter error

* chore: run linters with auto_fix = false for forks (#2852)

* fix: do not show urls if issue is not occurring on app.uniswap.org (#2855)

* fix: do not show urls if issue is not occurring on app.uniswap.org

fixes https://github.com/Uniswap/interface/issues/2572

* address comment

* fix: remove orphaned node (#2863)

* fix: remove orphaned node

* fix: react cleanup

* refactor: use ref for jazzicon (#2874)

* chore(i18n): synchronize translations from crowdin [skip ci]

* chore(deps): bump ws from 5.2.2 to 5.2.3 (#2759)

Bumps [ws](https://github.com/websockets/ws) from 5.2.2 to 5.2.3.
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/5.2.2...5.2.3)

---
updated-dependencies:
- dependency-name: ws
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps): bump url-parse from 1.5.1 to 1.5.3 (#2504)

Bumps [url-parse](https://github.com/unshiftio/url-parse) from 1.5.1 to 1.5.3.
- [Release notes](https://github.com/unshiftio/url-parse/releases)
- [Commits](https://github.com/unshiftio/url-parse/compare/1.5.1...1.5.3)

---
updated-dependencies:
- dependency-name: url-parse
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* add more tests for tryParseTick (#2110)

* fix(lint): clean up the eslint config (#2886)

* fix(lint): clean up the eslint config

* Fix code style issues with ESLint

* fix the linter errors that arose from using the proper config

* clean up the rebass text renames

* fix if statement, use the config

* use the same name prefix for both steps

* `TextPreset` -> `ThemedText`

Co-authored-by: Lint Action <lint-action@samuelmeuli.com>

* fix: Add routes for stakewise tokens (#2832)

* Add additional routes for stakewise tokens

* Reference StakeWise addresses with sdk tokens

* Sort token imports

* fix: fix layout of proposal list items on the vote page on mobile (#2898)

* fix: fixing layout from using grid to flexbox

* fix: setting WrapSmall to nowrap due to layout issue on mobile

* fix: using width auto instead of disabling flex wrap

Co-authored-by: Julian Anderson <juliancanderson@gmail.com>

* fix: typo in arweave URI recognition (#2901)

* deleted files

* Revert "Merge branch 'main' of https://github.com/Uniswap/interface" (#2912)

This reverts commit bf7a40be7a, reversing
changes made to 097b8361d4.

* fix: inadvertent merges/reverts (#2915)

* Revert "Revert "Merge branch 'main' of https://github.com/Uniswap/interface" (#2912)"

This reverts commit 7d343dcfbd.

* Revert "deleted files"

This reverts commit 097b8361d4.

* refactor: Replace multicall implementation with library (#2768)

- Replace the local implementation of multicall with the new redux-multicall lib
- Create wrappers for redux-multicall hooks to inject block number and chainId

* fix: introduce safeNamehash (#2925)

* namehash -> safeNamehash where necessary

* cleanup

* address comment

* feat: Add learn more link in TRM description (#2919)

* Add learn more link in TRM description

* Update src/components/PrivacyPolicy/index.tsx

Co-authored-by: Justin Domingue <judo@uniswap.org>

* give a bit more gas to balanceOf (#2943)

* fix: memoize hooks from /swap (#2949)

* fix: memoize hooks from /swap

* chore: rm console

* add fix for polygon proposal title (#2974)

* fix: display Uniswap token list in UI (#2821)

* fix: display Uniswap token list in UI

* chore: remove default-token-list build dependency

* fix: use ENS name for Uniswap token list

* fix: change Uniswap token list url

* fix: extend transaction deadline to 3 days (#2982)

* feat: integrate SwapRouter02 on L1/L2 + gas ui

* client-side smart order router support
* support auto router on L2s
* add swap router version in approval/swap callback GA events to save $ on approval txs
* add persistent UI view of gas estimate on L1s

Co-authored-by: Lint Action <lint-action@samuelmeuli.com>
Co-authored-by: Ian Lapham <ian@uniswap.org>
Co-authored-by: Callil Capuozzo <callil.capuozzo@gmail.com>

* Update CONTRIBUTING.md (#2992)

* feat: Update contribution spec (#2993)

* Update CONTRIBUTING.md (#2994)

* Update CONTRIBUTING.md (#2995)

* feat: Update contribution spec (#2996)

* chore(i18n): synchronize translations from crowdin [skip ci]

* fix: double scroll in manage token list (#3020)

* fix double scroll

* remove bottom padding

* restrict walletlink to mainnet only (#3024)

* increase warning timer (#3004)

* add index.html styles to widget

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: Micael Rodrigues <micaelr95@outlook.pt>
Co-authored-by: Justin Domingue <judo@uniswap.org>
Co-authored-by: Moody Salem <moodysalem@users.noreply.github.com>
Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
Co-authored-by: Ian Lapham <ian@uniswap.org>
Co-authored-by: Lint Action <lint-action@samuelmeuli.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: M0kY <46133205+M0kY@users.noreply.github.com>
Co-authored-by: M0kY <moky@example.com>
Co-authored-by: Will Hennessy <hennessywill@gmail.com>
Co-authored-by: Brendan Weinstein <65564422+brendanww@users.noreply.github.com>
Co-authored-by: Noah Zinsmeister <noahwz@gmail.com>
Co-authored-by: Ben Krochta <35636764+bkrochta@users.noreply.github.com>
Co-authored-by: Moody Salem <moody.salem@gmail.com>
Co-authored-by: Raj <sukhrajghuman@live.com>
Co-authored-by: Ikko Ashimine <eltociear@gmail.com>
Co-authored-by: Matthew Salamon <35425388+Matthews3301@users.noreply.github.com>
Co-authored-by: Sam Chen <chenxsan@gmail.com>
Co-authored-by: Ali Eray Kısabacak <eraykisabacak@hotmail.com>
Co-authored-by: Kimmo S <kkpsiren@gmail.com>
Co-authored-by: Dmitri Tsumak <tsumak.dmitri@gmail.com>
Co-authored-by: Julian Anderson <juliancanderson@gmail.com>
Co-authored-by: Carlos Diaz-Padron <carlosdiazpadron@gmail.com>
Co-authored-by: J M Rossy <jm.rossy@gmail.com>
Co-authored-by: Barry G <bgitarts@gmail.com>
Co-authored-by: Callil Capuozzo <callil.capuozzo@gmail.com>
Co-authored-by: Tina Zheng <59578595+tinaszheng@users.noreply.github.com>

* feat: widgets transitions (#3007)

* fix: logo target

* feat: settings transition

* feat: reverse transition

* fix: transitions will-change and durations

* fix: logo color

* fix: only will-change transform

* fix: header targets

* fix: clip modal transitions

* fix: token select header

* fix: safari transparent gradients

* fix: safari scrollbar

* fix: scroll overlay

* fix: safari bounce jank

* fix: firefox overscroll

* refactor: scrollbar hook

* feat: native event hook

* fix: details nowrap

* fix: settings cog transition

* feat: expando icon

* fix: expando transition

* refactor: cosmos web3 integration (#3052)

* chore: use zustand 4.0.0-beta for dynamic stores

* chore: use strict mode

* refactor: clean connector state

* chore: mv web3 state to cosmos selectors

* chore: dedup yarn.lock

* chore: define EthereumProvider in lib

* fix: destructure would not compile

* fix: make it bundle

* chore: prune deps

* refactor: use error handler instead of GA

* chore: add make-plural

* chore: add redux

* chore: yarn dedup

* chore: do not (re)load default locale

* fix: center error headings

* feat: error dialog for boundary

* fix: tighten up transitions

* test: include bundle depcheck

* fix: rm console

* fix: do not load empty sourceLocale

* fix: no lingui defaults

* refactor: mv svg to assets/svg

* chore: block font display

* fix: remove manual zustand resolution

* fix: svg generation script

Co-authored-by: Noah Zinsmeister <noahwz@gmail.com>

* chore: widget placeholders (#3061)

* chore: update comments

- typo
- performance comment was performant on retest

* nit: status placeholders

- prevent flashes of rerendering from lazy-loaded elements

* chore: initialize cosmos with json rpc

* refactor: token img component

- modularize the TokenImg
- add a placeholder for UX and broken images

* fix: recent tx token img usage

* pr feedback

* undo REACT_APP_IS_WIDGET network ternary

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: Micael Rodrigues <micaelr95@outlook.pt>
Co-authored-by: Justin Domingue <judo@uniswap.org>
Co-authored-by: Moody Salem <moodysalem@users.noreply.github.com>
Co-authored-by: Ian Lapham <ian@uniswap.org>
Co-authored-by: Lint Action <lint-action@samuelmeuli.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: M0kY <46133205+M0kY@users.noreply.github.com>
Co-authored-by: M0kY <moky@example.com>
Co-authored-by: Will Hennessy <hennessywill@gmail.com>
Co-authored-by: Brendan Weinstein <65564422+brendanww@users.noreply.github.com>
Co-authored-by: Noah Zinsmeister <noahwz@gmail.com>
Co-authored-by: Ben Krochta <35636764+bkrochta@users.noreply.github.com>
Co-authored-by: Moody Salem <moody.salem@gmail.com>
Co-authored-by: Raj <sukhrajghuman@live.com>
Co-authored-by: Ikko Ashimine <eltociear@gmail.com>
Co-authored-by: Matthew Salamon <35425388+Matthews3301@users.noreply.github.com>
Co-authored-by: Sam Chen <chenxsan@gmail.com>
Co-authored-by: Ali Eray Kısabacak <eraykisabacak@hotmail.com>
Co-authored-by: Kimmo S <kkpsiren@gmail.com>
Co-authored-by: Dmitri Tsumak <tsumak.dmitri@gmail.com>
Co-authored-by: Julian Anderson <juliancanderson@gmail.com>
Co-authored-by: Carlos Diaz-Padron <carlosdiazpadron@gmail.com>
Co-authored-by: J M Rossy <jm.rossy@gmail.com>
Co-authored-by: Barry G <bgitarts@gmail.com>
Co-authored-by: Callil Capuozzo <callil.capuozzo@gmail.com>
Co-authored-by: Tina Zheng <59578595+tinaszheng@users.noreply.github.com>
2022-01-05 12:38:53 -06:00
yj
5b7a80d10d fix: Add ENSName and address check to Web3Status (#3040)
* Add ENSName and address check to Web3Status

Issue #2838

* Update useENSName.ts

Do the forward ENSAddress check in useENSName

* Update index.tsx

Revert ENSAddress check, which has been moved into ENSName hook

* Update useENSName.ts

Correcting the equality check (was testing that things work, and made a wrong commit)

* add comment, change var names

Co-authored-by: Tina Zheng <tina.s.zheng+github@gmail.com>
2021-12-29 20:04:09 -08:00
Crowdin Bot
db8dab4559 chore(i18n): synchronize translations from crowdin [skip ci] 2021-12-28 17:11:16 +00:00
Crowdin Bot
7cc1b899ea chore(i18n): synchronize translations from crowdin [skip ci] 2021-12-24 21:06:39 +00:00
Crowdin Bot
339a35cb1b chore(i18n): synchronize translations from crowdin [skip ci] 2021-12-24 07:06:39 +00:00
Moody Salem
e2bd8020f3 fix(polygon): enable the smart order router for polygon (#3037)
* fix(polygon): enable the smart order router for polygon

* show gas estimates for polygon
2021-12-23 20:36:56 -05:00
Crowdin Bot
571a932d6e chore(i18n): synchronize translations from crowdin [skip ci] 2021-12-23 21:06:33 +00:00
Callil Capuozzo
3923438011 fix(style): improve the bridge assets style (#3036)
* Re-style bridge cards

* Tweaks

- Header button height and color treatment refinement
- Small sizing issues

* Address comments

* remove network alert state

* code style nits

* remove unused parameter, rename

* copy edit

Co-authored-by: Moody Salem <moody.salem@gmail.com>
2021-12-23 15:13:50 -05:00
Crowdin Bot
4ed9c7ba94 chore(i18n): synchronize translations from crowdin [skip ci] 2021-12-23 18:06:38 +00:00
Crowdin Bot
1ead35e782 chore(i18n): synchronize translations from crowdin [skip ci] 2021-12-23 17:11:21 +00:00
Crowdin Bot
0af516b884 chore(i18n): synchronize translations from crowdin [skip ci] 2021-12-23 16:07:14 +00:00
Moody Salem
13c42a384b fix(network switch): do not show failed to switch networks for successful network switches 2021-12-23 10:18:58 -05:00
Tina Zheng
458e04f94c feat: add santa hat to unicorn logo for the holidays 🎅🏼 (#3027)
* add santa hat to logo

* make generic component

* add 24th to christmas

* oops
2021-12-22 14:34:40 -08:00
351 changed files with 18149 additions and 6995 deletions

2
.env
View File

@@ -1 +1 @@
REACT_APP_INFURA_KEY="4bf032f2d38a4ed6bb975b80d6340847"
REACT_APP_INFURA_KEY="4bf032f2d38a4ed6bb975b80d6340847"

View File

@@ -58,10 +58,6 @@
"error",
{
"paths": [
{
"name": "lodash",
"message": "Please import from 'lodash/module' directly to support tree-shaking."
},
{
"name": "ethers",
"message": "Please import from '@ethersproject/module' directly to support tree-shaking."

40
.github/workflows/bundle.yaml vendored Normal file
View File

@@ -0,0 +1,40 @@
name: Widgets
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Set up node
uses: actions/setup-node@v2
with:
node-version: 14
registry-url: https://registry.npmjs.org
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v2
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Build
run: yarn widgets:build

6
.gitignore vendored
View File

@@ -3,8 +3,12 @@
# generated contract types
/src/types/v3
/src/abis/types
/src/lib/locales/**/*.js
/src/lib/locales/**/en-US.po
/src/lib/locales/**/pseudo.po
/src/locales/**/*.js
/src/locales/**/en-US.po
/src/locales/**/pseudo.po
/src/state/data/generated.ts
# dependencies
@@ -16,7 +20,7 @@
# production
/build
# bundle
# widgets
/dist
# misc

View File

@@ -1,7 +1,9 @@
{
"staticPath": "public",
"watchDirs": ["src"],
"watchDirs": [
"src"
],
"webpack": {
"configPath": "react-scripts/config/webpack.config"
"configPath": "react-scripts/config/webpack.config",
"overridePath": "cosmos.override.js"
}
}
}

25
cosmos.override.js Normal file
View File

@@ -0,0 +1,25 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { DefinePlugin } = require('webpack')
// Renders the cosmos fixtures in isolation, instead of using public/index.html.
module.exports = (webpackConfig) => ({
...webpackConfig,
plugins: webpackConfig.plugins.map((plugin) => {
if (plugin instanceof HtmlWebpackPlugin) {
return new HtmlWebpackPlugin({
templateContent: '<body></body>',
})
}
if (plugin instanceof DefinePlugin) {
return new DefinePlugin({
...plugin.definitions,
'process.env': {
...plugin.definitions['process.env'],
REACT_APP_IS_WIDGET: true,
},
})
}
return plugin
}),
})

View File

@@ -46,11 +46,13 @@ const linguiConfig = {
'vi-VN',
'zh-CN',
'zh-TW',
'pseudo',
],
orderBy: 'messageId',
rootDir: '.',
runtimeConfigModule: ['@lingui/core', 'i18n'],
sourceLocale: 'en-US',
pseudoLocale: 'pseudo',
}
export default linguiConfig

View File

@@ -18,14 +18,16 @@
"@graphql-codegen/typescript-operations": "^1.18.2",
"@graphql-codegen/typescript-rtk-query": "^1.1.1",
"@lingui/cli": "^3.9.0",
"@lingui/macro": "^3.9.0",
"@lingui/react": "^3.9.0",
"@metamask/jazzicon": "^2.0.0",
"@popperjs/core": "^2.4.4",
"@reach/dialog": "^0.10.3",
"@reach/portal": "^0.10.3",
"@react-hook/window-scroll": "^1.3.0",
"@reduxjs/toolkit": "^1.6.1",
"@rollup/plugin-eslint": "^8.0.1",
"@rollup/plugin-json": "^4.1.0",
"@rollup/plugin-replace": "^3.0.1",
"@rollup/plugin-url": "^6.1.0",
"@svgr/rollup": "^6.2.0",
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^12.0.0",
"@testing-library/react-hooks": "^7.0.2",
@@ -54,77 +56,58 @@
"@types/wcag-contrast": "^3.0.0",
"@typescript-eslint/eslint-plugin": "^4.1.0",
"@typescript-eslint/parser": "^4.1.0",
"@uniswap/default-token-list": "^3.0.0",
"@uniswap/governance": "^1.0.2",
"@uniswap/liquidity-staker": "^1.0.2",
"@uniswap/merkle-distributor": "1.0.1",
"@uniswap/redux-multicall": "^1.0.0",
"@uniswap/router-sdk": "^1.0.1",
"@uniswap/sdk-core": "^3.0.1",
"@uniswap/smart-order-router": "^2.5.4",
"@uniswap/token-lists": "^1.0.0-beta.27",
"@uniswap/v2-core": "1.0.0",
"@uniswap/v2-periphery": "^1.1.0-beta.0",
"@uniswap/v2-sdk": "^3.0.1",
"@uniswap/v3-core": "1.0.0",
"@uniswap/v3-periphery": "^1.1.1",
"@uniswap/v3-sdk": "^3.7.1",
"@web3-react/core": "^6.0.9",
"@web3-react/fortmatic-connector": "^6.0.9",
"@web3-react/injected-connector": "^6.0.7",
"@web3-react/portis-connector": "^6.0.9",
"@web3-react/walletconnect-connector": "^7.0.2-alpha.0",
"@web3-react/walletlink-connector": "^6.2.8",
"ajv": "^6.12.3",
"@web3-react/walletlink-connector": "^6.2.11",
"array.prototype.flat": "^1.2.4",
"array.prototype.flatmap": "^1.2.4",
"cids": "^1.0.0",
"copy-to-clipboard": "^3.2.0",
"cross-env": "^7.0.3",
"cypress": "^7.7.0",
"d3": "^7.0.0",
"eslint": "^7.11.0",
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-better-styled-components": "^1.1.2",
"eslint-plugin-prettier": "^3.1.3",
"eslint-plugin-react": "^7.19.0",
"eslint-plugin-react-hooks": "^4.0.0",
"eslint-plugin-simple-import-sort": "^7.0.0",
"eslint-plugin-unused-imports": "^2.0.0",
"ethers": "^5.4.6",
"firebase": "^9.1.3",
"graphql": "^15.5.0",
"graphql-request": "^3.4.0",
"inter-ui": "^3.13.1",
"jest-styled-components": "^7.0.5",
"microbundle": "^0.13.3",
"ms.macro": "^2.0.0",
"multicodec": "^3.0.1",
"multihashes": "^4.0.2",
"node-vibrant": "^3.2.1-alpha.1",
"polished": "^3.3.2",
"polyfill-object.fromentries": "^1.0.1",
"prettier": "^2.2.1",
"qs": "^6.9.4",
"react": "^17.0.1",
"react-confetti": "^6.0.0",
"react-cosmos": "^5.6.3",
"react-dom": "^17.0.1",
"react-feather": "^2.0.8",
"react-cosmos": "^5.6.6",
"react-ga": "^2.5.7",
"react-is": "^17.0.2",
"react-markdown": "^4.3.1",
"react-popper": "^2.2.3",
"react-redux": "^7.2.2",
"react-router-dom": "^5.0.0",
"react-scripts": "^4.0.3",
"react-spring": "^8.0.27",
"react-use-gesture": "^6.0.14",
"react-virtualized-auto-sizer": "^1.0.2",
"react-window": "^1.8.5",
"rebass": "^4.0.7",
"redux-localstorage-simple": "^2.3.1",
"rollup": "^2.63.0",
"rollup-plugin-dts": "^4.1.0",
"rollup-plugin-scss": "^3.0.0",
"rollup-plugin-typescript2": "^0.31.1",
"sass": "^1.45.1",
"serve": "^11.3.2",
"start-server-and-test": "^1.11.0",
"styled-components": "^5.3.0",
"typechain": "^5.0.0",
"typescript": "^4.2.3",
"ua-parser-js": "^0.7.28",
@@ -137,7 +120,7 @@
"workbox-routing": "^6.1.0"
},
"resolutions": {
"@walletconnect/ethereum-provider": "1.6.5"
"@walletconnect/ethereum-provider": "1.7.1"
},
"scripts": {
"contracts:compile:abi": "typechain --target ethers-v5 --out-dir src/abis/types \"./src/abis/**/*.json\"",
@@ -147,13 +130,14 @@
"prei18n:extract": "touch src/locales/en-US.po",
"i18n:extract": "lingui extract --locale en-US",
"i18n:compile": "yarn i18n:extract && lingui compile",
"i18n:pseudo": "lingui extract --locale pseudo && lingui compile",
"postinstall": "yarn contracts:compile && yarn graphql:generate && yarn i18n:compile",
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=./custom-test-env.js",
"test:e2e": "start-server-and-test 'serve build -l 3000' http://localhost:3000 'cypress run --record'",
"bundle": "microbundle --tsconfig tsconfig.lib.json src/lib/index.tsx --format esm,cjs",
"cosmos": "open http://localhost:5000 && cross-env FAST_REFRESH=false cosmos"
"widgets:start": "cosmos",
"widgets:build": "rollup --config --failAfterWarnings --configPlugin typescript2"
},
"browserslist": {
"production": [
@@ -168,5 +152,64 @@
]
},
"license": "GPL-3.0-or-later",
"dependencies": {}
"dependencies": {
"@ethersproject/abi": "^5.4.1",
"@ethersproject/abstract-provider": "^5.4.1",
"@ethersproject/address": "^5.4.0",
"@ethersproject/bignumber": "^5.4.2",
"@ethersproject/bytes": "^5.4.0",
"@ethersproject/constants": "^5.4.0",
"@ethersproject/contracts": "^5.4.1",
"@ethersproject/hash": "^5.4.0",
"@ethersproject/providers": "5.4.0",
"@ethersproject/solidity": "^5.4.0",
"@ethersproject/strings": "^5.4.0",
"@ethersproject/units": "^5.4.0",
"@ethersproject/wallet": "^5.4.0",
"@fontsource/ibm-plex-mono": "^4.5.1",
"@fontsource/inter": "^4.5.1",
"@lingui/core": "^3.9.0",
"@lingui/macro": "^3.9.0",
"@lingui/react": "^3.9.0",
"@popperjs/core": "^2.4.4",
"@uniswap/redux-multicall": "^1.0.0",
"@uniswap/router-sdk": "^1.0.3",
"@uniswap/sdk-core": "^3.0.1",
"@uniswap/smart-order-router": "^2.5.10",
"@uniswap/token-lists": "^1.0.0-beta.27",
"@uniswap/v2-sdk": "^3.0.1",
"@uniswap/v3-sdk": "^3.8.2",
"@web3-react/core": "^6.0.9",
"@widgets/web3-react/core": "npm:@web3-react/core@8.0.16-alpha.0",
"@widgets/web3-react/eip1193": "npm:@web3-react/eip1193@8.0.16-alpha.0",
"@widgets/web3-react/empty": "npm:@web3-react/empty@8.0.17-alpha.0",
"@widgets/web3-react/metamask": "npm:@web3-react/metamask@8.0.16-alpha.0",
"@widgets/web3-react/types": "npm:@web3-react/types@8.0.16-alpha.0",
"@widgets/web3-react/url": "npm:@web3-react/url@8.0.17-alpha.0",
"ajv": "^6.12.3",
"cids": "^1.0.0",
"immer": "^9.0.6",
"jotai": "^1.3.7",
"jsbi": "^3.1.4",
"make-plural": "^7.0.0",
"ms.macro": "^2.0.0",
"multicodec": "^3.0.1",
"multihashes": "^4.0.2",
"node-vibrant": "^3.2.1-alpha.1",
"polished": "^3.3.2",
"popper-max-size-modifier": "^0.2.0",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-feather": "^2.0.8",
"react-popper": "^2.2.3",
"react-redux": "^7.2.2",
"react-virtualized-auto-sizer": "^1.0.2",
"react-window": "^1.8.5",
"rebass": "^4.0.7",
"redux": "^4.1.2",
"styled-components": "^5.3.0",
"tiny-invariant": "^1.2.0",
"wcag-contrast": "^3.0.0",
"wicg-inert": "^3.1.1"
}
}

63
rollup.config.ts Normal file
View File

@@ -0,0 +1,63 @@
/**
* Bundles the widgets library, which is released independently of the interface application.
* This library lives in src/lib, but shares code with the interface application.
*/
import eslint from '@rollup/plugin-eslint'
import json from '@rollup/plugin-json'
import replace from '@rollup/plugin-replace'
import url from '@rollup/plugin-url'
import svgr from '@svgr/rollup'
import dts from 'rollup-plugin-dts'
import sass from 'rollup-plugin-scss'
import typescript from 'rollup-plugin-typescript2'
import { dependencies } from './package.json'
const deps = Object.keys(dependencies)
const replacements = {
'process.env.REACT_APP_IS_WIDGET': true,
}
const library = {
input: 'src/lib/index.tsx',
output: [
{
file: 'dist/widgets.js',
format: 'cjs',
inlineDynamicImports: true,
sourcemap: true,
},
{
file: 'dist/widgets.esm.js',
format: 'esm',
inlineDynamicImports: true,
sourcemap: true,
},
],
// necessary because some nested imports (eg jotai/*) would otherwise not resolve.
external: (source: string) => Boolean(deps.find((dep) => source === dep || source.startsWith(dep + '/'))),
plugins: [
eslint({ include: ['**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx'] }),
json(), // imports json
replace({ ...replacements, preventAssignment: true }),
url(), // imports files (including svgs) as data URIs
svgr({ exportType: 'named', svgo: false }), // imports svgs as React components
sass(), // imports sass styles
typescript({ tsconfig: './tsconfig.lib.json', useTsconfigDeclarationDir: true }),
],
}
const typings = {
input: 'dist/dts/lib/index.d.ts',
output: {
file: 'dist/widgets.d.ts',
format: 'es',
},
external: (source: string) => source.endsWith('.scss'),
plugins: [dts({ compilerOptions: { baseUrl: 'dist/dts' } })],
}
const config = [library, typings]
export default config

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 572 KiB

View File

@@ -1,7 +1,7 @@
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { CheckCircle, Triangle } from 'react-feather'
import styled from 'styled-components/macro'
import { useActiveWeb3React } from '../../hooks/web3'
import { useAllTransactions } from '../../state/transactions/hooks'
import { ExternalLink } from '../../theme'
import { ExplorerDataType, getExplorerLink } from '../../utils/getExplorerLink'

View File

@@ -1,5 +1,7 @@
import { Trans } from '@lingui/macro'
import { AbstractConnector } from '@web3-react/abstract-connector'
import { Connector } from '@widgets/web3-react/types'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { useCallback, useContext } from 'react'
import { ExternalLink as LinkIcon } from 'react-feather'
import { useAppDispatch } from 'state/hooks'
@@ -8,7 +10,6 @@ import styled, { ThemeContext } from 'styled-components/macro'
import { ReactComponent as Close } from '../../assets/images/x.svg'
import { injected, portis, walletlink } from '../../connectors'
import { SUPPORTED_WALLETS } from '../../constants/wallet'
import { useActiveWeb3React } from '../../hooks/web3'
import { clearAllTransactions } from '../../state/transactions/actions'
import { ExternalLink, LinkStyledButton, ThemedText } from '../../theme'
import { shortenAddress } from '../../utils'
@@ -176,7 +177,7 @@ const IconWrapper = styled.div<{ size?: number }>`
`};
`
function WrappedStatusIcon({ connector }: { connector: AbstractConnector }) {
function WrappedStatusIcon({ connector }: { connector: AbstractConnector | Connector }) {
return (
<IconWrapper size={16}>
<StatusIcon connector={connector} />

View File

@@ -1,11 +1,11 @@
import { Trans } from '@lingui/macro'
// eslint-disable-next-line no-restricted-imports
import { t } from '@lingui/macro'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { ReactNode, useCallback, useContext } from 'react'
import styled, { ThemeContext } from 'styled-components/macro'
import useENS from '../../hooks/useENS'
import { useActiveWeb3React } from '../../hooks/web3'
import { ExternalLink, ThemedText } from '../../theme'
import { ExplorerDataType, getExplorerLink } from '../../utils/getExplorerLink'
import { AutoColumn } from '../Column'

View File

@@ -1,8 +1,7 @@
import { Trans } from '@lingui/macro'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { ReactNode, useMemo } from 'react'
import { useActiveWeb3React } from '../../hooks/web3'
// SDN OFAC addresses
const BLOCKED_ADDRESSES: string[] = [
'0x7Db418b5D567A4e0E8c59Ad71BE1FcE48f3E6107',
@@ -20,6 +19,20 @@ const BLOCKED_ADDRESSES: string[] = [
'0x8576aCC5C05D6Ce88f4e49bf65BdF0C62F91353C',
'0xC8a65Fadf0e0dDAf421F28FEAb69Bf6E2E589963',
'0x308eD4B7b49797e1A98D3818bFF6fe5385410370',
'0x67d40EE1A85bf4a4Bb7Ffae16De985e8427B',
'0x6f1ca141a28907f78ebaa64fb83a9088b02a83',
'0x6acdfba02d390b97ac2b2d42a63e85293bcc1',
'0x48549a34ae37b12f6a30566245176994e17c6',
'0x5512d943ed1f7c8a43f3435c85f7ab68b30121',
'0xc455f7fd3e0e12afd51fba5c106909934d8a0e',
'0x3cbded43efdaf0fc77b9c55f6fc9988fcc9b757d',
'0x67d40EE1A85bf4a4Bb7Ffae16De985e8427B6b45',
'0x6f1ca141a28907f78ebaa64fb83a9088b02a8352',
'0x6acdfba02d390b97ac2b2d42a63e85293bcc160e',
'0x48549a34ae37b12f6a30566245176994e17c6b4a',
'0x5512d943ed1f7c8a43f3435c85f7ab68b30121b0',
'0xc455f7fd3e0e12afd51fba5c106909934d8a0e4a',
'0x629e7Da20197a5429d30da36E77d06CdF796b71A',
]
export default function Blocklist({ children }: { children: ReactNode }) {

View File

@@ -23,7 +23,7 @@ export const BaseButton = styled(RebassButton)<
border-radius: ${({ $borderRadius }) => $borderRadius ?? '20px'};
outline: none;
border: 1px solid transparent;
color: white;
color: ${({ theme }) => theme.text1};
text-decoration: none;
display: flex;
justify-content: center;

View File

@@ -3,6 +3,7 @@ import { Currency, CurrencyAmount, Percent, Token } from '@uniswap/sdk-core'
import { Pair } from '@uniswap/v2-sdk'
import { AutoColumn } from 'components/Column'
import { LoadingOpacityContainer, loadingOpacityMixin } from 'components/Loader/styled'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { darken } from 'polished'
import { ReactNode, useCallback, useState } from 'react'
import { Lock } from 'react-feather'
@@ -11,7 +12,6 @@ import { formatCurrencyAmount } from 'utils/formatCurrencyAmount'
import { ReactComponent as DropDown } from '../../assets/images/dropdown.svg'
import useTheme from '../../hooks/useTheme'
import { useActiveWeb3React } from '../../hooks/web3'
import { useCurrencyBalance } from '../../state/wallet/hooks'
import { ThemedText } from '../../theme'
import { ButtonGray } from '../Button'

View File

@@ -1,60 +1,18 @@
import { Currency } from '@uniswap/sdk-core'
import EthereumLogo from 'assets/images/ethereum-logo.png'
import MaticLogo from 'assets/svg/matic-token-icon.svg'
import { SupportedChainId } from 'constants/chains'
import useHttpLocations from 'hooks/useHttpLocations'
import React, { useMemo } from 'react'
import { WrappedTokenInfo } from 'state/lists/wrappedTokenInfo'
import useCurrencyLogoURIs from 'lib/hooks/useCurrencyLogoURIs'
import React from 'react'
import styled from 'styled-components/macro'
import Logo from '../Logo'
type Network = 'ethereum' | 'arbitrum' | 'optimism'
function chainIdToNetworkName(networkId: SupportedChainId): Network {
switch (networkId) {
case SupportedChainId.MAINNET:
return 'ethereum'
case SupportedChainId.ARBITRUM_ONE:
return 'arbitrum'
case SupportedChainId.OPTIMISM:
return 'optimism'
default:
return 'ethereum'
}
}
export const getTokenLogoURL = (
address: string,
chainId: SupportedChainId = SupportedChainId.MAINNET
): string | void => {
const networkName = chainIdToNetworkName(chainId)
const networksWithUrls = [SupportedChainId.ARBITRUM_ONE, SupportedChainId.MAINNET, SupportedChainId.OPTIMISM]
if (networksWithUrls.includes(chainId)) {
return `https://raw.githubusercontent.com/Uniswap/assets/master/blockchains/${networkName}/assets/${address}/logo.png`
}
}
const StyledNativeLogo = styled.img<{ size: string }>`
width: ${({ size }) => size};
height: ${({ size }) => size};
background: radial-gradient(white 50%, #ffffff00 calc(75% + 1px), #ffffff00 100%);
border-radius: 50%;
-mox-box-shadow: 0 0 1px white;
-webkit-box-shadow: 0 0 1px white;
box-shadow: 0 0 1px white;
border: 0px solid rgba(255, 255, 255, 0);
`
const StyledLogo = styled(Logo)<{ size: string }>`
const StyledLogo = styled(Logo)<{ size: string; native: boolean }>`
width: ${({ size }) => size};
height: ${({ size }) => size};
background: radial-gradient(white 50%, #ffffff00 calc(75% + 1px), #ffffff00 100%);
border-radius: 50%;
-mox-box-shadow: 0 0 1px black;
-webkit-box-shadow: 0 0 1px black;
box-shadow: 0 0 1px black;
-mox-box-shadow: 0 0 1px ${({ native }) => (native ? 'white' : 'black')};
-webkit-box-shadow: 0 0 1px ${({ native }) => (native ? 'white' : 'black')};
box-shadow: 0 0 1px ${({ native }) => (native ? 'white' : 'black')};
border: 0px solid rgba(255, 255, 255, 0);
`
@@ -68,38 +26,16 @@ export default function CurrencyLogo({
size?: string
style?: React.CSSProperties
}) {
const uriLocations = useHttpLocations(currency instanceof WrappedTokenInfo ? currency.logoURI : undefined)
const logoURIs = useCurrencyLogoURIs(currency)
const srcs: string[] = useMemo(() => {
if (!currency || currency.isNative) return []
if (currency.isToken) {
const defaultUrls = []
const url = getTokenLogoURL(currency.address, currency.chainId)
if (url) {
defaultUrls.push(url)
}
if (currency instanceof WrappedTokenInfo) {
return [...uriLocations, ...defaultUrls]
}
return defaultUrls
}
return []
}, [currency, uriLocations])
if (currency?.isNative) {
let nativeLogoUrl: string
switch (currency.chainId) {
case SupportedChainId.POLYGON_MUMBAI:
case SupportedChainId.POLYGON:
nativeLogoUrl = MaticLogo
break
default:
nativeLogoUrl = EthereumLogo
break
}
return <StyledNativeLogo src={nativeLogoUrl} alt="ethereum logo" size={size} style={style} {...rest} />
}
return <StyledLogo size={size} srcs={srcs} alt={`${currency?.symbol ?? 'token'} logo`} style={style} {...rest} />
return (
<StyledLogo
size={size}
native={currency?.isNative ?? false}
srcs={logoURIs}
alt={`${currency?.symbol ?? 'token'} logo`}
style={style}
{...rest}
/>
)
}

View File

@@ -1,6 +1,6 @@
import { Trans } from '@lingui/macro'
import { SupportedChainId } from 'constants/chains'
import { useActiveWeb3React } from 'hooks/web3'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { AlertOctagon } from 'react-feather'
import styled from 'styled-components/macro'
import { ExternalLink } from 'theme'

View File

@@ -5,10 +5,10 @@ import { ButtonGray } from 'components/Button'
import Card from 'components/Card'
import { AutoColumn } from 'components/Column'
import { RowBetween } from 'components/Row'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { useFeeTierDistribution } from 'hooks/useFeeTierDistribution'
import { PoolState, usePools } from 'hooks/usePools'
import usePrevious from 'hooks/usePrevious'
import { useActiveWeb3React } from 'hooks/web3'
import { DynamicSection } from 'pages/AddLiquidity/styled'
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import ReactGA from 'react-ga'

View File

@@ -1,6 +1,7 @@
import { Trans } from '@lingui/macro'
import { CHAIN_INFO, L2ChainInfo, SupportedChainId } from 'constants/chains'
import { useActiveWeb3React } from 'hooks/web3'
import { CHAIN_INFO, L2ChainInfo } from 'constants/chainInfo'
import { SupportedChainId } from 'constants/chains'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { AlertOctagon } from 'react-feather'
import styled from 'styled-components/macro'
import { ExternalLink, MEDIA_WIDTHS } from 'theme'

View File

@@ -0,0 +1,26 @@
import { ReactElement } from 'react'
import styled from 'styled-components/macro'
import SantaHat from '../../assets/images/santa-hat.png'
const SantaHatImage = styled.img`
position: absolute;
top: -4px;
right: -4px;
height: 18px;
`
const Christmas = <SantaHatImage src={SantaHat} alt="Santa hat" />
const DATE_TO_ORNAMENT: { [date: string]: ReactElement } = {
'12-24': Christmas,
'12-25': Christmas,
}
const HolidayOrnament = () => {
// months in javascript are 0 indexed...
const today = `${new Date().getMonth() + 1}-${new Date().getDate()}`
return DATE_TO_ORNAMENT[today] || null
}
export default HolidayOrnament

View File

@@ -1,13 +1,19 @@
import { Trans } from '@lingui/macro'
import { CHAIN_INFO, SupportedChainId } from 'constants/chains'
import { CHAIN_INFO } from 'constants/chainInfo'
import { CHAIN_IDS_TO_NAMES, SupportedChainId } from 'constants/chains'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { useOnClickOutside } from 'hooks/useOnClickOutside'
import { useActiveWeb3React } from 'hooks/web3'
import { useCallback, useRef } from 'react'
import useParsedQueryString from 'hooks/useParsedQueryString'
import usePrevious from 'hooks/usePrevious'
import { ParsedQs } from 'qs'
import { useCallback, useEffect, useRef } from 'react'
import { ArrowDownCircle, ChevronDown } from 'react-feather'
import { useHistory } from 'react-router-dom'
import { useModalOpen, useToggleModal } from 'state/application/hooks'
import { addPopup, ApplicationModal } from 'state/application/reducer'
import styled from 'styled-components/macro'
import { ExternalLink, MEDIA_WIDTHS } from 'theme'
import { replaceURLParam } from 'utils/routes'
import { useAppDispatch } from '../../state/hooks'
import { switchToNetwork } from '../../utils/switchToNetwork'
@@ -108,7 +114,7 @@ const SelectorControls = styled.div<{ interactive: boolean }>`
align-items: center;
background-color: ${({ theme }) => theme.bg0};
border: 2px solid ${({ theme }) => theme.bg0};
border-radius: 12px;
border-radius: 16px;
color: ${({ theme }) => theme.text1};
cursor: ${({ interactive }) => (interactive ? 'pointer' : 'auto')};
display: flex;
@@ -128,7 +134,7 @@ const SelectorWrapper = styled.div`
}
`
const StyledChevronDown = styled(ChevronDown)`
width: 12px;
width: 16px;
`
const BridgeLabel = ({ chainId }: { chainId: SupportedChainId }) => {
switch (chainId) {
@@ -210,31 +216,90 @@ function Row({
return rowContent
}
const getParsedChainId = (parsedQs?: ParsedQs) => {
const chain = parsedQs?.chain
if (!chain || typeof chain !== 'string') return { urlChain: undefined, urlChainId: undefined }
return { urlChain: chain.toLowerCase(), urlChainId: getChainIdFromName(chain) }
}
const getChainIdFromName = (name: string) => {
const entry = Object.entries(CHAIN_IDS_TO_NAMES).find(([_, n]) => n === name)
const chainId = entry?.[0]
return chainId ? parseInt(chainId) : undefined
}
const getChainNameFromId = (id: string | number) => {
// casting here may not be right but fine to return undefined if it's not a supported chain ID
return CHAIN_IDS_TO_NAMES[id as SupportedChainId] || ''
}
export default function NetworkSelector() {
const { chainId, library } = useActiveWeb3React()
const parsedQs = useParsedQueryString()
const { urlChain, urlChainId } = getParsedChainId(parsedQs)
const prevChainId = usePrevious(chainId)
const node = useRef<HTMLDivElement>()
const open = useModalOpen(ApplicationModal.NETWORK_SELECTOR)
const toggle = useToggleModal(ApplicationModal.NETWORK_SELECTOR)
useOnClickOutside(node, open ? toggle : undefined)
const history = useHistory()
const info = chainId ? CHAIN_INFO[chainId] : undefined
const dispatch = useAppDispatch()
const handleRowClick = useCallback(
(targetChain: number) => {
const handleChainSwitch = useCallback(
(targetChain: number, skipToggle?: boolean) => {
if (!library) return
switchToNetwork({ library, chainId: targetChain })
.then(() => toggle())
.then(() => {
if (!skipToggle) {
toggle()
}
history.replace({
search: replaceURLParam(history.location.search, 'chain', getChainNameFromId(targetChain)),
})
})
.catch((error) => {
console.error('Failed to switch networks', error)
toggle()
// we want app network <-> chainId param to be in sync, so if user changes the network by changing the URL
// but the request fails, revert the URL back to current chainId
if (chainId) {
history.replace({ search: replaceURLParam(history.location.search, 'chain', getChainNameFromId(chainId)) })
}
if (!skipToggle) {
toggle()
}
dispatch(addPopup({ content: { failedSwitchNetwork: targetChain }, key: `failed-network-switch` }))
})
},
[dispatch, library, toggle]
[dispatch, library, toggle, history, chainId]
)
useEffect(() => {
if (!chainId || !prevChainId) return
// when network change originates from wallet or dropdown selector, just update URL
if (chainId !== prevChainId) {
history.replace({ search: replaceURLParam(history.location.search, 'chain', getChainNameFromId(chainId)) })
// otherwise assume network change originates from URL
} else if (urlChainId && urlChainId !== chainId) {
handleChainSwitch(urlChainId, true)
}
}, [chainId, urlChainId, prevChainId, handleChainSwitch, history])
// set chain parameter on initial load if not there
useEffect(() => {
if (chainId && !urlChainId) {
history.replace({ search: replaceURLParam(history.location.search, 'chain', getChainNameFromId(chainId)) })
}
}, [chainId, history, urlChainId, urlChain])
if (!chainId || !info || !library) {
return null
}
@@ -247,14 +312,14 @@ export default function NetworkSelector() {
<StyledChevronDown />
</SelectorControls>
{open && (
<FlyoutMenu>
<FlyoutMenu onMouseLeave={toggle}>
<FlyoutHeader>
<Trans>Select a network</Trans>
</FlyoutHeader>
<Row onSelectChain={handleRowClick} targetChain={SupportedChainId.MAINNET} />
<Row onSelectChain={handleRowClick} targetChain={SupportedChainId.POLYGON} />
<Row onSelectChain={handleRowClick} targetChain={SupportedChainId.OPTIMISM} />
<Row onSelectChain={handleRowClick} targetChain={SupportedChainId.ARBITRUM_ONE} />
<Row onSelectChain={handleChainSwitch} targetChain={SupportedChainId.MAINNET} />
<Row onSelectChain={handleChainSwitch} targetChain={SupportedChainId.POLYGON} />
<Row onSelectChain={handleChainSwitch} targetChain={SupportedChainId.OPTIMISM} />
<Row onSelectChain={handleChainSwitch} targetChain={SupportedChainId.ARBITRUM_ONE} />
</FlyoutMenu>
)}
</SelectorWrapper>

View File

@@ -1,15 +1,15 @@
import { Trans } from '@lingui/macro'
import { RowFixed } from 'components/Row'
import { CHAIN_INFO } from 'constants/chains'
import { CHAIN_INFO } from 'constants/chainInfo'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import useCurrentBlockTimestamp from 'hooks/useCurrentBlockTimestamp'
import useGasPrice from 'hooks/useGasPrice'
import useMachineTimeMs from 'hooks/useMachineTime'
import useTheme from 'hooks/useTheme'
import { useActiveWeb3React } from 'hooks/web3'
import JSBI from 'jsbi'
import useBlockNumber from 'lib/hooks/useBlockNumber'
import ms from 'ms.macro'
import { useEffect, useState } from 'react'
import { useBlockNumber } from 'state/application/hooks'
import styled, { keyframes } from 'styled-components/macro'
import { ExternalLink, ThemedText } from 'theme'
import { ExplorerDataType, getExplorerLink } from 'utils/getExplorerLink'

View File

@@ -1,6 +1,8 @@
import { Trans } from '@lingui/macro'
import useScrollPosition from '@react-hook/window-scroll'
import { CHAIN_INFO, SupportedChainId } from 'constants/chains'
import { CHAIN_INFO } from 'constants/chainInfo'
import { SupportedChainId } from 'constants/chains'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import useTheme from 'hooks/useTheme'
import { darken } from 'polished'
import { NavLink } from 'react-router-dom'
@@ -13,7 +15,6 @@ import { useNativeCurrencyBalances } from 'state/wallet/hooks'
import styled from 'styled-components/macro'
import { ReactComponent as Logo } from '../../assets/svg/logo.svg'
import { useActiveWeb3React } from '../../hooks/web3'
import { ExternalLink, ThemedText } from '../../theme'
import ClaimModal from '../claim/ClaimModal'
import { CardNoise } from '../earn/styled'
@@ -21,6 +22,7 @@ import Menu from '../Menu'
import Row from '../Row'
import { Dots } from '../swap/styleds'
import Web3Status from '../Web3Status'
import HolidayOrnament from './HolidayOrnament'
import NetworkSelector from './NetworkSelector'
const HeaderFrame = styled.div<{ showBackground: boolean }>`
@@ -88,7 +90,7 @@ const HeaderLinks = styled(Row)`
justify-self: center;
background-color: ${({ theme }) => theme.bg0};
width: fit-content;
padding: 4px;
padding: 2px;
border-radius: 16px;
display: grid;
grid-auto-flow: column;
@@ -120,10 +122,11 @@ const AccountElement = styled.div<{ active: boolean }>`
display: flex;
flex-direction: row;
align-items: center;
background-color: ${({ theme, active }) => (!active ? theme.bg1 : theme.bg1)};
border-radius: 12px;
background-color: ${({ theme, active }) => (!active ? theme.bg0 : theme.bg0)};
border-radius: 16px;
white-space: nowrap;
width: 100%;
height: 40px;
:focus {
border: 1px solid blue;
@@ -178,6 +181,8 @@ const UniIcon = styled.div`
:hover {
transform: rotate(-5deg);
}
position: relative;
`
const activeClassName = 'ACTIVE'
@@ -199,11 +204,11 @@ const StyledNavLink = styled(NavLink).attrs({
overflow: hidden;
white-space: nowrap;
&.${activeClassName} {
border-radius: 12px;
border-radius: 14px;
font-weight: 600;
justify-content: center;
color: ${({ theme }) => theme.text1};
background-color: ${({ theme }) => theme.bg2};
background-color: ${({ theme }) => theme.bg1};
}
:hover,
@@ -228,7 +233,7 @@ const StyledExternalLink = styled(ExternalLink).attrs({
font-weight: 500;
&.${activeClassName} {
border-radius: 12px;
border-radius: 14px;
font-weight: 600;
color: ${({ theme }) => theme.text1};
}
@@ -259,9 +264,7 @@ export default function Header() {
const {
infoLink,
addNetworkInfo: {
nativeCurrency: { symbol: nativeCurrencySymbol },
},
nativeCurrency: { symbol: nativeCurrencySymbol },
} = CHAIN_INFO[chainId ? chainId : SupportedChainId.MAINNET]
return (
@@ -270,6 +273,7 @@ export default function Header() {
<Title href=".">
<UniIcon>
<Logo fill={darkMode ? white : black} width="24px" height="100%" title="logo" />
<HolidayOrnament />
</UniIcon>
</Title>
<HeaderLinks>

View File

@@ -1,4 +1,5 @@
import { AbstractConnector } from '@web3-react/abstract-connector'
import { Connector } from '@widgets/web3-react/types'
import CoinbaseWalletIcon from '../../assets/images/coinbaseWalletIcon.svg'
import FortmaticIcon from '../../assets/images/fortmaticIcon.png'
@@ -7,7 +8,7 @@ import WalletConnectIcon from '../../assets/images/walletConnectIcon.svg'
import { fortmatic, injected, portis, walletconnect, walletlink } from '../../connectors'
import Identicon from '../Identicon'
export default function StatusIcon({ connector }: { connector: AbstractConnector }) {
export default function StatusIcon({ connector }: { connector: AbstractConnector | Connector }) {
switch (connector) {
case injected:
return <Identicon />

View File

@@ -1,10 +1,9 @@
import jazzicon from '@metamask/jazzicon'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import useENSAvatar from 'hooks/useENSAvatar'
import { useLayoutEffect, useMemo, useRef, useState } from 'react'
import styled from 'styled-components/macro'
import { useActiveWeb3React } from '../../hooks/web3'
const StyledIdenticon = styled.div`
height: 1rem;
width: 1rem;

View File

@@ -1,16 +1,10 @@
import { Currency } from '@uniswap/sdk-core'
import { FeeAmount } from '@uniswap/v3-sdk'
import { usePoolActiveLiquidity } from 'hooks/usePoolTickData'
import JSBI from 'jsbi'
import { TickProcessed, usePoolActiveLiquidity } from 'hooks/usePoolTickData'
import { useCallback, useMemo } from 'react'
import { ChartEntry } from './types'
export interface TickProcessed {
liquidityActive: JSBI
price0: string
}
export function useDensityChartData({
currencyA,
currencyB,

View File

@@ -4,6 +4,7 @@ import { PrivacyPolicyModal } from 'components/PrivacyPolicy'
import { L2_CHAIN_IDS } from 'constants/chains'
import { LOCALE_LABEL, SUPPORTED_LOCALES, SupportedLocale } from 'constants/locales'
import { useActiveLocale } from 'hooks/useActiveLocale'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { useLocationLinkProps } from 'hooks/useLocationLinkProps'
import React, { useEffect, useRef, useState } from 'react'
import {
@@ -25,7 +26,6 @@ import styled, { css } from 'styled-components/macro'
import { ReactComponent as MenuIcon } from '../../assets/images/menu.svg'
import { useOnClickOutside } from '../../hooks/useOnClickOutside'
import { useActiveWeb3React } from '../../hooks/web3'
import { useModalOpen, useToggleModal } from '../../state/application/hooks'
import { ApplicationModal } from '../../state/application/reducer'
import { ExternalLink } from '../../theme'
@@ -49,12 +49,11 @@ const StyledMenuButton = styled.button`
background-color: transparent;
margin: 0;
padding: 0;
height: 38px;
height: 40px;
background-color: ${({ theme }) => theme.bg0};
border: 1px solid ${({ theme }) => theme.bg0};
padding: 0.15rem 0.5rem;
border-radius: 12px;
border-radius: 16px;
:hover,
:focus {

View File

@@ -1,10 +1,10 @@
import { Trans } from '@lingui/macro'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { useContext } from 'react'
import { ArrowUpCircle } from 'react-feather'
import styled, { ThemeContext } from 'styled-components/macro'
import Circle from '../../assets/images/blue-loader.svg'
import { useActiveWeb3React } from '../../hooks/web3'
import { CloseIcon, CustomLightSpinner, ThemedText } from '../../theme'
import { ExternalLink } from '../../theme/components'
import { ExplorerDataType, getExplorerLink } from '../../utils/getExplorerLink'

View File

@@ -1,108 +1,77 @@
import { Trans } from '@lingui/macro'
import { CHAIN_INFO } from 'constants/chainInfo'
import { SupportedChainId } from 'constants/chains'
import { useActiveWeb3React } from 'hooks/web3'
import { useCallback, useMemo, useState } from 'react'
import { ArrowDownCircle, X } from 'react-feather'
import { useDarkModeManager, useNetworkAlertStatus } from 'state/user/hooks'
import { useNativeCurrencyBalances } from 'state/wallet/hooks'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { ArrowUpRight } from 'react-feather'
import { useDarkModeManager } from 'state/user/hooks'
import styled from 'styled-components/macro'
import { ExternalLink, MEDIA_WIDTHS } from 'theme'
import { ExternalLink, HideSmall } from 'theme'
import { CHAIN_INFO } from '../../constants/chains'
import { ThemedText } from '../../theme'
import { AutoRow } from '../Row'
const L2Icon = styled.img`
width: 36px;
height: 36px;
justify-self: center;
margin-right: 14px;
`
const BetaTag = styled.span<{ color: string }>`
align-items: center;
background-color: ${({ color }) => color};
border-radius: 6px;
color: ${({ theme }) => theme.white};
display: flex;
font-size: 14px;
height: 28px;
justify-content: center;
left: -16px;
position: absolute;
transform: rotate(-15deg);
top: -16px;
width: 60px;
z-index: 1;
width: 24px;
height: 24px;
margin-right: 16px;
`
export const Controls = styled.div`
align-items: center;
display: flex;
justify-content: flex-start;
padding: 0 20px 20px 20px;
`
const CloseIcon = styled(X)`
cursor: pointer;
position: absolute;
top: 16px;
right: 16px;
`
const BodyText = styled.div`
align-items: center;
margin: 20px 16px;
@media screen and (min-width: ${MEDIA_WIDTHS.upToSmall}px) {
grid-template-columns: 42px 4fr;
grid-gap: 8px;
}
`
const LearnMoreLink = styled(ExternalLink)`
align-items: center;
background-color: transparent;
border: 1px solid rgba(255, 255, 255, 0.4);
border-radius: 8px;
color: ${({ theme }) => theme.text1};
color: ${({ color }) => color};
display: flex;
font-size: 16px;
height: 44px;
justify-content: space-between;
padding: 12px 16px;
text-decoration: none;
width: auto;
:hover,
:focus,
:active {
background-color: rgba(255, 255, 255, 0.05);
}
transition: background-color 150ms ease-in-out;
align-items: center;
justify-content: flex-start;
margin: 8px;
font-size: 14px;
`
const RootWrapper = styled.div`
position: relative;
margin-top: 16px;
`
const SHOULD_SHOW_ALERT = {
[SupportedChainId.OPTIMISM]: true,
[SupportedChainId.OPTIMISTIC_KOVAN]: true,
[SupportedChainId.ARBITRUM_ONE]: true,
[SupportedChainId.ARBITRUM_RINKEBY]: true,
[SupportedChainId.POLYGON]: true,
[SupportedChainId.POLYGON_MUMBAI]: true,
}
type NetworkAlertChains = keyof typeof SHOULD_SHOW_ALERT
const BG_COLORS_BY_DARK_MODE_AND_CHAIN_ID: {
[darkMode in 'dark' | 'light']: { [chainId in SupportedChainId]?: string }
[darkMode in 'dark' | 'light']: { [chainId in NetworkAlertChains]: string }
} = {
dark: {
[SupportedChainId.POLYGON]:
'radial-gradient(100% 93.36% at 0% 6.64%, rgba(160, 108, 247, 0.3) 0%, rgba(82, 32, 166, 0.3) 100%)',
'radial-gradient(100% 93.36% at 0% 6.64%, rgba(160, 108, 247, 0.1) 0%, rgba(82, 32, 166, 0.1) 100%)',
[SupportedChainId.POLYGON_MUMBAI]:
'radial-gradient(100% 93.36% at 0% 6.64%, rgba(160, 108, 247, 0.3) 0%, rgba(82, 32, 166, 0.3) 100%)',
'radial-gradient(100% 93.36% at 0% 6.64%, rgba(160, 108, 247, 0.1) 0%, rgba(82, 32, 166, 0.1) 100%)',
[SupportedChainId.OPTIMISM]:
'radial-gradient(948% 292% at 42% 0%, rgba(255, 58, 212, 0.2) 0%, rgba(255, 255, 255, 0.1) 100%),radial-gradient(98% 96% at 2% 0%, rgba(255, 39, 39, 0.5) 0%, rgba(235, 0, 255, 0.345) 96%)',
'radial-gradient(948% 292% at 42% 0%, rgba(255, 58, 212, 0.01) 0%, rgba(255, 255, 255, 0.04) 100%),radial-gradient(98% 96% at 2% 0%, rgba(255, 39, 39, 0.01) 0%, rgba(235, 0, 255, 0.01) 96%)',
[SupportedChainId.OPTIMISTIC_KOVAN]:
'radial-gradient(948% 292% at 42% 0%, rgba(255, 58, 212, 0.2) 0%, rgba(255, 255, 255, 0.1) 100%),radial-gradient(98% 96% at 2% 0%, rgba(255, 39, 39, 0.5) 0%, rgba(235, 0, 255, 0.345) 96%)',
'radial-gradient(948% 292% at 42% 0%, rgba(255, 58, 212, 0.04) 0%, rgba(255, 255, 255, 0.04) 100%),radial-gradient(98% 96% at 2% 0%, rgba(255, 39, 39, 0.04) 0%, rgba(235, 0, 255, 0.01 96%)',
[SupportedChainId.ARBITRUM_ONE]:
'radial-gradient(285% 8200% at 30% 50%, rgba(40, 160, 240, 0.1) 0%, rgba(219, 255, 0, 0) 100%),radial-gradient(75% 75% at 0% 0%, rgba(150, 190, 220, 0.3) 0%, rgba(33, 114, 229, 0.3) 100%), hsla(0, 0%, 100%, 0.1)',
'radial-gradient(285% 8200% at 30% 50%, rgba(40, 160, 240, 0.01) 0%, rgba(219, 255, 0, 0) 100%),radial-gradient(75% 75% at 0% 0%, rgba(150, 190, 220, 0.05) 0%, rgba(33, 114, 229, 0.05) 100%), hsla(0, 0%, 100%, 0.05)',
[SupportedChainId.ARBITRUM_RINKEBY]:
'radial-gradient(285% 8200% at 30% 50%, rgba(40, 160, 240, 0.1) 0%, rgba(219, 255, 0, 0) 100%),radial-gradient(75% 75% at 0% 0%, rgba(150, 190, 220, 0.3) 0%, rgba(33, 114, 229, 0.3) 100%), hsla(0, 0%, 100%, 0.1)',
'radial-gradient(285% 8200% at 30% 50%, rgba(40, 160, 240, 0.05) 0%, rgba(219, 255, 0, 0) 100%),radial-gradient(75% 75% at 0% 0%, rgba(150, 190, 220, 0.05) 0%, rgba(33, 114, 229, 0.1) 100%), hsla(0, 0%, 100%, 0.05)',
},
light: {
[SupportedChainId.POLYGON]:
'radial-gradient(182.71% 205.59% at 2.81% 7.69%, rgba(130, 71, 229, 0.3) 0%, rgba(167, 202, 255, 0.3) 100%)',
'radial-gradient(182.71% 205.59% at 2.81% 7.69%, rgba(130, 71, 229, 0.2) 0%, rgba(167, 202, 255, 0.2) 100%)',
[SupportedChainId.POLYGON_MUMBAI]:
'radial-gradient(182.71% 205.59% at 2.81% 7.69%, rgba(130, 71, 229, 0.3) 0%, rgba(167, 202, 255, 0.3) 100%)',
'radial-gradient(182.71% 205.59% at 2.81% 7.69%, rgba(130, 71, 229, 0.2) 0%, rgba(167, 202, 255, 0.2) 100%)',
[SupportedChainId.OPTIMISM]:
'radial-gradient(92% 105% at 50% 7%, rgba(255, 58, 212, 0.04) 0%, rgba(255, 255, 255, 0.03) 100%),radial-gradient(100% 97% at 0% 12%, rgba(235, 0, 255, 0.1) 0%, rgba(243, 19, 19, 0.1) 100%), hsla(0, 0%, 100%, 0.5)',
'radial-gradient(92% 105% at 50% 7%, rgba(255, 58, 212, 0.04) 0%, rgba(255, 255, 255, 0.03) 100%),radial-gradient(100% 97% at 0% 12%, rgba(235, 0, 255, 0.1) 0%, rgba(243, 19, 19, 0.1) 100%), hsla(0, 0%, 100%, 0.1)',
[SupportedChainId.OPTIMISTIC_KOVAN]:
'radial-gradient(92% 105% at 50% 7%, rgba(255, 58, 212, 0.04) 0%, rgba(255, 255, 255, 0.03) 100%),radial-gradient(100% 97% at 0% 12%, rgba(235, 0, 255, 0.1) 0%, rgba(243, 19, 19, 0.1) 100%), hsla(0, 0%, 100%, 0.5)',
'radial-gradient(92% 105% at 50% 7%, rgba(255, 58, 212, 0.04) 0%, rgba(255, 255, 255, 0.03) 100%),radial-gradient(100% 97% at 0% 12%, rgba(235, 0, 255, 0.1) 0%, rgba(243, 19, 19, 0.1) 100%), hsla(0, 0%, 100%, 0.1)',
[SupportedChainId.ARBITRUM_ONE]:
'radial-gradient(285% 8200% at 30% 50%, rgba(40, 160, 240, 0.1) 0%, rgba(219, 255, 0, 0) 100%),radial-gradient(circle at top left, hsla(206, 50%, 75%, 0.01), hsla(215, 79%, 51%, 0.12)), hsla(0, 0%, 100%, 0.1)',
[SupportedChainId.ARBITRUM_RINKEBY]:
@@ -110,14 +79,15 @@ const BG_COLORS_BY_DARK_MODE_AND_CHAIN_ID: {
},
}
const ContentWrapper = styled.div<{ chainId: SupportedChainId; darkMode: boolean; logoUrl: string }>`
const ContentWrapper = styled.div<{ chainId: NetworkAlertChains; darkMode: boolean; logoUrl: string }>`
background: ${({ chainId, darkMode }) => BG_COLORS_BY_DARK_MODE_AND_CHAIN_ID[darkMode ? 'dark' : 'light'][chainId]};
border-radius: 20px;
display: flex;
flex-direction: column;
flex-direction: row;
overflow: hidden;
position: relative;
width: 100%;
:before {
background-image: url(${({ logoUrl }) => logoUrl});
background-repeat: no-repeat;
@@ -133,137 +103,43 @@ const ContentWrapper = styled.div<{ chainId: SupportedChainId; darkMode: boolean
`
const Header = styled.h2`
font-weight: 600;
font-size: 20px;
font-size: 16px;
margin: 0;
padding-right: 30px;
`
const LinkOutCircle = styled(ArrowDownCircle)`
margin-left: 12px;
transform: rotate(230deg);
width: 20px;
height: 20px;
`
const LinkOutToBridge = styled(ExternalLink)`
align-items: center;
background-color: black;
border-radius: 8px;
color: white;
display: flex;
font-size: 16px;
height: 44px;
justify-content: space-between;
padding: 12px 16px;
margin-right: 20px;
text-decoration: none;
width: auto;
:hover,
:focus,
:active {
background-color: black;
}
padding: 6px 8px;
margin-right: 12px;
text-decoration: none !important;
width: 100%;
`
const DisclaimerText = styled(ThemedText.Body)`
padding: 0 0.5em;
font-size: 14px !important;
const StyledArrowUpRight = styled(ArrowUpRight)`
margin-left: 12px;
width: 24px;
height: 24px;
`
const BETA_TAG_COLORS: { [chainId in SupportedChainId]?: string } = {
[SupportedChainId.OPTIMISM]: '#ff0420',
[SupportedChainId.OPTIMISTIC_KOVAN]: '#ff0420',
const TEXT_COLORS: { [chainId in NetworkAlertChains]: string } = {
[SupportedChainId.POLYGON]: 'rgba(130, 71, 229)',
[SupportedChainId.POLYGON_MUMBAI]: 'rgba(130, 71, 229)',
[SupportedChainId.OPTIMISM]: '#ff3856',
[SupportedChainId.OPTIMISTIC_KOVAN]: '#ff3856',
[SupportedChainId.ARBITRUM_ONE]: '#0490ed',
[SupportedChainId.ARBITRUM_RINKEBY]: '#0490ed',
}
const SHOULD_SHOW_ALERT: { [chainId in SupportedChainId]?: true } = {
[SupportedChainId.OPTIMISM]: true,
[SupportedChainId.OPTIMISTIC_KOVAN]: true,
[SupportedChainId.ARBITRUM_ONE]: true,
[SupportedChainId.ARBITRUM_RINKEBY]: true,
[SupportedChainId.POLYGON]: true,
[SupportedChainId.POLYGON_MUMBAI]: true,
}
function shouldShowAlert(chainId: number | undefined): chainId is SupportedChainId {
return Boolean(chainId && SHOULD_SHOW_ALERT[chainId as SupportedChainId])
function shouldShowAlert(chainId: number | undefined): chainId is NetworkAlertChains {
return Boolean(chainId && SHOULD_SHOW_ALERT[chainId as unknown as NetworkAlertChains])
}
export function NetworkAlert() {
const { account, chainId } = useActiveWeb3React()
const [darkMode] = useDarkModeManager()
const [alertAcknowledged, acknowledgeAlert] = useNetworkAlertStatus(chainId)
const [locallyDismissed, setLocallyDimissed] = useState(false)
const accounts = useMemo(() => (account ? [account] : []), [account])
const userNativeCurrencyBalance = useNativeCurrencyBalances(accounts)?.[account ?? '']
const dismiss = useCallback(() => {
setLocallyDimissed(true)
if (!alertAcknowledged) acknowledgeAlert()
}, [acknowledgeAlert, alertAcknowledged])
if (!shouldShowAlert(chainId) || alertAcknowledged || locallyDismissed) {
return null
}
const { label, logoUrl, bridge, helpCenterUrl } = CHAIN_INFO[chainId]
const showCloseIcon = Boolean(userNativeCurrencyBalance?.greaterThan(0))
const betaColor = BETA_TAG_COLORS[chainId]
return (
<RootWrapper>
{betaColor ? <BetaTag color={betaColor}>Beta</BetaTag> : null}
<ContentWrapper chainId={chainId} darkMode={darkMode} logoUrl={logoUrl}>
{showCloseIcon && <CloseIcon onClick={dismiss} />}
<BodyText>
<AutoRow style={{ marginBottom: '1em' }}>
<L2Icon src={logoUrl} />
<Header>
<Trans>Uniswap on {label}</Trans>
</Header>
</AutoRow>
<DisclaimerText>
{betaColor ? (
<Trans>
Please treat this as a beta release and learn about the risks before using {label}. To start trading on{' '}
{label}, first bridge your assets from L1 to L2.
</Trans>
) : (
<Trans>To start trading on {label}, first bridge your assets from L1 to L2.</Trans>
)}
</DisclaimerText>
</BodyText>
<Controls>
{bridge ? (
<LinkOutToBridge href={bridge}>
<Trans>Deposit Assets</Trans>
<LinkOutCircle />
</LinkOutToBridge>
) : null}
{helpCenterUrl ? (
<LearnMoreLink href={helpCenterUrl}>
<Trans>Learn More</Trans>
</LearnMoreLink>
) : null}
</Controls>
</ContentWrapper>
</RootWrapper>
)
}
const AlertRow = styled.div`
display: flex;
padding: 1em;
align-items: center;
`
const ButtonContainer = styled.div`
flex-shrink: 0;
flex-grow: 0;
display: flex;
height: 100%;
`
const FlexGrow = styled.div`
flex-grow: 1;
`
export function SingleRowNetworkAlert() {
const { chainId } = useActiveWeb3React()
const [darkMode] = useDarkModeManager()
@@ -271,44 +147,27 @@ export function SingleRowNetworkAlert() {
return null
}
const { label, logoUrl, bridge, helpCenterUrl } = CHAIN_INFO[chainId]
const betaColor = BETA_TAG_COLORS[chainId]
const { label, logoUrl, bridge } = CHAIN_INFO[chainId]
const textColor = TEXT_COLORS[chainId]
return (
return bridge ? (
<RootWrapper>
{betaColor ? <BetaTag color={betaColor}>Beta</BetaTag> : null}
<ContentWrapper chainId={chainId} darkMode={darkMode} logoUrl={logoUrl}>
<AlertRow>
<L2Icon src={logoUrl} />
<FlexGrow>
<DisclaimerText>
{betaColor ? (
<Trans>
Please treat this as a beta release and learn about the risks before using {label}. To start trading
on {label}, first bridge your assets from L1 to L2.
</Trans>
) : (
<Trans>To start trading on {label}, first bridge your assets from L1 to L2.</Trans>
)}
</DisclaimerText>
</FlexGrow>
<ButtonContainer>
{bridge ? (
<LinkOutToBridge href={bridge}>
<Trans>Deposit Assets</Trans>
<LinkOutCircle />
</LinkOutToBridge>
) : null}
{helpCenterUrl ? (
<LearnMoreLink href={helpCenterUrl}>
<Trans>Learn More</Trans>
</LearnMoreLink>
) : null}
</ButtonContainer>
</AlertRow>
<LinkOutToBridge href={bridge}>
<BodyText color={textColor}>
<L2Icon src={logoUrl} />
<AutoRow>
<Header>
<Trans>{label} token bridge</Trans>
</Header>
<HideSmall>
<Trans>Deposit tokens to the {label} network.</Trans>
</HideSmall>
</AutoRow>
</BodyText>
<StyledArrowUpRight color={textColor} />
</LinkOutToBridge>
</ContentWrapper>
</RootWrapper>
)
) : null
}

View File

@@ -1,11 +1,10 @@
import { Options, Placement } from '@popperjs/core'
import Portal from '@reach/portal'
import useInterval from 'lib/hooks/useInterval'
import React, { useCallback, useMemo, useState } from 'react'
import { usePopper } from 'react-popper'
import styled from 'styled-components/macro'
import useInterval from '../../hooks/useInterval'
const PopoverContainer = styled.div<{ show: boolean }>`
z-index: 9999;
visibility: ${(props) => (props.show ? 'visible' : 'hidden')};

View File

@@ -1,12 +1,12 @@
import { Trans } from '@lingui/macro'
import { CurrencyAmount, Token } from '@uniswap/sdk-core'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { useCallback, useEffect } from 'react'
import { Heart, X } from 'react-feather'
import ReactGA from 'react-ga'
import styled, { keyframes } from 'styled-components/macro'
import tokenLogo from '../../assets/images/token-logo.png'
import { useActiveWeb3React } from '../../hooks/web3'
import {
useModalOpen,
useShowClaimPopup,

View File

@@ -1,9 +1,10 @@
import { Trans } from '@lingui/macro'
import { CHAIN_INFO } from 'constants/chainInfo'
import { SupportedChainId } from 'constants/chains'
import { useContext } from 'react'
import { AlertCircle } from 'react-feather'
import styled, { ThemeContext } from 'styled-components/macro'
import { CHAIN_INFO, SupportedChainId } from '../../constants/chains'
import { ThemedText } from '../../theme'
import { AutoColumn } from '../Column'
import { AutoRow } from '../Row'
@@ -24,8 +25,8 @@ export default function FailedNetworkSwitchPopup({ chainId }: { chainId: Support
<AutoColumn gap="8px">
<ThemedText.Body fontWeight={500}>
<Trans>
Your wallet does not support switching networks from the Uniswap Interface. In order to use Uniswap on{' '}
{chainInfo.label}, you must change the network in your wallet.
Failed to switch networks from the Uniswap Interface. In order to use Uniswap on {chainInfo.label}, you must
change the network in your wallet.
</Trans>
</ThemedText.Body>
</AutoColumn>

View File

@@ -0,0 +1,106 @@
import { Trans } from '@lingui/macro'
import { AutoColumn } from 'components/Column'
import { RowFixed } from 'components/Row'
import useCurrentBlockTimestamp from 'hooks/useCurrentBlockTimestamp'
import { useEffect } from 'react'
import { MessageCircle, X } from 'react-feather'
import ReactGA from 'react-ga'
import { useShowSurveyPopup } from 'state/user/hooks'
import styled from 'styled-components/macro'
import { ExternalLink, ThemedText, Z_INDEX } from 'theme'
import BGImage from '../../assets/images/survey-orb.svg'
import useTheme from '../../hooks/useTheme'
const Wrapper = styled(AutoColumn)`
background: #edeef2;
position: relative;
border-radius: 12px;
padding: 18px;
max-width: 360px;
box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.1);
color: ${({ theme }) => theme.text1};
overflow: hidden;
${({ theme }) => theme.mediaWidth.upToSmall`
max-width: 100%;
`}
`
const BGOrb = styled.img`
position: absolute;
right: -64px;
top: -64px;
width: 180px;
z-index: ${Z_INDEX.sticky};
`
const WrappedCloseIcon = styled(X)`
position: absolute;
top: 10px;
right: 10px;
width: 20px;
height: 20px;
stroke: #7c7c80;
z-index: ${Z_INDEX.fixed};
:hover {
cursor: pointer;
opacity: 0.8;
}
`
const END_TIMESTAMP = 1642272346 // Jan 15th
export default function SurveyPopup() {
const theme = useTheme()
const [showPopup, setShowSurveyPopup] = useShowSurveyPopup()
// show popup to 1% of users
useEffect(() => {
// has not visited page during A/B testing if undefined
if (showPopup === undefined) {
if (Math.random() < 0.01) {
setShowSurveyPopup(true)
// log a case of succesful view
ReactGA.event({
category: 'Survey',
action: 'Saw Survey',
})
}
}
}, [setShowSurveyPopup, showPopup])
// limit survey to 24 hours based on timestamps
const timestamp = useCurrentBlockTimestamp()
const durationOver = timestamp ? timestamp.toNumber() > END_TIMESTAMP : false
return (
<>
{!showPopup || durationOver ? null : (
<Wrapper gap="10px">
<WrappedCloseIcon
onClick={() => {
ReactGA.event({
category: 'Survey',
action: 'Clicked Survey Link',
})
setShowSurveyPopup(false)
}}
/>
<BGOrb src={BGImage} />
<ExternalLink href="https://www.surveymonkey.com/r/YGWV9VD">
<RowFixed>
<MessageCircle stroke={theme.black} size="20px" strokeWidth="1px" />
<ThemedText.White fontWeight={600} color={theme.black} ml="6px">
<Trans>Tell us what you think </Trans>
</ThemedText.White>
</RowFixed>
</ExternalLink>
<ThemedText.Black style={{ zIndex: Z_INDEX.fixed }} fontWeight={400} fontSize="12px" color={theme.black}>
<Trans>Take a 10 minute survey to help us improve your experience in the Uniswap app.</Trans>
</ThemedText.Black>
</Wrapper>
)}
</>
)
}

View File

@@ -1,8 +1,8 @@
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { useContext } from 'react'
import { AlertCircle, CheckCircle } from 'react-feather'
import styled, { ThemeContext } from 'styled-components/macro'
import { useActiveWeb3React } from '../../hooks/web3'
import { useTransaction } from '../../state/transactions/hooks'
import { ThemedText } from '../../theme'
import { ExternalLink } from '../../theme'

View File

@@ -1,5 +1,5 @@
import { SupportedChainId } from 'constants/chains'
import { useActiveWeb3React } from 'hooks/web3'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import styled from 'styled-components/macro'
import { MEDIA_WIDTHS } from 'theme'

View File

@@ -1,6 +1,7 @@
import { Trans } from '@lingui/macro'
import { CurrencyAmount, Percent, Token } from '@uniswap/sdk-core'
import { Pair } from '@uniswap/v2-sdk'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import JSBI from 'jsbi'
import { transparentize } from 'polished'
import { useState } from 'react'
@@ -12,7 +13,6 @@ import styled from 'styled-components/macro'
import { BIG_INT_ZERO } from '../../constants/misc'
import { useColor } from '../../hooks/useColor'
import { useTotalSupply } from '../../hooks/useTotalSupply'
import { useActiveWeb3React } from '../../hooks/web3'
import { useTokenBalance } from '../../state/wallet/hooks'
import { currencyId } from '../../utils/currencyId'
import { unwrappedToken } from '../../utils/unwrappedToken'

View File

@@ -1,6 +1,7 @@
import { Trans } from '@lingui/macro'
import { CurrencyAmount, Percent, Token } from '@uniswap/sdk-core'
import { Pair } from '@uniswap/v2-sdk'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import JSBI from 'jsbi'
import { transparentize } from 'polished'
import { useState } from 'react'
@@ -12,7 +13,6 @@ import styled from 'styled-components/macro'
import { BIG_INT_ZERO } from '../../constants/misc'
import { useColor } from '../../hooks/useColor'
import { useTotalSupply } from '../../hooks/useTotalSupply'
import { useActiveWeb3React } from '../../hooks/web3'
import { useTokenBalance } from '../../state/wallet/hooks'
import { ExternalLink, ThemedText } from '../../theme'
import { currencyId } from '../../utils/currencyId'

View File

@@ -1,4 +1,5 @@
import { Trans } from '@lingui/macro'
import { ButtonText } from 'components/Button'
import PositionListItem from 'components/PositionListItem'
import React from 'react'
import styled from 'styled-components/macro'
@@ -14,9 +15,7 @@ const DesktopHeader = styled.div`
@media screen and (min-width: ${MEDIA_WIDTHS.upToSmall}px) {
align-items: center;
display: flex;
display: grid;
grid-template-columns: 1fr 1fr;
justify-content: space-between;
& > div:last-child {
text-align: right;
margin-right: 12px;
@@ -36,9 +35,15 @@ const MobileHeader = styled.div`
type PositionListProps = React.PropsWithChildren<{
positions: PositionDetails[]
setUserHideClosedPositions: any
userHideClosedPositions: boolean
}>
export default function PositionList({ positions }: PositionListProps) {
export default function PositionList({
positions,
setUserHideClosedPositions,
userHideClosedPositions,
}: PositionListProps) {
return (
<>
<DesktopHeader>
@@ -46,9 +51,9 @@ export default function PositionList({ positions }: PositionListProps) {
<Trans>Your positions</Trans>
{positions && ' (' + positions.length + ')'}
</div>
<div>
<Trans>Status</Trans>
</div>
<ButtonText style={{ opacity: 0.6 }} onClick={() => setUserHideClosedPositions(!userHideClosedPositions)}>
<Trans>Hide closed positions</Trans>
</ButtonText>
</DesktopHeader>
<MobileHeader>
<Trans>Your positions</Trans>

View File

@@ -1,8 +1,6 @@
import { Trans } from '@lingui/macro'
import { Currency } from '@uniswap/sdk-core'
import { AutoColumn } from 'components/Column'
import CurrencyLogo from 'components/CurrencyLogo'
import QuestionHelper from 'components/QuestionHelper'
import { AutoRow } from 'components/Row'
import { COMMON_BASES } from 'constants/routing'
import { useTokenInfoFromActiveList } from 'hooks/useTokenInfoFromActiveList'
@@ -46,12 +44,6 @@ export default function CommonBases({
return bases.length > 0 ? (
<MobileWrapper gap="md">
<AutoRow>
<Text fontWeight={500} fontSize={14}>
<Trans>Common bases</Trans>
</Text>
<QuestionHelper text={<Trans>These tokens are commonly paired with other tokens.</Trans>} />
</AutoRow>
<AutoRow gap="4px">
{bases.map((currency: Currency) => {
const isSelected = selectedCurrency?.equals(currency)

View File

@@ -2,6 +2,7 @@ import { Trans } from '@lingui/macro'
import { Currency, CurrencyAmount, Token } from '@uniswap/sdk-core'
import { LightGreyCard } from 'components/Card'
import QuestionHelper from 'components/QuestionHelper'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import useTheme from 'hooks/useTheme'
import { CSSProperties, MutableRefObject, useCallback, useMemo } from 'react'
import { FixedSizeList } from 'react-window'
@@ -10,7 +11,6 @@ import styled from 'styled-components/macro'
import TokenListLogo from '../../assets/svg/tokenlist.svg'
import { useIsUserAddedToken } from '../../hooks/Tokens'
import { useActiveWeb3React } from '../../hooks/web3'
import { useCombinedActiveList } from '../../state/lists/hooks'
import { WrappedTokenInfo } from '../../state/lists/wrappedTokenInfo'
import { useCurrencyBalance } from '../../state/wallet/hooks'

View File

@@ -1,35 +1,31 @@
// eslint-disable-next-line no-restricted-imports
import { t, Trans } from '@lingui/macro'
import { Currency, Token } from '@uniswap/sdk-core'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import useDebounce from 'hooks/useDebounce'
import { useOnClickOutside } from 'hooks/useOnClickOutside'
import useTheme from 'hooks/useTheme'
import useToggle from 'hooks/useToggle'
import useNativeCurrency from 'lib/hooks/useNativeCurrency'
import { getTokenFilter } from 'lib/hooks/useTokenList/filtering'
import { tokenComparator, useSortTokensByQuery } from 'lib/hooks/useTokenList/sorting'
import { KeyboardEvent, RefObject, useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { Edit } from 'react-feather'
import ReactGA from 'react-ga'
import AutoSizer from 'react-virtualized-auto-sizer'
import { FixedSizeList } from 'react-window'
import { Text } from 'rebass'
import { useAllTokenBalances } from 'state/wallet/hooks'
import styled from 'styled-components/macro'
import {
useAllTokens,
useIsUserAddedToken,
useNativeCurrency,
useSearchInactiveTokenLists,
useToken,
} from '../../hooks/Tokens'
import { useActiveWeb3React } from '../../hooks/web3'
import { useAllTokens, useIsUserAddedToken, useSearchInactiveTokenLists, useToken } from '../../hooks/Tokens'
import { ButtonText, CloseIcon, IconWrapper, ThemedText } from '../../theme'
import { isAddress } from '../../utils'
import Column from '../Column'
import Row, { RowBetween, RowFixed } from '../Row'
import CommonBases from './CommonBases'
import CurrencyList from './CurrencyList'
import { filterTokens, useSortedTokensByQuery } from './filtering'
import ImportRow from './ImportRow'
import { useTokenComparator } from './sorting'
import { PaddedColumn, SearchInput, Separator } from './styleds'
const ContentWrapper = styled(Column)`
@@ -84,8 +80,6 @@ export function CurrencySearch({
const [searchQuery, setSearchQuery] = useState<string>('')
const debouncedQuery = useDebounce(searchQuery, 200)
const [invertSearchOrder] = useState<boolean>(false)
const allTokens = useAllTokens()
// if they input an address, use it
@@ -105,17 +99,16 @@ export function CurrencySearch({
}
}, [isAddressSearch])
const tokenComparator = useTokenComparator(invertSearchOrder)
const filteredTokens: Token[] = useMemo(() => {
return filterTokens(Object.values(allTokens), debouncedQuery)
return Object.values(allTokens).filter(getTokenFilter(debouncedQuery))
}, [allTokens, debouncedQuery])
const balances = useAllTokenBalances()
const sortedTokens: Token[] = useMemo(() => {
return filteredTokens.sort(tokenComparator)
}, [filteredTokens, tokenComparator])
return filteredTokens.sort(tokenComparator.bind(null, balances))
}, [balances, filteredTokens])
const filteredSortedTokens = useSortedTokensByQuery(sortedTokens, debouncedQuery)
const filteredSortedTokens = useSortTokensByQuery(debouncedQuery, sortedTokens)
const native = useNativeCurrency()

View File

@@ -3,8 +3,10 @@ import { t, Trans } from '@lingui/macro'
import { TokenList } from '@uniswap/token-lists'
import Card from 'components/Card'
import { UNSUPPORTED_LIST_URLS } from 'constants/lists'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { useListColor } from 'hooks/useColor'
import { useActiveWeb3React } from 'hooks/web3'
import parseENSAddress from 'lib/utils/parseENSAddress'
import uriToHttp from 'lib/utils/uriToHttp'
import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { CheckCircle, Settings } from 'react-feather'
import ReactGA from 'react-ga'
@@ -20,8 +22,6 @@ import { acceptListUpdate, disableList, enableList, removeList } from '../../sta
import { useActiveListUrls, useAllLists, useIsListActive } from '../../state/lists/hooks'
import { ExternalLink, IconWrapper, LinkStyledButton, ThemedText } from '../../theme'
import listVersionLabel from '../../utils/listVersionLabel'
import { parseENSAddress } from '../../utils/parseENSAddress'
import uriToHttp from '../../utils/uriToHttp'
import { ButtonEmpty, ButtonPrimary } from '../Button'
import Column, { AutoColumn } from '../Column'
import ListLogo from '../ListLogo'

View File

@@ -5,7 +5,7 @@ import Column from 'components/Column'
import CurrencyLogo from 'components/CurrencyLogo'
import Row, { RowBetween, RowFixed } from 'components/Row'
import { useToken } from 'hooks/Tokens'
import { useActiveWeb3React } from 'hooks/web3'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { RefObject, useCallback, useMemo, useRef, useState } from 'react'
import { useRemoveUserAddedToken, useUserAddedTokens } from 'state/user/hooks'
import styled from 'styled-components/macro'

View File

@@ -6,7 +6,7 @@ import { AutoColumn } from 'components/Column'
import CurrencyLogo from 'components/CurrencyLogo'
import ListLogo from 'components/ListLogo'
import { RowFixed } from 'components/Row'
import { useActiveWeb3React } from 'hooks/web3'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { transparentize } from 'polished'
import { AlertCircle } from 'react-feather'
import styled, { useTheme } from 'styled-components/macro'

View File

@@ -1,76 +0,0 @@
import { Token } from '@uniswap/sdk-core'
import { TokenInfo } from '@uniswap/token-lists'
import { useMemo } from 'react'
import { isAddress } from '../../utils'
const alwaysTrue = () => true
/**
* Create a filter function to apply to a token for whether it matches a particular search query
* @param search the search query to apply to the token
*/
export function createTokenFilterFunction<T extends Token | TokenInfo>(search: string): (tokens: T) => boolean {
const searchingAddress = isAddress(search)
if (searchingAddress) {
const lower = searchingAddress.toLowerCase()
return (t: T) => ('isToken' in t ? searchingAddress === t.address : lower === t.address.toLowerCase())
}
const lowerSearchParts = search
.toLowerCase()
.split(/\s+/)
.filter((s) => s.length > 0)
if (lowerSearchParts.length === 0) return alwaysTrue
const matchesSearch = (s: string): boolean => {
const sParts = s
.toLowerCase()
.split(/\s+/)
.filter((s) => s.length > 0)
return lowerSearchParts.every((p) => p.length === 0 || sParts.some((sp) => sp.startsWith(p) || sp.endsWith(p)))
}
return ({ name, symbol }: T): boolean => Boolean((symbol && matchesSearch(symbol)) || (name && matchesSearch(name)))
}
export function filterTokens<T extends Token | TokenInfo>(tokens: T[], search: string): T[] {
return tokens.filter(createTokenFilterFunction(search))
}
export function useSortedTokensByQuery(tokens: Token[] | undefined, searchQuery: string): Token[] {
return useMemo(() => {
if (!tokens) {
return []
}
const symbolMatch = searchQuery
.toLowerCase()
.split(/\s+/)
.filter((s) => s.length > 0)
if (symbolMatch.length > 1) {
return tokens
}
const exactMatches: Token[] = []
const symbolSubtrings: Token[] = []
const rest: Token[] = []
// sort tokens by exact match -> subtring on symbol match -> rest
tokens.map((token) => {
if (token.symbol?.toLowerCase() === symbolMatch[0]) {
return exactMatches.push(token)
} else if (token.symbol?.toLowerCase().startsWith(searchQuery.toLowerCase().trim())) {
return symbolSubtrings.push(token)
} else {
return rest.push(token)
}
})
return [...exactMatches, ...symbolSubtrings, ...rest]
}, [tokens, searchQuery])
}

View File

@@ -1,51 +0,0 @@
import { Currency, CurrencyAmount, Token } from '@uniswap/sdk-core'
import { useMemo } from 'react'
import { useAllTokenBalances } from '../../state/wallet/hooks'
// compare two token amounts with highest one coming first
function balanceComparator(balanceA?: CurrencyAmount<Currency>, balanceB?: CurrencyAmount<Currency>) {
if (balanceA && balanceB) {
return balanceA.greaterThan(balanceB) ? -1 : balanceA.equalTo(balanceB) ? 0 : 1
} else if (balanceA && balanceA.greaterThan('0')) {
return -1
} else if (balanceB && balanceB.greaterThan('0')) {
return 1
}
return 0
}
function getTokenComparator(balances: {
[tokenAddress: string]: CurrencyAmount<Currency> | undefined
}): (tokenA: Token, tokenB: Token) => number {
return function sortTokens(tokenA: Token, tokenB: Token): number {
// -1 = a is first
// 1 = b is first
// sort by balances
const balanceA = balances[tokenA.address]
const balanceB = balances[tokenB.address]
const balanceComp = balanceComparator(balanceA, balanceB)
if (balanceComp !== 0) return balanceComp
if (tokenA.symbol && tokenB.symbol) {
// sort by symbol
return tokenA.symbol.toLowerCase() < tokenB.symbol.toLowerCase() ? -1 : 1
} else {
return tokenA.symbol ? -1 : tokenB.symbol ? -1 : 0
}
}
}
export function useTokenComparator(inverted: boolean): (tokenA: Token, tokenB: Token) => number {
const balances = useAllTokenBalances()
const comparator = useMemo(() => getTokenComparator(balances ?? {}), [balances])
return useMemo(() => {
if (inverted) {
return (tokenA: Token, tokenB: Token) => comparator(tokenA, tokenB) * -1
} else {
return comparator
}
}, [inverted, comparator])
}

View File

@@ -1,12 +1,12 @@
// eslint-disable-next-line no-restricted-imports
import { t, Trans } from '@lingui/macro'
import { Percent } from '@uniswap/sdk-core'
import { useActiveWeb3React } from 'hooks/web3'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { AUTO_ROUTER_SUPPORTED_CHAINS } from 'lib/hooks/routing/clientSideSmartOrderRouter'
import { useContext, useRef, useState } from 'react'
import { Settings, X } from 'react-feather'
import ReactGA from 'react-ga'
import { Text } from 'rebass'
import { AUTO_ROUTER_SUPPORTED_CHAINS } from 'state/routing/clientSideSmartOrderRouter/constants'
import styled, { ThemeContext } from 'styled-components/macro'
import { useOnClickOutside } from '../../hooks/useOnClickOutside'

View File

@@ -1,7 +1,9 @@
import { Trans } from '@lingui/macro'
import { Currency } from '@uniswap/sdk-core'
import Badge from 'components/Badge'
import { CHAIN_INFO, L2_CHAIN_IDS, SupportedL2ChainId } from 'constants/chains'
import { CHAIN_INFO } from 'constants/chainInfo'
import { L2_CHAIN_IDS, SupportedL2ChainId } from 'constants/chains'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import useAddTokenToMetamask from 'hooks/useAddTokenToMetamask'
import { ReactNode, useContext } from 'react'
import { AlertCircle, AlertTriangle, ArrowUpCircle, CheckCircle } from 'react-feather'
@@ -11,7 +13,6 @@ import styled, { ThemeContext } from 'styled-components/macro'
import Circle from '../../assets/images/blue-loader.svg'
import MetaMaskLogo from '../../assets/images/metamask.png'
import { useActiveWeb3React } from '../../hooks/web3'
import { ExternalLink } from '../../theme'
import { CloseIcon, CustomLightSpinner } from '../../theme'
import { ExplorerDataType, getExplorerLink } from '../../utils/getExplorerLink'

View File

@@ -2,7 +2,7 @@ import { Trans } from '@lingui/macro'
import { Percent } from '@uniswap/sdk-core'
import { L2_CHAIN_IDS } from 'constants/chains'
import { DEFAULT_DEADLINE_FROM_NOW } from 'constants/misc'
import { useActiveWeb3React } from 'hooks/web3'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import ms from 'ms.macro'
import { darken } from 'polished'
import { useContext, useState } from 'react'

View File

@@ -320,7 +320,7 @@ export default function WalletModal({
<ContentWrapper>
{error instanceof UnsupportedChainIdError ? (
<h5>
<Trans>Please connect to the appropriate Ethereum network.</Trans>
<Trans>Please connect to a supported network in the dropdown menu or in your wallet.</Trans>
</h5>
) : (
<Trans>Error connecting. Try refreshing the page.</Trans>

View File

@@ -2,6 +2,7 @@
import { t, Trans } from '@lingui/macro'
import { AbstractConnector } from '@web3-react/abstract-connector'
import { UnsupportedChainIdError, useWeb3React } from '@web3-react/core'
import { Connector } from '@widgets/web3-react/types'
import { darken } from 'polished'
import { useMemo } from 'react'
import { Activity } from 'react-feather'
@@ -35,9 +36,12 @@ const Web3StatusGeneric = styled(ButtonSecondary)`
width: 100%;
align-items: center;
padding: 0.5rem;
border-radius: 12px;
border-radius: 14px;
cursor: pointer;
user-select: none;
height: 36px;
margin-right: 2px;
margin-left: 1px;
:focus {
outline: none;
}
@@ -82,7 +86,7 @@ const Web3StatusConnect = styled(Web3StatusGeneric)<{ faded?: boolean }>`
`
const Web3StatusConnected = styled(Web3StatusGeneric)<{ pending?: boolean }>`
background-color: ${({ pending, theme }) => (pending ? theme.primary1 : theme.bg0)};
background-color: ${({ pending, theme }) => (pending ? theme.primary1 : theme.bg1)};
border: 1px solid ${({ pending, theme }) => (pending ? theme.primary1 : theme.bg1)};
color: ${({ pending, theme }) => (pending ? theme.white : theme.text1)};
font-weight: 500;
@@ -127,7 +131,7 @@ function Sock() {
)
}
function WrappedStatusIcon({ connector }: { connector: AbstractConnector }) {
function WrappedStatusIcon({ connector }: { connector: AbstractConnector | Connector }) {
return (
<IconWrapper size={16}>
<StatusIcon connector={connector} />

View File

@@ -1,4 +1,4 @@
import { useActiveWeb3React } from 'hooks/web3'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { useEffect } from 'react'
import ReactGA from 'react-ga'
import { RouteComponentProps } from 'react-router-dom'

View File

@@ -1,6 +1,7 @@
import { isAddress } from '@ethersproject/address'
import { Trans } from '@lingui/macro'
import { CurrencyAmount, Token } from '@uniswap/sdk-core'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { useState } from 'react'
import { Text } from 'rebass'
import styled from 'styled-components/macro'
@@ -8,7 +9,6 @@ import styled from 'styled-components/macro'
import Circle from '../../assets/images/blue-loader.svg'
import tokenLogo from '../../assets/images/token-logo.png'
import useENS from '../../hooks/useENS'
import { useActiveWeb3React } from '../../hooks/web3'
import { useClaimCallback, useUserHasAvailableClaim, useUserUnclaimedAmount } from '../../state/claim/hooks'
import { useIsTransactionPending } from '../../state/transactions/hooks'
import { CloseIcon, CustomLightSpinner, ExternalLink, ThemedText, UniTokenAnimated } from '../../theme'

View File

@@ -1,6 +1,7 @@
import { isAddress } from '@ethersproject/address'
import { Trans } from '@lingui/macro'
import { CurrencyAmount, Token } from '@uniswap/sdk-core'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import JSBI from 'jsbi'
import { useEffect, useState } from 'react'
import { Text } from 'rebass'
@@ -8,7 +9,6 @@ import styled from 'styled-components/macro'
import Circle from '../../assets/images/blue-loader.svg'
import tokenLogo from '../../assets/images/token-logo.png'
import { useActiveWeb3React } from '../../hooks/web3'
import { useModalOpen, useToggleSelfClaimModal } from '../../state/application/hooks'
import { ApplicationModal } from '../../state/application/reducer'
import { useClaimCallback, useUserClaimData, useUserUnclaimedAmount } from '../../state/claim/hooks'

View File

@@ -1,10 +1,10 @@
import { TransactionResponse } from '@ethersproject/providers'
import { Trans } from '@lingui/macro'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { ReactNode, useState } from 'react'
import styled from 'styled-components/macro'
import { useStakingContract } from '../../hooks/useContract'
import { useActiveWeb3React } from '../../hooks/web3'
import { StakingInfo } from '../../state/stake/hooks'
import { TransactionType } from '../../state/transactions/actions'
import { useTransactionAdder } from '../../state/transactions/hooks'

View File

@@ -2,14 +2,14 @@ import { TransactionResponse } from '@ethersproject/providers'
import { Trans } from '@lingui/macro'
import { CurrencyAmount, Token } from '@uniswap/sdk-core'
import { Pair } from '@uniswap/v2-sdk'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { useV2LiquidityTokenPermit } from 'hooks/useV2LiquidityTokenPermit'
import { useCallback, useState } from 'react'
import styled from 'styled-components/macro'
import { ApprovalState, useApproveCallback } from '../../hooks/useApproveCallback'
import { usePairContract, useStakingContract, useV2RouterContract } from '../../hooks/useContract'
import { useV2LiquidityTokenPermit } from '../../hooks/useERC20Permit'
import useTransactionDeadline from '../../hooks/useTransactionDeadline'
import { useActiveWeb3React } from '../../hooks/web3'
import { StakingInfo, useDerivedStakeInfo } from '../../state/stake/hooks'
import { TransactionType } from '../../state/transactions/actions'
import { useTransactionAdder } from '../../state/transactions/hooks'

View File

@@ -1,10 +1,10 @@
import { TransactionResponse } from '@ethersproject/providers'
import { Trans } from '@lingui/macro'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { ReactNode, useState } from 'react'
import styled from 'styled-components/macro'
import { useStakingContract } from '../../hooks/useContract'
import { useActiveWeb3React } from '../../hooks/web3'
import { StakingInfo } from '../../state/stake/hooks'
import { TransactionType } from '../../state/transactions/actions'
import { useTransactionAdder } from '../../state/transactions/hooks'

View File

@@ -2,7 +2,8 @@ import { Trans } from '@lingui/macro'
import { Currency, Percent, TradeType } from '@uniswap/sdk-core'
import Card from 'components/Card'
import { LoadingRows } from 'components/Loader/styled'
import { useActiveWeb3React } from 'hooks/web3'
import { SUPPORTED_GAS_ESTIMATE_CHAIN_IDS } from 'constants/chains'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { useContext, useMemo } from 'react'
import { InterfaceTrade } from 'state/routing/types'
import styled, { ThemeContext } from 'styled-components/macro'
@@ -12,7 +13,6 @@ import { computeRealizedLPFeePercent } from '../../utils/prices'
import { AutoColumn } from '../Column'
import { RowBetween, RowFixed } from '../Row'
import FormattedPriceImpact from './FormattedPriceImpact'
import { SUPPORTED_GAS_ESTIMATE_CHAIN_IDS } from './GasEstimateBadge'
const StyledCard = styled(Card)`
padding: 0;

View File

@@ -3,6 +3,7 @@ import { Trade } from '@uniswap/router-sdk'
import { Currency, Percent, TradeType } from '@uniswap/sdk-core'
import { ReactNode, useCallback, useMemo } from 'react'
import { InterfaceTrade } from 'state/routing/types'
import { tradeMeaningfullyDiffers } from 'utils/tradeMeaningFullyDiffer'
import TransactionConfirmationModal, {
ConfirmationModalContent,
@@ -11,23 +12,6 @@ import TransactionConfirmationModal, {
import SwapModalFooter from './SwapModalFooter'
import SwapModalHeader from './SwapModalHeader'
/**
* Returns true if the trade requires a confirmation of details before we can submit it
* @param args either a pair of V2 trades or a pair of V3 trades
*/
function tradeMeaningfullyDiffers(
...args: [Trade<Currency, Currency, TradeType>, Trade<Currency, Currency, TradeType>]
): boolean {
const [tradeA, tradeB] = args
return (
tradeA.tradeType !== tradeB.tradeType ||
!tradeA.inputAmount.currency.equals(tradeB.inputAmount.currency) ||
!tradeA.inputAmount.equalTo(tradeB.inputAmount) ||
!tradeA.outputAmount.currency.equals(tradeB.outputAmount.currency) ||
!tradeA.outputAmount.equalTo(tradeB.outputAmount)
)
}
export default function ConfirmSwapModal({
trade,
originalTrade,

View File

@@ -1,6 +1,5 @@
import { Trans } from '@lingui/macro'
import { Currency, TradeType } from '@uniswap/sdk-core'
import { ChainId } from '@uniswap/smart-order-router'
import { AutoColumn } from 'components/Column'
import { LoadingOpacityContainer } from 'components/Loader/styled'
import { RowFixed } from 'components/Row'
@@ -32,8 +31,6 @@ const StyledGasIcon = styled(GasIcon)`
}
`
export const SUPPORTED_GAS_ESTIMATE_CHAIN_IDS = [ChainId.MAINNET]
export default function GasEstimateBadge({
trade,
loading,

View File

@@ -6,7 +6,8 @@ import { AutoColumn } from 'components/Column'
import { LoadingOpacityContainer } from 'components/Loader/styled'
import Row, { RowBetween, RowFixed } from 'components/Row'
import { MouseoverTooltipContent } from 'components/Tooltip'
import { useActiveWeb3React } from 'hooks/web3'
import { SUPPORTED_GAS_ESTIMATE_CHAIN_IDS } from 'constants/chains'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { darken } from 'polished'
import { useState } from 'react'
import { ChevronDown, Info } from 'react-feather'
@@ -15,7 +16,7 @@ import styled, { keyframes, useTheme } from 'styled-components/macro'
import { HideSmall, ThemedText } from 'theme'
import { AdvancedSwapDetails } from './AdvancedSwapDetails'
import GasEstimateBadge, { SUPPORTED_GAS_ESTIMATE_CHAIN_IDS } from './GasEstimateBadge'
import GasEstimateBadge from './GasEstimateBadge'
import { ResponsiveTooltipContainer } from './styleds'
import SwapRoute from './SwapRoute'
import TradePrice from './TradePrice'

View File

@@ -7,8 +7,9 @@ import { AutoColumn } from 'components/Column'
import { LoadingRows } from 'components/Loader/styled'
import RoutingDiagram, { RoutingDiagramEntry } from 'components/RoutingDiagram/RoutingDiagram'
import { AutoRow, RowBetween } from 'components/Row'
import { SUPPORTED_GAS_ESTIMATE_CHAIN_IDS } from 'constants/chains'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import useAutoRouterSupported from 'hooks/useAutoRouterSupported'
import { useActiveWeb3React } from 'hooks/web3'
import { memo, useState } from 'react'
import { Plus } from 'react-feather'
import { InterfaceTrade } from 'state/routing/types'
@@ -16,7 +17,6 @@ import { useDarkModeManager } from 'state/user/hooks'
import styled from 'styled-components/macro'
import { Separator, ThemedText } from 'theme'
import { SUPPORTED_GAS_ESTIMATE_CHAIN_IDS } from './GasEstimateBadge'
import { AutoRouterLabel, AutoRouterLogo } from './RouterLabel'
const Wrapper = styled(AutoColumn)<{ darkMode?: boolean; fixedOpen?: boolean }>`

View File

@@ -16,7 +16,7 @@ const StyledPriceContainer = styled.button`
background-color: transparent;
border: none;
cursor: pointer;
align-items: center
align-items: center;
justify-content: flex-start;
padding: 0;
grid-template-columns: 1fr auto;

View File

@@ -6,7 +6,7 @@ import { AutoColumn } from 'components/Column'
import CurrencyLogo from 'components/CurrencyLogo'
import Modal from 'components/Modal'
import { AutoRow, RowBetween } from 'components/Row'
import { useActiveWeb3React } from 'hooks/web3'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { useState } from 'react'
import styled from 'styled-components/macro'
import { CloseIcon, ExternalLink, ThemedText, Z_INDEX } from 'theme'

View File

@@ -1,5 +1,6 @@
import { isAddress } from '@ethersproject/address'
import { Trans } from '@lingui/macro'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { ReactNode, useState } from 'react'
import { X } from 'react-feather'
import styled from 'styled-components/macro'
@@ -7,7 +8,6 @@ import { formatCurrencyAmount } from 'utils/formatCurrencyAmount'
import { UNI } from '../../constants/tokens'
import useENS from '../../hooks/useENS'
import { useActiveWeb3React } from '../../hooks/web3'
import { useDelegateCallback } from '../../state/governance/hooks'
import { useTokenBalance } from '../../state/wallet/hooks'
import { ThemedText } from '../../theme'

View File

@@ -1,6 +1,6 @@
import { Trans } from '@lingui/macro'
import { L2_CHAIN_IDS } from 'constants/chains'
import { useActiveWeb3React } from 'hooks/web3'
import { SupportedChainId } from 'constants/chains'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import styled from 'styled-components/macro'
import { ThemedText } from 'theme'
@@ -38,7 +38,7 @@ const EmptyState = ({ HeaderContent, SubHeaderContent }: EmptyStateProps) => (
export default function ProposalEmptyState() {
const { chainId } = useActiveWeb3React()
if (chainId && L2_CHAIN_IDS.includes(chainId)) {
if (chainId && chainId !== SupportedChainId.MAINNET) {
return (
<EmptyState
HeaderContent={() => <Trans>Please connect to Layer 1 Ethereum</Trans>}

View File

@@ -1,11 +1,11 @@
import { Trans } from '@lingui/macro'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { useContext, useState } from 'react'
import { ArrowUpCircle, X } from 'react-feather'
import styled, { ThemeContext } from 'styled-components/macro'
import { formatCurrencyAmount } from 'utils/formatCurrencyAmount'
import Circle from '../../assets/images/blue-loader.svg'
import { useActiveWeb3React } from '../../hooks/web3'
import { useUserVotes, useVoteCallback } from '../../state/governance/hooks'
import { VoteOption } from '../../state/governance/types'
import { CustomLightSpinner, ThemedText } from '../../theme'

View File

@@ -4,9 +4,10 @@ import { InjectedConnector } from '@web3-react/injected-connector'
import { PortisConnector } from '@web3-react/portis-connector'
import { WalletConnectConnector } from '@web3-react/walletconnect-connector'
import { WalletLinkConnector } from '@web3-react/walletlink-connector'
import { ALL_SUPPORTED_CHAIN_IDS, SupportedChainId } from 'constants/chains'
import { INFURA_NETWORK_URLS } from 'constants/infura'
import UNISWAP_LOGO_URL from '../assets/svg/logo.svg'
import { ALL_SUPPORTED_CHAIN_IDS, INFURA_NETWORK_URLS, SupportedChainId } from '../constants/chains'
import getLibrary from '../utils/getLibrary'
import { FortmaticConnector } from './Fortmatic'
import { NetworkConnector } from './NetworkConnector'
@@ -48,10 +49,9 @@ export const portis = new PortisConnector({
networks: [1],
})
// mainnet only
export const walletlink = new WalletLinkConnector({
url: INFURA_NETWORK_URLS[SupportedChainId.MAINNET],
appName: 'Uniswap',
appLogoUrl: UNISWAP_LOGO_URL,
supportedChainIds: [SupportedChainId.MAINNET],
supportedChainIds: ALL_SUPPORTED_CHAIN_IDS,
})

View File

@@ -107,3 +107,8 @@ export const V3_MIGRATOR_ADDRESSES: AddressMap = constructSameAddressMap('0xA564
SupportedChainId.POLYGON_MUMBAI,
SupportedChainId.POLYGON,
])
export const TICK_LENS_ADDRESSES: AddressMap = {
[SupportedChainId.ARBITRUM_ONE]: '0xbfd8137f7d1516D3ea5cA83523914859ec47F573',
[SupportedChainId.ARBITRUM_RINKEBY]: '0xbfd8137f7d1516D3ea5cA83523914859ec47F573',
}

170
src/constants/chainInfo.ts Normal file
View File

@@ -0,0 +1,170 @@
import ms from 'ms.macro'
import ethereumLogoUrl from '../assets/images/ethereum-logo.png'
import arbitrumLogoUrl from '../assets/svg/arbitrum_logo.svg'
import optimismLogoUrl from '../assets/svg/optimistic_ethereum.svg'
import polygonMaticLogo from '../assets/svg/polygon-matic-logo.svg'
import { SupportedChainId, SupportedL1ChainId, SupportedL2ChainId } from './chains'
import { ARBITRUM_LIST, OPTIMISM_LIST } from './lists'
export enum NetworkType {
L1,
L2,
}
interface BaseChainInfo {
readonly networkType: NetworkType
readonly blockWaitMsBeforeWarning?: number
readonly docs: string
readonly bridge?: string
readonly explorer: string
readonly infoLink: string
readonly logoUrl: string
readonly label: string
readonly helpCenterUrl?: string
readonly nativeCurrency: {
name: string // e.g. 'Goerli ETH',
symbol: string // e.g. 'gorETH',
decimals: number // e.g. 18,
}
}
export interface L1ChainInfo extends BaseChainInfo {
readonly networkType: NetworkType.L1
}
export interface L2ChainInfo extends BaseChainInfo {
readonly networkType: NetworkType.L2
readonly bridge: string
readonly statusPage?: string
readonly defaultListUrl: string
}
export type ChainInfoMap = { readonly [chainId: number]: L1ChainInfo | L2ChainInfo } & {
readonly [chainId in SupportedL2ChainId]: L2ChainInfo
} &
{ readonly [chainId in SupportedL1ChainId]: L1ChainInfo }
export const CHAIN_INFO: ChainInfoMap = {
[SupportedChainId.MAINNET]: {
networkType: NetworkType.L1,
docs: 'https://docs.uniswap.org/',
explorer: 'https://etherscan.io/',
infoLink: 'https://info.uniswap.org/#/',
label: 'Ethereum',
logoUrl: ethereumLogoUrl,
nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
},
[SupportedChainId.RINKEBY]: {
networkType: NetworkType.L1,
docs: 'https://docs.uniswap.org/',
explorer: 'https://rinkeby.etherscan.io/',
infoLink: 'https://info.uniswap.org/#/',
label: 'Rinkeby',
logoUrl: ethereumLogoUrl,
nativeCurrency: { name: 'Rinkeby Ether', symbol: 'rETH', decimals: 18 },
},
[SupportedChainId.ROPSTEN]: {
networkType: NetworkType.L1,
docs: 'https://docs.uniswap.org/',
explorer: 'https://ropsten.etherscan.io/',
infoLink: 'https://info.uniswap.org/#/',
label: 'Ropsten',
logoUrl: ethereumLogoUrl,
nativeCurrency: { name: 'Ropsten Ether', symbol: 'ropETH', decimals: 18 },
},
[SupportedChainId.KOVAN]: {
networkType: NetworkType.L1,
docs: 'https://docs.uniswap.org/',
explorer: 'https://kovan.etherscan.io/',
infoLink: 'https://info.uniswap.org/#/',
label: 'Kovan',
logoUrl: ethereumLogoUrl,
nativeCurrency: { name: 'Kovan Ether', symbol: 'kovETH', decimals: 18 },
},
[SupportedChainId.GOERLI]: {
networkType: NetworkType.L1,
docs: 'https://docs.uniswap.org/',
explorer: 'https://goerli.etherscan.io/',
infoLink: 'https://info.uniswap.org/#/',
label: 'Görli',
logoUrl: ethereumLogoUrl,
nativeCurrency: { name: 'Görli Ether', symbol: 'görETH', decimals: 18 },
},
[SupportedChainId.OPTIMISM]: {
networkType: NetworkType.L2,
blockWaitMsBeforeWarning: ms`25m`,
bridge: 'https://gateway.optimism.io/?chainId=1',
defaultListUrl: OPTIMISM_LIST,
docs: 'https://optimism.io/',
explorer: 'https://optimistic.etherscan.io/',
infoLink: 'https://info.uniswap.org/#/optimism/',
label: 'Optimism',
logoUrl: optimismLogoUrl,
statusPage: 'https://optimism.io/status',
helpCenterUrl: 'https://help.uniswap.org/en/collections/3137778-uniswap-on-optimistic-ethereum-oξ',
nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
},
[SupportedChainId.OPTIMISTIC_KOVAN]: {
networkType: NetworkType.L2,
blockWaitMsBeforeWarning: ms`25m`,
bridge: 'https://gateway.optimism.io/',
defaultListUrl: OPTIMISM_LIST,
docs: 'https://optimism.io/',
explorer: 'https://optimistic.etherscan.io/',
infoLink: 'https://info.uniswap.org/#/optimism/',
label: 'Optimistic Kovan',
logoUrl: optimismLogoUrl,
statusPage: 'https://optimism.io/status',
helpCenterUrl: 'https://help.uniswap.org/en/collections/3137778-uniswap-on-optimistic-ethereum-oξ',
nativeCurrency: { name: 'Optimistic Kovan Ether', symbol: 'kovOpETH', decimals: 18 },
},
[SupportedChainId.ARBITRUM_ONE]: {
networkType: NetworkType.L2,
blockWaitMsBeforeWarning: ms`10m`,
bridge: 'https://bridge.arbitrum.io/',
docs: 'https://offchainlabs.com/',
explorer: 'https://arbiscan.io/',
infoLink: 'https://info.uniswap.org/#/arbitrum',
label: 'Arbitrum',
logoUrl: arbitrumLogoUrl,
defaultListUrl: ARBITRUM_LIST,
helpCenterUrl: 'https://help.uniswap.org/en/collections/3137787-uniswap-on-arbitrum',
nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
},
[SupportedChainId.ARBITRUM_RINKEBY]: {
networkType: NetworkType.L2,
blockWaitMsBeforeWarning: ms`10m`,
bridge: 'https://bridge.arbitrum.io/',
docs: 'https://offchainlabs.com/',
explorer: 'https://rinkeby-explorer.arbitrum.io/',
infoLink: 'https://info.uniswap.org/#/arbitrum/',
label: 'Arbitrum Rinkeby',
logoUrl: arbitrumLogoUrl,
defaultListUrl: ARBITRUM_LIST,
helpCenterUrl: 'https://help.uniswap.org/en/collections/3137787-uniswap-on-arbitrum',
nativeCurrency: { name: 'Rinkeby Arbitrum Ether', symbol: 'rinkArbETH', decimals: 18 },
},
[SupportedChainId.POLYGON]: {
networkType: NetworkType.L1,
blockWaitMsBeforeWarning: ms`10m`,
bridge: 'https://wallet.polygon.technology/bridge',
docs: 'https://polygon.io/',
explorer: 'https://polygonscan.com/',
infoLink: 'https://info.uniswap.org/#/polygon/',
label: 'Polygon',
logoUrl: polygonMaticLogo,
nativeCurrency: { name: 'Polygon Matic', symbol: 'MATIC', decimals: 18 },
},
[SupportedChainId.POLYGON_MUMBAI]: {
networkType: NetworkType.L1,
blockWaitMsBeforeWarning: ms`10m`,
bridge: 'https://wallet.polygon.technology/bridge',
docs: 'https://polygon.io/',
explorer: 'https://mumbai.polygonscan.com/',
infoLink: 'https://info.uniswap.org/#/polygon/',
label: 'Polygon Mumbai',
logoUrl: polygonMaticLogo,
nativeCurrency: { name: 'Polygon Mumbai Matic', symbol: 'mMATIC', decimals: 18 },
},
}

View File

@@ -1,11 +1,3 @@
import ethereumLogoUrl from 'assets/images/ethereum-logo.png'
import arbitrumLogoUrl from 'assets/svg/arbitrum_logo.svg'
import optimismLogoUrl from 'assets/svg/optimistic_ethereum.svg'
import polygonMaticLogo from 'assets/svg/polygon-matic-logo.svg'
import ms from 'ms.macro'
import { ARBITRUM_LIST, OPTIMISM_LIST } from './lists'
/**
* List of all the networks supported by the Uniswap Interface
*/
@@ -26,9 +18,18 @@ export enum SupportedChainId {
POLYGON_MUMBAI = 80001,
}
const INFURA_KEY = process.env.REACT_APP_INFURA_KEY
if (typeof INFURA_KEY === 'undefined') {
throw new Error(`REACT_APP_INFURA_KEY must be a defined environment variable`)
export const CHAIN_IDS_TO_NAMES = {
[SupportedChainId.MAINNET]: 'mainnet',
[SupportedChainId.ROPSTEN]: 'ropsten',
[SupportedChainId.RINKEBY]: 'rinkeby',
[SupportedChainId.GOERLI]: 'goerli',
[SupportedChainId.KOVAN]: 'kovan',
[SupportedChainId.POLYGON]: 'polygon',
[SupportedChainId.POLYGON_MUMBAI]: 'polygon_mumbai',
[SupportedChainId.ARBITRUM_ONE]: 'arbitrum',
[SupportedChainId.ARBITRUM_RINKEBY]: 'arbitrum_rinkeby',
[SupportedChainId.OPTIMISM]: 'optimism',
[SupportedChainId.OPTIMISTIC_KOVAN]: 'optimistic_kovan',
}
/**
@@ -38,6 +39,8 @@ export const ALL_SUPPORTED_CHAIN_IDS: SupportedChainId[] = Object.values(Support
(id) => typeof id === 'number'
) as SupportedChainId[]
export const SUPPORTED_GAS_ESTIMATE_CHAIN_IDS = [SupportedChainId.MAINNET, SupportedChainId.POLYGON]
/**
* All the chain IDs that are running the Ethereum protocol.
*/
@@ -65,223 +68,3 @@ export const L2_CHAIN_IDS = [
] as const
export type SupportedL2ChainId = typeof L2_CHAIN_IDS[number]
/**
* These are the network URLs used by the interface when there is not another available source of chain data
*/
export const INFURA_NETWORK_URLS: { [key in SupportedChainId]: string } = {
[SupportedChainId.MAINNET]: `https://mainnet.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.RINKEBY]: `https://rinkeby.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.ROPSTEN]: `https://ropsten.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.GOERLI]: `https://goerli.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.KOVAN]: `https://kovan.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.OPTIMISM]: `https://optimism-mainnet.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.OPTIMISTIC_KOVAN]: `https://optimism-kovan.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.ARBITRUM_ONE]: `https://arbitrum-mainnet.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.ARBITRUM_RINKEBY]: `https://arbitrum-rinkeby.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.POLYGON]: `https://polygon-mainnet.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.POLYGON_MUMBAI]: `https://polygon-mumbai.infura.io/v3/${INFURA_KEY}`,
}
/**
* This is used to call the add network RPC
*/
interface AddNetworkInfo {
readonly rpcUrl: string
readonly nativeCurrency: {
name: string // e.g. 'Goerli ETH',
symbol: string // e.g. 'gorETH',
decimals: number // e.g. 18,
}
}
export enum NetworkType {
L1,
L2,
}
interface BaseChainInfo {
readonly networkType: NetworkType
readonly blockWaitMsBeforeWarning?: number
readonly docs: string
readonly bridge?: string
readonly explorer: string
readonly infoLink: string
readonly logoUrl: string
readonly label: string
readonly helpCenterUrl?: string
readonly addNetworkInfo: AddNetworkInfo
}
export interface L1ChainInfo extends BaseChainInfo {
readonly networkType: NetworkType.L1
}
export interface L2ChainInfo extends BaseChainInfo {
readonly networkType: NetworkType.L2
readonly bridge: string
readonly statusPage?: string
readonly defaultListUrl: string
}
export type ChainInfoMap = { readonly [chainId: number]: L1ChainInfo | L2ChainInfo } & {
readonly [chainId in SupportedL2ChainId]: L2ChainInfo
} &
{ readonly [chainId in SupportedL1ChainId]: L1ChainInfo }
export const CHAIN_INFO: ChainInfoMap = {
[SupportedChainId.MAINNET]: {
networkType: NetworkType.L1,
docs: 'https://docs.uniswap.org/',
explorer: 'https://etherscan.io/',
infoLink: 'https://info.uniswap.org/#/',
label: 'Ethereum',
logoUrl: ethereumLogoUrl,
addNetworkInfo: {
nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
rpcUrl: INFURA_NETWORK_URLS[SupportedChainId.MAINNET],
},
},
[SupportedChainId.RINKEBY]: {
networkType: NetworkType.L1,
docs: 'https://docs.uniswap.org/',
explorer: 'https://rinkeby.etherscan.io/',
infoLink: 'https://info.uniswap.org/#/',
label: 'Rinkeby',
logoUrl: ethereumLogoUrl,
addNetworkInfo: {
nativeCurrency: { name: 'Rinkeby Ether', symbol: 'rETH', decimals: 18 },
rpcUrl: INFURA_NETWORK_URLS[SupportedChainId.RINKEBY],
},
},
[SupportedChainId.ROPSTEN]: {
networkType: NetworkType.L1,
docs: 'https://docs.uniswap.org/',
explorer: 'https://ropsten.etherscan.io/',
infoLink: 'https://info.uniswap.org/#/',
label: 'Ropsten',
logoUrl: ethereumLogoUrl,
addNetworkInfo: {
nativeCurrency: { name: 'Ropsten Ether', symbol: 'ropETH', decimals: 18 },
rpcUrl: INFURA_NETWORK_URLS[SupportedChainId.ROPSTEN],
},
},
[SupportedChainId.KOVAN]: {
networkType: NetworkType.L1,
docs: 'https://docs.uniswap.org/',
explorer: 'https://kovan.etherscan.io/',
infoLink: 'https://info.uniswap.org/#/',
label: 'Kovan',
logoUrl: ethereumLogoUrl,
addNetworkInfo: {
nativeCurrency: { name: 'Kovan Ether', symbol: 'kovETH', decimals: 18 },
rpcUrl: INFURA_NETWORK_URLS[SupportedChainId.KOVAN],
},
},
[SupportedChainId.GOERLI]: {
networkType: NetworkType.L1,
docs: 'https://docs.uniswap.org/',
explorer: 'https://goerli.etherscan.io/',
infoLink: 'https://info.uniswap.org/#/',
label: 'Görli',
logoUrl: ethereumLogoUrl,
addNetworkInfo: {
nativeCurrency: { name: 'Görli Ether', symbol: 'görETH', decimals: 18 },
rpcUrl: INFURA_NETWORK_URLS[SupportedChainId.GOERLI],
},
},
[SupportedChainId.OPTIMISM]: {
networkType: NetworkType.L2,
blockWaitMsBeforeWarning: ms`25m`,
bridge: 'https://gateway.optimism.io/?chainId=1',
defaultListUrl: OPTIMISM_LIST,
docs: 'https://optimism.io/',
explorer: 'https://optimistic.etherscan.io/',
infoLink: 'https://info.uniswap.org/#/optimism/',
label: 'Optimism',
logoUrl: optimismLogoUrl,
statusPage: 'https://optimism.io/status',
helpCenterUrl: 'https://help.uniswap.org/en/collections/3137778-uniswap-on-optimistic-ethereum-oξ',
addNetworkInfo: {
nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
rpcUrl: 'https://mainnet.optimism.io',
},
},
[SupportedChainId.OPTIMISTIC_KOVAN]: {
networkType: NetworkType.L2,
blockWaitMsBeforeWarning: ms`25m`,
bridge: 'https://gateway.optimism.io/',
defaultListUrl: OPTIMISM_LIST,
docs: 'https://optimism.io/',
explorer: 'https://optimistic.etherscan.io/',
infoLink: 'https://info.uniswap.org/#/optimism/',
label: 'Optimistic Kovan',
logoUrl: optimismLogoUrl,
statusPage: 'https://optimism.io/status',
helpCenterUrl: 'https://help.uniswap.org/en/collections/3137778-uniswap-on-optimistic-ethereum-oξ',
addNetworkInfo: {
nativeCurrency: { name: 'Optimistic Kovan Ether', symbol: 'kovOpETH', decimals: 18 },
rpcUrl: 'https://kovan.optimism.io',
},
},
[SupportedChainId.ARBITRUM_ONE]: {
networkType: NetworkType.L2,
blockWaitMsBeforeWarning: ms`10m`,
bridge: 'https://bridge.arbitrum.io/',
docs: 'https://offchainlabs.com/',
explorer: 'https://arbiscan.io/',
infoLink: 'https://info.uniswap.org/#/arbitrum',
label: 'Arbitrum',
logoUrl: arbitrumLogoUrl,
defaultListUrl: ARBITRUM_LIST,
helpCenterUrl: 'https://help.uniswap.org/en/collections/3137787-uniswap-on-arbitrum',
addNetworkInfo: {
nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
rpcUrl: 'https://arb1.arbitrum.io/rpc',
},
},
[SupportedChainId.ARBITRUM_RINKEBY]: {
networkType: NetworkType.L2,
blockWaitMsBeforeWarning: ms`10m`,
bridge: 'https://bridge.arbitrum.io/',
docs: 'https://offchainlabs.com/',
explorer: 'https://rinkeby-explorer.arbitrum.io/',
infoLink: 'https://info.uniswap.org/#/arbitrum/',
label: 'Arbitrum Rinkeby',
logoUrl: arbitrumLogoUrl,
defaultListUrl: ARBITRUM_LIST,
helpCenterUrl: 'https://help.uniswap.org/en/collections/3137787-uniswap-on-arbitrum',
addNetworkInfo: {
nativeCurrency: { name: 'Rinkeby Arbitrum Ether', symbol: 'rinkArbETH', decimals: 18 },
rpcUrl: 'https://rinkeby.arbitrum.io/rpc',
},
},
[SupportedChainId.POLYGON]: {
networkType: NetworkType.L1,
blockWaitMsBeforeWarning: ms`10m`,
bridge: 'https://wallet.polygon.technology/bridge',
docs: 'https://polygon.io/',
explorer: 'https://polygonscan.com/',
infoLink: 'https://info.uniswap.org/#/polygon/',
label: 'Polygon',
logoUrl: polygonMaticLogo,
addNetworkInfo: {
rpcUrl: 'https://polygon-rpc.com/',
nativeCurrency: { name: 'Polygon Matic', symbol: 'MATIC', decimals: 18 },
},
},
[SupportedChainId.POLYGON_MUMBAI]: {
networkType: NetworkType.L1,
blockWaitMsBeforeWarning: ms`10m`,
bridge: 'https://wallet.polygon.technology/bridge',
docs: 'https://polygon.io/',
explorer: 'https://mumbai.polygonscan.com/',
infoLink: 'https://info.uniswap.org/#/polygon/',
label: 'Polygon Mumbai',
logoUrl: polygonMaticLogo,
addNetworkInfo: {
nativeCurrency: { name: 'Polygon Mumbai Matic', symbol: 'mMATIC', decimals: 18 },
rpcUrl: 'https://rpc-endpoints.superfluid.dev/mumbai',
},
},
}

23
src/constants/infura.ts Normal file
View File

@@ -0,0 +1,23 @@
import { SupportedChainId } from './chains'
const INFURA_KEY = process.env.REACT_APP_INFURA_KEY
if (typeof INFURA_KEY === 'undefined') {
throw new Error(`REACT_APP_INFURA_KEY must be a defined environment variable`)
}
/**
* These are the network URLs used by the interface when there is not another available source of chain data
*/
export const INFURA_NETWORK_URLS: { [key in SupportedChainId]: string } = {
[SupportedChainId.MAINNET]: `https://mainnet.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.RINKEBY]: `https://rinkeby.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.ROPSTEN]: `https://ropsten.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.GOERLI]: `https://goerli.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.KOVAN]: `https://kovan.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.OPTIMISM]: `https://optimism-mainnet.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.OPTIMISTIC_KOVAN]: `https://optimism-kovan.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.ARBITRUM_ONE]: `https://arbitrum-mainnet.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.ARBITRUM_RINKEBY]: `https://arbitrum-rinkeby.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.POLYGON]: `https://polygon-mainnet.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.POLYGON_MUMBAI]: `https://polygon-mumbai.infura.io/v3/${INFURA_KEY}`,
}

View File

@@ -33,11 +33,12 @@ export const SUPPORTED_LOCALES = [
'zh-CN',
'zh-TW',
] as const
export type SupportedLocale = typeof SUPPORTED_LOCALES[number]
export type SupportedLocale = typeof SUPPORTED_LOCALES[number] | 'pseudo'
// eslint-disable-next-line import/first
import * as enUS from '../locales/en-US'
export const DEFAULT_LOCALE: SupportedLocale = 'en-US'
export { messages as DEFAULT_MESSAGES } from '../locales/en-US'
export const DEFAULT_CATALOG = enUS
export const LOCALE_LABEL: { [locale in SupportedLocale]: string } = {
'af-ZA': 'Afrikaans',
@@ -72,4 +73,5 @@ export const LOCALE_LABEL: { [locale in SupportedLocale]: string } = {
'vi-VN': 'Tiếng Việt',
'zh-CN': '简体中文',
'zh-TW': '繁体中文',
pseudo: 'ƥƨèúδô',
}

View File

@@ -1094,6 +1094,13 @@
"name": "ENS DAO",
"symbol": "ENS",
"decimals": 18
},
{
"chainId": 1,
"address": "0xa82AA729AE2F0d78e961D66db53949e27a9E866d",
"name": "BMEX",
"symbol": "BMEX",
"decimals": 18
}
]
}

View File

@@ -1,19 +1,15 @@
import { arrayify } from '@ethersproject/bytes'
import { parseBytes32String } from '@ethersproject/strings'
import { Currency, Token } from '@uniswap/sdk-core'
import { CHAIN_INFO, L2_CHAIN_IDS, SupportedChainId, SupportedL2ChainId } from 'constants/chains'
import { CHAIN_INFO } from 'constants/chainInfo'
import { L2_CHAIN_IDS, SupportedChainId, SupportedL2ChainId } from 'constants/chains'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { useCurrencyFromMap, useTokenFromMap } from 'lib/hooks/useCurrency'
import { getTokenFilter } from 'lib/hooks/useTokenList/filtering'
import { useMemo } from 'react'
import { createTokenFilterFunction } from '../components/SearchModal/filtering'
import { nativeOnChain } from '../constants/tokens'
import { useAllLists, useCombinedActiveList, useInactiveListUrls } from '../state/lists/hooks'
import { WrappedTokenInfo } from '../state/lists/wrappedTokenInfo'
import { NEVER_RELOAD, useSingleCallResult } from '../state/multicall/hooks'
import { useUserAddedTokens } from '../state/user/hooks'
import { isAddress } from '../utils'
import { TokenAddressMap, useUnsupportedTokenList } from './../state/lists/hooks'
import { useBytes32TokenContract, useTokenContract } from './useContract'
import { useActiveWeb3React } from './web3'
// reduce token map into standard address <-> Token mapping, optionally include user added tokens
function useTokensFromMap(tokenMap: TokenAddressMap, includeUserAdded: boolean): { [address: string]: Token } {
@@ -116,7 +112,7 @@ export function useSearchInactiveTokenLists(search: string | undefined, minResul
const activeTokens = useAllTokens()
return useMemo(() => {
if (!search || search.trim().length === 0) return []
const tokenFilter = createTokenFilterFunction(search)
const tokenFilter = getTokenFilter(search)
const result: WrappedTokenInfo[] = []
const addressSet: { [address: string]: true } = {}
for (const url of inactiveUrls) {
@@ -158,95 +154,15 @@ export function useIsUserAddedToken(currency: Currency | undefined | null): bool
return !!userAddedTokens.find((token) => currency.equals(token))
}
// parse a name or symbol from a token response
const BYTES32_REGEX = /^0x[a-fA-F0-9]{64}$/
function parseStringOrBytes32(str: string | undefined, bytes32: string | undefined, defaultValue: string): string {
return str && str.length > 0
? str
: // need to check for proper bytes string and valid terminator
bytes32 && BYTES32_REGEX.test(bytes32) && arrayify(bytes32)[31] === 0
? parseBytes32String(bytes32)
: defaultValue
}
// undefined if invalid or does not exist
// null if loading or null was passed
// otherwise returns the token
export function useToken(tokenAddress?: string | null): Token | undefined | null {
const { chainId } = useActiveWeb3React()
export function useToken(tokenAddress?: string | null): Token | null | undefined {
const tokens = useAllTokens()
const address = isAddress(tokenAddress)
const tokenContract = useTokenContract(address ? address : undefined, false)
const tokenContractBytes32 = useBytes32TokenContract(address ? address : undefined, false)
const token: Token | undefined = address ? tokens[address] : undefined
const tokenName = useSingleCallResult(token ? undefined : tokenContract, 'name', undefined, NEVER_RELOAD)
const tokenNameBytes32 = useSingleCallResult(
token ? undefined : tokenContractBytes32,
'name',
undefined,
NEVER_RELOAD
)
const symbol = useSingleCallResult(token ? undefined : tokenContract, 'symbol', undefined, NEVER_RELOAD)
const symbolBytes32 = useSingleCallResult(token ? undefined : tokenContractBytes32, 'symbol', undefined, NEVER_RELOAD)
const decimals = useSingleCallResult(token ? undefined : tokenContract, 'decimals', undefined, NEVER_RELOAD)
return useMemo(() => {
if (token) return token
if (tokenAddress === null) return null
if (!chainId || !address) return undefined
if (decimals.loading || symbol.loading || tokenName.loading) return null
if (decimals.result) {
return new Token(
chainId,
address,
decimals.result[0],
parseStringOrBytes32(symbol.result?.[0], symbolBytes32.result?.[0], 'UNKNOWN'),
parseStringOrBytes32(tokenName.result?.[0], tokenNameBytes32.result?.[0], 'Unknown Token')
)
}
return undefined
}, [
address,
chainId,
decimals.loading,
decimals.result,
symbol.loading,
symbol.result,
symbolBytes32.result,
token,
tokenAddress,
tokenName.loading,
tokenName.result,
tokenNameBytes32.result,
])
return useTokenFromMap(tokens, tokenAddress)
}
export function useNativeCurrency(): Currency {
const { chainId } = useActiveWeb3React()
return useMemo(
() =>
chainId
? nativeOnChain(chainId)
: // display mainnet when not connected
nativeOnChain(SupportedChainId.MAINNET),
[chainId]
)
}
export function useCurrency(currencyId: string | null | undefined): Currency | null | undefined {
const nativeCurrency = useNativeCurrency()
const isNative = Boolean(nativeCurrency && currencyId?.toUpperCase() === 'ETH')
const token = useToken(isNative ? undefined : currencyId)
if (currencyId === null || currencyId === undefined) return currencyId
// this case so we use our builtin wrapped token instead of wrapped tokens on token lists
const wrappedNative = nativeCurrency?.wrapped
if (wrappedNative?.address?.toUpperCase() === currencyId?.toUpperCase()) return wrappedNative
return isNative ? nativeCurrency : token
export function useCurrency(currencyId?: string | null): Currency | null | undefined {
const tokens = useAllTokens()
return useCurrencyFromMap(tokens, currencyId)
}

View File

@@ -0,0 +1,23 @@
/* eslint-disable react-hooks/rules-of-hooks */
import { Web3Provider } from '@ethersproject/providers'
import { useWeb3React } from '@web3-react/core'
import { default as useWidgetsWeb3React } from 'lib/hooks/useActiveWeb3React'
import { NetworkContextName } from '../constants/misc'
export default function useActiveWeb3React() {
if (process.env.REACT_APP_IS_WIDGET) {
return useWidgetsWeb3React()
}
const interfaceContext = useWeb3React<Web3Provider>()
const interfaceNetworkContext = useWeb3React<Web3Provider>(
process.env.REACT_APP_IS_WIDGET ? undefined : NetworkContextName
)
if (interfaceContext.active) {
return interfaceContext
}
return interfaceNetworkContext
}

View File

@@ -1,9 +1,8 @@
import { Currency, Token } from '@uniswap/sdk-core'
import { useActiveWeb3React } from 'hooks/web3'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import useCurrencyLogoURIs from 'lib/hooks/useCurrencyLogoURIs'
import { useCallback, useState } from 'react'
import { getTokenLogoURL } from './../components/CurrencyLogo/index'
export default function useAddTokenToMetamask(currencyToAdd: Currency | undefined): {
addToken: () => void
success: boolean | undefined
@@ -13,6 +12,7 @@ export default function useAddTokenToMetamask(currencyToAdd: Currency | undefine
const token: Token | undefined = currencyToAdd?.wrapped
const [success, setSuccess] = useState<boolean | undefined>()
const logoURL = useCurrencyLogoURIs(token)[0]
const addToken = useCallback(() => {
if (library && library.provider.isMetaMask && library.provider.request && token) {
@@ -26,7 +26,7 @@ export default function useAddTokenToMetamask(currencyToAdd: Currency | undefine
address: token.address,
symbol: token.symbol,
decimals: token.decimals,
image: getTokenLogoURL(token.address),
image: logoURL,
},
},
})
@@ -37,7 +37,7 @@ export default function useAddTokenToMetamask(currencyToAdd: Currency | undefine
} else {
setSuccess(false)
}
}, [library, token])
}, [library, logoURL, token])
return { addToken, success }
}

View File

@@ -1,9 +1,9 @@
import { Currency } from '@uniswap/sdk-core'
import { Pool, Route } from '@uniswap/v3-sdk'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { useMemo } from 'react'
import { useV3SwapPools } from './useV3SwapPools'
import { useActiveWeb3React } from './web3'
/**
* Returns true if poolA is equivalent to poolB

View File

@@ -1,69 +1,25 @@
import { MaxUint256 } from '@ethersproject/constants'
import { TransactionResponse } from '@ethersproject/providers'
import { Protocol, Trade } from '@uniswap/router-sdk'
import { Trade } from '@uniswap/router-sdk'
import { Currency, CurrencyAmount, Percent, TradeType } from '@uniswap/sdk-core'
import { Pair, Route as V2Route, Trade as V2Trade } from '@uniswap/v2-sdk'
import { Pool, Route as V3Route, Trade as V3Trade } from '@uniswap/v3-sdk'
import { useCallback, useMemo } from 'react'
import { getTxOptimizedSwapRouter, SwapRouterVersion } from 'utils/getTxOptimizedSwapRouter'
import { Trade as V2Trade } from '@uniswap/v2-sdk'
import { Trade as V3Trade } from '@uniswap/v3-sdk'
import useSwapApproval, { useSwapApprovalOptimizedTrade } from 'lib/hooks/swap/useSwapApproval'
import { ApprovalState, useApproval } from 'lib/hooks/useApproval'
import { useCallback } from 'react'
import { SWAP_ROUTER_ADDRESSES, V2_ROUTER_ADDRESS, V3_ROUTER_ADDRESS } from '../constants/addresses'
import { TransactionType } from '../state/transactions/actions'
import { useHasPendingApproval, useTransactionAdder } from '../state/transactions/hooks'
import { calculateGasMargin } from '../utils/calculateGasMargin'
import { useTokenContract } from './useContract'
import { useTokenAllowance } from './useTokenAllowance'
import { useActiveWeb3React } from './web3'
export { ApprovalState } from 'lib/hooks/useApproval'
export enum ApprovalState {
UNKNOWN = 'UNKNOWN',
NOT_APPROVED = 'NOT_APPROVED',
PENDING = 'PENDING',
APPROVED = 'APPROVED',
}
export function useApprovalState(amountToApprove?: CurrencyAmount<Currency>, spender?: string) {
const { account } = useActiveWeb3React()
const token = amountToApprove?.currency?.isToken ? amountToApprove.currency : undefined
const currentAllowance = useTokenAllowance(token, account ?? undefined, spender)
const pendingApproval = useHasPendingApproval(token?.address, spender)
return useMemo(() => {
if (!amountToApprove || !spender) return ApprovalState.UNKNOWN
if (amountToApprove.currency.isNative) return ApprovalState.APPROVED
// we might not have enough data to know whether or not we need to approve
if (!currentAllowance) return ApprovalState.UNKNOWN
// amountToApprove will be defined if currentAllowance is
return currentAllowance.lessThan(amountToApprove)
? pendingApproval
? ApprovalState.PENDING
: ApprovalState.NOT_APPROVED
: ApprovalState.APPROVED
}, [amountToApprove, currentAllowance, pendingApproval, spender])
}
/** Returns approval state for all known swap routers */
export function useAllApprovalStates(
trade: Trade<Currency, Currency, TradeType> | undefined,
allowedSlippage: Percent
) {
const { chainId } = useActiveWeb3React()
const amountToApprove = useMemo(
() => (trade && trade.inputAmount.currency.isToken ? trade.maximumAmountIn(allowedSlippage) : undefined),
[trade, allowedSlippage]
)
const v2ApprovalState = useApprovalState(amountToApprove, chainId ? V2_ROUTER_ADDRESS[chainId] : undefined)
const v3ApprovalState = useApprovalState(amountToApprove, chainId ? V3_ROUTER_ADDRESS[chainId] : undefined)
const v2V3ApprovalState = useApprovalState(amountToApprove, chainId ? SWAP_ROUTER_ADDRESSES[chainId] : undefined)
return useMemo(
() => ({ v2: v2ApprovalState, v3: v3ApprovalState, v2V3: v2V3ApprovalState }),
[v2ApprovalState, v2V3ApprovalState, v3ApprovalState]
)
function useGetAndTrackApproval(getApproval: ReturnType<typeof useApproval>[1]) {
const addTransaction = useTransactionAdder()
return useCallback(() => {
return getApproval().then((pending) => {
if (pending) {
const { response, tokenAddress, spenderAddress: spender } = pending
addTransaction(response, { type: TransactionType.APPROVAL, tokenAddress, spender })
}
})
}, [addTransaction, getApproval])
}
// returns a variable indicating the state of the approval and a function which approves if necessary or early returns
@@ -71,69 +27,17 @@ export function useApproveCallback(
amountToApprove?: CurrencyAmount<Currency>,
spender?: string
): [ApprovalState, () => Promise<void>] {
const { chainId } = useActiveWeb3React()
const token = amountToApprove?.currency?.isToken ? amountToApprove.currency : undefined
// check the current approval status
const approvalState = useApprovalState(amountToApprove, spender)
const tokenContract = useTokenContract(token?.address)
const addTransaction = useTransactionAdder()
const approve = useCallback(async (): Promise<void> => {
if (approvalState !== ApprovalState.NOT_APPROVED) {
console.error('approve was called unnecessarily')
return
}
if (!chainId) {
console.error('no chainId')
return
}
if (!token) {
console.error('no token')
return
}
if (!tokenContract) {
console.error('tokenContract is null')
return
}
if (!amountToApprove) {
console.error('missing amount to approve')
return
}
if (!spender) {
console.error('no spender')
return
}
let useExact = false
const estimatedGas = await tokenContract.estimateGas.approve(spender, MaxUint256).catch(() => {
// general fallback for tokens who restrict approval amounts
useExact = true
return tokenContract.estimateGas.approve(spender, amountToApprove.quotient.toString())
})
return tokenContract
.approve(spender, useExact ? amountToApprove.quotient.toString() : MaxUint256, {
gasLimit: calculateGasMargin(estimatedGas),
})
.then((response: TransactionResponse) => {
addTransaction(response, { type: TransactionType.APPROVAL, tokenAddress: token.address, spender })
})
.catch((error: Error) => {
console.debug('Failed to approve token', error)
throw error
})
}, [approvalState, token, tokenContract, amountToApprove, spender, addTransaction, chainId])
return [approvalState, approve]
const [approval, getApproval] = useApproval(amountToApprove, spender, useHasPendingApproval)
return [approval, useGetAndTrackApproval(getApproval)]
}
export function useApprovalOptimizedTrade(
trade: Trade<Currency, Currency, TradeType> | undefined,
allowedSlippage: Percent
) {
return useSwapApprovalOptimizedTrade(trade, allowedSlippage, useHasPendingApproval)
}
// wraps useApproveCallback in the context of a swap
export function useApproveCallbackFromTrade(
trade:
| V2Trade<Currency, Currency, TradeType>
@@ -141,85 +45,7 @@ export function useApproveCallbackFromTrade(
| Trade<Currency, Currency, TradeType>
| undefined,
allowedSlippage: Percent
) {
const { chainId } = useActiveWeb3React()
const amountToApprove = useMemo(
() => (trade && trade.inputAmount.currency.isToken ? trade.maximumAmountIn(allowedSlippage) : undefined),
[trade, allowedSlippage]
)
const approveCallback = useApproveCallback(
amountToApprove,
chainId
? trade instanceof V2Trade
? V2_ROUTER_ADDRESS[chainId]
: trade instanceof V3Trade
? V3_ROUTER_ADDRESS[chainId]
: SWAP_ROUTER_ADDRESSES[chainId]
: undefined
)
// TODO: remove L162-168 after testing is done. This error will help detect mistakes in the logic.
if (
(Trade instanceof V2Trade && approveCallback[0] !== ApprovalState.APPROVED) ||
(trade instanceof V3Trade && approveCallback[0] !== ApprovalState.APPROVED)
) {
throw new Error('Trying to approve legacy router')
}
return approveCallback
}
export function useApprovalOptimizedTrade(
trade: Trade<Currency, Currency, TradeType> | undefined,
allowedSlippage: Percent
):
| V2Trade<Currency, Currency, TradeType>
| V3Trade<Currency, Currency, TradeType>
| Trade<Currency, Currency, TradeType>
| undefined {
const onlyV2Routes = trade?.routes.every((route) => route.protocol === Protocol.V2)
const onlyV3Routes = trade?.routes.every((route) => route.protocol === Protocol.V3)
const tradeHasSplits = (trade?.routes.length ?? 0) > 1
const approvalStates = useAllApprovalStates(trade, allowedSlippage)
const optimizedSwapRouter = useMemo(
() => getTxOptimizedSwapRouter({ onlyV2Routes, onlyV3Routes, tradeHasSplits, approvalStates }),
[approvalStates, tradeHasSplits, onlyV2Routes, onlyV3Routes]
)
return useMemo(() => {
if (!trade) return undefined
try {
switch (optimizedSwapRouter) {
case SwapRouterVersion.V2V3:
return trade
case SwapRouterVersion.V2:
const pairs = trade.swaps[0].route.pools.filter((pool) => pool instanceof Pair) as Pair[]
const v2Route = new V2Route(pairs, trade.inputAmount.currency, trade.outputAmount.currency)
return new V2Trade(v2Route, trade.inputAmount, trade.tradeType)
case SwapRouterVersion.V3:
return V3Trade.createUncheckedTradeWithMultipleRoutes({
routes: trade.swaps.map(({ route, inputAmount, outputAmount }) => ({
route: new V3Route(
route.pools.filter((p) => p instanceof Pool) as Pool[],
inputAmount.currency,
outputAmount.currency
),
inputAmount,
outputAmount,
})),
tradeType: trade.tradeType,
})
default:
return undefined
}
} catch (e) {
// TODO(#2989): remove try-catch
console.debug(e)
return undefined
}
}, [trade, optimizedSwapRouter])
): [ApprovalState, () => Promise<void>] {
const [approval, getApproval] = useSwapApproval(trade, allowedSlippage, useHasPendingApproval)
return [approval, useGetAndTrackApproval(getApproval)]
}

View File

@@ -1,8 +1,9 @@
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import ArgentWalletContractABI from '../abis/argent-wallet-contract.json'
import { ArgentWalletContract } from '../abis/types'
import { useContract } from './useContract'
import useIsArgentWallet from './useIsArgentWallet'
import { useActiveWeb3React } from './web3'
export function useArgentWalletContract(): ArgentWalletContract | null {
const { account } = useActiveWeb3React()

View File

@@ -1,6 +1,5 @@
import { AUTO_ROUTER_SUPPORTED_CHAINS } from 'state/routing/clientSideSmartOrderRouter/constants'
import { useActiveWeb3React } from './web3'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { AUTO_ROUTER_SUPPORTED_CHAINS } from 'lib/hooks/routing/clientSideSmartOrderRouter'
export default function useAutoRouterSupported(): boolean {
const { chainId } = useActiveWeb3React()

View File

@@ -1,16 +1,15 @@
import { Trade } from '@uniswap/router-sdk'
import { Currency, CurrencyAmount, Percent, TradeType } from '@uniswap/sdk-core'
import { SUPPORTED_GAS_ESTIMATE_CHAIN_IDS } from 'components/swap/GasEstimateBadge'
import { SUPPORTED_GAS_ESTIMATE_CHAIN_IDS } from 'constants/chains'
import { L2_CHAIN_IDS } from 'constants/chains'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import JSBI from 'jsbi'
import useNativeCurrency from 'lib/hooks/useNativeCurrency'
import { useMemo } from 'react'
import { InterfaceTrade } from 'state/routing/types'
import { useUserSlippageToleranceWithDefault } from '../state/user/hooks'
import { useNativeCurrency } from './Tokens'
import useGasPrice from './useGasPrice'
import useUSDCPrice, { useUSDCValue } from './useUSDCPrice'
import { useActiveWeb3React } from './web3'
const V3_SWAP_DEFAULT_SLIPPAGE = new Percent(50, 10_000) // .50%
const ONE_TENTHS_PERCENT = new Percent(10, 10_000) // .10%
@@ -29,7 +28,10 @@ function guesstimateGas(trade: Trade<Currency, Currency, TradeType> | undefined)
const MIN_AUTO_SLIPPAGE_TOLERANCE = new Percent(5, 1000) // 0.5%
const MAX_AUTO_SLIPPAGE_TOLERANCE = new Percent(25, 100) // 25%
export default function useSwapSlippageTolerance(
/**
* Returns slippage tolerance based on values from current trade, gas estimates from api, and active network.
*/
export default function useAutoSlippageTolerance(
trade: InterfaceTrade<Currency, Currency, TradeType> | undefined
): Percent {
const { chainId } = useActiveWeb3React()
@@ -41,7 +43,7 @@ export default function useSwapSlippageTolerance(
const nativeCurrency = useNativeCurrency()
const nativeCurrencyPrice = useUSDCPrice(nativeCurrency ?? undefined)
const defaultSlippageTolerance = useMemo(() => {
return useMemo(() => {
if (!trade || onL2) return ONE_TENTHS_PERCENT
const nativeGasCost =
@@ -73,6 +75,4 @@ export default function useSwapSlippageTolerance(
return V3_SWAP_DEFAULT_SLIPPAGE
}, [trade, onL2, nativeGasPrice, gasEstimate, nativeCurrency, nativeCurrencyPrice, chainId, outputDollarValue])
return useUserSlippageToleranceWithDefault(defaultSlippageTolerance)
}

View File

@@ -1,4 +1,5 @@
import { Currency, CurrencyAmount, TradeType } from '@uniswap/sdk-core'
import { useMemo } from 'react'
import { InterfaceTrade, TradeState } from 'state/routing/types'
import { useRoutingAPITrade } from 'state/routing/useRoutingAPITrade'
@@ -24,7 +25,10 @@ export function useBestTrade(
const autoRouterSupported = useAutoRouterSupported()
const isWindowVisible = useIsWindowVisible()
const [debouncedAmount, debouncedOtherCurrency] = useDebounce([amountSpecified, otherCurrency], 200)
const [debouncedAmount, debouncedOtherCurrency] = useDebounce(
useMemo(() => [amountSpecified, otherCurrency], [amountSpecified, otherCurrency]),
200
)
const routingAPITrade = useRoutingAPITrade(
tradeType,
@@ -56,9 +60,12 @@ export function useBestTrade(
)
// only return gas estimate from api if routing api trade is used
return {
...(useFallback ? bestV3Trade : routingAPITrade),
...(debouncing ? { state: TradeState.SYNCING } : {}),
...(isLoading ? { state: TradeState.LOADING } : {}),
}
return useMemo(
() => ({
...(useFallback ? bestV3Trade : routingAPITrade),
...(debouncing ? { state: TradeState.SYNCING } : {}),
...(isLoading ? { state: TradeState.LOADING } : {}),
}),
[bestV3Trade, debouncing, isLoading, routingAPITrade, useFallback]
)
}

View File

@@ -1,14 +1,14 @@
import { Currency, CurrencyAmount, TradeType } from '@uniswap/sdk-core'
import { Route, SwapQuoter } from '@uniswap/v3-sdk'
import { SupportedChainId } from 'constants/chains'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import JSBI from 'jsbi'
import { useSingleContractWithCallData } from 'lib/hooks/multicall'
import { useMemo } from 'react'
import { InterfaceTrade, TradeState } from 'state/routing/types'
import { useSingleContractWithCallData } from '../state/multicall/hooks'
import { useAllV3Routes } from './useAllV3Routes'
import { useV3Quoter } from './useContract'
import { useActiveWeb3React } from './web3'
const QUOTE_GAS_OVERRIDES: { [chainId: number]: number } = {
[SupportedChainId.ARBITRUM_ONE]: 25_000_000,

View File

@@ -1,10 +1,10 @@
import { Token } from '@uniswap/sdk-core'
import { SupportedChainId } from 'constants/chains'
import uriToHttp from 'lib/utils/uriToHttp'
import Vibrant from 'node-vibrant/lib/bundle'
import { shade } from 'polished'
import { useLayoutEffect, useState } from 'react'
import { WrappedTokenInfo } from 'state/lists/wrappedTokenInfo'
import uriToHttp from 'utils/uriToHttp'
import { hex } from 'wcag-contrast'
function URIForEthToken(address: string) {

View File

@@ -1,14 +1,15 @@
import { Contract } from '@ethersproject/contracts'
import { abi as GOVERNANCE_ABI } from '@uniswap/governance/build/GovernorAlpha.json'
import { abi as UNI_ABI } from '@uniswap/governance/build/Uni.json'
import { abi as STAKING_REWARDS_ABI } from '@uniswap/liquidity-staker/build/StakingRewards.json'
import { abi as MERKLE_DISTRIBUTOR_ABI } from '@uniswap/merkle-distributor/build/MerkleDistributor.json'
import { abi as IUniswapV2PairABI } from '@uniswap/v2-core/build/IUniswapV2Pair.json'
import { abi as IUniswapV2Router02ABI } from '@uniswap/v2-periphery/build/IUniswapV2Router02.json'
import { abi as QuoterABI } from '@uniswap/v3-periphery/artifacts/contracts/lens/Quoter.sol/Quoter.json'
import { abi as MulticallABI } from '@uniswap/v3-periphery/artifacts/contracts/lens/UniswapInterfaceMulticall.sol/UniswapInterfaceMulticall.json'
import { abi as NFTPositionManagerABI } from '@uniswap/v3-periphery/artifacts/contracts/NonfungiblePositionManager.sol/NonfungiblePositionManager.json'
import { abi as V2MigratorABI } from '@uniswap/v3-periphery/artifacts/contracts/V3Migrator.sol/V3Migrator.json'
import GovernorAlphaJson from '@uniswap/governance/build/GovernorAlpha.json'
import UniJson from '@uniswap/governance/build/Uni.json'
import StakingRewardsJson from '@uniswap/liquidity-staker/build/StakingRewards.json'
import MerkleDistributorJson from '@uniswap/merkle-distributor/build/MerkleDistributor.json'
import IUniswapV2PairJson from '@uniswap/v2-core/build/IUniswapV2Pair.json'
import IUniswapV2Router02Json from '@uniswap/v2-periphery/build/IUniswapV2Router02.json'
import QuoterJson from '@uniswap/v3-periphery/artifacts/contracts/lens/Quoter.sol/Quoter.json'
import TickLensJson from '@uniswap/v3-periphery/artifacts/contracts/lens/TickLens.sol/TickLens.json'
import UniswapInterfaceMulticallJson from '@uniswap/v3-periphery/artifacts/contracts/lens/UniswapInterfaceMulticall.sol/UniswapInterfaceMulticall.json'
import NonfungiblePositionManagerJson from '@uniswap/v3-periphery/artifacts/contracts/NonfungiblePositionManager.sol/NonfungiblePositionManager.json'
import V3MigratorJson from '@uniswap/v3-periphery/artifacts/contracts/V3Migrator.sol/V3Migrator.json'
import ARGENT_WALLET_DETECTOR_ABI from 'abis/argent-wallet-detector.json'
import EIP_2612 from 'abis/eip_2612.json'
import ENS_PUBLIC_RESOLVER_ABI from 'abis/ens-public-resolver.json'
@@ -18,6 +19,7 @@ import ERC20_BYTES32_ABI from 'abis/erc20_bytes32.json'
import ERC721_ABI from 'abis/erc721.json'
import ERC1155_ABI from 'abis/erc1155.json'
import GOVERNOR_BRAVO_ABI from 'abis/governor-bravo.json'
import { ArgentWalletDetector, EnsPublicResolver, EnsRegistrar, Erc20, Erc721, Erc1155, Weth } from 'abis/types'
import WETH_ABI from 'abis/weth.json'
import {
ARGENT_WALLET_DETECTOR_ADDRESS,
@@ -29,17 +31,29 @@ import {
MULTICALL_ADDRESS,
NONFUNGIBLE_POSITION_MANAGER_ADDRESSES,
QUOTER_ADDRESSES,
TICK_LENS_ADDRESSES,
V2_ROUTER_ADDRESS,
V3_MIGRATOR_ADDRESSES,
} from 'constants/addresses'
import { UNI, WRAPPED_NATIVE_CURRENCY } from 'constants/tokens'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { useMemo } from 'react'
import { NonfungiblePositionManager, Quoter, UniswapInterfaceMulticall } from 'types/v3'
import { NonfungiblePositionManager, Quoter, TickLens, UniswapInterfaceMulticall } from 'types/v3'
import { V3Migrator } from 'types/v3/V3Migrator'
import { getContract } from 'utils'
import { ArgentWalletDetector, EnsPublicResolver, EnsRegistrar, Erc20, Erc721, Erc1155, Weth } from '../abis/types'
import { UNI, WRAPPED_NATIVE_CURRENCY } from '../constants/tokens'
import { useActiveWeb3React } from './web3'
import { getContract } from '../utils'
const { abi: GOVERNANCE_ABI } = GovernorAlphaJson
const { abi: UNI_ABI } = UniJson
const { abi: STAKING_REWARDS_ABI } = StakingRewardsJson
const { abi: MERKLE_DISTRIBUTOR_ABI } = MerkleDistributorJson
const { abi: IUniswapV2PairABI } = IUniswapV2PairJson
const { abi: IUniswapV2Router02ABI } = IUniswapV2Router02Json
const { abi: QuoterABI } = QuoterJson
const { abi: TickLensABI } = TickLensJson
const { abi: MulticallABI } = UniswapInterfaceMulticallJson
const { abi: NFTPositionManagerABI } = NonfungiblePositionManagerJson
const { abi: V2MigratorABI } = V3MigratorJson
// returns null on errors
export function useContract<T extends Contract = Contract>(
@@ -159,3 +173,9 @@ export function useV3NFTPositionManagerContract(withSignerIfPossible?: boolean):
export function useV3Quoter() {
return useContract<Quoter>(QUOTER_ADDRESSES, QuoterABI)
}
export function useTickLens(): TickLens | null {
const { chainId } = useActiveWeb3React()
const address = chainId ? TICK_LENS_ADDRESSES[chainId] : undefined
return useContract(address, TickLensABI) as TickLens | null
}

View File

@@ -1,6 +1,6 @@
import { BigNumber } from '@ethersproject/bignumber'
import { useSingleCallResult } from 'lib/hooks/multicall'
import { useSingleCallResult } from '../state/multicall/hooks'
import { useInterfaceMulticall } from './useContract'
// gets the current timestamp from the blockchain

View File

@@ -1,5 +1,9 @@
import { useEffect, useState } from 'react'
/**
* Debounces updates to a value.
* Non-primitives *must* wrap the value in useMemo, or the value will be updated due to referential inequality.
*/
// modified from https://usehooks.com/useDebounce/
export default function useDebounce<T>(value: T, delay: number): T {
const [debouncedValue, setDebouncedValue] = useState<T>(value)

View File

@@ -1,7 +1,7 @@
import { useSingleCallResult } from 'lib/hooks/multicall'
import { useMemo } from 'react'
import { safeNamehash } from 'utils/safeNamehash'
import { useSingleCallResult } from '../state/multicall/hooks'
import isZero from '../utils/isZero'
import { useENSRegistrarContract, useENSResolverContract } from './useContract'
import useDebounce from './useDebounce'

View File

@@ -1,15 +1,17 @@
import { BigNumber } from '@ethersproject/bignumber'
import { hexZeroPad } from '@ethersproject/bytes'
import { namehash } from '@ethersproject/hash'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { useSingleCallResult } from 'lib/hooks/multicall'
import uriToHttp from 'lib/utils/uriToHttp'
import { useEffect, useMemo, useState } from 'react'
import { safeNamehash } from 'utils/safeNamehash'
import uriToHttp from 'utils/uriToHttp'
import { useSingleCallResult } from '../state/multicall/hooks'
import { isAddress } from '../utils'
import isZero from '../utils/isZero'
import { useENSRegistrarContract, useENSResolverContract, useERC721Contract, useERC1155Contract } from './useContract'
import useDebounce from './useDebounce'
import useENSName from './useENSName'
import { useActiveWeb3React } from './web3'
/**
* Returns the ENS avatar URI, if available.
@@ -134,11 +136,14 @@ function useERC1155Uri(
const contract = useERC1155Contract(contractAddress)
const balance = useSingleCallResult(contract, 'balanceOf', accountArgument)
const uri = useSingleCallResult(contract, 'uri', idArgument)
// ERC-1155 allows a generic {id} in the URL, so prepare to replace if relevant,
// in lowercase hexadecimal (with no 0x prefix) and leading zero padded to 64 hex characters.
const idHex = id ? hexZeroPad(BigNumber.from(id).toHexString(), 32).substring(2) : id
return useMemo(
() => ({
uri: !enforceOwnership || balance.result?.[0] > 0 ? uri.result?.[0] : undefined,
uri: !enforceOwnership || balance.result?.[0] > 0 ? uri.result?.[0]?.replaceAll('{id}', idHex) : undefined,
loading: balance.loading || uri.loading,
}),
[balance.loading, balance.result, enforceOwnership, uri.loading, uri.result]
[balance.loading, balance.result, enforceOwnership, uri.loading, uri.result, idHex]
)
}

View File

@@ -1,7 +1,7 @@
import { useSingleCallResult } from 'lib/hooks/multicall'
import { useMemo } from 'react'
import { safeNamehash } from 'utils/safeNamehash'
import { useSingleCallResult } from '../state/multicall/hooks'
import isZero from '../utils/isZero'
import { useENSRegistrarContract, useENSResolverContract } from './useContract'

View File

@@ -1,11 +1,12 @@
import { namehash } from '@ethersproject/hash'
import { useSingleCallResult } from 'lib/hooks/multicall'
import { useMemo } from 'react'
import { useSingleCallResult } from '../state/multicall/hooks'
import { isAddress } from '../utils'
import isZero from '../utils/isZero'
import { useENSRegistrarContract, useENSResolverContract } from './useContract'
import useDebounce from './useDebounce'
import useENSAddress from './useENSAddress'
/**
* Does a reverse lookup for an address to find its ENS name.
@@ -24,14 +25,22 @@ export default function useENSName(address?: string): { ENSName: string | null;
resolverAddressResult && !isZero(resolverAddressResult) ? resolverAddressResult : undefined,
false
)
const name = useSingleCallResult(resolverContract, 'name', ensNodeArgument)
const nameCallRes = useSingleCallResult(resolverContract, 'name', ensNodeArgument)
const name = nameCallRes.result?.[0]
/* ENS does not enforce that an address owns a .eth domain before setting it as a reverse proxy
and recommends that you perform a match on the forward resolution
see: https://docs.ens.domains/dapp-developer-guide/resolving-names#reverse-resolution
*/
const fwdAddr = useENSAddress(name)
const checkedName = address === fwdAddr?.address ? name : null
const changed = debouncedAddress !== address
return useMemo(
() => ({
ENSName: changed ? null : name.result?.[0] ?? null,
loading: changed || resolverAddress.loading || name.loading,
ENSName: changed ? null : checkedName,
loading: changed || resolverAddress.loading || nameCallRes.loading,
}),
[changed, name.loading, name.result, resolverAddress.loading]
[changed, nameCallRes.loading, checkedName, resolverAddress.loading]
)
}

View File

@@ -1,20 +1,20 @@
import { BigNumber } from '@ethersproject/bignumber'
import { splitSignature } from '@ethersproject/bytes'
import { Trade } from '@uniswap/router-sdk'
import { Currency, CurrencyAmount, Percent, Token, TradeType } from '@uniswap/sdk-core'
import { Currency, CurrencyAmount, Percent, TradeType } from '@uniswap/sdk-core'
import { Trade as V2Trade } from '@uniswap/v2-sdk'
import { Trade as V3Trade } from '@uniswap/v3-sdk'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import JSBI from 'jsbi'
import { useSingleCallResult } from 'lib/hooks/multicall'
import { useMemo, useState } from 'react'
import { SWAP_ROUTER_ADDRESSES, V3_ROUTER_ADDRESS } from '../constants/addresses'
import { DAI, UNI, USDC } from '../constants/tokens'
import { useSingleCallResult } from '../state/multicall/hooks'
import { useEIP2612Contract } from './useContract'
import useIsArgentWallet from './useIsArgentWallet'
import useTransactionDeadline from './useTransactionDeadline'
import { useActiveWeb3React } from './web3'
enum PermitType {
export enum PermitType {
AMOUNT = 1,
ALLOWED = 2,
}
@@ -22,7 +22,7 @@ enum PermitType {
// 20 minutes to submit after signing
const PERMIT_VALIDITY_BUFFER = 20 * 60
interface PermitInfo {
export interface PermitInfo {
type: PermitType
name: string
// version is optional, and if omitted, will not be included in the domain
@@ -116,9 +116,10 @@ const PERMIT_ALLOWED_TYPE = [
{ name: 'allowed', type: 'bool' },
]
function useERC20Permit(
export function useERC20Permit(
currencyAmount: CurrencyAmount<Currency> | null | undefined,
spender: string | null | undefined,
transactionDeadline: BigNumber | undefined,
overridePermitInfo: PermitInfo | undefined | null
): {
signatureData: SignatureData | null
@@ -126,7 +127,6 @@ function useERC20Permit(
gatherPermitSignature: null | (() => Promise<void>)
} {
const { account, chainId, library } = useActiveWeb3React()
const transactionDeadline = useTransactionDeadline()
const tokenAddress = currencyAmount?.currency?.isToken ? currencyAmount.currency.address : undefined
const eip2612Contract = useEIP2612Contract(tokenAddress)
const isArgentWallet = useIsArgentWallet()
@@ -259,26 +259,14 @@ function useERC20Permit(
])
}
const REMOVE_V2_LIQUIDITY_PERMIT_INFO: PermitInfo = {
version: '1',
name: 'Uniswap V2',
type: PermitType.AMOUNT,
}
export function useV2LiquidityTokenPermit(
liquidityAmount: CurrencyAmount<Token> | null | undefined,
spender: string | null | undefined
) {
return useERC20Permit(liquidityAmount, spender, REMOVE_V2_LIQUIDITY_PERMIT_INFO)
}
export function useERC20PermitFromTrade(
trade:
| V2Trade<Currency, Currency, TradeType>
| V3Trade<Currency, Currency, TradeType>
| Trade<Currency, Currency, TradeType>
| undefined,
allowedSlippage: Percent
allowedSlippage: Percent,
transactionDeadline: BigNumber | undefined
) {
const { chainId } = useActiveWeb3React()
const swapRouterAddress = chainId
@@ -294,5 +282,5 @@ export function useERC20PermitFromTrade(
[trade, allowedSlippage]
)
return useERC20Permit(amountToApprove, swapRouterAddress, null)
return useERC20Permit(amountToApprove, swapRouterAddress, transactionDeadline, null)
}

View File

@@ -1,10 +1,10 @@
import { skipToken } from '@reduxjs/toolkit/query/react'
import { Currency, Token } from '@uniswap/sdk-core'
import { FeeAmount } from '@uniswap/v3-sdk'
import useBlockNumber from 'lib/hooks/useBlockNumber'
import ms from 'ms.macro'
import { useMemo } from 'react'
import ReactGA from 'react-ga'
import { useBlockNumber } from 'state/application/hooks'
import { useFeeTierDistributionQuery } from 'state/data/enhanced'
import { FeeTierDistributionQuery } from 'state/data/generated'

View File

@@ -1,13 +1,13 @@
import { nanoid } from '@reduxjs/toolkit'
import { TokenList } from '@uniswap/token-lists'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import getTokenList from 'lib/hooks/useTokenList/fetchTokenList'
import resolveENSContentHash from 'lib/utils/resolveENSContentHash'
import { useCallback } from 'react'
import { useAppDispatch } from 'state/hooks'
import { getNetworkLibrary } from '../connectors'
import { fetchTokenList } from '../state/lists/actions'
import getTokenList from '../utils/getTokenList'
import resolveENSContentHash from '../utils/resolveENSContentHash'
import { useActiveWeb3React } from './web3'
export function useFetchListCallback(): (listUrl: string, sendDispatch?: boolean) => Promise<TokenList> {
const { chainId, library } = useActiveWeb3React()

View File

@@ -1,6 +1,6 @@
import JSBI from 'jsbi'
import { useSingleCallResult } from 'lib/hooks/multicall'
import { useSingleCallResult } from '../state/multicall/hooks'
import { useContract } from './useContract'
import useENSAddress from './useENSAddress'

View File

@@ -1,8 +1,8 @@
import contenthashToUri from 'lib/utils/contenthashToUri'
import parseENSAddress from 'lib/utils/parseENSAddress'
import uriToHttp from 'lib/utils/uriToHttp'
import { useMemo } from 'react'
import contenthashToUri from '../utils/contenthashToUri'
import { parseENSAddress } from '../utils/parseENSAddress'
import uriToHttp from '../utils/uriToHttp'
import useENSContentHash from './useENSContentHash'
export default function useHttpLocations(uri: string | undefined): string[] {

View File

@@ -1,8 +1,8 @@
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { NEVER_RELOAD, useSingleCallResult } from 'lib/hooks/multicall'
import { useMemo } from 'react'
import { NEVER_RELOAD, useSingleCallResult } from '../state/multicall/hooks'
import { useArgentWalletDetectorContract } from './useContract'
import { useActiveWeb3React } from './web3'
export default function useIsArgentWallet(): boolean {
const { account } = useActiveWeb3React()

Some files were not shown because too many files have changed in this diff Show More