Compare commits
444 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
361e0ca8d7 | ||
|
|
cc0a757ddd | ||
|
|
31632d3c5b | ||
|
|
9cfbec4b8b | ||
|
|
b5ac5d882f | ||
|
|
130606cab4 | ||
|
|
fa56919a06 | ||
|
|
633f65676e | ||
|
|
9bccb7ae3a | ||
|
|
8a2e4123c6 | ||
|
|
e93ddbedfa | ||
|
|
1667b56a04 | ||
|
|
6e995d6c09 | ||
|
|
f096112716 | ||
|
|
50c7d36164 | ||
|
|
8a7f1d51ce | ||
|
|
8f59f501cc | ||
|
|
197947835b | ||
|
|
94081b29a3 | ||
|
|
69183ed8c2 | ||
|
|
05e741b6c9 | ||
|
|
dfe550c43b | ||
|
|
65dfb40e44 | ||
|
|
25f5ed9983 | ||
|
|
9b1ef415c6 | ||
|
|
70f481430a | ||
|
|
942211eb00 | ||
|
|
6589c41800 | ||
|
|
14bac770b6 | ||
|
|
c9dbe2f0ac | ||
|
|
775cf57c30 | ||
|
|
f4935e9264 | ||
|
|
6b3914b7b9 | ||
|
|
41efb6f617 | ||
|
|
52df5f14cf | ||
|
|
b48a7c529f | ||
|
|
2eca50be93 | ||
|
|
be2ce18bfa | ||
|
|
fe13b29e5e | ||
|
|
02aac08489 | ||
|
|
8f29980b94 | ||
|
|
bb542ef0fb | ||
|
|
c2fe17615f | ||
|
|
a4cab75d09 | ||
|
|
882457cfef | ||
|
|
9a1bb5dbfb | ||
|
|
767cc85b3e | ||
|
|
47d726e544 | ||
|
|
32118520cd | ||
|
|
ada8a3af92 | ||
|
|
63694b32c0 | ||
|
|
c9ab94d799 | ||
|
|
a990c4af70 | ||
|
|
b5cc33c1f5 | ||
|
|
31da6cdb9d | ||
|
|
4079d8a517 | ||
|
|
e93fbfd31b | ||
|
|
7817846368 | ||
|
|
fc6a69a9af | ||
|
|
93a774092f | ||
|
|
55563e9bb2 | ||
|
|
f44aae2f53 | ||
|
|
7d674c33e7 | ||
|
|
79e6337629 | ||
|
|
3c8e8604b8 | ||
|
|
b763659788 | ||
|
|
1ac2581419 | ||
|
|
9f556680ed | ||
|
|
3f242f1b44 | ||
|
|
126688c753 | ||
|
|
374cc361a6 | ||
|
|
0198d0baa1 | ||
|
|
da2d7ba648 | ||
|
|
37cf492dd5 | ||
|
|
9e93f809a0 | ||
|
|
d9bd392e6d | ||
|
|
c48adc519f | ||
|
|
9f8983a92e | ||
|
|
c9d3d81768 | ||
|
|
c6f73c35ee | ||
|
|
7a2777b814 | ||
|
|
014595cdfb | ||
|
|
1b27d8dab0 | ||
|
|
c4d12c86a8 | ||
|
|
8d2feeb89e | ||
|
|
576b399768 | ||
|
|
eb8ce85872 | ||
|
|
1644e4f9c6 | ||
|
|
574fab54d1 | ||
|
|
8e581c19ff | ||
|
|
8c2fa89e9e | ||
|
|
0ae7452eca | ||
|
|
4589beb789 | ||
|
|
55aee86971 | ||
|
|
a457af91b6 | ||
|
|
e61b5da3c5 | ||
|
|
b4f44744c1 | ||
|
|
27f4e2e750 | ||
|
|
01159c53d5 | ||
|
|
8d8d63b873 | ||
|
|
da9db4b5f1 | ||
|
|
1724bee0f5 | ||
|
|
48e526554b | ||
|
|
53add345de | ||
|
|
e28faf0da2 | ||
|
|
f79dc5fe82 | ||
|
|
a6f29cbff8 | ||
|
|
68f0d4b725 | ||
|
|
111e7dc929 | ||
|
|
39d61e4913 | ||
|
|
3e6d3ec1b5 | ||
|
|
3f65530bf4 | ||
|
|
dba0d20781 | ||
|
|
a0f3bd0dc6 | ||
|
|
bef85abfd4 | ||
|
|
9934dba805 | ||
|
|
72d94b2831 | ||
|
|
138697a30a | ||
|
|
0add8ae177 | ||
|
|
13f7859aaa | ||
|
|
3337b5de22 | ||
|
|
55ea6616a4 | ||
|
|
5dd1249ddd | ||
|
|
4ab2bd3474 | ||
|
|
9eb20624cb | ||
|
|
25c5cf04e6 | ||
|
|
1f70e63cd0 | ||
|
|
df88b0ddd1 | ||
|
|
679759c3a0 | ||
|
|
9b6003bdc5 | ||
|
|
2b32824c26 | ||
|
|
a4e4cf8ab9 | ||
|
|
f08cea1820 | ||
|
|
e2d35c56fc | ||
|
|
5f20040107 | ||
|
|
9344abd1cf | ||
|
|
426e31230d | ||
|
|
06c48559c5 | ||
|
|
0a33ed1a50 | ||
|
|
d5c490b871 | ||
|
|
099c2adea3 | ||
|
|
d387538576 | ||
|
|
a3a7d01ce9 | ||
|
|
549e67bcea | ||
|
|
932992b57f | ||
|
|
76a24376d4 | ||
|
|
f873b2249f | ||
|
|
22452c03b0 | ||
|
|
14e045b999 | ||
|
|
948781f927 | ||
|
|
2f72d6b77e | ||
|
|
a78209690d | ||
|
|
98a2f51125 | ||
|
|
a1043573af | ||
|
|
63760faa9d | ||
|
|
0566ec28be | ||
|
|
d4c1baba57 | ||
|
|
7e41b27cd3 | ||
|
|
1d18a5159f | ||
|
|
bb87d2dd03 | ||
|
|
0b27528a6a | ||
|
|
5788a273ba | ||
|
|
4d322b17da | ||
|
|
cb5b80b558 | ||
|
|
6964b519bc | ||
|
|
ee4ea2a1f0 | ||
|
|
3763ad15e0 | ||
|
|
557042a88f | ||
|
|
860413dd52 | ||
|
|
18d4cdcce4 | ||
|
|
55767de484 | ||
|
|
60d5cef69b | ||
|
|
ad2833a3ed | ||
|
|
e4a105714a | ||
|
|
3e842d3259 | ||
|
|
e9d18acd41 | ||
|
|
abeba3d6b6 | ||
|
|
84c4219c02 | ||
|
|
50b81c8334 | ||
|
|
8986b63335 | ||
|
|
631b4c08b6 | ||
|
|
b92f0b8d90 | ||
|
|
ce926e91b7 | ||
|
|
4857281a1e | ||
|
|
d2a872e7d2 | ||
|
|
73042f20fd | ||
|
|
29b5e583c5 | ||
|
|
d67f3158bd | ||
|
|
817732d62e | ||
|
|
562a54a175 | ||
|
|
cd1e0cf378 | ||
|
|
0c81b08d66 | ||
|
|
2662f8afbc | ||
|
|
355012eec9 | ||
|
|
68518d7ce0 | ||
|
|
2c9c99b868 | ||
|
|
7b78dfa2c4 | ||
|
|
e6cbab3c72 | ||
|
|
144f86bdfd | ||
|
|
6703743aef | ||
|
|
0320083909 | ||
|
|
b96f7d27ca | ||
|
|
45e85bc857 | ||
|
|
24e1a01b1a | ||
|
|
0e7a94313c | ||
|
|
35e80fa3ed | ||
|
|
4a70d8eb28 | ||
|
|
706d8724c1 | ||
|
|
6e363c1ff1 | ||
|
|
27007708ec | ||
|
|
c4739ea963 | ||
|
|
50954eff0f | ||
|
|
af112765e4 | ||
|
|
52b71004d0 | ||
|
|
2ba7c857cd | ||
|
|
67f3b40671 | ||
|
|
c2acf5c1a8 | ||
|
|
51cf8aa0da | ||
|
|
bc0e578610 | ||
|
|
1b13cac0fb | ||
|
|
14ed4dbb2e | ||
|
|
dc140901b3 | ||
|
|
07a92ba63b | ||
|
|
3f2f46df43 | ||
|
|
2dc5c0d386 | ||
|
|
38de86f4c9 | ||
|
|
b2196e7e48 | ||
|
|
30f66f7062 | ||
|
|
b87430277a | ||
|
|
b4c59cfc6e | ||
|
|
2326dfa108 | ||
|
|
97bf36efbf | ||
|
|
264acaae48 | ||
|
|
63e9f6e4d2 | ||
|
|
02d80e07dc | ||
|
|
ad53da5efe | ||
|
|
29223ce34f | ||
|
|
b88919ed69 | ||
|
|
ab80910553 | ||
|
|
1cdb8aa6a4 | ||
|
|
88976d0294 | ||
|
|
b908c81e2b | ||
|
|
5c20d0adb7 | ||
|
|
ca6295fcb7 | ||
|
|
e8af59198d | ||
|
|
cd4c43b482 | ||
|
|
c1e07f3713 | ||
|
|
bccda20473 | ||
|
|
bed8dd5110 | ||
|
|
6bcbabec23 | ||
|
|
71a490f2aa | ||
|
|
abcf1f5a5c | ||
|
|
65e5e9c98e | ||
|
|
fdabb90f0e | ||
|
|
049054f5bb | ||
|
|
91d0a002c9 | ||
|
|
305d2e1df9 | ||
|
|
6bb7d9d9b2 | ||
|
|
55d5762e39 | ||
|
|
979686100e | ||
|
|
a7a1607faa | ||
|
|
5125cbb1a3 | ||
|
|
e89387bb26 | ||
|
|
f7896db5aa | ||
|
|
0a0053c6f1 | ||
|
|
9e10abbf97 | ||
|
|
c38771a6aa | ||
|
|
8e364680b6 | ||
|
|
04c25685f7 | ||
|
|
be1e184d88 | ||
|
|
b485b14395 | ||
|
|
44ef0138de | ||
|
|
a1142cc7af | ||
|
|
089280ddf0 | ||
|
|
f3c2a6eaea | ||
|
|
54dc5b1f19 | ||
|
|
0af7651c0b | ||
|
|
61d9dfe127 | ||
|
|
d990dfdec7 | ||
|
|
4336e08233 | ||
|
|
3840daf365 | ||
|
|
1104bdcefc | ||
|
|
499ef27722 | ||
|
|
1ea0769ba3 | ||
|
|
637d43621b | ||
|
|
9831cda290 | ||
|
|
62d4bb8b51 | ||
|
|
58a1be8421 | ||
|
|
40b939df58 | ||
|
|
3ccecc5ca1 | ||
|
|
9df5b536c9 | ||
|
|
4b72d757c5 | ||
|
|
63affd9828 | ||
|
|
135f9dc219 | ||
|
|
08b74b2524 | ||
|
|
ffcea6388e | ||
|
|
408a07ebd4 | ||
|
|
7f837810e0 | ||
|
|
57a7a4995a | ||
|
|
cc66783278 | ||
|
|
f97dcaef1d | ||
|
|
cfea3723a2 | ||
|
|
7d0fb9cc10 | ||
|
|
8633dc7a50 | ||
|
|
f340537544 | ||
|
|
3e9289dc35 | ||
|
|
4eb5c3cac8 | ||
|
|
cfadd3b165 | ||
|
|
d6db79b8f5 | ||
|
|
6007527ce0 | ||
|
|
06c8db917f | ||
|
|
3394bc738f | ||
|
|
32b56ba0fd | ||
|
|
f97ce35cee | ||
|
|
0dafd3e7ba | ||
|
|
d719942931 | ||
|
|
62b9b5d527 | ||
|
|
ab34645073 | ||
|
|
dab3671cfe | ||
|
|
478cb3afa3 | ||
|
|
d56015d750 | ||
|
|
a639e65cee | ||
|
|
243e14b74e | ||
|
|
70174140bc | ||
|
|
4fede9df36 | ||
|
|
fbd5dab53e | ||
|
|
ecdce21b16 | ||
|
|
1a38309500 | ||
|
|
46f539c604 | ||
|
|
ad65b63868 | ||
|
|
f9a5dbf6ce | ||
|
|
7991b0b0d8 | ||
|
|
d85dccd01a | ||
|
|
37799caa03 | ||
|
|
04878e095c | ||
|
|
14a6953b90 | ||
|
|
d866d79578 | ||
|
|
7f1def300d | ||
|
|
8930627064 | ||
|
|
efb939297f | ||
|
|
69cc728d43 | ||
|
|
a6bc7775bc | ||
|
|
3452be9a45 | ||
|
|
be6e2fe74a | ||
|
|
83b1297ff6 | ||
|
|
a20ed15b00 | ||
|
|
1413ab91bf | ||
|
|
c4846c8832 | ||
|
|
dbbffd17a6 | ||
|
|
85d8b1e514 | ||
|
|
739986ba66 | ||
|
|
e9148b30c9 | ||
|
|
6e46f25bd4 | ||
|
|
02269e9376 | ||
|
|
9822e68d5a | ||
|
|
9d1556b777 | ||
|
|
858b6afb2f | ||
|
|
da14d8fd5b | ||
|
|
3aaa3fef89 | ||
|
|
bc243e1c07 | ||
|
|
679a58daf4 | ||
|
|
eff512deb8 | ||
|
|
562b402293 | ||
|
|
99ad4ae44c | ||
|
|
6e52a43584 | ||
|
|
d4c5d3e8c8 | ||
|
|
a6e46623ad | ||
|
|
9353c7838c | ||
|
|
816249b4b1 | ||
|
|
70292a5512 | ||
|
|
ecdbb4a49f | ||
|
|
536a5d99de | ||
|
|
ffc2015595 | ||
|
|
5e30a4b4ad | ||
|
|
b14da2844d | ||
|
|
d3c04b7246 | ||
|
|
307a995a50 | ||
|
|
46911593e5 | ||
|
|
1ac36c7b6b | ||
|
|
8e055df447 | ||
|
|
02ecd727eb | ||
|
|
adc8429bdc | ||
|
|
458d34d96c | ||
|
|
6a4fa0c9bf | ||
|
|
7fc9a655fc | ||
|
|
8d3babd015 | ||
|
|
75ed4c5dae | ||
|
|
58dfadb13c | ||
|
|
3d5f5f783c | ||
|
|
ecb7132843 | ||
|
|
980eb8a518 | ||
|
|
a11e89c0e1 | ||
|
|
3efe5268ae | ||
|
|
3f43a8fbaf | ||
|
|
cccf149568 | ||
|
|
604ea49567 | ||
|
|
4c0c6dfde6 | ||
|
|
a160bb8f02 | ||
|
|
e86946b104 | ||
|
|
03108b981e | ||
|
|
ae27e245b4 | ||
|
|
897f354202 | ||
|
|
4745052f0e | ||
|
|
5bc5d6504e | ||
|
|
7a0b85bf41 | ||
|
|
534afb3278 | ||
|
|
7d71af353e | ||
|
|
af6098bfe5 | ||
|
|
fce29bb36f | ||
|
|
4517af39ba | ||
|
|
b40163ce05 | ||
|
|
809902efec | ||
|
|
70be9894fa | ||
|
|
698ad5bac9 | ||
|
|
cd37b7533d | ||
|
|
c0cd6a1c8d | ||
|
|
f6245d1093 | ||
|
|
83c784f7c0 | ||
|
|
3d95b1a33b | ||
|
|
5c96942922 | ||
|
|
d27c83b382 | ||
|
|
b2f88965a9 | ||
|
|
95db44e0fc | ||
|
|
7d45ff5ca8 | ||
|
|
8964cf86aa | ||
|
|
0e9f23ed56 | ||
|
|
e08e597655 | ||
|
|
744db49803 | ||
|
|
54f59e02fd | ||
|
|
7950e5c083 | ||
|
|
dd33205bf6 | ||
|
|
397a20b9ec | ||
|
|
0aac0b43aa | ||
|
|
702500794d | ||
|
|
8bea95fab2 | ||
|
|
27094c87f2 | ||
|
|
bede9171c3 | ||
|
|
251d7c0bc2 | ||
|
|
285e4f28f5 | ||
|
|
3aa045303a | ||
|
|
e0a7c3794e | ||
|
|
f5fc5da341 | ||
|
|
bea5c0484b | ||
|
|
27960532ca |
5
.env
@@ -1,5 +1,2 @@
|
||||
REACT_APP_CHAIN_ID="1"
|
||||
REACT_APP_NETWORK_URL="https://mainnet.infura.io/v3/4bf032f2d38a4ed6bb975b80d6340847"
|
||||
REACT_APP_INFURA_KEY="4bf032f2d38a4ed6bb975b80d6340847"
|
||||
REACT_APP_WALLETCONNECT_BRIDGE_URL="https://uniswap.bridge.walletconnect.org"
|
||||
# Because we use storybook which has its own babel-loader dependency @ 8.2.2, where react-scripts uses 8.1.0
|
||||
SKIP_PREFLIGHT_CHECK=true
|
||||
@@ -1,5 +1,4 @@
|
||||
REACT_APP_CHAIN_ID="1"
|
||||
REACT_APP_NETWORK_URL="https://mainnet.infura.io/v3/099fc58e0de9451d80b18d7c74caa7c1"
|
||||
REACT_APP_INFURA_KEY="099fc58e0de9451d80b18d7c74caa7c1"
|
||||
REACT_APP_PORTIS_ID="c0e2bf01-4b08-4fd5-ac7b-8e26b58cd236"
|
||||
REACT_APP_FORTMATIC_KEY="pk_live_F937DF033A1666BF"
|
||||
REACT_APP_GOOGLE_ANALYTICS_ID="UA-128182339-4"
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"@typescript-eslint/ban-ts-comment": "off",
|
||||
"@typescript-eslint/ban-ts-ignore": "off",
|
||||
"@typescript-eslint/explicit-module-boundary-types": "off"
|
||||
"@typescript-eslint/explicit-module-boundary-types": "off",
|
||||
"react/react-in-jsx-scope": "off"
|
||||
}
|
||||
}
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,4 +1,4 @@
|
||||
blank_issues_enabled: false
|
||||
blank_issues_enabled: true
|
||||
contact_links:
|
||||
- name: Support
|
||||
url: https://discord.gg/FCfyBSbCU5
|
||||
|
||||
17
.github/workflows/check-pr-title.yaml
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
name: "Check PR Title"
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types:
|
||||
- opened
|
||||
- edited
|
||||
- synchronize
|
||||
|
||||
jobs:
|
||||
check-pr-title:
|
||||
name: Check PR Title
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: amannn/action-semantic-pull-request@v3.4.0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
57
.github/workflows/crowdin-sync.yaml
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
name: Crowdin Download
|
||||
|
||||
# hourly we sync translations from Crowdin
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 * * * *' # every hour we download translations and update the pr from crowdin
|
||||
|
||||
# manual trigger
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
download-translations:
|
||||
name: Download translations
|
||||
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: Extract translations
|
||||
run: "yarn i18n:extract"
|
||||
|
||||
- name: Synchronize
|
||||
uses: crowdin/github-action@1.1.0
|
||||
with:
|
||||
upload_sources: false
|
||||
download_translations: true
|
||||
project_id: 458284
|
||||
token: ${{ secrets.CROWDIN_PERSONAL_TOKEN_SECRET }}
|
||||
source: 'src/locales/en-US.po'
|
||||
translation: 'src/locales/%locale%.po'
|
||||
create_pull_request: false
|
||||
localization_branch_name: main
|
||||
commit_message: "chore(i18n): synchronize translations from crowdin [skip ci]"
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
52
.github/workflows/crowdin.yaml
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
name: Crowdin Upload
|
||||
|
||||
# on any push to main, we upload the translations to be translated
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
synchronize-with-crowdin:
|
||||
name: Upload sources to Crowdin
|
||||
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: Extract translations
|
||||
run: "yarn i18n:extract"
|
||||
|
||||
- name: Synchronize
|
||||
uses: crowdin/github-action@1.1.0
|
||||
with:
|
||||
upload_sources: true
|
||||
download_translations: false
|
||||
project_id: 458284
|
||||
token: ${{ secrets.CROWDIN_PERSONAL_TOKEN_SECRET }}
|
||||
source: 'src/locales/en-US.po'
|
||||
translation: 'src/locales/%locale%.po'
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
13
.github/workflows/integration-tests.yaml
vendored
@@ -22,6 +22,18 @@ jobs:
|
||||
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
|
||||
|
||||
@@ -34,5 +46,6 @@ jobs:
|
||||
- run: yarn integration-test
|
||||
env:
|
||||
CYPRESS_INTEGRATION_TEST_PRIVATE_KEY: ${{ secrets.CYPRESS_INTEGRATION_TEST_PRIVATE_KEY }}
|
||||
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
|
||||
|
||||
|
||||
|
||||
12
.github/workflows/lint.yml
vendored
@@ -23,6 +23,18 @@ jobs:
|
||||
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
|
||||
|
||||
|
||||
16
.github/workflows/release.yaml
vendored
@@ -19,7 +19,7 @@ jobs:
|
||||
|
||||
- name: Bump version and push tag
|
||||
id: github_tag_action
|
||||
uses: mathieudutour/github-tag-action@v4.5
|
||||
uses: mathieudutour/github-tag-action@331898d5052eedac9b15fec867b5ba66ebf9b692
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
release_branches: .*
|
||||
@@ -94,19 +94,13 @@ jobs:
|
||||
The latest release is always accessible via our alias to the Cloudflare IPFS gateway at [app.uniswap.org](https://app.uniswap.org).
|
||||
|
||||
You can also access the Uniswap Interface directly from an IPFS gateway.
|
||||
The Uniswap interface uses [`localStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) to store your settings.
|
||||
**Beware** that other sites you access via the _same_ IPFS gateway can read and modify your settings on the Uniswap interface without your permission.
|
||||
You can avoid this issue by using a subdomain IPFS gateway, or our alias to the latest release at [app.uniswap.org](https://app.uniswap.org).
|
||||
The preferred URLs below are safe to use to access this specific release.
|
||||
**BEWARE**: The Uniswap interface uses [`localStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) to remember your settings, such as which tokens you have imported.
|
||||
**You should always use an IPFS gateway that enforces origin separation**, or our alias to the latest release at [app.uniswap.org](https://app.uniswap.org).
|
||||
Your Uniswap settings are never remembered across different URLs.
|
||||
|
||||
Preferred URLs:
|
||||
IPFS gateways:
|
||||
- https://${{ steps.convert_cidv0.outputs.cidv1 }}.ipfs.dweb.link/
|
||||
- https://${{ steps.convert_cidv0.outputs.cidv1 }}.ipfs.cf-ipfs.com/
|
||||
- [ipfs://${{ steps.upload.outputs.hash }}/](ipfs://${{ steps.upload.outputs.hash }}/)
|
||||
|
||||
Other IPFS gateways:
|
||||
- https://cloudflare-ipfs.com/ipfs/${{ steps.upload.outputs.hash }}/
|
||||
- https://ipfs.infura.io/ipfs/${{ steps.upload.outputs.hash }}/
|
||||
- https://ipfs.io/ipfs/${{ steps.upload.outputs.hash }}/
|
||||
|
||||
${{ needs.bump_version.outputs.changelog }}
|
||||
|
||||
12
.github/workflows/unit-tests.yaml
vendored
@@ -21,6 +21,18 @@ jobs:
|
||||
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
|
||||
|
||||
|
||||
7
.gitignore
vendored
@@ -3,6 +3,11 @@
|
||||
# generated contract types
|
||||
/src/types/v3
|
||||
/src/abis/types
|
||||
/src/locales/**/*.js
|
||||
/src/locales/**/*.ts
|
||||
/src/locales/**/*.json
|
||||
/src/locales/**/en-US.po
|
||||
/src/state/data/generated.ts
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
@@ -35,4 +40,4 @@ package-lock.json
|
||||
|
||||
cypress/videos
|
||||
cypress/screenshots
|
||||
cypress/fixtures/example.json
|
||||
cypress/fixtures/example.json
|
||||
|
||||
1
.prettierignore
Normal file
@@ -0,0 +1 @@
|
||||
/src/state/data/generated.ts
|
||||
@@ -1,16 +0,0 @@
|
||||
const { dirname, join, parse, resolve } = require('path')
|
||||
const { existsSync } = require('fs')
|
||||
|
||||
module.exports = {
|
||||
stories: ['../src/**/*.stories.@(ts|tsx)'],
|
||||
addons: ['@storybook/addon-links', '@storybook/addon-essentials', '@storybook/preset-create-react-app'],
|
||||
typescript: {
|
||||
check: true,
|
||||
checkOptions: {},
|
||||
reactDocgen: 'react-docgen-typescript',
|
||||
reactDocgenTypescriptOptions: {
|
||||
shouldExtractLiteralValuesFromEnum: true,
|
||||
propFilter: (prop) => (prop.parent ? !/node_modules/.test(prop.parent.fileName) : true),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
import { addons } from '@storybook/addons'
|
||||
import { light } from './theme'
|
||||
|
||||
addons.setConfig({ theme: light })
|
||||
@@ -1,91 +0,0 @@
|
||||
import 'inter-ui'
|
||||
import { Story } from '@storybook/react/types-6-0'
|
||||
import { createWeb3ReactRoot, Web3ReactProvider } from '@web3-react/core'
|
||||
import React from 'react'
|
||||
import { Provider as StoreProvider } from 'react-redux'
|
||||
import { ThemeProvider as SCThemeProvider } from 'styled-components'
|
||||
import { NetworkContextName } from '../src/constants'
|
||||
import store from '../src/state'
|
||||
import { FixedGlobalStyle, theme, ThemedGlobalStyle } from '../src/theme'
|
||||
import getLibrary from '../src/utils/getLibrary'
|
||||
import * as storybookThemes from './theme'
|
||||
|
||||
export const parameters = {
|
||||
actions: { argTypesRegex: '^on[A-Z].*' },
|
||||
dependencies: {
|
||||
withStoriesOnly: true,
|
||||
hideEmpty: true,
|
||||
},
|
||||
docs: {
|
||||
theme: storybookThemes.light,
|
||||
},
|
||||
viewport: {
|
||||
viewports: {
|
||||
mobile: {
|
||||
name: 'iPhone X',
|
||||
styles: {
|
||||
width: '375px',
|
||||
height: '812px',
|
||||
},
|
||||
},
|
||||
tablet: {
|
||||
name: 'iPad',
|
||||
styles: {
|
||||
width: '768px',
|
||||
height: '1024px',
|
||||
},
|
||||
},
|
||||
laptop: {
|
||||
name: 'Laptop',
|
||||
styles: {
|
||||
width: '1024px',
|
||||
height: '768px',
|
||||
},
|
||||
},
|
||||
desktop: {
|
||||
name: 'Desktop',
|
||||
styles: {
|
||||
width: '1440px',
|
||||
height: '1024px',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
export const globalTypes = {
|
||||
theme: {
|
||||
name: 'Theme',
|
||||
description: 'Global theme for components',
|
||||
defaultValue: 'light',
|
||||
toolbar: {
|
||||
icon: 'circlehollow',
|
||||
items: ['light', 'dark'],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
const Web3ProviderNetwork = createWeb3ReactRoot(NetworkContextName)
|
||||
|
||||
const withProviders = (Component: Story, context: Record<string, any>) => {
|
||||
const THEME = theme(context.globals.theme === 'dark')
|
||||
return (
|
||||
<>
|
||||
<Web3ReactProvider getLibrary={getLibrary}>
|
||||
<Web3ProviderNetwork getLibrary={getLibrary}>
|
||||
<StoreProvider store={store}>
|
||||
<SCThemeProvider theme={THEME}>
|
||||
<FixedGlobalStyle />
|
||||
<ThemedGlobalStyle />
|
||||
<main>
|
||||
<Component />
|
||||
</main>
|
||||
</SCThemeProvider>
|
||||
</StoreProvider>
|
||||
</Web3ProviderNetwork>
|
||||
</Web3ReactProvider>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export const decorators = [withProviders]
|
||||
@@ -1,17 +0,0 @@
|
||||
import { create } from '@storybook/theming'
|
||||
|
||||
// this themes the storybook UI
|
||||
const uniswapBaseTheme = {
|
||||
brandTitle: 'Uniswap Design',
|
||||
brandUrl: 'https://uniswap.org',
|
||||
brandImage: 'https://ipfs.io/ipfs/QmNa8mQkrNKp1WEEeGjFezDmDeodkWRevGFN8JCV7b4Xir',
|
||||
}
|
||||
export const light = create({
|
||||
base: 'light',
|
||||
...uniswapBaseTheme,
|
||||
})
|
||||
|
||||
// export const dark = create({
|
||||
// base: 'dark',
|
||||
// ...uniswapBaseTheme,
|
||||
// })
|
||||
47
CONTRIBUTING.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# Development
|
||||
|
||||
## Install Dependencies
|
||||
|
||||
```bash
|
||||
yarn install
|
||||
```
|
||||
|
||||
## Generate locale files
|
||||
|
||||
```
|
||||
yarn i18n:extract
|
||||
```
|
||||
|
||||
## Run the interface
|
||||
|
||||
```bash
|
||||
yarn start
|
||||
```
|
||||
|
||||
# Contributing
|
||||
|
||||
Thank you for your interest in contributing to the Uniswap interface! 🦄
|
||||
|
||||
## Finding a first issue
|
||||
|
||||
Start with issues with the label
|
||||
[`good first issue`](https://github.com/Uniswap/uniswap-interface/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22).
|
||||
|
||||
## Pull requests
|
||||
|
||||
**Please open all pull requests against the `main` branch.**
|
||||
CI checks will run against all PRs.
|
||||
|
||||
# Translations
|
||||
|
||||
Help Uniswap reach a global audience!
|
||||
|
||||
Uniswap uses [Crowdin](https://crowdin.com/project/uniswap-interface)
|
||||
for managing translations. Whenever a new string is added to the project,
|
||||
it gets uploaded to Crowdin for translation by [this workflow](./.github/workflows/crowdin.yaml).
|
||||
|
||||
Every hour, translations are synced from Crowdin in [this other workflow](./.github/workflows/crowdin-sync.yaml).
|
||||
|
||||
You can contribute by joining Crowdin to proofread existing translations [here](https://crowdin.com/project/uniswap-interface/invite?d=93i5n413q403t4g473p443o4c3t2g3s21343u2c3n403l4b3v2735353i4g4k4l4g453j4g4o4j4e4k4b323l4a3h463s4g453q443m4e3t2b303s2a35353l403o443v293e303k4g4n4r4g483i4g4r4j4e4o473i5n4a3t463t4o4)
|
||||
|
||||
Or, ask to join us as a translator in the Discord!
|
||||
59
README.md
@@ -4,17 +4,21 @@
|
||||
[](https://github.com/Uniswap/uniswap-interface/actions/workflows/integration-tests.yaml)
|
||||
[](https://github.com/Uniswap/uniswap-interface/actions/workflows/lint.yml)
|
||||
[](https://github.com/Uniswap/uniswap-interface/actions/workflows/release.yaml)
|
||||
[](https://crowdin.com/project/uniswap-interface)
|
||||
|
||||
An open source interface for Uniswap -- a protocol for decentralized exchange of Ethereum tokens.
|
||||
|
||||
- Website: [uniswap.org](https://uniswap.org/)
|
||||
- Interface: [app.uniswap.org](https://app.uniswap.org)
|
||||
- Docs: [uniswap.org/docs/](https://uniswap.org/docs/)
|
||||
- Twitter: [@UniswapProtocol](https://twitter.com/UniswapProtocol)
|
||||
- Twitter: [@Uniswap](https://twitter.com/Uniswap)
|
||||
- Reddit: [/r/Uniswap](https://www.reddit.com/r/Uniswap/)
|
||||
- Email: [contact@uniswap.org](mailto:contact@uniswap.org)
|
||||
- Discord: [Uniswap](https://discord.gg/FCfyBSbCU5)
|
||||
- Whitepaper: [Link](https://hackmd.io/C-DvwDSfSxuh-Gd4WKE_ig)
|
||||
- Whitepapers:
|
||||
- [V1](https://hackmd.io/C-DvwDSfSxuh-Gd4WKE_ig)
|
||||
- [V2](https://uniswap.org/whitepaper.pdf)
|
||||
- [V3](https://uniswap.org/whitepaper-v3.pdf)
|
||||
|
||||
## Accessing the Uniswap Interface
|
||||
|
||||
@@ -22,46 +26,21 @@ To access the Uniswap Interface, use an IPFS gateway link from the
|
||||
[latest release](https://github.com/Uniswap/uniswap-interface/releases/latest),
|
||||
or visit [app.uniswap.org](https://app.uniswap.org).
|
||||
|
||||
## Listing a token
|
||||
|
||||
Please see the
|
||||
[@uniswap/default-token-list](https://github.com/uniswap/default-token-list)
|
||||
repository.
|
||||
|
||||
## Development
|
||||
|
||||
### Install Dependencies
|
||||
|
||||
```bash
|
||||
yarn
|
||||
```
|
||||
|
||||
### Run
|
||||
|
||||
```bash
|
||||
yarn start
|
||||
```
|
||||
|
||||
### Configuring the environment (optional)
|
||||
|
||||
To have the interface default to a different network when a wallet is not connected:
|
||||
|
||||
1. Make a copy of `.env` named `.env.local`
|
||||
2. Change `REACT_APP_NETWORK_ID` to `"{YOUR_NETWORK_ID}"`
|
||||
3. Change `REACT_APP_NETWORK_URL` to e.g. `"https://{YOUR_NETWORK_ID}.infura.io/v3/{YOUR_INFURA_KEY}"`
|
||||
|
||||
Note that the interface only works on testnets where both
|
||||
[Uniswap V2](https://uniswap.org/docs/v2/smart-contracts/factory/) and
|
||||
[multicall](https://github.com/makerdao/multicall) are deployed.
|
||||
The interface will not work on other networks.
|
||||
|
||||
## Contributions
|
||||
|
||||
**Please open all pull requests against the `main` branch.**
|
||||
CI checks will run against all PRs.
|
||||
For steps on local deployment, development, and code contribution, please see [CONTRIBUTING](./CONTRIBUTING.md).
|
||||
|
||||
## Accessing Uniswap Interface V1
|
||||
## Accessing Uniswap V2
|
||||
|
||||
The Uniswap Interface supports swapping against, and migrating or removing liquidity from Uniswap V1. However,
|
||||
if you would like to use Uniswap V1, the Uniswap V1 interface for mainnet and testnets is accessible via IPFS gateways
|
||||
The Uniswap Interface supports swapping, adding liquidity, removing liquidity and migrating liquidity for
|
||||
Uniswap protocol V2.
|
||||
|
||||
- Swap on Uniswap V2: https://app.uniswap.org/#/swap?use=v2
|
||||
- View V2 liquidity: https://app.uniswap.org/#/pool/v2
|
||||
- Add V2 liquidity: https://app.uniswap.org/#/add/v2
|
||||
- Migrate V2 liquidity to V3: https://app.uniswap.org/#/migrate/v2
|
||||
|
||||
## Accessing Uniswap V1
|
||||
|
||||
The Uniswap V1 interface for mainnet and testnets is accessible via IPFS gateways
|
||||
linked from the [v1.0.0 release](https://github.com/Uniswap/uniswap-interface/releases/tag/v1.0.0).
|
||||
|
||||
8
babel-plugin-macros.config.js
Normal file
@@ -0,0 +1,8 @@
|
||||
const isDev = process.env.NODE_ENV !== 'production'
|
||||
|
||||
module.exports = {
|
||||
styledComponents: {
|
||||
fileName: isDev,
|
||||
displayName: isDev,
|
||||
},
|
||||
}
|
||||
10
codegen.yml
Normal file
@@ -0,0 +1,10 @@
|
||||
schema: 'https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v3'
|
||||
documents: 'src/**/!(*.d).{ts,tsx}'
|
||||
generates:
|
||||
./src/state/data/generated.ts:
|
||||
plugins:
|
||||
- typescript
|
||||
- typescript-operations
|
||||
- typescript-rtk-query:
|
||||
importBaseApiFrom: './slice'
|
||||
exportHooks: true
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"projectId": "yp82ef",
|
||||
"baseUrl": "http://localhost:3000",
|
||||
"pluginsFile": false,
|
||||
"fixturesFolder": false,
|
||||
|
||||
@@ -4,6 +4,7 @@ describe('Landing Page', () => {
|
||||
beforeEach(() => cy.visit('/'))
|
||||
it('loads swap page', () => {
|
||||
cy.get('#swap-page')
|
||||
cy.screenshot()
|
||||
})
|
||||
|
||||
it('redirects to url /swap', () => {
|
||||
|
||||
@@ -8,7 +8,9 @@ import { JsonRpcProvider } from '@ethersproject/providers'
|
||||
import { Wallet } from '@ethersproject/wallet'
|
||||
import { Eip1193Bridge } from '@ethersproject/experimental/lib/eip1193-bridge'
|
||||
|
||||
const TEST_PRIVATE_KEY = Cypress.env('INTEGRATION_TEST_PRIVATE_KEY')
|
||||
// todo: figure out how env vars actually work in CI
|
||||
// const TEST_PRIVATE_KEY = Cypress.env('INTEGRATION_TEST_PRIVATE_KEY')
|
||||
const TEST_PRIVATE_KEY = '0xe580410d7c37d26c6ad1a837bbae46bc27f9066a466fb3a66e770523b4666d19'
|
||||
|
||||
// address of the above key
|
||||
export const TEST_ADDRESS_NEVER_USE = new Wallet(TEST_PRIVATE_KEY).address
|
||||
|
||||
53
lingui.config.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
export default {
|
||||
catalogs: [
|
||||
{
|
||||
path: '<rootDir>/src/locales/{locale}',
|
||||
include: ['<rootDir>/src'],
|
||||
},
|
||||
],
|
||||
compileNamespace: 'cjs',
|
||||
fallbackLocales: {
|
||||
default: 'en-US',
|
||||
},
|
||||
format: 'po',
|
||||
formatOptions: {
|
||||
lineNumbers: false,
|
||||
},
|
||||
locales: [
|
||||
'af-ZA',
|
||||
'ar-SA',
|
||||
'ca-ES',
|
||||
'cs-CZ',
|
||||
'da-DK',
|
||||
'de-DE',
|
||||
'el-GR',
|
||||
'en-US',
|
||||
'es-ES',
|
||||
'fi-FI',
|
||||
'fr-FR',
|
||||
'he-IL',
|
||||
'hu-HU',
|
||||
'id-ID',
|
||||
'it-IT',
|
||||
'ja-JP',
|
||||
'ko-KR',
|
||||
'nl-NL',
|
||||
'no-NO',
|
||||
'pl-PL',
|
||||
'pt-BR',
|
||||
'pt-PT',
|
||||
'ro-RO',
|
||||
'ru-RU',
|
||||
'sr-SP',
|
||||
'sv-SE',
|
||||
'tr-TR',
|
||||
'uk-UA',
|
||||
'vi-VN',
|
||||
'zh-CN',
|
||||
'zh-TW',
|
||||
],
|
||||
orderBy: 'messageId',
|
||||
rootDir: '.',
|
||||
runtimeConfigModule: ['@lingui/core', 'i18n'],
|
||||
sourceLocale: 'en-US',
|
||||
}
|
||||
65
package.json
@@ -4,24 +4,27 @@
|
||||
"homepage": ".",
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"@emotion/core": "^11.0.0",
|
||||
"@ethersproject/experimental": "^5.0.1",
|
||||
"@ethersproject/experimental": "^5.2.0",
|
||||
"@graphql-codegen/cli": "1.21.5",
|
||||
"@graphql-codegen/typescript": "1.22.3",
|
||||
"@graphql-codegen/typescript-operations": "^1.18.2",
|
||||
"@graphql-codegen/typescript-rtk-query": "^1.1.1",
|
||||
"@lingui/cli": "^3.9.0",
|
||||
"@lingui/loader": "^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",
|
||||
"@reduxjs/toolkit": "^1.3.5",
|
||||
"@storybook/addon-actions": "^6.1.17",
|
||||
"@storybook/addon-essentials": "^6.1.17",
|
||||
"@storybook/addon-links": "^6.1.17",
|
||||
"@storybook/addons": "^6.1.17",
|
||||
"@storybook/components": "^6.1.17",
|
||||
"@storybook/preset-create-react-app": "^3.1.5",
|
||||
"@storybook/preset-typescript": "^3.0.0",
|
||||
"@storybook/react": "^6.1.17",
|
||||
"@storybook/theming": "^6.1.17",
|
||||
"@styled-system/css": "^5.1.5",
|
||||
"@react-hook/window-scroll": "^1.3.0",
|
||||
"@reduxjs/toolkit": "^1.6.0",
|
||||
"@rtk-query/graphql-request-base-query": "^1.0.3",
|
||||
"@typechain/ethers-v5": "^7.0.0",
|
||||
"@types/jest": "^25.2.1",
|
||||
"@types/lingui__core": "^2.7.1",
|
||||
"@types/lingui__macro": "^2.7.4",
|
||||
"@types/lingui__react": "^2.8.3",
|
||||
"@types/lodash.flatmap": "^4.5.6",
|
||||
"@types/luxon": "^1.24.4",
|
||||
"@types/multicodec": "^1.0.0",
|
||||
@@ -47,16 +50,16 @@
|
||||
"@uniswap/token-lists": "^1.0.0-beta.19",
|
||||
"@uniswap/v2-core": "1.0.0",
|
||||
"@uniswap/v2-periphery": "^1.1.0-beta.0",
|
||||
"@uniswap/v2-sdk": "^1.0.9",
|
||||
"@uniswap/v2-sdk": "^3.0.0-alpha.2",
|
||||
"@uniswap/v3-core": "1.0.0",
|
||||
"@uniswap/v3-periphery": "1.0.0",
|
||||
"@uniswap/v3-sdk": "^1.0.8",
|
||||
"@uniswap/v3-sdk": "^3.0.0-alpha.9",
|
||||
"@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": "^6.1.1",
|
||||
"@web3-react/walletlink-connector": "^6.0.9",
|
||||
"@web3-react/walletconnect-connector": "^6.2.0",
|
||||
"@web3-react/walletlink-connector": "^6.2.0",
|
||||
"ajv": "^6.12.3",
|
||||
"cids": "^1.0.0",
|
||||
"copy-to-clipboard": "^3.2.0",
|
||||
@@ -67,12 +70,10 @@
|
||||
"eslint-plugin-prettier": "^3.1.3",
|
||||
"eslint-plugin-react": "^7.19.0",
|
||||
"eslint-plugin-react-hooks": "^4.0.0",
|
||||
"ethers": "^5.0.7",
|
||||
"i18next": "^15.0.9",
|
||||
"i18next-browser-languagedetector": "^3.0.1",
|
||||
"i18next-xhr-backend": "^2.0.1",
|
||||
"ethers": "^5.2.0",
|
||||
"graphql": "^15.5.0",
|
||||
"graphql-request": "^3.4.0",
|
||||
"inter-ui": "^3.13.1",
|
||||
"jazzicon": "^1.5.0",
|
||||
"lightweight-charts": "^3.3.0",
|
||||
"lodash.flatmap": "^4.5.0",
|
||||
"luxon": "^1.25.0",
|
||||
@@ -88,7 +89,6 @@
|
||||
"react-dom": "^17.0.1",
|
||||
"react-feather": "^2.0.8",
|
||||
"react-ga": "^2.5.7",
|
||||
"react-i18next": "^10.7.0",
|
||||
"react-markdown": "^4.3.1",
|
||||
"react-popper": "^2.2.3",
|
||||
"react-redux": "^7.2.2",
|
||||
@@ -99,6 +99,7 @@
|
||||
"react-virtualized-auto-sizer": "^1.0.2",
|
||||
"react-window": "^1.8.5",
|
||||
"rebass": "^4.0.7",
|
||||
"redux-devtools-extension": "^2.13.9",
|
||||
"redux-localstorage-simple": "^2.3.1",
|
||||
"serve": "^11.3.2",
|
||||
"start-server-and-test": "^1.11.0",
|
||||
@@ -115,16 +116,22 @@
|
||||
"workbox-routing": "^6.1.0",
|
||||
"workbox-strategies": "^6.1.0"
|
||||
},
|
||||
"resolutions": {
|
||||
"@walletconnect/web3-provider": "1.4.2-rc.2"
|
||||
},
|
||||
"scripts": {
|
||||
"compile-contract-types": "yarn compile-external-abi-types && yarn compile-v3-contract-types",
|
||||
"compile-external-abi-types": "npx typechain --target ethers-v5 --out-dir src/abis/types './src/abis/**/*.json'",
|
||||
"compile-v3-contract-types": "npx typechain --target ethers-v5 --out-dir src/types/v3 './node_modules/@uniswap/?(v3-core|v3-periphery)/artifacts/contracts/**/*.json'",
|
||||
"build": "yarn compile-contract-types && react-scripts build",
|
||||
"integration-test": "start-server-and-test 'serve build -l 3000' http://localhost:3000 'cypress run'",
|
||||
"compile-external-abi-types": "typechain --target ethers-v5 --out-dir src/abis/types './src/abis/**/*.json'",
|
||||
"compile-v3-contract-types": "typechain --target ethers-v5 --out-dir src/types/v3 './node_modules/@uniswap/?(v3-core|v3-periphery)/artifacts/contracts/**/*.json'",
|
||||
"build": "yarn compile-contract-types && yarn graphql:generate && yarn i18n:extract && yarn i18n:compile && react-scripts build",
|
||||
"i18n:extract": "lingui extract --locale en-US",
|
||||
"i18n:compile": "lingui compile",
|
||||
"integration-test": "start-server-and-test 'serve build -l 3000' http://localhost:3000 'cypress run --record'",
|
||||
"graphql:generate": "graphql-codegen --config codegen.yml",
|
||||
"postinstall": "yarn compile-contract-types",
|
||||
"start": "yarn compile-contract-types && react-scripts start",
|
||||
"storybook": "start-storybook -p 6006",
|
||||
"test": "react-scripts test --env=jsdom"
|
||||
"test": "react-scripts test --env=jsdom",
|
||||
"prestart": "yarn graphql:generate && touch src/locales/en-US.po"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": "react-app",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<html translate="no">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="shortcut icon" type="image/png" href="%PUBLIC_URL%/favicon.png" />
|
||||
@@ -24,11 +24,79 @@
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
|
||||
<style>
|
||||
* {
|
||||
font-family: 'Inter', sans-serif;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
@supports (font-variation-settings: normal) {
|
||||
* {
|
||||
font-family: 'Inter var', sans-serif;
|
||||
}
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
button {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
html {
|
||||
font-size: 16px;
|
||||
font-variant: none;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
font-feature-settings: 'ss01' on, 'ss02' on, 'cv01' on, 'cv03' on;
|
||||
}
|
||||
|
||||
#background-radial-gradient {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
pointer-events: none;
|
||||
width: 200vw;
|
||||
height: 200vh;
|
||||
background: radial-gradient(50% 50% at 50% 50%, #fc077d10 0%, rgba(255, 255, 255, 0) 100%);
|
||||
transform: translate(-50vw, -100vh);
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
html {
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
html {
|
||||
background-color: #212429;
|
||||
}
|
||||
}
|
||||
@media (prefers-color-scheme: light) {
|
||||
html {
|
||||
background-color: #F7F8FA;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<title>Uniswap Interface</title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
|
||||
<!-- The root is the container of the app -->
|
||||
<div id="root">
|
||||
<!-- Triggers the font to load immediately and then is replaced by the app -->
|
||||
<div style="visibility: hidden">X</div>
|
||||
</div>
|
||||
|
||||
<div id="background-radial-gradient"></div>
|
||||
|
||||
<!--
|
||||
This HTML file is a template.
|
||||
If you open it directly in the browser, you will see an empty page.
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
{
|
||||
"noWallet": "Keine Ethereum-Wallet gefunden",
|
||||
"wrongNetwork": "Du bist auf dem falschen Netzwerk.",
|
||||
"switchNetwork": "Bitte wechsle zum {{ correctNetwork }}",
|
||||
"installWeb3MobileBrowser": "Bitte besuche uns mit einem web3-fähigen mobilen Browser wie z.B. Trust Wallet oder Coinbase Wallet.",
|
||||
"installMetamask": "Bitte besuch uns erneut, nachdem du Metamask oder Brave installiert hast.",
|
||||
"disconnected": "Nicht verbunden",
|
||||
"swap": "Tauschen",
|
||||
"swapAnyway": "Trotzdem tauschen",
|
||||
"send": "Senden",
|
||||
"sendAnyway": "Trotzdem senden",
|
||||
"pool": "Pool",
|
||||
"betaWarning": "Dieses Projekt ist in beta. Nutzung auf eigenes Risiko.",
|
||||
"input": "Input",
|
||||
"output": "Output",
|
||||
"estimated": "geschätzt",
|
||||
"balance": "Guthaben: {{ balanceInput }}",
|
||||
"unlock": "Freischalten",
|
||||
"pending": "hängige",
|
||||
"selectToken": "Token auswählen",
|
||||
"searchOrPaste": "Token Name, Symbol oder Adresse suchen",
|
||||
"searchOrPasteMobile": "Name, Symbol oder Adresse",
|
||||
"noExchange": "Exchange nicht gefunden",
|
||||
"exchangeRate": "Wechselkurs",
|
||||
"invertedRate": "Invertierter Wechselkurs",
|
||||
"unknownError": "Oops! Ein unbekannter Fehler ist aufgetreten. Bitte Seite neu laden oder uns von einem anderen Browser oder Gerät erneut besuchen.",
|
||||
"enterValueCont": "Wert {{ missingCurrencyValue }} eingeben um fortzufahren.",
|
||||
"selectTokenCont": "Token auswählen um fortzufahren.",
|
||||
"noLiquidity": "Keine Liquidität.",
|
||||
"insufficientLiquidity": "Liquidität ungenügend.",
|
||||
"unlockTokenCont": "Token freischalten um fortzufahren.",
|
||||
"transactionDetails": "Details der Transaktion",
|
||||
"hideDetails": "Details ausblenden",
|
||||
"slippageWarning": "Wechselkursrutsch",
|
||||
"highSlippageWarning": "Hoher Wechselkursrutsch",
|
||||
"youAreSelling": "Du verkaufst",
|
||||
"orTransFail": "oder die Transaktion wird fehlschlagen.",
|
||||
"youWillReceive": "Du erhältst mindestens",
|
||||
"youAreBuying": "Du kaufst",
|
||||
"itWillCost": "Es kostet höchstens",
|
||||
"forAtMost": "für maximal",
|
||||
"insufficientBalance": "Guthaben ungenügend",
|
||||
"inputNotValid": "Eingabewert ungültig",
|
||||
"differentToken": "Es müssen unterschiedliche Token sein.",
|
||||
"noRecipient": "Empfängeradresse angeben.",
|
||||
"invalidRecipient": "Bitte gib eine gültige Empfängeradresse an.",
|
||||
"recipientAddress": "Adresse des Empfängers",
|
||||
"youAreSending": "Du schickst",
|
||||
"willReceive": "erhält mindestens",
|
||||
"to": "zu",
|
||||
"addLiquidity": "Liquidität hinzufügen",
|
||||
"deposit": "Depot",
|
||||
"currentPoolSize": "Aktuelle Größe des Pools",
|
||||
"yourPoolShare": "Dein Anteil am Pool",
|
||||
"noZero": "Wert darf nicht Null sein.",
|
||||
"mustBeETH": "Einer der Inputs muß ETH sein.",
|
||||
"enterCurrencyOrLabelCont": "{{ inputCurrency }} oder {{ label }} Wert eingeben um fortzufahren.",
|
||||
"youAreAdding": "Du fügst zwischen",
|
||||
"and": "und",
|
||||
"intoPool": "in den Liquiditätspool.",
|
||||
"outPool": "vom Liquiditätspool.",
|
||||
"youWillMint": "Du prägst",
|
||||
"liquidityTokens": "Liquiditätstokens.",
|
||||
"totalSupplyIs": "Die gesamte Anzahl Liquiditätstokens ist aktuell",
|
||||
"youAreSettingExRate": "Du setzt den anfänglichen Wechselkurs auf",
|
||||
"totalSupplyIs0": "Die gesamte Anzahl Liquiditätstokens ist aktuell 0.",
|
||||
"tokenWorth": "Zum gegenwärtigen Wechselkurs ist jeder Pool Token so viel Wert",
|
||||
"firstLiquidity": "Du bist die erste Person die Liquidität bereitstellt!",
|
||||
"initialExchangeRate": "Der initiale Wechselkurs wird auf deiner Überweisung basieren. Stelle sicher, dass deine ETH und {{ label }} denselben Fiatwert haben.",
|
||||
"removeLiquidity": "Liquidität entfernen",
|
||||
"poolTokens": "Pool Tokens",
|
||||
"enterLabelCont": "{{ label }} Wert eingeben um fortzufahren.",
|
||||
"youAreRemoving": "Du entfernst zwischen",
|
||||
"youWillRemove": "Du entfernst",
|
||||
"createExchange": "Exchange erstellen",
|
||||
"invalidTokenAddress": "Ungültige Tokenadresse",
|
||||
"exchangeExists": "{{ label }} Exchange existiert bereits!",
|
||||
"invalidSymbol": "Symbol ungültig",
|
||||
"invalidDecimals": "Dezimalstellen ungültig",
|
||||
"tokenAddress": "Tokenadresse",
|
||||
"label": "Label",
|
||||
"name": "Name",
|
||||
"symbol": "Symbol",
|
||||
"decimals": "Dezimalstellen",
|
||||
"enterTokenCont": "Tokenadresse eingeben um fortzufahren",
|
||||
"priceChange": "Geschätzter Wechselkursrutsch",
|
||||
"forAtLeast": "für mindestens ",
|
||||
"brokenToken": "Der ausgewählte Token ist nicht kompatibel mit Uniswap V1. Liquidität hinzufügen wird zu nicht mehr zugänglichen Token führen!"
|
||||
}
|
||||
@@ -1,116 +0,0 @@
|
||||
{
|
||||
"noWallet": "No Ethereum wallet found",
|
||||
"wrongNetwork": "You are on the wrong network",
|
||||
"switchNetwork": "Please switch to {{ correctNetwork }}",
|
||||
"installWeb3MobileBrowser": "Please visit us from a web3-enabled mobile browser such as Trust Wallet or Coinbase Wallet.",
|
||||
"installMetamask": "Please visit us after installing Metamask on Chrome or Brave.",
|
||||
"disconnected": "Disconnected",
|
||||
"swap": "Swap",
|
||||
"swapAnyway": "Swap Anyway",
|
||||
"send": "Send",
|
||||
"sendAnyway": "Send Anyway",
|
||||
"pool": "Pool",
|
||||
"betaWarning": "This project is in beta. Use at your own risk.",
|
||||
"input": "Input",
|
||||
"output": "Output",
|
||||
"estimated": "estimated",
|
||||
"balance": "Balance: {{ balanceInput }}",
|
||||
"unlock": "Unlock",
|
||||
"pending": "Pending",
|
||||
"selectToken": "Select a token",
|
||||
"searchOrPaste": "Search Token Name, Symbol, or Address",
|
||||
"searchOrPasteMobile": "Name, Symbol, or Address",
|
||||
"noExchange": "No Exchange Found",
|
||||
"noToken": "No Token Found",
|
||||
"exchangeRate": "Exchange Rate",
|
||||
"unknownError": "Oops! An unknown error occurred. Please refresh the page, or visit from another browser or device.",
|
||||
"enterValueCont": "Enter a {{ missingCurrencyValue }} value to continue.",
|
||||
"selectTokenCont": "Select a token to continue.",
|
||||
"noLiquidity": "No liquidity.",
|
||||
"insufficientLiquidity": "Insufficient liquidity.",
|
||||
"unlockTokenCont": "Please unlock token to continue.",
|
||||
"transactionDetails": "Advanced Details",
|
||||
"hideDetails": "Hide Details",
|
||||
"slippageWarning": "Slippage Warning",
|
||||
"highSlippageWarning": "High Slippage Warning",
|
||||
"youAreSelling": "You are selling",
|
||||
"orTransFail": "or the transaction will fail.",
|
||||
"youWillReceive": "You will receive at least",
|
||||
"youAreBuying": "You are buying",
|
||||
"itWillCost": "It will cost at most",
|
||||
"forAtMost": "for at most",
|
||||
"insufficientBalance": "Insufficient Balance",
|
||||
"inputNotValid": "Not a valid input value",
|
||||
"differentToken": "Must be different token.",
|
||||
"noRecipient": "Enter a wallet address to send to.",
|
||||
"invalidRecipient": "Please enter a valid wallet address recipient.",
|
||||
"recipientAddress": "Recipient Address",
|
||||
"youAreSending": "You are sending",
|
||||
"willReceive": "will receive at least",
|
||||
"to": "to",
|
||||
"addLiquidity": "Add Liquidity",
|
||||
"deposit": "Deposit",
|
||||
"currentPoolSize": "Current Pool Size",
|
||||
"yourPoolShare": "Your Pool Share",
|
||||
"noZero": "Amount cannot be zero.",
|
||||
"mustBeETH": "One of the input must be ETH.",
|
||||
"enterCurrencyOrLabelCont": "Enter a {{ inputCurrency }} or {{ label }} value to continue.",
|
||||
"youAreAdding": "You are adding",
|
||||
"and": "and",
|
||||
"intoPool": "into the liquidity pool.",
|
||||
"outPool": "from the liquidity pool.",
|
||||
"youWillMint": "You will mint",
|
||||
"liquidityTokens": "liquidity tokens.",
|
||||
"totalSupplyIs": "Current total supply of liquidity tokens is",
|
||||
"youAreSettingExRate": "You are setting the initial exchange rate to",
|
||||
"totalSupplyIs0": "Current total supply of liquidity tokens is 0.",
|
||||
"tokenWorth": "At current exchange rate, each pool token is worth",
|
||||
"firstLiquidity": "You are the first person to add liquidity!",
|
||||
"initialExchangeRate": "The initial exchange rate will be set based on your deposits. Please make sure that your ETH and {{ label }} deposits have the same fiat value.",
|
||||
"removeLiquidity": "Remove Liquidity",
|
||||
"poolTokens": "Pool Tokens",
|
||||
"enterLabelCont": "Enter a {{ label }} value to continue.",
|
||||
"youAreRemoving": "You are removing between",
|
||||
"youWillRemove": "You will remove",
|
||||
"createExchange": "Create Exchange",
|
||||
"invalidTokenAddress": "Not a valid token address",
|
||||
"exchangeExists": "{{ label }} Exchange already exists!",
|
||||
"invalidSymbol": "Invalid symbol",
|
||||
"invalidDecimals": "Invalid decimals",
|
||||
"tokenAddress": "Token Address",
|
||||
"label": "Label",
|
||||
"name": "Name",
|
||||
"symbol": "Symbol",
|
||||
"decimals": "Decimals",
|
||||
"enterTokenCont": "Enter a token address to continue",
|
||||
"priceChange": "Expected price slippage",
|
||||
"forAtLeast": "for at least ",
|
||||
"brokenToken": "The selected token is not compatible with Uniswap V1. Adding liquidity will result in locked funds.",
|
||||
"toleranceExplanation": "Lowering this limit decreases your risk of frontrunning. However, this makes more likely that your transaction will fail due to normal price movements.",
|
||||
"tokenSearchPlaceholder": "Search name or paste address",
|
||||
"selectFee": "Select Fee",
|
||||
"selectLiquidityRange": "Set Price Range",
|
||||
"selectPool": "Select Fee Tier",
|
||||
"depositAmounts": "Deposit Amounts",
|
||||
"fee": "fee",
|
||||
"setLimits": "Set Limits",
|
||||
"percent": "Percent",
|
||||
"rate": "Rate",
|
||||
"currentRate": "Current {{label}} Price:",
|
||||
"inactiveRangeWarning": "Your position will not earn fees or be used in trades until the market price moves into your range.",
|
||||
"invalidRangeWarning": "Invalid range selected. The min price must be lower than the max price.",
|
||||
"connectWallet": "Connect Wallet",
|
||||
"unsupportedAsset": "Unsupported Asset",
|
||||
"feePool": "Fee Pool",
|
||||
"feeTier": "Fee Tier",
|
||||
"rebalanceMessage": "Your underlying tokens will be automatically rebalanced when the rate of the pool changes and may be different when you withdraw the position.",
|
||||
"addEarnHelper": "You will earn fees from trades proportional to your share of the pool.",
|
||||
"learnMoreAboutFess": " Learn more about earning fees.",
|
||||
"selectAPool": "Choose the best fee tier for your selected pair.",
|
||||
"poolType": "Select a fee tier based on your preferred liquidity provider fee.",
|
||||
"rangeWarning": "Your liquidity will only be active and earning fees when the rate of the pool is within this price range.",
|
||||
"chooseLiquidityAmount": "Choose an amount of tokens to open this liquidity position. If you don’t have enough tokens you can trade for them with a Swap.",
|
||||
"inputTokenDynamic": "Input {{label}}",
|
||||
"selectStartingPrice": "Set Starting Price",
|
||||
"newPoolPrice": "Select the market rate for the tokens being added."
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
{
|
||||
"noWallet": "No se encontró billetera de Ethereum",
|
||||
"wrongNetwork": "Te encontrás en la red equivocada",
|
||||
"switchNetwork": "Por favor cambia a {{ correctNetwork }}",
|
||||
"installWeb3MobileBrowser": "Por favor ingresá desde un navegador móvil con web3 habilitado como Trust Wallet o Coinbase Wallet.",
|
||||
"installMetamask": "Por favor visítanos nuevamente luego de instalar Metamask en Chrome o Brave.",
|
||||
"disconnected": "Desconectado",
|
||||
"swap": "Intercambiar",
|
||||
"send": "Enviar",
|
||||
"pool": "Pool",
|
||||
"betaWarning": "Este proyecto se encuentra en beta. Usalo bajo tu propio riesgo.",
|
||||
"input": "Entrada",
|
||||
"output": "Salida",
|
||||
"estimated": "estimado",
|
||||
"balance": "Saldo: {{ balanceInput }}",
|
||||
"unlock": "Desbloquear",
|
||||
"pending": "Pendiente",
|
||||
"selectToken": "Seleccioná un token",
|
||||
"searchOrPaste": "Buscar Token o Pegar Dirección",
|
||||
"noExchange": "No se encontró la divisa",
|
||||
"exchangeRate": "Tasa de Cambio",
|
||||
"enterValueCont": "Ingresá un valor en {{ missingCurrencyValue }} para continuar.",
|
||||
"selectTokenCont": "Seleccioná un token para continuar.",
|
||||
"noLiquidity": "Sin liquidez.",
|
||||
"unlockTokenCont": "Por favor desbloqueá un token para continuar.",
|
||||
"transactionDetails": "Detalles de la transacción",
|
||||
"hideDetails": "Ocultar detalles",
|
||||
"youAreSelling": "Estás vendiendo",
|
||||
"orTransFail": "o la transacción fallará.",
|
||||
"youWillReceive": "Vas a recibir al menos",
|
||||
"youAreBuying": "Estás comprando",
|
||||
"itWillCost": "Costará a lo sumo",
|
||||
"insufficientBalance": "Saldo insuficiente",
|
||||
"inputNotValid": "No es un valor de entrada válido",
|
||||
"differentToken": "Debe ser un token distinto.",
|
||||
"noRecipient": "Ingresá una dirección de billetera para enviar.",
|
||||
"invalidRecipient": "Por favor ingrese una billetera de destino válida.",
|
||||
"recipientAddress": "Dirección del recipiente",
|
||||
"youAreSending": "Estás enviando",
|
||||
"willReceive": "recibirá al menos",
|
||||
"to": "a",
|
||||
"addLiquidity": "Agregar liquidez",
|
||||
"deposit": "Depositar",
|
||||
"currentPoolSize": "Tamaño del Pool Actual",
|
||||
"yourPoolShare": "Tu parte del Pool",
|
||||
"noZero": "El monto no puede ser cero.",
|
||||
"mustBeETH": "Una de las entradas debe ser ETH.",
|
||||
"enterCurrencyOrLabelCont": "Ingresá un valor de {{ inputCurrency }} o de {{ label }} para continuar.",
|
||||
"youAreAdding": "Estás agregando entre",
|
||||
"and": "y",
|
||||
"intoPool": "en el pool de liquidez.",
|
||||
"outPool": "en el pool de liquidez.",
|
||||
"youWillMint": "Vas a acuñar",
|
||||
"liquidityTokens": "tokens de liquidez.",
|
||||
"totalSupplyIs": "El actual suministro total de tokens de liquidez es",
|
||||
"youAreSettingExRate": "Está configurando el tipo de cambio inicial a",
|
||||
"totalSupplyIs0": "El actual suministro total de tokens de liquidez es 0.",
|
||||
"tokenWorth": "Al tipo de cambio actual, cada token del pool vale",
|
||||
"firstLiquidity": "Sos la primer persona en agregar liquidez!",
|
||||
"initialExchangeRate": "El tipo de cambio inicial se establecerá en función de tus depósitos. Por favor, asegúrate de que tus depósitos en ETH y {{ label }} tengan el mismo valor fíat.",
|
||||
"removeLiquidity": "Remover Liquidez",
|
||||
"poolTokens": "Pool de Tokens",
|
||||
"enterLabelCont": "Ingresá un valor de {{ label }} para continuar.",
|
||||
"youAreRemoving": "Estás quitando entre",
|
||||
"youWillRemove": "Vas a remover",
|
||||
"createExchange": "Crear divisa",
|
||||
"invalidTokenAddress": "No es una dirección de token válida",
|
||||
"exchangeExists": "La divisa {{ label }} ya existe!",
|
||||
"invalidSymbol": "Símbolo inválido",
|
||||
"invalidDecimals": "Decimales inválidos",
|
||||
"tokenAddress": "Dirección de Token",
|
||||
"label": "Etiqueta",
|
||||
"decimals": "Decimales",
|
||||
"enterTokenCont": "Ingresá una dirección de token para continuar"
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
{
|
||||
"noWallet": "No se ha encontrado billetera de Ethereum",
|
||||
"wrongNetwork": "Se encuentra en la red equivocada",
|
||||
"switchNetwork": "Por favor cambie a {{ correctNetwork }}",
|
||||
"installWeb3MobileBrowser": "Por favor ingrese desde un navegador móvil con web3 habilitado como Trust Wallet o Coinbase Wallet.",
|
||||
"installMetamask": "Por favor visítenos nuevamente luego de instalar Metamask en Chrome o Brave.",
|
||||
"disconnected": "Desconectado",
|
||||
"swap": "Intercambiar",
|
||||
"send": "Enviar",
|
||||
"pool": "Pool",
|
||||
"betaWarning": "Este proyecto se encuentra en beta. Úselo bajo tu propio riesgo.",
|
||||
"input": "Entrada",
|
||||
"output": "Salida",
|
||||
"estimated": "estimado",
|
||||
"balance": "Saldo: {{ balanceInput }}",
|
||||
"unlock": "Desbloquear",
|
||||
"pending": "Pendiente",
|
||||
"selectToken": "Seleccione un token",
|
||||
"searchOrPaste": "Buscar Token o Pegar Dirección",
|
||||
"noExchange": "No se ha encontrado la divisa",
|
||||
"exchangeRate": "Tasa de Cambio",
|
||||
"enterValueCont": "Ingrese un valor en {{ missingCurrencyValue }} para continuar.",
|
||||
"selectTokenCont": "Seleccione un token para continuar.",
|
||||
"noLiquidity": "Sin liquidez.",
|
||||
"unlockTokenCont": "Por favor desbloquea un token para continuar.",
|
||||
"transactionDetails": "Detalles de la transacción",
|
||||
"hideDetails": "Ocultar detalles",
|
||||
"youAreSelling": "Está vendiendo",
|
||||
"orTransFail": "o la transacción fallará.",
|
||||
"youWillReceive": "Va a recibir al menos",
|
||||
"youAreBuying": "Está comprando",
|
||||
"itWillCost": "Costará a lo sumo",
|
||||
"insufficientBalance": "Saldo insuficiente",
|
||||
"inputNotValid": "No es un valor de entrada válido",
|
||||
"differentToken": "Debe ser un token distinto.",
|
||||
"noRecipient": "Ingrese una dirección de billetera para enviar.",
|
||||
"invalidRecipient": "Por favor ingrese una billetera de destino válida.",
|
||||
"recipientAddress": "Dirección del recipiente",
|
||||
"youAreSending": "Está enviando",
|
||||
"willReceive": "recibirá al menos",
|
||||
"to": "a",
|
||||
"addLiquidity": "Agregar liquidez",
|
||||
"deposit": "Depositar",
|
||||
"currentPoolSize": "Tamaño del Pool Actual",
|
||||
"yourPoolShare": "Su parte del Pool",
|
||||
"noZero": "El monto no puede ser cero.",
|
||||
"mustBeETH": "Una de las entradas debe ser ETH.",
|
||||
"enterCurrencyOrLabelCont": "Ingrese un valor de {{ inputCurrency }} o de {{ label }} para continuar.",
|
||||
"youAreAdding": "Está agregando entre",
|
||||
"and": "y",
|
||||
"intoPool": "en el pool de liquidez.",
|
||||
"outPool": "en el pool de liquidez.",
|
||||
"youWillMint": "Va a acuñar",
|
||||
"liquidityTokens": "tokens de liquidez.",
|
||||
"totalSupplyIs": "El actual suministro total de tokens de liquidez es",
|
||||
"youAreSettingExRate": "Está configurando el tipo de cambio inicial a",
|
||||
"totalSupplyIs0": "El actual suministro total de tokens de liquidez es 0.",
|
||||
"tokenWorth": "Al tipo de cambio actual, cada token del pool vale",
|
||||
"firstLiquidity": "Es la primer persona en agregar liquidez!",
|
||||
"initialExchangeRate": "El tipo de cambio inicial se establecerá en función de sus depósitos. Por favor, asegúrese de que sus depósitos en ETH y {{ label }} tengan el mismo valor fíat.",
|
||||
"removeLiquidity": "Remover Liquidez",
|
||||
"poolTokens": "Pool de Tokens",
|
||||
"enterLabelCont": "Ingresa un valor de {{ label }} para continuar.",
|
||||
"youAreRemoving": "Está quitando entre",
|
||||
"youWillRemove": "Va a remover",
|
||||
"createExchange": "Crear tipo de cambio",
|
||||
"invalidTokenAddress": "No es una dirección de token válida",
|
||||
"exchangeExists": "El tipo de cambio {{ label }} ya existe!",
|
||||
"invalidSymbol": "Símbolo inválido",
|
||||
"invalidDecimals": "Decimales inválidos",
|
||||
"tokenAddress": "Dirección de Token",
|
||||
"label": "Etiqueta",
|
||||
"decimals": "Decimales",
|
||||
"enterTokenCont": "Ingrese una dirección de token para continuar"
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
{
|
||||
"noWallet": "Wallet Ethereum non trovato",
|
||||
"wrongNetwork": "Sei connesso alla rete sbagliata",
|
||||
"switchNetwork": "Perfavore connettiti su {{ correctNetwork }}",
|
||||
"installWeb3MobileBrowser": "Perfavore visita il sito da un browser abilitato web3 o da un app mobile come Trust Wallet o Coinbase Wallet.",
|
||||
"installMetamask": "Perfavore ritorna dopo aver installato Metamask su Chrome o Brave.",
|
||||
"disconnected": "Disconnesso",
|
||||
"swap": "Scambia",
|
||||
"swapAnyway": "Scambia comunque",
|
||||
"send": "Invia",
|
||||
"sendAnyway": "Invia comunque",
|
||||
"pool": "Riserva",
|
||||
"betaWarning": "Questo progetto è in beta. Usalo a tuo rischio.",
|
||||
"input": "Input",
|
||||
"output": "Output",
|
||||
"estimated": "stimato",
|
||||
"balance": "Saldo: {{ balanceInput }}",
|
||||
"unlock": "Sblocca",
|
||||
"pending": "In attesa",
|
||||
"selectToken": "Seleziona un token",
|
||||
"searchOrPaste": "Cerca Nome, Simbolo o Indirizzo Token",
|
||||
"searchOrPasteMobile": "Nome, Simbolo, o Indirizzo",
|
||||
"noExchange": "Nessun Exchange Trovato",
|
||||
"exchangeRate": "Tasso di cambio",
|
||||
"unknownError": "Oops! Si è verificato un Errore imprevisto. Aggiorna la pagina o visita da un altro browser o dispositivo.",
|
||||
"enterValueCont": "Inserisci un valore {{ missingCurrencyValue }} per continuare.",
|
||||
"selectTokenCont": "Seleziona un token per continuare.",
|
||||
"noLiquidity": "Nessuna liquidità.",
|
||||
"insufficientLiquidity": "Liquidità insufficiente.",
|
||||
"unlockTokenCont": "Si prega di sbloccare il token per continuare.",
|
||||
"transactionDetails": "Dettagli avanzati",
|
||||
"hideDetails": "Nascondi dettagli",
|
||||
"slippageWarning": "Avviso di scostamento",
|
||||
"highSlippageWarning": "Avviso di elevato scostamento",
|
||||
"youAreSelling": "Stai vendendo",
|
||||
"orTransFail": "o la transazione fallità.",
|
||||
"youWillReceive": "Riceverai almeno",
|
||||
"youAreBuying": "Stai comprando",
|
||||
"itWillCost": "Costerà al massimo",
|
||||
"forAtMost": "per al massimo",
|
||||
"insufficientBalance": "Saldo insufficente",
|
||||
"inputNotValid": "Non è un valore di input valido",
|
||||
"differentToken": "Deve essere un token diverso.",
|
||||
"noRecipient": "Inserisci un indirizzo di wallet a cui inviare.",
|
||||
"invalidRecipient": "Inserisci un destinatario valido per l'indirizzo del wallet.",
|
||||
"recipientAddress": "Indirizzo del destinatario",
|
||||
"youAreSending": "Stai inviando",
|
||||
"willReceive": "riceverà almeno",
|
||||
"to": "a",
|
||||
"addLiquidity": "Aggiungi liquidità",
|
||||
"deposit": "Depositare",
|
||||
"currentPoolSize": "Dimensione attuale del pool",
|
||||
"yourPoolShare": "La tua parte di pool condivisa",
|
||||
"noZero": "L'importo non può essere zero.",
|
||||
"mustBeETH": "Uno degli input deve essere ETH.",
|
||||
"enterCurrencyOrLabelCont": "Inserisci un valore {{ inputCurrency }} o {{ label }} per continuare.",
|
||||
"youAreAdding": "Stai agginugendo",
|
||||
"and": "e",
|
||||
"intoPool": "nella riserva di liquidità.",
|
||||
"outPool": "dalla riserva di liquidità.",
|
||||
"youWillMint": "Tu conierai",
|
||||
"liquidityTokens": "token di liquidità.",
|
||||
"totalSupplyIs": "L'attuale disponibilità totale di token di liquidità è",
|
||||
"youAreSettingExRate": "Stai impostando il tasso di cambio iniziale su",
|
||||
"totalSupplyIs0": "L'attuale disponibilità totale di token di liquidità è 0.",
|
||||
"tokenWorth": "Al tasso di cambio corrente, ogni token del pool vale",
|
||||
"firstLiquidity": "Sei la prima persona ad aggiungere liquidità!",
|
||||
"initialExchangeRate": "Il tasso di cambio iniziale verrà impostato in base ai tuoi depositi. Assicurati che i tuoi depositi ETH e {{ label }} abbiano lo stesso valore fiat.",
|
||||
"removeLiquidity": "Rimuovi Liquidità",
|
||||
"poolTokens": "Token Pool",
|
||||
"enterLabelCont": "Inserisci un valore {{ label }} per continuare.",
|
||||
"youAreRemoving": "Stai rimuovendo tra",
|
||||
"youWillRemove": "Rimuoverai",
|
||||
"createExchange": "Crea scambio",
|
||||
"invalidTokenAddress": "Indirizzo token non valido",
|
||||
"exchangeExists": "{{ label }} Exchange già esistente!",
|
||||
"invalidSymbol": "Simbolo non valido",
|
||||
"invalidDecimals": "Decimali non validi",
|
||||
"tokenAddress": "Indirizzo Token",
|
||||
"label": "Etichetta",
|
||||
"name": "Nome",
|
||||
"symbol": "Simbolo",
|
||||
"decimals": "Decimali",
|
||||
"enterTokenCont": "Inserire un indirizzo token per continuare",
|
||||
"priceChange": "Scostamento del prezzo previsto",
|
||||
"forAtLeast": "per almeno "
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
{
|
||||
"noWallet": "לא נמצא ארנק",
|
||||
"wrongNetwork": "נבחרה רשת לא נכונה",
|
||||
"switchNetwork": "{{ correctNetwork }} יש צורך לשנות את הרשת ל",
|
||||
"installWeb3MobileBrowser": "יש צורך בארנק ווב3.0, תתקין מטאמאסק או ארנק דומה",
|
||||
"installMetamask": " Metamask יש צורך להתקין תוסף מטאמאסק לדפדפן, חפשו בגוגל ",
|
||||
"disconnected": "מנותק",
|
||||
"swap": "המרה",
|
||||
"send": "שליחה",
|
||||
"pool": "להפקיד",
|
||||
"betaWarning": "הפרויקט נמצא בשלב בטא, השתמשו באחריות",
|
||||
"input": "מוכר",
|
||||
"output": "אקבל",
|
||||
"estimated": "הערכה",
|
||||
"balance": "בארנק שלי {{ balanceInput }}",
|
||||
"unlock": "שחרור נעילת ארנק",
|
||||
"pending": "ממתין לאישור",
|
||||
"selectToken": "בחרו את הטוקן להמרה",
|
||||
"searchOrPaste": "הכניסו שם או כתובת של טוקן לחיפוש",
|
||||
"noExchange": "לא מתאפשרת המרה",
|
||||
"exchangeRate": "שער המרה",
|
||||
"enterValueCont": "כדי להמשיך {{ missingCurrencyValue }} הזינו ",
|
||||
"selectTokenCont": "בחרו טוקן כדי להמשיך",
|
||||
"noLiquidity": "אין נזילות",
|
||||
"unlockTokenCont": "יש צורך לאשר את הטוקן למסחר",
|
||||
"transactionDetails": "פרטי הטרנזקציה",
|
||||
"hideDetails": "הסתר פרטים נוספים",
|
||||
"youAreSelling": "למכירה",
|
||||
"orTransFail": "או שהטרנזקציה תיכשל",
|
||||
"youWillReceive": "תוצר המרה מינימלי",
|
||||
"youAreBuying": "קונה",
|
||||
"itWillCost": "זה יעלה",
|
||||
"insufficientBalance": "אין בחשבון מספיק מטבעות",
|
||||
"inputNotValid": "קלט לא תקין",
|
||||
"differentToken": "יש צורך בטוקנים שונים",
|
||||
"noRecipient": "לא הוכנסה כתובת ארנק יעד",
|
||||
"invalidRecipient": "לא הוכנסה כתובת תקינה",
|
||||
"recipientAddress": "כתובת יעד",
|
||||
"youAreSending": "כמות לשליחה",
|
||||
"willReceive": "יתקבל לכל הפחות",
|
||||
"to": "אל",
|
||||
"addLiquidity": "להוספת נזילות למאגר",
|
||||
"deposit": "הפקדה",
|
||||
"currentPoolSize": "גודל מאגר הנזילות הכולל",
|
||||
"yourPoolShare": "חלקך במאגר הנזילות",
|
||||
"noZero": "אפס אינו ערך תקין",
|
||||
"mustBeETH": "ETH חייב להופיע באחד מהצדדים",
|
||||
"enterCurrencyOrLabelCont": "כדי להמשיך {{ inputCurrency }} או {{ label }} הכנס",
|
||||
"youAreAdding": "מתווספים למאגר",
|
||||
"and": "וגם",
|
||||
"intoPool": "לתוך הנזילות",
|
||||
"outPool": "מתוך",
|
||||
"youWillMint": "יונפקו לכם",
|
||||
"liquidityTokens": "טוקנים של נזילות",
|
||||
"totalSupplyIs": "חלקך במאגר הנזילות",
|
||||
"youAreSettingExRate": "שער ההמרה יקבע על ידך",
|
||||
"totalSupplyIs0": "אין לך טוקנים של נזילות",
|
||||
"tokenWorth": "שווי כל טוקן נזילות הינו",
|
||||
"firstLiquidity": "אתה הראשוןה שמזרים נזילות למאגר",
|
||||
"initialExchangeRate": "ושל האית'ר הינן בערך שווה {{ label }} תוודאו שההפקדה של הטוקן",
|
||||
"removeLiquidity": "הוצאה של נזילות",
|
||||
"poolTokens": "טוקנים של מאגר הנזילות",
|
||||
"enterLabelCont": "כדי להמשיך {{ label }} הכנס ",
|
||||
"youAreRemoving": "יוסרו",
|
||||
"youWillRemove": "יוסרו",
|
||||
"createExchange": "ליצירת זוג מסחר",
|
||||
"invalidTokenAddress": "כתובת טוקן לא נכונה",
|
||||
"exchangeExists": "{{ label }} כבר קיים זוג המרה עבור",
|
||||
"invalidSymbol": "תו שגוי",
|
||||
"invalidDecimals": "ספרות עשרוניות שגויות",
|
||||
"tokenAddress": "כתובת הטוקן",
|
||||
"label": "שם",
|
||||
"decimals": "ספרות עשרויות",
|
||||
"enterTokenCont": "הכניסו כתובת טוקן כדי להמשיך"
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
{
|
||||
"noWallet": "Niciun portofel Ethereum găsit",
|
||||
"wrongNetwork": "Nu ești conectat la rețeaua corectă",
|
||||
"switchNetwork": "Conectează-te te rog la {{ correctNetwork }}",
|
||||
"installWeb3MobileBrowser": "Incearcă să vizitezi această pagina folosind un browser precum Trust Wallet sau Coinbase Wallet.",
|
||||
"installMetamask": "Vizitează această pagină din nou după ce instalezi MetaMask în Chrome sau Brave",
|
||||
"disconnected": "Deconectat",
|
||||
"swap": "Schimbă",
|
||||
"swapAnyway": "Schimbă Oricum",
|
||||
"send": "Trimite",
|
||||
"sendAnyway": "Trimite Oricum",
|
||||
"pool": "Depune Lichiditate",
|
||||
"betaWarning": "Proiectul este încă în versiunea beta. Folosește-l cu grijă, riscul este al tău.",
|
||||
"input": "Input",
|
||||
"output": "Output",
|
||||
"estimated": "estimat",
|
||||
"balance": "Balanță: {{ balanceInput }}",
|
||||
"unlock": "Deblochează",
|
||||
"pending": "În Așteptare",
|
||||
"selectToken": "Selectează un jeton",
|
||||
"searchOrPaste": "Caută după Numele, Simbolul sau Adresa Jetonului",
|
||||
"searchOrPasteMobile": "Nume, Simbol sau Adresă",
|
||||
"noExchange": "Nicio Piață de Schimb Găsită",
|
||||
"noToken": "Nicin Jeton Găsit",
|
||||
"exchangeRate": "Curs de Schimb",
|
||||
"unknownError": "Ups! A intervenit o eroare tehnică. Te rog reîncarcă pagina, sau acceseaz-o de pe alt navigator sau dispozitiv.",
|
||||
"enterValueCont": "Setează o valoare pentru {{ missingCurrencyValue }} pentru a continua.",
|
||||
"selectTokenCont": "Selectează un jeton pentru a continua.",
|
||||
"noLiquidity": "Nu Există Lichiditate.",
|
||||
"insufficientLiquidity": "Lichiditate Insuficientă.",
|
||||
"unlockTokenCont": "Te rog deblochează jetonul pentru a continua.",
|
||||
"transactionDetails": "Detalii Avansate",
|
||||
"hideDetails": "Ascunde Detaili",
|
||||
"slippageWarning": "Alertă Deviație de Preț",
|
||||
"highSlippageWarning": "Alertă Deviație de Preț Mare",
|
||||
"youAreSelling": "Tu vinzi",
|
||||
"orTransFail": "sau tranzacția va eșua.",
|
||||
"youWillReceive": "Vei primi cel puțin",
|
||||
"youAreBuying": "Tu cumperi",
|
||||
"itWillCost": "Va costa cel mult",
|
||||
"forAtMost": "pentru maximum",
|
||||
"insufficientBalance": "Balanță Insuficientă",
|
||||
"inputNotValid": "Valoarea setată nu este validă",
|
||||
"differentToken": "Trebuie să fie un jeton diferit.",
|
||||
"noRecipient": "Setează o adresă de portofel pentru destinatar.",
|
||||
"invalidRecipient": "Te rog setează o adresă de portofel validă pentru destinatar.",
|
||||
"recipientAddress": "Adresa Destinatarului",
|
||||
"youAreSending": "Tu trimiți",
|
||||
"willReceive": "vei primi cel puțin",
|
||||
"to": "spre",
|
||||
"addLiquidity": "Adaugă Lichiditate",
|
||||
"deposit": "Depozitează",
|
||||
"currentPoolSize": "Volumul Actual al Fondului",
|
||||
"yourPoolShare": "Partea Ta din Fond",
|
||||
"noZero": "Cantitatea nu poate fi zero.",
|
||||
"mustBeETH": "Una dintre valori trebuie să fie ETH.",
|
||||
"enterCurrencyOrLabelCont": "Setează o valoare pentru {{ inputCurrency }} sau {{ label }} pentru a continua. ",
|
||||
"youAreAdding": "Tu adaugi",
|
||||
"and": "și",
|
||||
"intoPool": "în fondul de lichidatate.",
|
||||
"outPool": "din fondul de lichiditate.",
|
||||
"youWillMint": "Tu vei tipări",
|
||||
"liquidityTokens": "jetoane de lichiditate.",
|
||||
"totalSupplyIs": "Cantitatea totală de jetoane de lichiditate este",
|
||||
"youAreSettingExRate": "Setezi cursul de schimb inițial la",
|
||||
"totalSupplyIs0": "Cantitatea totală de jetoane de lichiditate este 0.",
|
||||
"tokenWorth": "La cursul de schimb actual, fiecare jeton de lichiditate este valorat la",
|
||||
"firstLiquidity": "Ești prima persoană care depune lichiditate!",
|
||||
"initialExchangeRate": "Cursul de schimb inițial va fi setat în funcție de depozitele tale. Te rog asigură-te că ETH-ul și {{ label }}-ul pe care le-ai depozitat au aceeași valoare în bani fiat.",
|
||||
"removeLiquidity": "Retrage Lichiditat",
|
||||
"poolTokens": "Depune Jetoane",
|
||||
"enterLabelCont": "Setează o valoare pentru {{ label }} pentru a continua.",
|
||||
"youAreRemoving": "Retragi între",
|
||||
"youWillRemove": "Vei retrage",
|
||||
"createExchange": "Creează Piață de Schimb",
|
||||
"invalidTokenAddress": "Adresa de jeton nu este validă",
|
||||
"exchangeExists": "{{ label }} Piața de schimb există deja!",
|
||||
"invalidSymbol": "Simbol invalid",
|
||||
"invalidDecimals": "Zecimale invalide",
|
||||
"tokenAddress": "Adresă Jeton",
|
||||
"label": "Denumire",
|
||||
"name": "Nume",
|
||||
"symbol": "Simbol",
|
||||
"decimals": "Zecimale",
|
||||
"enterTokenCont": "Setează o adresă de jeton pentru a continua",
|
||||
"priceChange": "Deviație de preț așteptată",
|
||||
"forAtLeast": "pentru cel puțin ",
|
||||
"brokenToken": "Jetonul selectat nu este compatibil cu Uniswap V1. Depunerea de lichiditate îți va bloca fondurile pe vecie.",
|
||||
"toleranceExplanation": "Micșorând această limită, vei reduce riscul de frontrunning. În același timp, devine mai probabil că tranzacția va eșua din cauza variațiilor normale de preț.",
|
||||
"tokenSearchPlaceholder": "Caută nume sau lipește adresă"
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
{
|
||||
"noWallet": "Кошелек эфира не найден",
|
||||
"wrongNetwork": "Некорректная сеть",
|
||||
"switchNetwork": "Пожалуйста, перейдите в {{ correctNetwork }}",
|
||||
"installWeb3MobileBrowser": "Пожалуйста, откройте в браузере с поддержкой web3, таком, как Trust Wallet или Coinbase Wallet.",
|
||||
"installMetamask": "Пожалуйста, откройте в Chrome или Brave с установленным расширением Metamask.",
|
||||
"disconnected": "Нет подключения",
|
||||
"swap": "Обменять",
|
||||
"send": "Отправить",
|
||||
"pool": "Вложить",
|
||||
"betaWarning": "Проект находится на стадии бета тестирования.",
|
||||
"input": "Ввести",
|
||||
"output": "Вывести",
|
||||
"estimated": "по оценке",
|
||||
"balance": "Баланс: {{ balanceInput }}",
|
||||
"unlock": "Разблокировать",
|
||||
"pending": "Ожидание",
|
||||
"selectToken": "Выберите токен",
|
||||
"searchOrPaste": "Поиск токена или вставить адрес токена",
|
||||
"noExchange": "Обмен не найден",
|
||||
"exchangeRate": "Курс обмена",
|
||||
"enterValueCont": "Введите {{ missingCurrencyValue }}, чтобы продолжить.",
|
||||
"selectTokenCont": "Введите токен, чтобы продолжить.",
|
||||
"noLiquidity": "Нет ликвидности.",
|
||||
"unlockTokenCont": "Пожалуйста, разблокируйте токен, чтобы продолжить.",
|
||||
"transactionDetails": "Детали транзакции",
|
||||
"hideDetails": "Скрыть подробности",
|
||||
"youAreSelling": "Вы продаете",
|
||||
"orTransFail": "или транзакция будет отклонена.",
|
||||
"youWillReceive": "Вы получите как минимум",
|
||||
"youAreBuying": "Вы покупаете",
|
||||
"itWillCost": "В крайнем случае это будет стоить",
|
||||
"insufficientBalance": "Недостаточно средств",
|
||||
"inputNotValid": "Некорректное значение",
|
||||
"differentToken": "Должны быть разные токены.",
|
||||
"noRecipient": "Введите адрес кошелька эфира, куда перечислить.",
|
||||
"invalidRecipient": "Пожалуйста, введите корректный адрес кошелька получателя.",
|
||||
"recipientAddress": "Адрес получателя",
|
||||
"youAreSending": "Вы отправляете",
|
||||
"willReceive": "получит как минимум",
|
||||
"to": "",
|
||||
"addLiquidity": "Добавить ликвидность",
|
||||
"deposit": "Вложить",
|
||||
"currentPoolSize": "Текущий размер пула",
|
||||
"yourPoolShare": "Ваша доля в пуле",
|
||||
"noZero": "Значение не может быть нулевым.",
|
||||
"mustBeETH": "Одно из значений должно быть ETH.",
|
||||
"enterCurrencyOrLabelCont": "Введите {{ inputCurrency }} или {{ label }}, чтобы продолжить.",
|
||||
"youAreAdding": "Вы добавляете от",
|
||||
"and": "и",
|
||||
"intoPool": "в пул ликвидности.",
|
||||
"outPool": "из пула ликвидности.",
|
||||
"youWillMint": "Вы произведёте",
|
||||
"liquidityTokens": "токенов ликвидности.",
|
||||
"totalSupplyIs": "Ваш объем токенов ликвидности",
|
||||
"youAreSettingExRate": "Вы устанавливаете начальный курс обмена",
|
||||
"totalSupplyIs0": "Ваш объем токенов ликвидности 0.",
|
||||
"tokenWorth": "При текущем курсе, каждый токен пула оценивается в",
|
||||
"firstLiquidity": "Вы первый, кто создаст ликвидность!",
|
||||
"initialExchangeRate": "Начальный курс обмена будет установлен согласно вашим депозитам. Убедитесь, что ваши депозиты ETH и {{ label }} имеют одинаковое значение в валюте.",
|
||||
"removeLiquidity": "Убрать ликвидность",
|
||||
"poolTokens": "Токены пула",
|
||||
"enterLabelCont": "Введите {{ label }}, чтобы продолжить.",
|
||||
"youAreRemoving": "Вы убираете в от",
|
||||
"youWillRemove": "Вы уберёте",
|
||||
"createExchange": "Создать обмен",
|
||||
"invalidTokenAddress": "Некорректный адрес токена",
|
||||
"exchangeExists": "{{ label }} Обмен уже существует!",
|
||||
"invalidSymbol": "Некорректный символ",
|
||||
"invalidDecimals": "Некорректное десятичное значение",
|
||||
"tokenAddress": "Адрес токена",
|
||||
"label": "Название",
|
||||
"decimals": "Десятичное значение",
|
||||
"enterTokenCont": "Чтобы продолжить, введите адрес токена"
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
{
|
||||
"noWallet": "Không tìm thấy ví tiền Ethereum",
|
||||
"wrongNetwork": "Kết nối mạng không đúng",
|
||||
"switchNetwork": "Vui lòng chuyển sang {{ correctNetwork }}",
|
||||
"installWeb3MobileBrowser": "Vui lòng truy cập từ trình duyệt di động hỗ trợ web3 như là Ví Trust hoặc Ví Coinbase",
|
||||
"installMetamask": "Vui lòng truy cập sau khi cài đặt Metamask trên Chrome hoặc Brave.",
|
||||
"disconnected": "Ngắt kết nối rồi",
|
||||
"swap": "Hoán đổi",
|
||||
"swapAnyway": "Tiếp tục hoán đổi?",
|
||||
"send": "Gửi",
|
||||
"sendAnyway": "Tiếp tục gửi?",
|
||||
"pool": "Chung vốn",
|
||||
"betaWarning": "Dự án này đang trong giai đoạn thử nghiệm. Sử dụng có rủi ro của riêng bạn",
|
||||
"input": "Đầu vào",
|
||||
"output": "Đầu ra",
|
||||
"estimated": "ước lượng",
|
||||
"balance": "Số dư: {{ balanceInput }}",
|
||||
"unlock": "Mở khóa",
|
||||
"pending": "Đang chờ xử lý",
|
||||
"selectToken": "Chọn một đồng tiền ảo",
|
||||
"searchOrPaste": "Tìm kiếm tên, biểu tượng, hoặc địa chỉ của đồng tiền ảo",
|
||||
"searchOrPasteMobile": "Tên, Biểu tượng, hoặc Địa chỉ",
|
||||
"noExchange": "Không tìm thấy giao dịch",
|
||||
"exchangeRate": "Tỷ giá",
|
||||
"unknownError": "Rất tiếc! Xảy ra lỗi không xác định. Vui lòng làm mới trang, hoặc truy cập từ trình duyệt hay thiết bị khác.",
|
||||
"enterValueCont": "Nhập một giá trị {{ missingCurrencyValue }} để tiếp tục.",
|
||||
"selectTokenCont": "Chọn một đồng tiền ảo để tiếp tục.",
|
||||
"noLiquidity": "Không có tính thanh khoản.",
|
||||
"insufficientLiquidity": "Không đủ tính thanh khoản.",
|
||||
"unlockTokenCont": "Vui lòng mở khoá đồng tiền ảo để tiếp tục",
|
||||
"transactionDetails": "Chi tiết nâng cao",
|
||||
"hideDetails": "Ẩn chi tiết",
|
||||
"slippageWarning": "Cảnh báo trượt giá",
|
||||
"highSlippageWarning": "Cảnh báo trượt giá cao",
|
||||
"youAreSelling": "Bạn đang bán",
|
||||
"orTransFail": "hoặc giao dịch sẽ thất bại.",
|
||||
"youWillReceive": "Bạn sẽ nhận dược ít nhất là",
|
||||
"youAreBuying": "Bạn đang mua",
|
||||
"itWillCost": "Nó sẽ có giá cao nhất",
|
||||
"forAtMost": "nhiều nhất",
|
||||
"insufficientBalance": "Số dư không đủ",
|
||||
"inputNotValid": "Giá trị nhập vào không hợp lệ",
|
||||
"differentToken": "Đồng tiền ảo phải khác nhau.",
|
||||
"noRecipient": "Nhập địa chỉ ví để gửi đến.",
|
||||
"invalidRecipient": "Vui lòng nhập một người nhận địa chỉ ví hợp lệ.",
|
||||
"recipientAddress": "Địa chỉ người nhận",
|
||||
"youAreSending": "Bạn đang gửi",
|
||||
"willReceive": "sẽ nhận dược ít nhất là",
|
||||
"to": "đến",
|
||||
"addLiquidity": "Thêm tiền thanh khoản",
|
||||
"deposit": "Gửi tiền",
|
||||
"currentPoolSize": "Quy mô hiện tại của quỹ",
|
||||
"yourPoolShare": "Phần hùn của bạn trong quỹ",
|
||||
"noZero": "Số tiền không thể bằng không.",
|
||||
"mustBeETH": "Một trong những đầu vào phải là ETH.",
|
||||
"enterCurrencyOrLabelCont": "Nhập giá trị {{ inputCurrency }} hoặc {{ label }} để tiếp tục.",
|
||||
"youAreAdding": "Bạn đang thêm",
|
||||
"and": "và",
|
||||
"intoPool": "vào nhóm thanh khoản.",
|
||||
"outPool": "từ nhóm thanh khoản.",
|
||||
"youWillMint": "Bạn sẽ đúc tiền",
|
||||
"liquidityTokens": "đồng thanh khoản.",
|
||||
"totalSupplyIs": "Tổng cung hiện tại của đồng thanh khoản là",
|
||||
"youAreSettingExRate": "Bạn đang đặt tỷ giá hối đoái ban đầu thành",
|
||||
"totalSupplyIs0": "Tổng cung hiện tại của đồng thanh khoản là 0.",
|
||||
"tokenWorth": "Tại tỷ giá hối đoái hiện tại, giá trị đồng token của quỹ là",
|
||||
"firstLiquidity": "Bạn là người đầu tiên thêm thanh khoản!",
|
||||
"initialExchangeRate": "Tỷ giá hối đoái ban đầu sẽ được thiết lập dựa trên tiền gửi của bạn. Vui lòng đảm bảo rằng tiền gửi ETH và {{ label }} của bạn có cùng giá trị tiền định danh.",
|
||||
"removeLiquidity": "Loại bỏ thanh khoản",
|
||||
"poolTokens": "Đồng tiền ảo của quỹ",
|
||||
"enterLabelCont": "Nhập giá trị {{ label }} để tiếp tục",
|
||||
"youAreRemoving": "Bạn đang loại bỏ giữa",
|
||||
"youWillRemove": "Bạn sẽ loại bỏ",
|
||||
"createExchange": "Tạo giao dịch",
|
||||
"invalidTokenAddress": "Địa chỉ đồng tiền điện tử không hợp lệ",
|
||||
"exchangeExists": "{{ label }} Giao dịch đã tồn tại!",
|
||||
"invalidSymbol": "Biểu tượng không hợp lệ",
|
||||
"invalidDecimals": "Số thập phân không hợp lệ",
|
||||
"tokenAddress": "Địa chỉ đồng tiền điện tử",
|
||||
"label": "Nhãn",
|
||||
"name": "Tên",
|
||||
"symbol": "Biểu tượng",
|
||||
"decimals": "Số thập phân",
|
||||
"enterTokenCont": "Nhập địa chỉ đồng tiền ảo để tiếp tục",
|
||||
"priceChange": "Trượt giá dự kiến",
|
||||
"forAtLeast": "cho ít nhất "
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
{
|
||||
"noWallet": "未发现以太钱包",
|
||||
"wrongNetwork": "网络错误",
|
||||
"switchNetwork": "请切换到 {{ correctNetwork }}",
|
||||
"installWeb3MobileBrowser": "请从支持web3的移动端浏览器,如 Trust Wallet 或 Coinbase Wallet 访问。",
|
||||
"installMetamask": "请从安装了 Metamask 插件的 Chrome 或 Brave 访问。",
|
||||
"disconnected": "未连接",
|
||||
"swap": "兑换",
|
||||
"send": "发送",
|
||||
"pool": "资金池",
|
||||
"betaWarning": "项目尚处于beta阶段。使用需自行承担风险。",
|
||||
"input": "输入",
|
||||
"output": "输出",
|
||||
"estimated": "估计",
|
||||
"balance": "余额: {{ balanceInput }}",
|
||||
"unlock": "解锁",
|
||||
"pending": "处理中",
|
||||
"selectToken": "选择通证",
|
||||
"searchOrPaste": "搜索通证或粘贴地址",
|
||||
"noExchange": "未找到交易所",
|
||||
"exchangeRate": "兑换率",
|
||||
"enterValueCont": "输入{{ missingCurrencyValue }}值并继续。",
|
||||
"selectTokenCont": "选取通证继续。",
|
||||
"noLiquidity": "没有流动金。",
|
||||
"unlockTokenCont": "请解锁通证并继续。",
|
||||
"transactionDetails": "交易明细",
|
||||
"hideDetails": "隐藏明细",
|
||||
"youAreSelling": "你正在出售",
|
||||
"orTransFail": "或交易失败。",
|
||||
"youWillReceive": "你将至少收到",
|
||||
"youAreBuying": "你正在购买",
|
||||
"itWillCost": "它将至少花费",
|
||||
"insufficientBalance": "余额不足",
|
||||
"inputNotValid": "无效的输入值",
|
||||
"differentToken": "必须是不同的通证。",
|
||||
"noRecipient": "输入接收钱包地址。",
|
||||
"invalidRecipient": "请输入有效的收钱地址。",
|
||||
"recipientAddress": "接收地址",
|
||||
"youAreSending": "你正在发送",
|
||||
"willReceive": "将至少收到",
|
||||
"to": "至",
|
||||
"addLiquidity": "添加流动金",
|
||||
"deposit": "存入",
|
||||
"currentPoolSize": "当前资金池大小",
|
||||
"yourPoolShare": "你的资金池份额",
|
||||
"noZero": "金额不能为零。",
|
||||
"mustBeETH": "输入中必须有一个是 ETH。",
|
||||
"enterCurrencyOrLabelCont": "输入 {{ inputCurrency }} 或 {{ label }} 值并继续。",
|
||||
"youAreAdding": "你将添加",
|
||||
"and": "和",
|
||||
"intoPool": "入流动资金池。",
|
||||
"outPool": "出流动资金池。",
|
||||
"youWillMint": "你将铸造",
|
||||
"liquidityTokens": "流动通证。",
|
||||
"totalSupplyIs": "当前流动通证的总量是",
|
||||
"youAreSettingExRate": "你将初始兑换率设置为",
|
||||
"totalSupplyIs0": "当前流动通证的总量是0。",
|
||||
"tokenWorth": "当前兑换率下,每个资金池通证价值",
|
||||
"firstLiquidity": "你是第一个添加流动金的人!",
|
||||
"initialExchangeRate": "初始兑换率将由你的存入情况决定。请确保你存入的 ETH 和 {{ label }} 具有相同的总市值。",
|
||||
"removeLiquidity": "删除流动金",
|
||||
"poolTokens": "资金池通证",
|
||||
"enterLabelCont": "输入 {{ label }} 值并继续。",
|
||||
"youAreRemoving": "你正在移除",
|
||||
"youWillRemove": "你将移除",
|
||||
"createExchange": "创建交易所",
|
||||
"invalidTokenAddress": "通证地址无效",
|
||||
"exchangeExists": "{{ label }} 交易所已存在!",
|
||||
"invalidSymbol": "通证符号无效",
|
||||
"invalidDecimals": "小数位数无效",
|
||||
"tokenAddress": "通证地址",
|
||||
"label": "通证符号",
|
||||
"decimals": "小数位数",
|
||||
"enterTokenCont": "输入通证地址并继续"
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
{
|
||||
"noWallet": "未偵測到以太坊錢包",
|
||||
"wrongNetwork": "你位在錯誤的網路",
|
||||
"switchNetwork": "請切換到 {{ correctNetwork }}",
|
||||
"installWeb3MobileBrowser": "請安裝含有 web3 瀏覽器的手機錢包,如 Trust Wallet 或 Coinbase Wallet。",
|
||||
"installMetamask": "請使用 Chrome 或 Brave 瀏覽器安裝 Metamask。",
|
||||
"disconnected": "未連接",
|
||||
"swap": "兌換",
|
||||
"send": "發送",
|
||||
"pool": "資金池",
|
||||
"betaWarning": "本產品仍在測試階段。使用者需自負風險。",
|
||||
"input": "輸入",
|
||||
"output": "輸出",
|
||||
"estimated": "估計",
|
||||
"balance": "餘額: {{ balanceInput }}",
|
||||
"unlock": "解鎖",
|
||||
"pending": "處理中",
|
||||
"selectToken": "選擇代幣",
|
||||
"searchOrPaste": "選擇代幣或輸入地址",
|
||||
"noExchange": "找不到交易所",
|
||||
"exchangeRate": "匯率",
|
||||
"enterValueCont": "輸入 {{ missingCurrencyValue }} 以繼續。",
|
||||
"selectTokenCont": "選擇代幣以繼續。",
|
||||
"noLiquidity": "沒有流動性資金。",
|
||||
"unlockTokenCont": "解鎖代幣以繼續。",
|
||||
"transactionDetails": "交易明細",
|
||||
"hideDetails": "隱藏明細",
|
||||
"youAreSelling": "你正在出售",
|
||||
"orTransFail": "或交易失敗。",
|
||||
"youWillReceive": "你將至少收到",
|
||||
"youAreBuying": "你正在購買",
|
||||
"itWillCost": "這將花費至多",
|
||||
"insufficientBalance": "餘額不足",
|
||||
"inputNotValid": "無效的輸入值",
|
||||
"differentToken": "必須是不同的代幣。",
|
||||
"noRecipient": "請輸入收款人錢包地址。",
|
||||
"invalidRecipient": "請輸入有效的錢包地址。",
|
||||
"recipientAddress": "收款人錢包地址",
|
||||
"youAreSending": "你正在發送",
|
||||
"willReceive": "將至少收到",
|
||||
"to": "至",
|
||||
"addLiquidity": "增加流動性資金",
|
||||
"deposit": "存入",
|
||||
"currentPoolSize": "目前的資金池總量",
|
||||
"yourPoolShare": "你在資金池中的佔比",
|
||||
"noZero": "金額不能為零。",
|
||||
"mustBeETH": "輸入中必須包含 ETH。",
|
||||
"enterCurrencyOrLabelCont": "輸入 {{ inputCurrency }} 或 {{ label }} 以繼續。",
|
||||
"youAreAdding": "你將把",
|
||||
"and": "和",
|
||||
"intoPool": "加入資金池。",
|
||||
"outPool": "領出資金池。",
|
||||
"youWillMint": "你將產生",
|
||||
"liquidityTokens": "流動性代幣。",
|
||||
"totalSupplyIs": "目前流動性代幣供給總量為",
|
||||
"youAreSettingExRate": "初始的匯率將被設定為",
|
||||
"totalSupplyIs0": "目前流動性代幣供給為零。",
|
||||
"tokenWorth": "依據目前的匯率,每個流動性代幣價值",
|
||||
"firstLiquidity": "您是第一個提供流動性資金的人!",
|
||||
"initialExchangeRate": "初始的匯率將取決於你存入的資金。請確保存入的 ETH 和 {{ label }} 的價值相等。",
|
||||
"removeLiquidity": "領出流動性資金",
|
||||
"poolTokens": "資金池代幣",
|
||||
"enterLabelCont": "輸入 {{ label }} 以繼續。",
|
||||
"youAreRemoving": "您正在移除",
|
||||
"youWillRemove": "您即將移除",
|
||||
"createExchange": "創建交易所",
|
||||
"invalidTokenAddress": "無效的代幣地址",
|
||||
"exchangeExists": "{{ label }} 的交易所已經存在!",
|
||||
"invalidSymbol": "代幣符號錯誤",
|
||||
"invalidDecimals": "小數位數錯誤",
|
||||
"tokenAddress": "代幣地址",
|
||||
"label": "代幣符號",
|
||||
"decimals": "小數位數",
|
||||
"enterTokenCont": "輸入代幣地址"
|
||||
}
|
||||
61
src/abis/argent-wallet-contract.json
Normal file
@@ -0,0 +1,61 @@
|
||||
[
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"components": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "bytes",
|
||||
"name": "data",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "_transactions",
|
||||
"type": "tuple[]"
|
||||
}
|
||||
],
|
||||
"name": "wc_multiCall",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bytes[]",
|
||||
"name": "",
|
||||
"type": "bytes[]"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "_msgHash",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"internalType": "bytes",
|
||||
"name": "_signature",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "isValidSignature",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bytes4",
|
||||
"name": "",
|
||||
"type": "bytes4"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
@@ -1,55 +0,0 @@
|
||||
[
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_factoryV1",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_router",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "constructor"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "amountTokenMin",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "amountETHMin",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "deadline",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "migrate",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"stateMutability": "payable",
|
||||
"type": "receive"
|
||||
}
|
||||
]
|
||||
@@ -1,6 +0,0 @@
|
||||
import { Interface } from '@ethersproject/abi'
|
||||
import { abi as STAKING_REWARDS_ABI } from '@uniswap/liquidity-staker/build/StakingRewards.json'
|
||||
|
||||
const STAKING_REWARDS_INTERFACE = new Interface(STAKING_REWARDS_ABI)
|
||||
|
||||
export { STAKING_REWARDS_INTERFACE }
|
||||
|
Before Width: | Height: | Size: 883 KiB After Width: | Height: | Size: 221 KiB |
|
Before Width: | Height: | Size: 1.3 MiB After Width: | Height: | Size: 670 KiB |
|
Before Width: | Height: | Size: 2.2 MiB After Width: | Height: | Size: 140 KiB |
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 413 KiB |
181
src/assets/svg/arbitrum_logo.svg
Normal file
@@ -0,0 +1,181 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 470.287 514.251" enable-background="new 0 0 470.287 514.251" xml:space="preserve">
|
||||
<g id="Background">
|
||||
</g>
|
||||
<g id="Logos_and_symbols">
|
||||
<g id="SYMBOL_VER_3">
|
||||
</g>
|
||||
<g id="SYMBOL_VER_3_3_">
|
||||
</g>
|
||||
<g id="SYMBOL_VER_4">
|
||||
</g>
|
||||
<g id="SYMBOL_VER_4_1_">
|
||||
<g id="SYMBOL_VER_4_3_">
|
||||
</g>
|
||||
</g>
|
||||
<g id="SYMBOL_VER_5_1_">
|
||||
</g>
|
||||
<g id="off_2_1_">
|
||||
</g>
|
||||
<g id="VER_3_1_">
|
||||
<g id="SYMBOL_VER_2_1_">
|
||||
</g>
|
||||
</g>
|
||||
<g id="VER_3">
|
||||
<g id="SYMBOL_VER_2">
|
||||
</g>
|
||||
</g>
|
||||
<g id="off_2">
|
||||
</g>
|
||||
<g id="SYMBOL_VER_5">
|
||||
</g>
|
||||
<g id="SYMBOL_VER_1">
|
||||
</g>
|
||||
<g id="SYMBOL_VER_1_1_">
|
||||
</g>
|
||||
<g id="SYMBOL_VER_1-1_3_">
|
||||
</g>
|
||||
<g id="SYMBOL_VER_1-1_2_">
|
||||
</g>
|
||||
<g id="SYMBOL_VER_1-1">
|
||||
</g>
|
||||
<g id="SYMBOL_VER_1-1_1_">
|
||||
<g id="_x31_-3">
|
||||
</g>
|
||||
<g id="Symbol_-_Original_14_">
|
||||
<path fill="#2D374B" d="M291.134,237.469l35.654-60.5l96.103,149.684l0.046,28.727l-0.313-197.672
|
||||
c-0.228-4.832-2.794-9.252-6.887-11.859L242.715,46.324c-4.045-1.99-9.18-1.967-13.22,0.063c-0.546,0.272-1.06,0.57-1.548,0.895
|
||||
l-0.604,0.379L59.399,144.983l-0.651,0.296c-0.838,0.385-1.686,0.875-2.48,1.444c-3.185,2.283-5.299,5.66-5.983,9.448
|
||||
c-0.103,0.574-0.179,1.158-0.214,1.749l0.264,161.083l89.515-138.745c11.271-18.397,35.825-24.323,58.62-24.001l26.753,0.706
|
||||
L67.588,409.765l18.582,10.697L245.692,157.22l70.51-0.256L157.091,426.849l66.306,38.138l7.922,4.556
|
||||
c3.351,1.362,7.302,1.431,10.681,0.21l175.453-101.678l-33.544,19.438L291.134,237.469z M304.736,433.395l-66.969-105.108
|
||||
l40.881-69.371l87.952,138.628L304.736,433.395z"/>
|
||||
<polygon fill="#28A0F0" points="237.768,328.286 304.736,433.395 366.601,397.543 278.648,258.915 "/>
|
||||
<path fill="#28A0F0" d="M422.937,355.379l-0.046-28.727l-96.103-149.684l-35.654,60.5l92.774,150.043l33.544-19.438
|
||||
c3.29-2.673,5.281-6.594,5.49-10.825L422.937,355.379z"/>
|
||||
<path fill="#FFFFFF" d="M20.219,382.469l47.369,27.296l157.634-252.801l-26.753-0.706c-22.795-0.322-47.35,5.604-58.62,24.001
|
||||
L50.334,319.004l-30.115,46.271V382.469z"/>
|
||||
<polygon fill="#FFFFFF" points="316.202,156.964 245.692,157.22 86.17,420.462 141.928,452.565 157.091,426.849 "/>
|
||||
<path fill="#96BEDC" d="M452.65,156.601c-0.59-14.746-8.574-28.245-21.08-36.104L256.28,19.692
|
||||
c-12.371-6.229-27.825-6.237-40.218-0.004c-1.465,0.739-170.465,98.752-170.465,98.752c-2.339,1.122-4.592,2.458-6.711,3.975
|
||||
c-11.164,8.001-17.969,20.435-18.668,34.095v208.765l30.115-46.271L50.07,157.921c0.035-0.589,0.109-1.169,0.214-1.741
|
||||
c0.681-3.79,2.797-7.171,5.983-9.456c0.795-0.569,172.682-100.064,173.228-100.337c4.04-2.029,9.175-2.053,13.22-0.063
|
||||
l173.022,99.523c4.093,2.607,6.659,7.027,6.887,11.859v199.542c-0.209,4.231-1.882,8.152-5.172,10.825l-33.544,19.438
|
||||
l-17.308,10.031l-61.864,35.852l-62.737,36.357c-3.379,1.221-7.33,1.152-10.681-0.21l-74.228-42.693l-15.163,25.717
|
||||
l66.706,38.406c2.206,1.255,4.171,2.367,5.784,3.272c2.497,1.4,4.199,2.337,4.8,2.629c4.741,2.303,11.563,3.643,17.71,3.643
|
||||
c5.636,0,11.132-1.035,16.332-3.072l182.225-105.531c10.459-8.104,16.612-20.325,17.166-33.564V156.601z"/>
|
||||
</g>
|
||||
<g id="Symbol_-_Original_13_">
|
||||
</g>
|
||||
<g id="Symbol_-_Original_6_">
|
||||
</g>
|
||||
<g id="Symbol_-_Original_4_">
|
||||
</g>
|
||||
<g id="One_color_version_-_White_3_">
|
||||
<g id="Symbol_-_Original_15_">
|
||||
</g>
|
||||
</g>
|
||||
<g id="One_color_version_-_White">
|
||||
<g id="Symbol_-_Original">
|
||||
</g>
|
||||
</g>
|
||||
<g id="Symbol_-_Monochromatic_3_">
|
||||
<g id="_x33__7_">
|
||||
</g>
|
||||
</g>
|
||||
<g id="Symbol_-_Monochromatic">
|
||||
<g id="_x33__3_">
|
||||
</g>
|
||||
</g>
|
||||
<g id="_x33__2_">
|
||||
</g>
|
||||
<g id="_x33__1_">
|
||||
</g>
|
||||
<g id="_x33_">
|
||||
</g>
|
||||
<g id="Symbol_-_Original_10_">
|
||||
</g>
|
||||
<g id="Symbol_-_Original_1_">
|
||||
</g>
|
||||
<g id="Symbol_-_Original_2_">
|
||||
</g>
|
||||
<g id="_x34__1_">
|
||||
</g>
|
||||
<g id="Symbol_-_Monochromatic_2_">
|
||||
<g id="_x33__6_">
|
||||
</g>
|
||||
</g>
|
||||
<g id="One_color_version_-_White_2_">
|
||||
<g id="Symbol_-_Original_11_">
|
||||
</g>
|
||||
</g>
|
||||
<g id="Symbol_-_Original_5_">
|
||||
<g id="Symbol_-_Original_12_">
|
||||
</g>
|
||||
</g>
|
||||
<g id="One_color_version_-_White_1_">
|
||||
<g id="Symbol_-_Original_9_">
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g id="SYMBOL_VER_1_2_">
|
||||
<g id="SYMBOL_VER_2_4_">
|
||||
</g>
|
||||
<g id="SYMBOL_VER_2-1-1_1_">
|
||||
</g>
|
||||
<g id="SYMBOL_VER_2-2-1_1_">
|
||||
</g>
|
||||
<g id="SYMBOL_VER_2-3-1_4_">
|
||||
</g>
|
||||
<g id="New_Symbol_1_">
|
||||
<g id="SYMBOL_VER_2-3-1_3_">
|
||||
</g>
|
||||
</g>
|
||||
<g id="New_Symbol">
|
||||
<g id="SYMBOL_VER_2-3-1_1_">
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g id="SYMBOL_VER_2_2_">
|
||||
</g>
|
||||
<g id="SYMBOL_VER_4_2_">
|
||||
</g>
|
||||
<g id="SYMBOL_VER_3_2_">
|
||||
</g>
|
||||
<g id="SYMBOL_VER_3_1_">
|
||||
</g>
|
||||
<g id="SYMBOL_VER_1-1-1_1_">
|
||||
</g>
|
||||
<g id="SYMBOL_VER_1-1-1">
|
||||
</g>
|
||||
<g id="SYMBOL_VER_1-1-1_2_2_">
|
||||
</g>
|
||||
<g id="SYMBOL_VER_1-1-1_2">
|
||||
</g>
|
||||
<g id="SYMBOL_VER_1-1-1_2_1_">
|
||||
</g>
|
||||
<g id="Symbol_-_Original_7_">
|
||||
</g>
|
||||
<g id="Symbol_-_Original_8_">
|
||||
</g>
|
||||
<g id="SYMBOL_VER_2-1-1">
|
||||
</g>
|
||||
<g id="SYMBOL_VER_2-2-1">
|
||||
</g>
|
||||
<g id="SYMBOL_VER_2-3-1">
|
||||
</g>
|
||||
<g id="SYMBOL_VER_5-1_1_">
|
||||
</g>
|
||||
<g id="SYMBOL_VER_5-1">
|
||||
</g>
|
||||
<g id="SYMBOL_VER_5-2_1_">
|
||||
</g>
|
||||
<g id="SYMBOL_VER_5-2">
|
||||
</g>
|
||||
<g id="Symbol_-_Monochromatic_1_">
|
||||
<g id="_x33__4_">
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.3 KiB |
14
src/assets/svg/arbitrum_mask.svg
Normal file
|
After Width: | Height: | Size: 250 KiB |
@@ -1,9 +1,10 @@
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import useCopyClipboard from '../../hooks/useCopyClipboard'
|
||||
|
||||
import { LinkStyledButton } from '../../theme'
|
||||
import { CheckCircle, Copy } from 'react-feather'
|
||||
import { Trans } from '@lingui/macro'
|
||||
|
||||
const CopyIcon = styled(LinkStyledButton)`
|
||||
color: ${({ theme }) => theme.text3};
|
||||
@@ -33,7 +34,9 @@ export default function CopyHelper(props: { toCopy: string; children?: React.Rea
|
||||
{isCopied ? (
|
||||
<TransactionStatusText>
|
||||
<CheckCircle size={'16'} />
|
||||
<TransactionStatusText>Copied</TransactionStatusText>
|
||||
<TransactionStatusText>
|
||||
<Trans>Copied</Trans>
|
||||
</TransactionStatusText>
|
||||
</TransactionStatusText>
|
||||
) : (
|
||||
<TransactionStatusText>
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { CheckCircle, Triangle } from 'react-feather'
|
||||
|
||||
import { useActiveWeb3React } from '../../hooks'
|
||||
import { getEtherscanLink } from '../../utils'
|
||||
import { useActiveWeb3React } from '../../hooks/web3'
|
||||
import { ExternalLink } from '../../theme'
|
||||
import { useAllTransactions } from '../../state/transactions/hooks'
|
||||
import { ExplorerDataType, getExplorerLink } from '../../utils/getExplorerLink'
|
||||
import { RowFixed } from '../Row'
|
||||
import Loader from '../Loader'
|
||||
|
||||
@@ -49,7 +48,11 @@ export default function Transaction({ hash }: { hash: string }) {
|
||||
|
||||
return (
|
||||
<TransactionWrapper>
|
||||
<TransactionState href={getEtherscanLink(chainId, hash, 'transaction')} pending={pending} success={success}>
|
||||
<TransactionState
|
||||
href={getExplorerLink(chainId, hash, ExplorerDataType.TRANSACTION)}
|
||||
pending={pending}
|
||||
success={success}
|
||||
>
|
||||
<RowFixed>
|
||||
<TransactionStatusText>{summary ?? hash} ↗</TransactionStatusText>
|
||||
</RowFixed>
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
import React, { useCallback, useContext } from 'react'
|
||||
import { useDispatch } from 'react-redux'
|
||||
import { useCallback, useContext } from 'react'
|
||||
import styled, { ThemeContext } from 'styled-components'
|
||||
import { useActiveWeb3React } from '../../hooks'
|
||||
import { AppDispatch } from '../../state'
|
||||
import { SUPPORTED_WALLETS } from '../../constants/wallet'
|
||||
import { useActiveWeb3React } from '../../hooks/web3'
|
||||
import { clearAllTransactions } from '../../state/transactions/actions'
|
||||
import { shortenAddress } from '../../utils'
|
||||
import { ExplorerDataType, getExplorerLink } from '../../utils/getExplorerLink'
|
||||
import { AutoRow } from '../Row'
|
||||
import Copy from './Copy'
|
||||
import Transaction from './Transaction'
|
||||
|
||||
import { SUPPORTED_WALLETS } from '../../constants'
|
||||
import { ReactComponent as Close } from '../../assets/images/x.svg'
|
||||
import { getEtherscanLink } from '../../utils'
|
||||
import { injected, walletconnect, walletlink, fortmatic, portis } from '../../connectors'
|
||||
import CoinbaseWalletIcon from '../../assets/images/coinbaseWalletIcon.svg'
|
||||
import WalletConnectIcon from '../../assets/images/walletConnectIcon.svg'
|
||||
@@ -21,6 +19,8 @@ import Identicon from '../Identicon'
|
||||
import { ButtonSecondary } from '../Button'
|
||||
import { ExternalLink as LinkIcon } from 'react-feather'
|
||||
import { ExternalLink, LinkStyledButton, TYPE } from '../../theme'
|
||||
import { Trans } from '@lingui/macro'
|
||||
import { useAppDispatch } from 'state/hooks'
|
||||
|
||||
const HeaderRow = styled.div`
|
||||
${({ theme }) => theme.flexRowNoWrap};
|
||||
@@ -226,7 +226,7 @@ export default function AccountDetails({
|
||||
}: AccountDetailsProps) {
|
||||
const { chainId, account, connector } = useActiveWeb3React()
|
||||
const theme = useContext(ThemeContext)
|
||||
const dispatch = useDispatch<AppDispatch>()
|
||||
const dispatch = useAppDispatch()
|
||||
|
||||
function formatConnectorName() {
|
||||
const { ethereum } = window
|
||||
@@ -237,7 +237,11 @@ export default function AccountDetails({
|
||||
SUPPORTED_WALLETS[k].connector === connector && (connector !== injected || isMetaMask === (k === 'METAMASK'))
|
||||
)
|
||||
.map((k) => SUPPORTED_WALLETS[k].name)[0]
|
||||
return <WalletName>Connected with {name}</WalletName>
|
||||
return (
|
||||
<WalletName>
|
||||
<Trans>Connected with {name}</Trans>
|
||||
</WalletName>
|
||||
)
|
||||
}
|
||||
|
||||
function getStatusIcon() {
|
||||
@@ -250,32 +254,32 @@ export default function AccountDetails({
|
||||
} else if (connector === walletconnect) {
|
||||
return (
|
||||
<IconWrapper size={16}>
|
||||
<img src={WalletConnectIcon} alt={'wallet connect logo'} />
|
||||
<img src={WalletConnectIcon} alt={'WalletConnect logo'} />
|
||||
</IconWrapper>
|
||||
)
|
||||
} else if (connector === walletlink) {
|
||||
return (
|
||||
<IconWrapper size={16}>
|
||||
<img src={CoinbaseWalletIcon} alt={'coinbase wallet logo'} />
|
||||
<img src={CoinbaseWalletIcon} alt={'Coinbase Wallet logo'} />
|
||||
</IconWrapper>
|
||||
)
|
||||
} else if (connector === fortmatic) {
|
||||
return (
|
||||
<IconWrapper size={16}>
|
||||
<img src={FortmaticIcon} alt={'fortmatic logo'} />
|
||||
<img src={FortmaticIcon} alt={'Fortmatic logo'} />
|
||||
</IconWrapper>
|
||||
)
|
||||
} else if (connector === portis) {
|
||||
return (
|
||||
<>
|
||||
<IconWrapper size={16}>
|
||||
<img src={PortisIcon} alt={'portis logo'} />
|
||||
<img src={PortisIcon} alt={'Portis logo'} />
|
||||
<MainWalletAction
|
||||
onClick={() => {
|
||||
portis.portis.showPortis()
|
||||
}}
|
||||
>
|
||||
Show Portis
|
||||
<Trans>Show Portis</Trans>
|
||||
</MainWalletAction>
|
||||
</IconWrapper>
|
||||
</>
|
||||
@@ -294,7 +298,9 @@ export default function AccountDetails({
|
||||
<CloseIcon onClick={toggleWalletModal}>
|
||||
<CloseColor />
|
||||
</CloseIcon>
|
||||
<HeaderRow>Account</HeaderRow>
|
||||
<HeaderRow>
|
||||
<Trans>Account</Trans>
|
||||
</HeaderRow>
|
||||
<AccountSection>
|
||||
<YourAccount>
|
||||
<InfoCard>
|
||||
@@ -308,7 +314,7 @@ export default function AccountDetails({
|
||||
;(connector as any).close()
|
||||
}}
|
||||
>
|
||||
Disconnect
|
||||
<Trans>Disconnect</Trans>
|
||||
</WalletAction>
|
||||
)}
|
||||
<WalletAction
|
||||
@@ -317,7 +323,7 @@ export default function AccountDetails({
|
||||
openOptions()
|
||||
}}
|
||||
>
|
||||
Change
|
||||
<Trans>Change</Trans>
|
||||
</WalletAction>
|
||||
</div>
|
||||
</AccountGroupingRow>
|
||||
@@ -347,17 +353,21 @@ export default function AccountDetails({
|
||||
<div>
|
||||
{account && (
|
||||
<Copy toCopy={account}>
|
||||
<span style={{ marginLeft: '4px' }}>Copy Address</span>
|
||||
<span style={{ marginLeft: '4px' }}>
|
||||
<Trans>Copy Address</Trans>
|
||||
</span>
|
||||
</Copy>
|
||||
)}
|
||||
{chainId && account && (
|
||||
<AddressLink
|
||||
hasENS={!!ENSName}
|
||||
isENS={true}
|
||||
href={chainId && getEtherscanLink(chainId, ENSName, 'address')}
|
||||
href={getExplorerLink(chainId, ENSName, ExplorerDataType.ADDRESS)}
|
||||
>
|
||||
<LinkIcon size={16} />
|
||||
<span style={{ marginLeft: '4px' }}>View on Etherscan</span>
|
||||
<span style={{ marginLeft: '4px' }}>
|
||||
<Trans>View on Explorer</Trans>
|
||||
</span>
|
||||
</AddressLink>
|
||||
)}
|
||||
</div>
|
||||
@@ -369,17 +379,21 @@ export default function AccountDetails({
|
||||
<div>
|
||||
{account && (
|
||||
<Copy toCopy={account}>
|
||||
<span style={{ marginLeft: '4px' }}>Copy Address</span>
|
||||
<span style={{ marginLeft: '4px' }}>
|
||||
<Trans>Copy Address</Trans>
|
||||
</span>
|
||||
</Copy>
|
||||
)}
|
||||
{chainId && account && (
|
||||
<AddressLink
|
||||
hasENS={!!ENSName}
|
||||
isENS={false}
|
||||
href={getEtherscanLink(chainId, account, 'address')}
|
||||
href={getExplorerLink(chainId, account, ExplorerDataType.ADDRESS)}
|
||||
>
|
||||
<LinkIcon size={16} />
|
||||
<span style={{ marginLeft: '4px' }}>View on Etherscan</span>
|
||||
<span style={{ marginLeft: '4px' }}>
|
||||
<Trans>View on Explorer</Trans>
|
||||
</span>
|
||||
</AddressLink>
|
||||
)}
|
||||
</div>
|
||||
@@ -394,15 +408,21 @@ export default function AccountDetails({
|
||||
{!!pendingTransactions.length || !!confirmedTransactions.length ? (
|
||||
<LowerSection>
|
||||
<AutoRow mb={'1rem'} style={{ justifyContent: 'space-between' }}>
|
||||
<TYPE.body>Recent Transactions</TYPE.body>
|
||||
<LinkStyledButton onClick={clearAllTransactionsCallback}>(clear all)</LinkStyledButton>
|
||||
<TYPE.body>
|
||||
<Trans>Recent Transactions</Trans>
|
||||
</TYPE.body>
|
||||
<LinkStyledButton onClick={clearAllTransactionsCallback}>
|
||||
<Trans>(clear all)</Trans>
|
||||
</LinkStyledButton>
|
||||
</AutoRow>
|
||||
{renderTransactions(pendingTransactions)}
|
||||
{renderTransactions(confirmedTransactions)}
|
||||
</LowerSection>
|
||||
) : (
|
||||
<LowerSection>
|
||||
<TYPE.body color={theme.text1}>Your transactions will appear here...</TYPE.body>
|
||||
<TYPE.body color={theme.text1}>
|
||||
<Trans>Your transactions will appear here...</Trans>
|
||||
</TYPE.body>
|
||||
</LowerSection>
|
||||
)}
|
||||
</>
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import React, { useContext, useCallback } from 'react'
|
||||
import { t, Trans } from '@lingui/macro'
|
||||
import { useContext, useCallback, ReactNode } from 'react'
|
||||
import styled, { ThemeContext } from 'styled-components'
|
||||
import useENS from '../../hooks/useENS'
|
||||
import { useActiveWeb3React } from '../../hooks'
|
||||
import { useActiveWeb3React } from '../../hooks/web3'
|
||||
import { ExternalLink, TYPE } from '../../theme'
|
||||
import { ExplorerDataType, getExplorerLink } from '../../utils/getExplorerLink'
|
||||
import { AutoColumn } from '../Column'
|
||||
import { RowBetween } from '../Row'
|
||||
import { getEtherscanLink } from '../../utils'
|
||||
|
||||
const InputPanel = styled.div`
|
||||
${({ theme }) => theme.flexColumnNoWrap}
|
||||
@@ -40,7 +41,7 @@ const Input = styled.input<{ error?: boolean }>`
|
||||
width: 0;
|
||||
background-color: ${({ theme }) => theme.bg1};
|
||||
transition: color 300ms ${({ error }) => (error ? 'step-end' : 'step-start')};
|
||||
color: ${({ error, theme }) => (error ? theme.red1 : theme.primary1)};
|
||||
color: ${({ error, theme }) => (error ? theme.red1 : theme.text1)};
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
font-weight: 500;
|
||||
@@ -67,10 +68,16 @@ const Input = styled.input<{ error?: boolean }>`
|
||||
|
||||
export default function AddressInputPanel({
|
||||
id,
|
||||
className = 'recipient-address-input',
|
||||
label,
|
||||
placeholder,
|
||||
value,
|
||||
onChange,
|
||||
}: {
|
||||
id?: string
|
||||
className?: string
|
||||
label?: ReactNode
|
||||
placeholder?: string
|
||||
// the typed string value
|
||||
value: string
|
||||
// triggers whenever the typed value changes
|
||||
@@ -99,22 +106,25 @@ export default function AddressInputPanel({
|
||||
<AutoColumn gap="md">
|
||||
<RowBetween>
|
||||
<TYPE.black color={theme.text2} fontWeight={500} fontSize={14}>
|
||||
Recipient
|
||||
{label ?? <Trans>Recipient</Trans>}
|
||||
</TYPE.black>
|
||||
{address && chainId && (
|
||||
<ExternalLink href={getEtherscanLink(chainId, name ?? address, 'address')} style={{ fontSize: '14px' }}>
|
||||
(View on Etherscan)
|
||||
<ExternalLink
|
||||
href={getExplorerLink(chainId, name ?? address, ExplorerDataType.ADDRESS)}
|
||||
style={{ fontSize: '14px' }}
|
||||
>
|
||||
<Trans>(View on Explorer)</Trans>
|
||||
</ExternalLink>
|
||||
)}
|
||||
</RowBetween>
|
||||
<Input
|
||||
className="recipient-address-input"
|
||||
className={className}
|
||||
type="text"
|
||||
autoComplete="off"
|
||||
autoCorrect="off"
|
||||
autoCapitalize="off"
|
||||
spellCheck="false"
|
||||
placeholder="Wallet Address or ENS name"
|
||||
placeholder={placeholder ?? t`Wallet Address or ENS name`}
|
||||
error={error}
|
||||
pattern="^(0x[a-fA-F0-9]{40})$"
|
||||
onChange={handleInput}
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
import { Story } from '@storybook/react/types-6-0'
|
||||
import React, { PropsWithChildren } from 'react'
|
||||
import Component, { BadgeProps, BadgeVariant } from './index'
|
||||
|
||||
export default {
|
||||
title: 'Badge',
|
||||
argTypes: {
|
||||
variant: {
|
||||
name: 'variant',
|
||||
type: { name: 'string', require: false },
|
||||
defaultValue: BadgeVariant.DEFAULT,
|
||||
description: 'badge variant',
|
||||
control: {
|
||||
type: 'select',
|
||||
options: Object.values(BadgeVariant),
|
||||
},
|
||||
},
|
||||
},
|
||||
args: {
|
||||
children: '🦄 UNISWAP 🦄',
|
||||
},
|
||||
}
|
||||
|
||||
const Template: Story<PropsWithChildren<BadgeProps>> = (args) => <Component {...args}>{args.children}</Component>
|
||||
|
||||
export const DefaultBadge = Template.bind({})
|
||||
DefaultBadge.args = {
|
||||
variant: BadgeVariant.DEFAULT,
|
||||
}
|
||||
|
||||
export const WarningBadge = Template.bind({})
|
||||
WarningBadge.args = {
|
||||
variant: BadgeVariant.WARNING,
|
||||
}
|
||||
|
||||
export const NegativeBadge = Template.bind({})
|
||||
NegativeBadge.args = {
|
||||
variant: BadgeVariant.NEGATIVE,
|
||||
}
|
||||
|
||||
export const PositiveBadge = Template.bind({})
|
||||
PositiveBadge.args = {
|
||||
variant: BadgeVariant.POSITIVE,
|
||||
}
|
||||
@@ -1,10 +1,8 @@
|
||||
import React from 'react'
|
||||
|
||||
import Badge, { BadgeVariant } from 'components/Badge'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
|
||||
import { MouseoverTooltip } from '../../components/Tooltip'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Trans } from '@lingui/macro'
|
||||
import { AlertCircle } from 'react-feather'
|
||||
|
||||
const BadgeWrapper = styled.div`
|
||||
@@ -40,35 +38,47 @@ export default function RangeBadge({
|
||||
removed: boolean | undefined
|
||||
inRange: boolean | undefined
|
||||
}) {
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<BadgeWrapper>
|
||||
{removed ? (
|
||||
<MouseoverTooltip text={`Your position has 0 liquidity, and is not earning fees.`}>
|
||||
<MouseoverTooltip text={<Trans>Your position has 0 liquidity, and is not earning fees.</Trans>}>
|
||||
<Badge variant={BadgeVariant.DEFAULT}>
|
||||
<AlertCircle width={14} height={14} />
|
||||
|
||||
<BadgeText>{t('Inactive')}</BadgeText>
|
||||
<BadgeText>
|
||||
<Trans>Closed</Trans>
|
||||
</BadgeText>
|
||||
</Badge>
|
||||
</MouseoverTooltip>
|
||||
) : inRange ? (
|
||||
<MouseoverTooltip
|
||||
text={`The price of this pool is within your selected range. Your position is currently earning fees.`}
|
||||
text={
|
||||
<Trans>
|
||||
The price of this pool is within your selected range. Your position is currently earning fees.
|
||||
</Trans>
|
||||
}
|
||||
>
|
||||
<Badge variant={BadgeVariant.DEFAULT}>
|
||||
<ActiveDot />
|
||||
<BadgeText>{t('In range')}</BadgeText>
|
||||
<BadgeText>
|
||||
<Trans>In range</Trans>
|
||||
</BadgeText>
|
||||
</Badge>
|
||||
</MouseoverTooltip>
|
||||
) : (
|
||||
<MouseoverTooltip
|
||||
text={`The price of this pool is outside of your selected range. Your position is not currently earning fees.`}
|
||||
text={
|
||||
<Trans>
|
||||
The price of this pool is outside of your selected range. Your position is not currently earning fees.
|
||||
</Trans>
|
||||
}
|
||||
>
|
||||
<Badge variant={BadgeVariant.WARNING}>
|
||||
<AlertCircle width={14} height={14} />
|
||||
|
||||
<BadgeText>{t('Out of range')}</BadgeText>
|
||||
<BadgeText>
|
||||
<Trans>Out of range</Trans>
|
||||
</BadgeText>
|
||||
</Badge>
|
||||
</MouseoverTooltip>
|
||||
)}
|
||||
|
||||
@@ -1,12 +1,25 @@
|
||||
import React, { ReactNode, useMemo } from 'react'
|
||||
import { BLOCKED_ADDRESSES } from '../../constants'
|
||||
import { useActiveWeb3React } from '../../hooks'
|
||||
import { ReactNode, useMemo } from 'react'
|
||||
import { useActiveWeb3React } from '../../hooks/web3'
|
||||
import { Trans } from '@lingui/macro'
|
||||
|
||||
// SDN OFAC addresses
|
||||
const BLOCKED_ADDRESSES: string[] = [
|
||||
'0x7F367cC41522cE07553e823bf3be79A889DEbe1B',
|
||||
'0xd882cFc20F52f2599D84b8e8D58C7FB62cfE344b',
|
||||
'0x901bb9583b24D97e995513C6778dc6888AB6870e',
|
||||
'0xA7e5d5A720f06526557c513402f2e6B5fA20b008',
|
||||
'0x8576aCC5C05D6Ce88f4e49bf65BdF0C62F91353C',
|
||||
]
|
||||
|
||||
export default function Blocklist({ children }: { children: ReactNode }) {
|
||||
const { account } = useActiveWeb3React()
|
||||
const blocked: boolean = useMemo(() => Boolean(account && BLOCKED_ADDRESSES.indexOf(account) !== -1), [account])
|
||||
if (blocked) {
|
||||
return <div>Blocked address</div>
|
||||
return (
|
||||
<div>
|
||||
<Trans>Blocked address</Trans>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
return <>{children}</>
|
||||
}
|
||||
|
||||
@@ -1,153 +0,0 @@
|
||||
import { Story } from '@storybook/react/types-6-0'
|
||||
import styled from 'styled-components'
|
||||
import React from 'react'
|
||||
import {
|
||||
ButtonConfirmed,
|
||||
ButtonDropdown,
|
||||
ButtonDropdownGrey,
|
||||
ButtonDropdownLight,
|
||||
ButtonEmpty,
|
||||
ButtonError,
|
||||
ButtonGray,
|
||||
ButtonLight,
|
||||
ButtonOutlined,
|
||||
ButtonPink,
|
||||
ButtonPrimary,
|
||||
ButtonRadio,
|
||||
ButtonSecondary,
|
||||
ButtonUNIGradient,
|
||||
ButtonWhite,
|
||||
} from './index'
|
||||
|
||||
const wrapperCss = styled.main`
|
||||
font-size: 2em;
|
||||
margin: 3em;
|
||||
max-width: 300px;
|
||||
`
|
||||
|
||||
export default {
|
||||
title: 'Buttons',
|
||||
argTypes: {
|
||||
disabled: { control: { type: 'boolean' } },
|
||||
onClick: { action: 'clicked' },
|
||||
},
|
||||
decorators: [
|
||||
(Component: Story) => (
|
||||
<div css={wrapperCss}>
|
||||
<Component />
|
||||
</div>
|
||||
),
|
||||
],
|
||||
}
|
||||
|
||||
const Unicorn = () => (
|
||||
<span role="img" aria-label="unicorn">
|
||||
🦄
|
||||
</span>
|
||||
)
|
||||
|
||||
export const Radio = () => (
|
||||
<ButtonRadio>
|
||||
<Unicorn />
|
||||
UNISWAP
|
||||
<Unicorn />
|
||||
</ButtonRadio>
|
||||
)
|
||||
export const DropdownLight = () => (
|
||||
<ButtonDropdownLight>
|
||||
<Unicorn />
|
||||
UNISWAP
|
||||
<Unicorn />
|
||||
</ButtonDropdownLight>
|
||||
)
|
||||
export const DropdownGrey = () => (
|
||||
<ButtonDropdownGrey>
|
||||
<Unicorn />
|
||||
UNISWAP
|
||||
<Unicorn />
|
||||
</ButtonDropdownGrey>
|
||||
)
|
||||
export const Dropdown = () => (
|
||||
<ButtonDropdown>
|
||||
<Unicorn />
|
||||
UNISWAP
|
||||
<Unicorn />
|
||||
</ButtonDropdown>
|
||||
)
|
||||
export const Error = () => (
|
||||
<ButtonError>
|
||||
<Unicorn />
|
||||
UNISWAP
|
||||
<Unicorn />
|
||||
</ButtonError>
|
||||
)
|
||||
export const Confirmed = () => (
|
||||
<ButtonConfirmed>
|
||||
<Unicorn />
|
||||
UNISWAP
|
||||
<Unicorn />
|
||||
</ButtonConfirmed>
|
||||
)
|
||||
export const White = () => (
|
||||
<ButtonWhite>
|
||||
<Unicorn />
|
||||
UNISWAP
|
||||
<Unicorn />
|
||||
</ButtonWhite>
|
||||
)
|
||||
export const Empty = () => (
|
||||
<ButtonEmpty>
|
||||
<Unicorn />
|
||||
UNISWAP
|
||||
<Unicorn />
|
||||
</ButtonEmpty>
|
||||
)
|
||||
export const Outlined = () => (
|
||||
<ButtonOutlined>
|
||||
<Unicorn />
|
||||
UNISWAP
|
||||
<Unicorn />
|
||||
</ButtonOutlined>
|
||||
)
|
||||
export const UNIGradient = () => (
|
||||
<ButtonUNIGradient>
|
||||
<Unicorn />
|
||||
UNISWAP
|
||||
<Unicorn />
|
||||
</ButtonUNIGradient>
|
||||
)
|
||||
export const Pink = () => (
|
||||
<ButtonPink>
|
||||
<Unicorn />
|
||||
UNISWAP
|
||||
<Unicorn />
|
||||
</ButtonPink>
|
||||
)
|
||||
export const Secondary = () => (
|
||||
<ButtonSecondary>
|
||||
<Unicorn />
|
||||
UNISWAP
|
||||
<Unicorn />
|
||||
</ButtonSecondary>
|
||||
)
|
||||
export const Gray = () => (
|
||||
<ButtonGray>
|
||||
<Unicorn />
|
||||
UNISWAP
|
||||
<Unicorn />
|
||||
</ButtonGray>
|
||||
)
|
||||
export const Light = () => (
|
||||
<ButtonLight>
|
||||
<Unicorn />
|
||||
UNISWAP
|
||||
<Unicorn />
|
||||
</ButtonLight>
|
||||
)
|
||||
export const Primary = () => (
|
||||
<ButtonPrimary>
|
||||
<Unicorn />
|
||||
UNISWAP
|
||||
<Unicorn />
|
||||
</ButtonPrimary>
|
||||
)
|
||||
@@ -1,18 +1,21 @@
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { darken } from 'polished'
|
||||
|
||||
import { RowBetween } from '../Row'
|
||||
import { ChevronDown, Check } from 'react-feather'
|
||||
import { Button as RebassButton, ButtonProps } from 'rebass/styled-components'
|
||||
import { Button as RebassButton, ButtonProps as ButtonPropsOriginal } from 'rebass/styled-components'
|
||||
import useTheme from 'hooks/useTheme'
|
||||
|
||||
const Base = styled(RebassButton)<{
|
||||
padding?: string
|
||||
width?: string
|
||||
borderRadius?: string
|
||||
altDisabledStyle?: boolean
|
||||
}>`
|
||||
type ButtonProps = Omit<ButtonPropsOriginal, 'css'>
|
||||
|
||||
const Base = styled(RebassButton)<
|
||||
{
|
||||
padding?: string
|
||||
width?: string
|
||||
borderRadius?: string
|
||||
altDisabledStyle?: boolean
|
||||
} & ButtonProps
|
||||
>`
|
||||
padding: ${({ padding }) => (padding ? padding : '16px')};
|
||||
width: ${({ width }) => (width ? width : '100%')};
|
||||
font-weight: 500;
|
||||
@@ -68,14 +71,12 @@ export const ButtonPrimary = styled(Base)`
|
||||
}
|
||||
&:disabled {
|
||||
background-color: ${({ theme, altDisabledStyle, disabled }) =>
|
||||
altDisabledStyle ? (disabled ? theme.primary1 : theme.primary1) : theme.primary1};
|
||||
color: white;
|
||||
altDisabledStyle ? (disabled ? theme.primary1 : theme.bg2) : theme.bg2};
|
||||
color: ${({ theme }) => theme.text2};
|
||||
cursor: auto;
|
||||
box-shadow: none;
|
||||
border: 1px solid transparent;
|
||||
outline: none;
|
||||
opacity: 0.4;
|
||||
opacity: ${({ altDisabledStyle }) => (altDisabledStyle ? '0.5' : '0.4')};
|
||||
}
|
||||
`
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { Box } from 'rebass/styled-components'
|
||||
|
||||
const Card = styled(Box)<{ width?: string; padding?: string; border?: string; borderRadius?: string }>`
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
|
||||
const Column = styled.div`
|
||||
display: flex;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react'
|
||||
import ReactConfetti from 'react-confetti'
|
||||
import { useWindowSize } from '../../hooks/useWindowSize'
|
||||
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
import { CurrencyAmount, Percent } from '@uniswap/sdk-core'
|
||||
import React, { useMemo } from 'react'
|
||||
import { Currency, CurrencyAmount, Percent } from '@uniswap/sdk-core'
|
||||
import { useMemo } from 'react'
|
||||
import useTheme from '../../hooks/useTheme'
|
||||
import { TYPE } from '../../theme'
|
||||
import { warningSeverity } from '../../utils/prices'
|
||||
import HoverInlineText from 'components/HoverInlineText'
|
||||
import { Trans } from '@lingui/macro'
|
||||
|
||||
export function FiatValue({
|
||||
fiatValue,
|
||||
priceImpact,
|
||||
}: {
|
||||
fiatValue: CurrencyAmount | null | undefined
|
||||
fiatValue: CurrencyAmount<Currency> | null | undefined
|
||||
priceImpact?: Percent
|
||||
}) {
|
||||
const theme = useTheme()
|
||||
@@ -17,17 +18,25 @@ export function FiatValue({
|
||||
if (!priceImpact) return undefined
|
||||
if (priceImpact.lessThan('0')) return theme.green1
|
||||
const severity = warningSeverity(priceImpact)
|
||||
if (severity < 1) return theme.text4
|
||||
if (severity < 1) return theme.text3
|
||||
if (severity < 3) return theme.yellow1
|
||||
return theme.red1
|
||||
}, [priceImpact, theme.green1, theme.red1, theme.text4, theme.yellow1])
|
||||
}, [priceImpact, theme.green1, theme.red1, theme.text3, theme.yellow1])
|
||||
|
||||
return (
|
||||
<TYPE.body fontSize={14} color={fiatValue ? theme.text2 : theme.text4}>
|
||||
{fiatValue ? '~' : ''}$
|
||||
<HoverInlineText text={fiatValue ? Number(fiatValue?.toSignificant(6)).toLocaleString('en') : '-'} />{' '}
|
||||
{fiatValue ? (
|
||||
<Trans>
|
||||
~$ <HoverInlineText text={fiatValue?.toSignificant(6, { groupSeparator: ',' })} />
|
||||
</Trans>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
{priceImpact ? (
|
||||
<span style={{ color: priceImpactColor }}> ({priceImpact.multiply(-100).toSignificant(3)}%)</span>
|
||||
<span style={{ color: priceImpactColor }}>
|
||||
{' '}
|
||||
(<Trans>{priceImpact.multiply(-1).toSignificant(3)}%</Trans>)
|
||||
</span>
|
||||
) : null}
|
||||
</TYPE.body>
|
||||
)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Pair } from '@uniswap/v2-sdk'
|
||||
import { Currency, CurrencyAmount, Percent } from '@uniswap/sdk-core'
|
||||
import React, { useState, useCallback } from 'react'
|
||||
import styled from 'styled-components'
|
||||
import { Currency, CurrencyAmount, Percent, Token } from '@uniswap/sdk-core'
|
||||
import { useState, useCallback, ReactNode } from 'react'
|
||||
import styled from 'styled-components/macro'
|
||||
import { darken } from 'polished'
|
||||
import { useCurrencyBalance } from '../../state/wallet/hooks'
|
||||
import CurrencySearchModal from '../SearchModal/CurrencySearchModal'
|
||||
@@ -12,12 +12,13 @@ import { RowBetween, RowFixed } from '../Row'
|
||||
import { TYPE } from '../../theme'
|
||||
import { Input as NumericalInput } from '../NumericalInput'
|
||||
import { ReactComponent as DropDown } from '../../assets/images/dropdown.svg'
|
||||
import { useActiveWeb3React } from '../../hooks'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useActiveWeb3React } from '../../hooks/web3'
|
||||
import { Trans } from '@lingui/macro'
|
||||
import useTheme from '../../hooks/useTheme'
|
||||
import { Lock } from 'react-feather'
|
||||
import { AutoColumn } from 'components/Column'
|
||||
import { FiatValue } from './FiatValue'
|
||||
import { formatCurrencyAmount } from 'utils/formatCurrencyAmount'
|
||||
|
||||
const InputPanel = styled.div<{ hideInput?: boolean }>`
|
||||
${({ theme }) => theme.flexColumnNoWrap}
|
||||
@@ -129,16 +130,12 @@ const StyledBalanceMax = styled.button<{ disabled?: boolean }>`
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
color: ${({ theme }) => theme.primary1};
|
||||
color: ${({ theme }) => theme.primaryText1};
|
||||
opacity: ${({ disabled }) => (!disabled ? 1 : 0.4)};
|
||||
pointer-events: ${({ disabled }) => (!disabled ? 'initial' : 'none')};
|
||||
margin-left: 0.25rem;
|
||||
|
||||
:hover {
|
||||
/* border: 1px solid ${({ theme }) => theme.primary1}; */
|
||||
}
|
||||
:focus {
|
||||
/* border: 1px solid ${({ theme }) => theme.primary1}; */
|
||||
outline: none;
|
||||
}
|
||||
|
||||
@@ -152,18 +149,20 @@ interface CurrencyInputPanelProps {
|
||||
onUserInput: (value: string) => void
|
||||
onMax?: () => void
|
||||
showMaxButton: boolean
|
||||
label?: string
|
||||
label?: ReactNode
|
||||
onCurrencySelect?: (currency: Currency) => void
|
||||
currency?: Currency | null
|
||||
hideBalance?: boolean
|
||||
pair?: Pair | null
|
||||
hideInput?: boolean
|
||||
otherCurrency?: Currency | null
|
||||
fiatValue?: CurrencyAmount | null
|
||||
fiatValue?: CurrencyAmount<Token> | null
|
||||
priceImpact?: Percent
|
||||
id: string
|
||||
showCommonBases?: boolean
|
||||
customBalanceText?: string
|
||||
showCurrencyAmount?: boolean
|
||||
disableNonToken?: boolean
|
||||
renderBalance?: (amount: CurrencyAmount<Currency>) => ReactNode
|
||||
locked?: boolean
|
||||
}
|
||||
|
||||
@@ -177,7 +176,9 @@ export default function CurrencyInputPanel({
|
||||
otherCurrency,
|
||||
id,
|
||||
showCommonBases,
|
||||
customBalanceText,
|
||||
showCurrencyAmount,
|
||||
disableNonToken,
|
||||
renderBalance,
|
||||
fiatValue,
|
||||
priceImpact,
|
||||
hideBalance = false,
|
||||
@@ -186,8 +187,6 @@ export default function CurrencyInputPanel({
|
||||
locked = false,
|
||||
...rest
|
||||
}: CurrencyInputPanelProps) {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const [modalOpen, setModalOpen] = useState(false)
|
||||
const { account } = useActiveWeb3React()
|
||||
const selectedCurrencyBalance = useCurrencyBalance(account ?? undefined, currency ?? undefined)
|
||||
@@ -203,8 +202,8 @@ export default function CurrencyInputPanel({
|
||||
<FixedContainer>
|
||||
<AutoColumn gap="sm" justify="center">
|
||||
<Lock />
|
||||
<TYPE.label fontSize="12px" textAlign="center">
|
||||
The market price is outside your specified price range. Single-asset deposit only.
|
||||
<TYPE.label fontSize="12px" textAlign="center" padding="0 12px">
|
||||
<Trans>The market price is outside your specified price range. Single-asset deposit only.</Trans>
|
||||
</TYPE.label>
|
||||
</AutoColumn>
|
||||
</FixedContainer>
|
||||
@@ -240,7 +239,7 @@ export default function CurrencyInputPanel({
|
||||
? currency.symbol.slice(0, 4) +
|
||||
'...' +
|
||||
currency.symbol.slice(currency.symbol.length - 5, currency.symbol.length)
|
||||
: currency?.symbol) || t('selectToken')}
|
||||
: currency?.symbol) || <Trans>Select a token</Trans>}
|
||||
</StyledTokenName>
|
||||
)}
|
||||
</RowFixed>
|
||||
@@ -271,21 +270,25 @@ export default function CurrencyInputPanel({
|
||||
fontSize={14}
|
||||
style={{ display: 'inline', cursor: 'pointer' }}
|
||||
>
|
||||
{!hideBalance && !!currency && selectedCurrencyBalance
|
||||
? (customBalanceText ?? 'Balance: ') +
|
||||
selectedCurrencyBalance?.toSignificant(4) +
|
||||
' ' +
|
||||
currency.symbol
|
||||
: '-'}
|
||||
{!hideBalance && currency && selectedCurrencyBalance ? (
|
||||
renderBalance ? (
|
||||
renderBalance(selectedCurrencyBalance)
|
||||
) : (
|
||||
<Trans>
|
||||
Balance: {formatCurrencyAmount(selectedCurrencyBalance, 4)} {currency.symbol}
|
||||
</Trans>
|
||||
)
|
||||
) : null}
|
||||
</TYPE.body>
|
||||
{showMaxButton && selectedCurrencyBalance ? (
|
||||
<StyledBalanceMax onClick={onMax}>(Max)</StyledBalanceMax>
|
||||
<StyledBalanceMax onClick={onMax}>
|
||||
<Trans>(Max)</Trans>
|
||||
</StyledBalanceMax>
|
||||
) : null}
|
||||
</RowFixed>
|
||||
) : (
|
||||
'-'
|
||||
<span />
|
||||
)}
|
||||
|
||||
<FiatValue fiatValue={fiatValue} priceImpact={priceImpact} />
|
||||
</RowBetween>
|
||||
</FiatRow>
|
||||
@@ -299,6 +302,8 @@ export default function CurrencyInputPanel({
|
||||
selectedCurrency={currency}
|
||||
otherSelectedCurrency={otherCurrency}
|
||||
showCommonBases={showCommonBases}
|
||||
showCurrencyAmount={showCurrencyAmount}
|
||||
disableNonToken={disableNonToken}
|
||||
/>
|
||||
)}
|
||||
</InputPanel>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { ChainId, Currency, ETHER, Token } from '@uniswap/sdk-core'
|
||||
import { Currency } from '@uniswap/sdk-core'
|
||||
import React, { useMemo } from 'react'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import EthereumLogo from '../../assets/images/ethereum-logo.png'
|
||||
import useHttpLocations from '../../hooks/useHttpLocations'
|
||||
import { WrappedTokenInfo } from '../../state/lists/hooks'
|
||||
import { WrappedTokenInfo } from '../../state/lists/wrappedTokenInfo'
|
||||
import Logo from '../Logo'
|
||||
|
||||
export const getTokenLogoURL = (address: string) =>
|
||||
`https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/${address}/logo.png`
|
||||
`https://raw.githubusercontent.com/uniswap/assets/master/blockchains/ethereum/assets/${address}/logo.png`
|
||||
|
||||
const StyledEthereumLogo = styled.img<{ size: string }>`
|
||||
width: ${({ size }) => size};
|
||||
@@ -37,10 +37,10 @@ export default function CurrencyLogo({
|
||||
const uriLocations = useHttpLocations(currency instanceof WrappedTokenInfo ? currency.logoURI : undefined)
|
||||
|
||||
const srcs: string[] = useMemo(() => {
|
||||
if (currency === ETHER) return []
|
||||
if (!currency || currency.isNative) return []
|
||||
|
||||
if (currency instanceof Token) {
|
||||
const defaultUrls = currency.chainId === ChainId.MAINNET ? [getTokenLogoURL(currency.address)] : []
|
||||
if (currency.isToken) {
|
||||
const defaultUrls = currency.chainId === 1 ? [getTokenLogoURL(currency.address)] : []
|
||||
if (currency instanceof WrappedTokenInfo) {
|
||||
return [...uriLocations, ...defaultUrls]
|
||||
}
|
||||
@@ -49,7 +49,7 @@ export default function CurrencyLogo({
|
||||
return []
|
||||
}, [currency, uriLocations])
|
||||
|
||||
if (currency === ETHER) {
|
||||
if (currency?.isNative) {
|
||||
return <StyledEthereumLogo src={EthereumLogo} size={size} style={style} {...rest} />
|
||||
}
|
||||
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
import { Story } from '@storybook/react/types-6-0'
|
||||
import React from 'react'
|
||||
import { DAI, WBTC } from '../../constants'
|
||||
import Component, { DoubleCurrencyLogoProps } from './index'
|
||||
|
||||
export default {
|
||||
title: 'DoubleCurrencyLogo',
|
||||
decorators: [],
|
||||
}
|
||||
|
||||
const Template: Story<DoubleCurrencyLogoProps> = (args) => <Component {...args} />
|
||||
|
||||
export const DoubleCurrencyLogo = Template.bind({})
|
||||
DoubleCurrencyLogo.args = {
|
||||
currency0: DAI,
|
||||
currency1: WBTC,
|
||||
size: 220,
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Currency } from '@uniswap/sdk-core'
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import CurrencyLogo from '../CurrencyLogo'
|
||||
|
||||
const Wrapper = styled.div<{ margin: boolean; sizeraw: number }>`
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
import { Trans } from '@lingui/macro'
|
||||
import React, { ErrorInfo } from 'react'
|
||||
import { ExternalLink, ThemedBackground, TYPE } from '../../theme'
|
||||
import store, { AppState } from '../../state'
|
||||
import { ExternalLink, TYPE } from '../../theme'
|
||||
import { AutoColumn } from '../Column'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import ReactGA from 'react-ga'
|
||||
import { getUserAgent } from '../../utils/getUserAgent'
|
||||
import { AutoRow } from '../Row'
|
||||
|
||||
const FallbackWrapper = styled.div`
|
||||
display: flex;
|
||||
@@ -14,14 +17,15 @@ const FallbackWrapper = styled.div`
|
||||
`
|
||||
|
||||
const BodyWrapper = styled.div<{ margin?: string }>`
|
||||
position: relative;
|
||||
margin-top: 1rem;
|
||||
max-width: 60%;
|
||||
padding: 1rem;
|
||||
width: 100%;
|
||||
white-space: ;
|
||||
`
|
||||
|
||||
const CodeBlockWrapper = styled.div`
|
||||
background: ${({ theme }) => theme.bg0};
|
||||
overflow: auto;
|
||||
white-space: pre;
|
||||
box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.01), 0px 4px 8px rgba(0, 0, 0, 0.04), 0px 16px 24px rgba(0, 0, 0, 0.04),
|
||||
0px 24px 32px rgba(0, 0, 0, 0.01);
|
||||
border-radius: 24px;
|
||||
@@ -66,12 +70,11 @@ export default class ErrorBoundary extends React.Component<unknown, ErrorBoundar
|
||||
const encodedBody = encodeURIComponent(issueBody(error))
|
||||
return (
|
||||
<FallbackWrapper>
|
||||
<ThemedBackground />
|
||||
<BodyWrapper>
|
||||
<AutoColumn gap={'md'}>
|
||||
<SomethingWentWrongWrapper>
|
||||
<TYPE.label fontSize={24} fontWeight={600}>
|
||||
Something went wrong
|
||||
<Trans>Something went wrong</Trans>
|
||||
</TYPE.label>
|
||||
</SomethingWentWrongWrapper>
|
||||
<CodeBlockWrapper>
|
||||
@@ -79,18 +82,30 @@ export default class ErrorBoundary extends React.Component<unknown, ErrorBoundar
|
||||
<TYPE.main fontSize={10}>{error.stack}</TYPE.main>
|
||||
</code>
|
||||
</CodeBlockWrapper>
|
||||
<LinkWrapper>
|
||||
<ExternalLink
|
||||
id={`create-github-issue-link`}
|
||||
href={`https://github.com/Uniswap/uniswap-interface/issues/new?assignees=&labels=bug&body=${encodedBody}&title=Crash report`}
|
||||
target="_blank"
|
||||
>
|
||||
<TYPE.link fontSize={16}>
|
||||
Create an issue on GitHub
|
||||
<span>↗</span>
|
||||
</TYPE.link>
|
||||
</ExternalLink>
|
||||
</LinkWrapper>
|
||||
<AutoRow>
|
||||
<LinkWrapper>
|
||||
<ExternalLink
|
||||
id="create-github-issue-link"
|
||||
href={`https://github.com/Uniswap/uniswap-interface/issues/new?assignees=&labels=bug&body=${encodedBody}&title=${encodeURIComponent(
|
||||
`Crash report: \`${error.name}${error.message && `: ${error.message}`}\``
|
||||
)}`}
|
||||
target="_blank"
|
||||
>
|
||||
<TYPE.link fontSize={16}>
|
||||
<Trans>Create an issue on GitHub</Trans>
|
||||
<span>↗</span>
|
||||
</TYPE.link>
|
||||
</ExternalLink>
|
||||
</LinkWrapper>
|
||||
<LinkWrapper>
|
||||
<ExternalLink id="get-support-on-discord" href="https://discord.gg/FCfyBSbCU5" target="_blank">
|
||||
<TYPE.link fontSize={16}>
|
||||
<Trans>Get support on Discord</Trans>
|
||||
<span>↗</span>
|
||||
</TYPE.link>
|
||||
</ExternalLink>
|
||||
</LinkWrapper>
|
||||
</AutoRow>
|
||||
</AutoColumn>
|
||||
</BodyWrapper>
|
||||
</FallbackWrapper>
|
||||
@@ -100,22 +115,45 @@ export default class ErrorBoundary extends React.Component<unknown, ErrorBoundar
|
||||
}
|
||||
}
|
||||
|
||||
function getRelevantState(): null | keyof AppState {
|
||||
const path = window.location.hash
|
||||
if (!path.startsWith('#/')) {
|
||||
return null
|
||||
}
|
||||
const pieces = path.substring(2).split(/[\/\\?]/)
|
||||
switch (pieces[0]) {
|
||||
case 'swap':
|
||||
return 'swap'
|
||||
case 'add':
|
||||
if (pieces[1] === 'v2') return 'mint'
|
||||
else return 'mintV3'
|
||||
case 'remove':
|
||||
if (pieces[1] === 'v2') return 'burn'
|
||||
else return 'burnV3'
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
function issueBody(error: Error): string {
|
||||
if (!error) throw new Error('no error to report')
|
||||
const relevantState = getRelevantState()
|
||||
const deviceData = getUserAgent()
|
||||
return `**Bug Description**
|
||||
return `## URL
|
||||
|
||||
App crashed
|
||||
${window.location.href}
|
||||
|
||||
**Steps to Reproduce**
|
||||
|
||||
1. Go to ...
|
||||
2. Click on ...
|
||||
...
|
||||
|
||||
${
|
||||
relevantState
|
||||
? `## \`${relevantState}\` state
|
||||
|
||||
\`\`\`json
|
||||
${JSON.stringify(store.getState()[relevantState], null, 2)}
|
||||
\`\`\`
|
||||
`
|
||||
: ''
|
||||
}
|
||||
${
|
||||
error.name &&
|
||||
`**Error**
|
||||
`## Error
|
||||
|
||||
\`\`\`
|
||||
${error.name}${error.message && `: ${error.message}`}
|
||||
@@ -124,7 +162,7 @@ ${error.name}${error.message && `: ${error.message}`}
|
||||
}
|
||||
${
|
||||
error.stack &&
|
||||
`**Stacktrace**
|
||||
`## Stacktrace
|
||||
|
||||
\`\`\`
|
||||
${error.stack}
|
||||
@@ -133,9 +171,9 @@ ${error.stack}
|
||||
}
|
||||
${
|
||||
deviceData &&
|
||||
`**Device data**
|
||||
`## Device data
|
||||
|
||||
\`\`\`json5
|
||||
\`\`\`json
|
||||
${JSON.stringify(deviceData, null, 2)}
|
||||
\`\`\`
|
||||
`
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import React from 'react'
|
||||
import { FeeAmount } from '@uniswap/v3-sdk'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Trans } from '@lingui/macro'
|
||||
import { AutoColumn } from 'components/Column'
|
||||
import { DynamicSection } from 'pages/AddLiquidity/styled'
|
||||
import { TYPE } from 'theme'
|
||||
import { RowBetween } from 'components/Row'
|
||||
import { ButtonRadioChecked } from 'components/Button'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
|
||||
const ResponsiveText = styled(TYPE.label)`
|
||||
${({ theme }) => theme.mediaWidth.upToSmall`
|
||||
@@ -23,14 +22,14 @@ export default function FeeSelector({
|
||||
feeAmount?: FeeAmount
|
||||
handleFeePoolSelect: (feeAmount: FeeAmount) => void
|
||||
}) {
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<AutoColumn gap="16px">
|
||||
<DynamicSection gap="md" disabled={disabled}>
|
||||
<TYPE.label>{t('selectPool')}</TYPE.label>
|
||||
<TYPE.label>
|
||||
<Trans>Select Pool</Trans>
|
||||
</TYPE.label>
|
||||
<TYPE.main fontSize={14} fontWeight={400} style={{ marginBottom: '.5rem', lineHeight: '125%' }}>
|
||||
Select a pool type based on your preferred liquidity provider fee.
|
||||
<Trans>Select a pool type based on your preferred liquidity provider fee.</Trans>
|
||||
</TYPE.main>
|
||||
<RowBetween>
|
||||
<ButtonRadioChecked
|
||||
@@ -39,9 +38,11 @@ export default function FeeSelector({
|
||||
onClick={() => handleFeePoolSelect(FeeAmount.LOW)}
|
||||
>
|
||||
<AutoColumn gap="sm" justify="flex-start">
|
||||
<ResponsiveText>0.05% {t('fee')}</ResponsiveText>
|
||||
<ResponsiveText>
|
||||
<Trans>0.05% fee</Trans>
|
||||
</ResponsiveText>
|
||||
<TYPE.main fontWeight={400} fontSize="12px" textAlign="left">
|
||||
Best for stable pairs.
|
||||
<Trans>Best for stable pairs.</Trans>
|
||||
</TYPE.main>
|
||||
</AutoColumn>
|
||||
</ButtonRadioChecked>
|
||||
@@ -51,9 +52,11 @@ export default function FeeSelector({
|
||||
onClick={() => handleFeePoolSelect(FeeAmount.MEDIUM)}
|
||||
>
|
||||
<AutoColumn gap="sm" justify="flex-start">
|
||||
<ResponsiveText>0.3% {t('fee')}</ResponsiveText>
|
||||
<ResponsiveText>
|
||||
<Trans>0.3% fee</Trans>
|
||||
</ResponsiveText>
|
||||
<TYPE.main fontWeight={400} fontSize="12px" textAlign="left">
|
||||
Best for most pairs.
|
||||
<Trans>Best for most pairs.</Trans>
|
||||
</TYPE.main>
|
||||
</AutoColumn>
|
||||
</ButtonRadioChecked>
|
||||
@@ -63,9 +66,11 @@ export default function FeeSelector({
|
||||
onClick={() => handleFeePoolSelect(FeeAmount.HIGH)}
|
||||
>
|
||||
<AutoColumn gap="sm" justify="flex-start">
|
||||
<ResponsiveText>1% {t('fee')}</ResponsiveText>
|
||||
<ResponsiveText>
|
||||
<Trans>1% fee</Trans>
|
||||
</ResponsiveText>
|
||||
<TYPE.main fontWeight={400} fontSize="12px" textAlign="left">
|
||||
Best for exotic pairs.
|
||||
<Trans>Best for exotic pairs.</Trans>
|
||||
</TYPE.main>
|
||||
</AutoColumn>
|
||||
</ButtonRadioChecked>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import React from 'react'
|
||||
import { CurrencyAmount, Fraction } from '@uniswap/sdk-core'
|
||||
import { JSBI } from '@uniswap/v2-sdk'
|
||||
import JSBI from 'jsbi'
|
||||
import { Currency, CurrencyAmount, Fraction } from '@uniswap/sdk-core'
|
||||
|
||||
const CURRENCY_AMOUNT_MIN = new Fraction(JSBI.BigInt(1), JSBI.BigInt(1000000))
|
||||
|
||||
@@ -8,7 +7,7 @@ export default function FormattedCurrencyAmount({
|
||||
currencyAmount,
|
||||
significantDigits = 4,
|
||||
}: {
|
||||
currencyAmount: CurrencyAmount
|
||||
currencyAmount: CurrencyAmount<Currency>
|
||||
significantDigits?: number
|
||||
}) {
|
||||
return (
|
||||
|
||||
219
src/components/Header/NetworkCard.tsx
Normal file
@@ -0,0 +1,219 @@
|
||||
import { Trans } from '@lingui/macro'
|
||||
import arbitrumLogoUrl from 'assets/svg/arbitrum_logo.svg'
|
||||
import { YellowCard } from 'components/Card'
|
||||
import { useOnClickOutside } from 'hooks/useOnClickOutside'
|
||||
import { useActiveWeb3React } from 'hooks/web3'
|
||||
import { transparentize } from 'polished'
|
||||
import React, { useEffect, useRef, useState } from 'react'
|
||||
import { ArrowDownCircle } from 'react-feather'
|
||||
import { ApplicationModal } from 'state/application/actions'
|
||||
import { useModalOpen, useToggleModal } from 'state/application/hooks'
|
||||
import styled, { css } from 'styled-components'
|
||||
import { ExternalLink } from 'theme'
|
||||
import { switchToNetwork } from 'utils/switchToNetwork'
|
||||
import { NETWORK_LABELS, SupportedChainId } from '../../constants/chains'
|
||||
|
||||
const BaseWrapper = css`
|
||||
position: relative;
|
||||
${({ theme }) => theme.mediaWidth.upToMedium`
|
||||
margin-left: 12px;
|
||||
`};
|
||||
${({ theme }) => theme.mediaWidth.upToSmall`
|
||||
margin: 0 0.5rem 0 0;
|
||||
width: initial;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
flex-shrink: 1;
|
||||
`};
|
||||
`
|
||||
const ArbitrumWrapper = styled.div`
|
||||
${BaseWrapper}
|
||||
`
|
||||
const BaseMenuItem = css`
|
||||
align-items: center;
|
||||
background-color: ${({ theme }) => transparentize(0.9, theme.primary1)};
|
||||
border-radius: 12px;
|
||||
color: ${({ theme }) => theme.text2};
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: row;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
justify-content: space-between;
|
||||
padding: 12px;
|
||||
:hover {
|
||||
color: ${({ theme }) => theme.text1};
|
||||
text-decoration: none;
|
||||
}
|
||||
`
|
||||
const DisabledMenuItem = styled.div`
|
||||
${BaseMenuItem}
|
||||
align-items: center;
|
||||
background-color: ${({ theme }) => theme.bg2};
|
||||
cursor: auto;
|
||||
display: flex;
|
||||
font-size: 10px;
|
||||
font-style: italic;
|
||||
justify-content: center;
|
||||
:hover,
|
||||
:active,
|
||||
:focus {
|
||||
color: ${({ theme }) => theme.text2};
|
||||
}
|
||||
`
|
||||
const FallbackWrapper = styled(YellowCard)`
|
||||
${BaseWrapper}
|
||||
border-radius: 12px;
|
||||
padding: 8px 12px;
|
||||
`
|
||||
const Icon = styled.img`
|
||||
width: 17px;
|
||||
`
|
||||
const L1Tag = styled.div`
|
||||
color: #c4d9f8;
|
||||
opacity: 40%;
|
||||
`
|
||||
const L2Tag = styled.div`
|
||||
background-color: ${({ theme }) => theme.primary1};
|
||||
border-radius: 6px;
|
||||
color: white;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
padding: 2px 6px;
|
||||
`
|
||||
const MenuFlyout = styled.span`
|
||||
background-color: ${({ theme }) => theme.bg2};
|
||||
box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.01), 0px 4px 8px rgba(0, 0, 0, 0.04), 0px 16px 24px rgba(0, 0, 0, 0.04),
|
||||
0px 24px 32px rgba(0, 0, 0, 0.01);
|
||||
border-radius: 20px;
|
||||
padding: 8px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-size: 1rem;
|
||||
position: absolute;
|
||||
left: 0rem;
|
||||
top: 3rem;
|
||||
z-index: 100;
|
||||
width: 237px;
|
||||
${({ theme }) => theme.mediaWidth.upToMedium`
|
||||
top: -14.25rem;
|
||||
`};
|
||||
> {
|
||||
padding: 12px;
|
||||
}
|
||||
> :not(:first-child) {
|
||||
margin-top: 4px;
|
||||
}
|
||||
> :not(:last-child) {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
`
|
||||
const LinkOutCircle = styled(ArrowDownCircle)`
|
||||
transform: rotate(230deg);
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
`
|
||||
const MenuItem = styled(ExternalLink)`
|
||||
${BaseMenuItem}
|
||||
`
|
||||
const ButtonMenuItem = styled.button`
|
||||
${BaseMenuItem}
|
||||
border: none;
|
||||
outline: none;
|
||||
box-shadow: none;
|
||||
`
|
||||
const NetworkInfo = styled.button`
|
||||
align-items: center;
|
||||
background-color: ${({ theme }) => theme.bg2};
|
||||
border-radius: 8px;
|
||||
border: none;
|
||||
color: ${({ theme }) => theme.text1};
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
font-weight: 500;
|
||||
height: 100%;
|
||||
justify-content: space-between;
|
||||
margin: 0;
|
||||
padding: 8px;
|
||||
width: 172px;
|
||||
|
||||
:hover,
|
||||
:focus {
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
background-color: ${({ theme }) => theme.bg3};
|
||||
}
|
||||
`
|
||||
export default function NetworkCard() {
|
||||
const { chainId, library } = useActiveWeb3React()
|
||||
const node = useRef<HTMLDivElement>(null)
|
||||
const open = useModalOpen(ApplicationModal.ARBITRUM_OPTIONS)
|
||||
const toggle = useToggleModal(ApplicationModal.ARBITRUM_OPTIONS)
|
||||
useOnClickOutside(node, open ? toggle : undefined)
|
||||
|
||||
const [implements3085, setImplements3085] = useState(false)
|
||||
useEffect(() => {
|
||||
// metamask is currently the only known implementer of this EIP
|
||||
// here we proceed w/ a noop feature check to ensure the user's version of metamask supports network switching
|
||||
// if not, we hide the UI
|
||||
if (!library?.provider?.request || !chainId || !library?.provider?.isMetaMask) {
|
||||
return
|
||||
}
|
||||
switchToNetwork({ library, chainId })
|
||||
.then((x) => x ?? setImplements3085(true))
|
||||
.catch(() => setImplements3085(false))
|
||||
}, [library, chainId])
|
||||
|
||||
if (!chainId || chainId === SupportedChainId.MAINNET || !NETWORK_LABELS[chainId] || !library) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (chainId === SupportedChainId.ARBITRUM_ONE) {
|
||||
return (
|
||||
<ArbitrumWrapper ref={node}>
|
||||
<NetworkInfo onClick={toggle}>
|
||||
<Icon src={arbitrumLogoUrl} />
|
||||
<span>Arbitrum</span>
|
||||
<L2Tag>L2 Alpha</L2Tag>
|
||||
</NetworkInfo>
|
||||
{open && (
|
||||
<MenuFlyout>
|
||||
<MenuItem href="https://bridge.arbitrum.io/">
|
||||
<div>
|
||||
<Trans>Arbitrum Token Bridge</Trans>
|
||||
</div>
|
||||
<LinkOutCircle />
|
||||
</MenuItem>
|
||||
<MenuItem href="https://explorer.arbitrum.io/">
|
||||
<div>
|
||||
<Trans>Arbitrum Explorer</Trans>
|
||||
</div>
|
||||
<LinkOutCircle />
|
||||
</MenuItem>
|
||||
<MenuItem href="https://offchainlabs.com/">
|
||||
<div>
|
||||
<Trans>Learn more</Trans>
|
||||
</div>
|
||||
<LinkOutCircle />
|
||||
</MenuItem>
|
||||
{implements3085 ? (
|
||||
<ButtonMenuItem onClick={() => switchToNetwork({ library, chainId: SupportedChainId.MAINNET })}>
|
||||
<div>
|
||||
<Trans>Switch to Ethereum</Trans>
|
||||
</div>
|
||||
<L1Tag>L1</L1Tag>
|
||||
</ButtonMenuItem>
|
||||
) : (
|
||||
<DisabledMenuItem>
|
||||
<Trans>Change your network to go back to L1</Trans>
|
||||
</DisabledMenuItem>
|
||||
)}
|
||||
</MenuFlyout>
|
||||
)}
|
||||
</ArbitrumWrapper>
|
||||
)
|
||||
}
|
||||
|
||||
return <FallbackWrapper title={NETWORK_LABELS[chainId]}>{NETWORK_LABELS[chainId]}</FallbackWrapper>
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import { useEffect, useState } from 'react'
|
||||
import styled, { keyframes } from 'styled-components'
|
||||
import { TYPE, ExternalLink } from '../../theme'
|
||||
import { useActiveWeb3React } from '../../hooks/web3'
|
||||
|
||||
import { useBlockNumber } from '../../state/application/hooks'
|
||||
import { getEtherscanLink } from '../../utils'
|
||||
import { useActiveWeb3React } from '../../hooks'
|
||||
import { ExternalLink, TYPE } from '../../theme'
|
||||
import { ExplorerDataType, getExplorerLink } from '../../utils/getExplorerLink'
|
||||
|
||||
const StyledPolling = styled.div`
|
||||
position: fixed;
|
||||
@@ -21,7 +21,7 @@ const StyledPolling = styled.div`
|
||||
`
|
||||
const StyledPollingNumber = styled(TYPE.small)<{ breathe: boolean; hovering: boolean }>`
|
||||
transition: opacity 0.25s ease;
|
||||
opacity: ${({ breathe, hovering }) => (hovering ? 0.7 : breathe ? 1 : 0.2)};
|
||||
opacity: ${({ breathe, hovering }) => (hovering ? 0.7 : breathe ? 1 : 0.5)};
|
||||
:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
@@ -91,7 +91,9 @@ export default function Polling() {
|
||||
)
|
||||
|
||||
return (
|
||||
<ExternalLink href={chainId && blockNumber ? getEtherscanLink(chainId, blockNumber.toString(), 'block') : ''}>
|
||||
<ExternalLink
|
||||
href={chainId && blockNumber ? getExplorerLink(chainId, blockNumber.toString(), ExplorerDataType.BLOCK) : ''}
|
||||
>
|
||||
<StyledPolling onMouseEnter={() => setIsHover(true)} onMouseLeave={() => setIsHover(false)}>
|
||||
<StyledPollingNumber breathe={isMounting} hovering={isHover}>
|
||||
{blockNumber}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
|
||||
import { AlertTriangle, X } from 'react-feather'
|
||||
import { useURLWarningToggle, useURLWarningVisible } from '../../state/user/hooks'
|
||||
import { isMobile } from 'react-device-detect'
|
||||
import { Trans } from '@lingui/macro'
|
||||
|
||||
const PhishAlert = styled.div<{ isActive: any }>`
|
||||
width: 100%;
|
||||
@@ -29,17 +29,23 @@ export default function URLWarning() {
|
||||
return isMobile ? (
|
||||
<PhishAlert isActive={showURLWarning}>
|
||||
<div style={{ display: 'flex' }}>
|
||||
<AlertTriangle style={{ marginRight: 6 }} size={12} /> Make sure the URL is
|
||||
<code style={{ padding: '0 4px', display: 'inline', fontWeight: 'bold' }}>app.uniswap.org</code>
|
||||
<AlertTriangle style={{ marginRight: 6 }} size={12} />
|
||||
<Trans>
|
||||
Make sure the URL is
|
||||
<code style={{ padding: '0 4px', display: 'inline', fontWeight: 'bold' }}>app.uniswap.org</code>
|
||||
</Trans>
|
||||
</div>
|
||||
<StyledClose size={12} onClick={toggleURLWarning} />
|
||||
</PhishAlert>
|
||||
) : window.location.hostname === 'app.uniswap.org' ? (
|
||||
<PhishAlert isActive={showURLWarning}>
|
||||
<div style={{ display: 'flex' }}>
|
||||
<AlertTriangle style={{ marginRight: 6 }} size={12} /> Always make sure the URL is
|
||||
<code style={{ padding: '0 4px', display: 'inline', fontWeight: 'bold' }}>app.uniswap.org</code> - bookmark it
|
||||
to be safe.
|
||||
<AlertTriangle style={{ marginRight: 6 }} size={12} />
|
||||
<Trans>
|
||||
Always make sure the URL is
|
||||
<code style={{ padding: '0 4px', display: 'inline', fontWeight: 'bold' }}>app.uniswap.org</code> - bookmark it
|
||||
to be safe.
|
||||
</Trans>
|
||||
</div>
|
||||
<StyledClose size={12} onClick={toggleURLWarning} />
|
||||
</PhishAlert>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { ChainId, TokenAmount } from '@uniswap/sdk-core'
|
||||
import React, { useMemo } from 'react'
|
||||
import { CurrencyAmount, Token } from '@uniswap/sdk-core'
|
||||
import { useMemo } from 'react'
|
||||
import { X } from 'react-feather'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import tokenLogo from '../../assets/images/token-logo.png'
|
||||
import { UNI } from '../../constants'
|
||||
import { UNI } from '../../constants/tokens'
|
||||
import { useTotalSupply } from '../../hooks/useTotalSupply'
|
||||
import { useActiveWeb3React } from '../../hooks'
|
||||
import { useActiveWeb3React } from '../../hooks/web3'
|
||||
import { useMerkleDistributorContract } from '../../hooks/useContract'
|
||||
import useCurrentBlockTimestamp from '../../hooks/useCurrentBlockTimestamp'
|
||||
import { useTotalUniEarned } from '../../state/stake/hooks'
|
||||
@@ -16,6 +16,7 @@ import useUSDCPrice from '../../hooks/useUSDCPrice'
|
||||
import { AutoColumn } from '../Column'
|
||||
import { RowBetween } from '../Row'
|
||||
import { Break, CardBGImage, CardNoise, CardSection, DataCard } from '../earn/styled'
|
||||
import { Trans } from '@lingui/macro'
|
||||
|
||||
const ContentWrapper = styled(AutoColumn)`
|
||||
width: 100%;
|
||||
@@ -45,18 +46,16 @@ export default function UniBalanceContent({ setShowUniBalanceModal }: { setShowU
|
||||
const uni = chainId ? UNI[chainId] : undefined
|
||||
|
||||
const total = useAggregateUniBalance()
|
||||
const uniBalance: TokenAmount | undefined = useTokenBalance(account ?? undefined, uni)
|
||||
const uniToClaim: TokenAmount | undefined = useTotalUniEarned()
|
||||
const uniBalance: CurrencyAmount<Token> | undefined = useTokenBalance(account ?? undefined, uni)
|
||||
const uniToClaim: CurrencyAmount<Token> | undefined = useTotalUniEarned()
|
||||
|
||||
const totalSupply: TokenAmount | undefined = useTotalSupply(uni)
|
||||
const totalSupply: CurrencyAmount<Token> | undefined = useTotalSupply(uni)
|
||||
const uniPrice = useUSDCPrice(uni)
|
||||
const blockTimestamp = useCurrentBlockTimestamp()
|
||||
const unclaimedUni = useTokenBalance(useMerkleDistributorContract()?.address, uni)
|
||||
const circulation: TokenAmount | undefined = useMemo(
|
||||
const circulation: CurrencyAmount<Token> | undefined = useMemo(
|
||||
() =>
|
||||
blockTimestamp && uni && chainId === ChainId.MAINNET
|
||||
? computeUniCirculation(uni, blockTimestamp, unclaimedUni)
|
||||
: totalSupply,
|
||||
blockTimestamp && uni && chainId === 1 ? computeUniCirculation(uni, blockTimestamp, unclaimedUni) : totalSupply,
|
||||
[blockTimestamp, chainId, totalSupply, unclaimedUni, uni]
|
||||
)
|
||||
|
||||
@@ -67,7 +66,9 @@ export default function UniBalanceContent({ setShowUniBalanceModal }: { setShowU
|
||||
<CardNoise />
|
||||
<CardSection gap="md">
|
||||
<RowBetween>
|
||||
<TYPE.white color="white">Your UNI Breakdown</TYPE.white>
|
||||
<TYPE.white color="white">
|
||||
<Trans>Your UNI Breakdown</Trans>
|
||||
</TYPE.white>
|
||||
<StyledClose stroke="white" onClick={() => setShowUniBalanceModal(false)} />
|
||||
</RowBetween>
|
||||
</CardSection>
|
||||
@@ -83,16 +84,20 @@ export default function UniBalanceContent({ setShowUniBalanceModal }: { setShowU
|
||||
</AutoColumn>
|
||||
<AutoColumn gap="md">
|
||||
<RowBetween>
|
||||
<TYPE.white color="white">Balance:</TYPE.white>
|
||||
<TYPE.white color="white">
|
||||
<Trans>Balance:</Trans>
|
||||
</TYPE.white>
|
||||
<TYPE.white color="white">{uniBalance?.toFixed(2, { groupSeparator: ',' })}</TYPE.white>
|
||||
</RowBetween>
|
||||
<RowBetween>
|
||||
<TYPE.white color="white">Unclaimed:</TYPE.white>
|
||||
<TYPE.white color="white">
|
||||
<Trans>Unclaimed:</Trans>
|
||||
</TYPE.white>
|
||||
<TYPE.white color="white">
|
||||
{uniToClaim?.toFixed(4, { groupSeparator: ',' })}{' '}
|
||||
{uniToClaim && uniToClaim.greaterThan('0') && (
|
||||
<StyledInternalLink onClick={() => setShowUniBalanceModal(false)} to="/uni">
|
||||
(claim)
|
||||
<Trans>(claim)</Trans>
|
||||
</StyledInternalLink>
|
||||
)}
|
||||
</TYPE.white>
|
||||
@@ -105,19 +110,27 @@ export default function UniBalanceContent({ setShowUniBalanceModal }: { setShowU
|
||||
<CardSection gap="sm">
|
||||
<AutoColumn gap="md">
|
||||
<RowBetween>
|
||||
<TYPE.white color="white">UNI price:</TYPE.white>
|
||||
<TYPE.white color="white">
|
||||
<Trans>UNI price:</Trans>
|
||||
</TYPE.white>
|
||||
<TYPE.white color="white">${uniPrice?.toFixed(2) ?? '-'}</TYPE.white>
|
||||
</RowBetween>
|
||||
<RowBetween>
|
||||
<TYPE.white color="white">UNI in circulation:</TYPE.white>
|
||||
<TYPE.white color="white">
|
||||
<Trans>UNI in circulation:</Trans>
|
||||
</TYPE.white>
|
||||
<TYPE.white color="white">{circulation?.toFixed(0, { groupSeparator: ',' })}</TYPE.white>
|
||||
</RowBetween>
|
||||
<RowBetween>
|
||||
<TYPE.white color="white">Total Supply</TYPE.white>
|
||||
<TYPE.white color="white">
|
||||
<Trans>Total Supply</Trans>
|
||||
</TYPE.white>
|
||||
<TYPE.white color="white">{totalSupply?.toFixed(0, { groupSeparator: ',' })}</TYPE.white>
|
||||
</RowBetween>
|
||||
{uni && uni.chainId === ChainId.MAINNET ? (
|
||||
<ExternalLink href={`https://info.uniswap.org/token/${uni.address}`}>View UNI Analytics</ExternalLink>
|
||||
{uni && uni.chainId === 1 ? (
|
||||
<ExternalLink href={`https://info.uniswap.org/token/${uni.address}`}>
|
||||
<Trans>View UNI Analytics</Trans>
|
||||
</ExternalLink>
|
||||
) : null}
|
||||
</AutoColumn>
|
||||
</CardSection>
|
||||
|
||||
@@ -1,35 +1,31 @@
|
||||
import { ChainId } from '@uniswap/sdk-core'
|
||||
import React, { useState } from 'react'
|
||||
import { Text } from 'rebass'
|
||||
import { NavLink } from 'react-router-dom'
|
||||
import { Trans } from '@lingui/macro'
|
||||
import useScrollPosition from '@react-hook/window-scroll'
|
||||
import { darken } from 'polished'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useState } from 'react'
|
||||
import { Moon, Sun } from 'react-feather'
|
||||
import styled from 'styled-components'
|
||||
|
||||
import { NavLink } from 'react-router-dom'
|
||||
import { Text } from 'rebass'
|
||||
import { useShowClaimPopup, useToggleSelfClaimModal } from 'state/application/hooks'
|
||||
import { useUserHasAvailableClaim } from 'state/claim/hooks'
|
||||
import { useUserHasSubmittedClaim } from 'state/transactions/hooks'
|
||||
import { useDarkModeManager } from 'state/user/hooks'
|
||||
import { useETHBalances } from 'state/wallet/hooks'
|
||||
import styled from 'styled-components/macro'
|
||||
import Logo from '../../assets/svg/logo.svg'
|
||||
import LogoDark from '../../assets/svg/logo_white.svg'
|
||||
|
||||
import { useActiveWeb3React } from '../../hooks'
|
||||
import { useDarkModeManager } from '../../state/user/hooks'
|
||||
import { useETHBalances } from '../../state/wallet/hooks'
|
||||
import { CardNoise } from '../earn/styled'
|
||||
import { TYPE, ExternalLink } from '../../theme'
|
||||
|
||||
import { YellowCard } from '../Card'
|
||||
import Menu from '../Menu'
|
||||
|
||||
import Row, { RowFixed } from '../Row'
|
||||
import Web3Status from '../Web3Status'
|
||||
import { useActiveWeb3React } from '../../hooks/web3'
|
||||
import { ExternalLink, TYPE } from '../../theme'
|
||||
import ClaimModal from '../claim/ClaimModal'
|
||||
import { useToggleSelfClaimModal, useShowClaimPopup } from '../../state/application/hooks'
|
||||
import { useUserHasAvailableClaim } from '../../state/claim/hooks'
|
||||
import { useUserHasSubmittedClaim } from '../../state/transactions/hooks'
|
||||
import { Dots } from '../swap/styleds'
|
||||
import { CardNoise } from '../earn/styled'
|
||||
import Menu from '../Menu'
|
||||
import Modal from '../Modal'
|
||||
import Row, { RowFixed } from '../Row'
|
||||
import { Dots } from '../swap/styleds'
|
||||
import Web3Status from '../Web3Status'
|
||||
import NetworkCard from './NetworkCard'
|
||||
import UniBalanceContent from './UniBalanceContent'
|
||||
|
||||
const HeaderFrame = styled.div`
|
||||
const HeaderFrame = styled.div<{ showBackground: boolean }>`
|
||||
display: grid;
|
||||
grid-template-columns: 120px 1fr 120px;
|
||||
align-items: center;
|
||||
@@ -39,16 +35,20 @@ const HeaderFrame = styled.div`
|
||||
width: 100%;
|
||||
top: 0;
|
||||
position: relative;
|
||||
/* border-bottom: 1px solid ${({ theme }) => theme.bg2}; */
|
||||
padding: 1rem;
|
||||
z-index: 21;
|
||||
/* background-color: ${({ theme }) => theme.bg1}; */
|
||||
position: relative;
|
||||
|
||||
/* Background slide effect on scroll. */
|
||||
background-image: ${({ theme }) => `linear-gradient(to bottom, transparent 50%, ${theme.bg0} 50% )}}`}
|
||||
background-position: ${({ showBackground }) => (showBackground ? '0 -100%' : '0 0')};
|
||||
background-size: 100% 200%;
|
||||
box-shadow: 0px 0px 0px 1px ${({ theme, showBackground }) => (showBackground ? theme.bg2 : 'transparent;')};
|
||||
transition: background-position .1s, box-shadow .1s;
|
||||
|
||||
${({ theme }) => theme.mediaWidth.upToMedium`
|
||||
padding: 1rem;
|
||||
grid-template-columns: 120px 1fr;
|
||||
|
||||
grid-template-columns: auto 1fr;
|
||||
`};
|
||||
|
||||
${({ theme }) => theme.mediaWidth.upToExtraSmall`
|
||||
@@ -165,19 +165,6 @@ const HideSmall = styled.span`
|
||||
`};
|
||||
`
|
||||
|
||||
const NetworkCard = styled(YellowCard)`
|
||||
border-radius: 12px;
|
||||
padding: 8px 12px;
|
||||
${({ theme }) => theme.mediaWidth.upToSmall`
|
||||
margin: 0;
|
||||
margin-right: 0.5rem;
|
||||
width: initial;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
flex-shrink: 1;
|
||||
`};
|
||||
`
|
||||
|
||||
const BalanceText = styled(Text)`
|
||||
${({ theme }) => theme.mediaWidth.upToExtraSmall`
|
||||
display: none;
|
||||
@@ -221,6 +208,7 @@ const StyledNavLink = styled(NavLink).attrs({
|
||||
width: fit-content;
|
||||
font-weight: 500;
|
||||
padding: 8px 12px;
|
||||
word-break: break-word;
|
||||
|
||||
&.${activeClassName} {
|
||||
border-radius: 12px;
|
||||
@@ -259,6 +247,7 @@ const StyledExternalLink = styled(ExternalLink).attrs({
|
||||
:hover,
|
||||
:focus {
|
||||
color: ${({ theme }) => darken(0.1, theme.text1)};
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
${({ theme }) => theme.mediaWidth.upToExtraSmall`
|
||||
@@ -295,16 +284,8 @@ export const StyledMenuButton = styled.button`
|
||||
}
|
||||
`
|
||||
|
||||
const NETWORK_LABELS: { [chainId in ChainId]?: string } = {
|
||||
[ChainId.RINKEBY]: 'Rinkeby',
|
||||
[ChainId.ROPSTEN]: 'Ropsten',
|
||||
[ChainId.GÖRLI]: 'Görli',
|
||||
[ChainId.KOVAN]: 'Kovan',
|
||||
}
|
||||
|
||||
export default function Header() {
|
||||
const { account, chainId } = useActiveWeb3React()
|
||||
const { t } = useTranslation()
|
||||
const { account } = useActiveWeb3React()
|
||||
|
||||
const userEthBalance = useETHBalances(account ? [account] : [])?.[account ?? '']
|
||||
// const [isDark] = useDarkModeManager()
|
||||
@@ -319,8 +300,10 @@ export default function Header() {
|
||||
const [showUniBalanceModal, setShowUniBalanceModal] = useState(false)
|
||||
const showClaimPopup = useShowClaimPopup()
|
||||
|
||||
const scrollY = useScrollPosition()
|
||||
|
||||
return (
|
||||
<HeaderFrame>
|
||||
<HeaderFrame showBackground={scrollY > 45}>
|
||||
<ClaimModal />
|
||||
<Modal isOpen={showUniBalanceModal} onDismiss={() => setShowUniBalanceModal(false)}>
|
||||
<UniBalanceContent setShowUniBalanceModal={setShowUniBalanceModal} />
|
||||
@@ -334,7 +317,7 @@ export default function Header() {
|
||||
</HeaderRow>
|
||||
<HeaderLinks>
|
||||
<StyledNavLink id={`swap-nav-link`} to={'/swap'}>
|
||||
{t('swap')}
|
||||
<Trans>Swap</Trans>
|
||||
</StyledNavLink>
|
||||
<StyledNavLink
|
||||
id={`pool-nav-link`}
|
||||
@@ -347,27 +330,32 @@ export default function Header() {
|
||||
pathname.startsWith('/find')
|
||||
}
|
||||
>
|
||||
{t('pool')}
|
||||
<Trans>Pool</Trans>
|
||||
</StyledNavLink>
|
||||
<StyledNavLink id={`stake-nav-link`} to={'/vote'}>
|
||||
Vote
|
||||
<Trans>Vote</Trans>
|
||||
</StyledNavLink>
|
||||
<StyledExternalLink id={`stake-nav-link`} href={'https://info.uniswap.org'}>
|
||||
Charts <span style={{ fontSize: '11px', textDecoration: 'none !important' }}>↗</span>
|
||||
<Trans>Charts</Trans>
|
||||
<sup>↗</sup>
|
||||
</StyledExternalLink>
|
||||
</HeaderLinks>
|
||||
<HeaderControls>
|
||||
<HeaderElement>
|
||||
<HideSmall>
|
||||
{chainId && NETWORK_LABELS[chainId] && (
|
||||
<NetworkCard title={NETWORK_LABELS[chainId]}>{NETWORK_LABELS[chainId]}</NetworkCard>
|
||||
)}
|
||||
<NetworkCard />
|
||||
</HideSmall>
|
||||
{availableClaim && !showClaimPopup && (
|
||||
<UNIWrapper onClick={toggleClaimModal}>
|
||||
<UNIAmount active={!!account && !availableClaim} style={{ pointerEvents: 'auto' }}>
|
||||
<TYPE.white padding="0 2px">
|
||||
{claimTxn && !claimTxn?.receipt ? <Dots>Claiming UNI</Dots> : 'Claim UNI'}
|
||||
{claimTxn && !claimTxn?.receipt ? (
|
||||
<Dots>
|
||||
<Trans>Claiming UNI</Trans>
|
||||
</Dots>
|
||||
) : (
|
||||
<Trans>Claim UNI</Trans>
|
||||
)}
|
||||
</TYPE.white>
|
||||
</UNIAmount>
|
||||
<CardNoise />
|
||||
@@ -376,7 +364,7 @@ export default function Header() {
|
||||
<AccountElement active={!!account} style={{ pointerEvents: 'auto' }}>
|
||||
{account && userEthBalance ? (
|
||||
<BalanceText style={{ flexShrink: 0 }} pl="0.75rem" pr="0.5rem" fontWeight={500}>
|
||||
{userEthBalance?.toSignificant(4)} ETH
|
||||
<Trans>{userEthBalance?.toSignificant(4)} ETH</Trans>
|
||||
</BalanceText>
|
||||
) : null}
|
||||
<Web3Status />
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import Tooltip from 'components/Tooltip'
|
||||
import React, { useState } from 'react'
|
||||
import styled from 'styled-components'
|
||||
import { useState } from 'react'
|
||||
import styled from 'styled-components/macro'
|
||||
|
||||
const TextWrapper = styled.span<{ margin: boolean; link: boolean; fontSize?: string; adjustSize?: boolean }>`
|
||||
position: relative;
|
||||
const TextWrapper = styled.span<{ margin: boolean; link?: boolean; fontSize?: string; adjustSize?: boolean }>`
|
||||
margin-left: ${({ margin }) => margin && '4px'};
|
||||
color: ${({ theme, link }) => (link ? theme.blue1 : theme.text1)};
|
||||
font-size: ${({ fontSize }) => fontSize ?? 'inherit'};
|
||||
@@ -22,7 +21,7 @@ const HoverInlineText = ({
|
||||
link,
|
||||
...rest
|
||||
}: {
|
||||
text: string
|
||||
text?: string
|
||||
maxCharacters?: number
|
||||
margin?: boolean
|
||||
adjustSize?: boolean
|
||||
@@ -32,7 +31,7 @@ const HoverInlineText = ({
|
||||
const [showHover, setShowHover] = useState(false)
|
||||
|
||||
if (!text) {
|
||||
return <span></span>
|
||||
return <span />
|
||||
}
|
||||
|
||||
if (text.length > maxCharacters) {
|
||||
@@ -43,7 +42,7 @@ const HoverInlineText = ({
|
||||
onMouseLeave={() => setShowHover(false)}
|
||||
margin={margin}
|
||||
adjustSize={adjustSize}
|
||||
link={!!link}
|
||||
link={link}
|
||||
fontSize={fontSize}
|
||||
{...rest}
|
||||
>
|
||||
@@ -54,7 +53,7 @@ const HoverInlineText = ({
|
||||
}
|
||||
|
||||
return (
|
||||
<TextWrapper margin={margin} adjustSize={adjustSize} link={!!link} fontSize={fontSize} {...rest}>
|
||||
<TextWrapper margin={margin} adjustSize={adjustSize} link={link} fontSize={fontSize} {...rest}>
|
||||
{text}
|
||||
</TextWrapper>
|
||||
)
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import React, { useEffect, useRef } from 'react'
|
||||
import { useEffect, useRef } from 'react'
|
||||
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
|
||||
import { useActiveWeb3React } from '../../hooks'
|
||||
import Jazzicon from 'jazzicon'
|
||||
import { useActiveWeb3React } from '../../hooks/web3'
|
||||
import Jazzicon from '@metamask/jazzicon'
|
||||
|
||||
const StyledIdenticonContainer = styled.div`
|
||||
height: 1rem;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState, useCallback, useEffect } from 'react'
|
||||
import { useState, useCallback, useEffect, ReactNode } from 'react'
|
||||
import { LightCard } from 'components/Card'
|
||||
import { RowBetween } from 'components/Row'
|
||||
import { Input as NumericalInput } from '../NumericalInput'
|
||||
@@ -8,6 +8,7 @@ import { AutoColumn } from 'components/Column'
|
||||
import { ButtonPrimary } from 'components/Button'
|
||||
import { FeeAmount } from '@uniswap/v3-sdk'
|
||||
import { formattedFeeAmount } from 'utils'
|
||||
import { Trans } from '@lingui/macro'
|
||||
|
||||
const pulse = (color: string) => keyframes`
|
||||
0% {
|
||||
@@ -59,7 +60,7 @@ interface StepCounterProps {
|
||||
label?: string
|
||||
width?: string
|
||||
locked?: boolean // disable input
|
||||
title: string
|
||||
title: ReactNode
|
||||
tokenA: string | undefined
|
||||
tokenB: string | undefined
|
||||
}
|
||||
@@ -139,16 +140,22 @@ const StepCounter = ({
|
||||
}}
|
||||
/>
|
||||
<InputTitle fontSize={12} textAlign="center">
|
||||
{tokenB + ' per ' + tokenA}
|
||||
<Trans>
|
||||
{tokenB} per {tokenA}
|
||||
</Trans>
|
||||
</InputTitle>
|
||||
</AutoColumn>
|
||||
{!locked ? (
|
||||
<RowBetween>
|
||||
<SmallButton onClick={handleDecrement}>
|
||||
<TYPE.white fontSize="12px">-{feeAmountFormatted}%</TYPE.white>
|
||||
<TYPE.white fontSize="12px">
|
||||
<Trans>-{feeAmountFormatted}%</Trans>
|
||||
</TYPE.white>
|
||||
</SmallButton>
|
||||
<SmallButton onClick={handleIncrement}>
|
||||
<TYPE.white fontSize="12px">+{feeAmountFormatted}%</TYPE.white>
|
||||
<TYPE.white fontSize="12px">
|
||||
<Trans>+{feeAmountFormatted}%</Trans>
|
||||
</TYPE.white>
|
||||
</SmallButton>
|
||||
</RowBetween>
|
||||
) : null}
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
import { Story } from '@storybook/react/types-6-0'
|
||||
import React from 'react'
|
||||
// import Row, { RowFixed } from 'components/Row'
|
||||
import styled from 'styled-components'
|
||||
import Component, { LineChartProps } from './'
|
||||
import { dummyData } from './data'
|
||||
// import { AutoColumn } from 'components/Column'
|
||||
// import { TYPE } from 'theme'
|
||||
// import DoubleCurrencyLogo from 'components/DoubleLogo'
|
||||
// import { MKR } from 'constants'
|
||||
// import { ETHER } from '@uniswap/sdk'
|
||||
// import LineChart from '.'
|
||||
|
||||
const Wrapper = styled.div`
|
||||
margin: 1em 2em;
|
||||
max-width: 500px;
|
||||
& > * {
|
||||
font-size: 1em;
|
||||
}
|
||||
`
|
||||
|
||||
export default {
|
||||
title: 'Charts',
|
||||
argTypes: {
|
||||
disabled: { control: { type: 'boolean' } },
|
||||
onClick: { action: 'clicked' },
|
||||
},
|
||||
decorators: [
|
||||
(Component: Story) => (
|
||||
<Wrapper>
|
||||
<Component />
|
||||
</Wrapper>
|
||||
),
|
||||
],
|
||||
}
|
||||
|
||||
const Template: Story<LineChartProps> = (args) => <Component {...args}>{args.children}</Component>
|
||||
|
||||
export const Basic = Template.bind({})
|
||||
Basic.args = { data: dummyData }
|
||||
|
||||
// const Full = () => {
|
||||
// const [value, setValue] = useState<number | undefined>(dummyData[dummyData.length - 1].value)
|
||||
|
||||
// const dummyUSDPrice = 410 // used for conversion
|
||||
|
||||
// const TopLeftContent = () => (
|
||||
// <AutoColumn gap="md">
|
||||
// <RowFixed align="center">
|
||||
// <DoubleCurrencyLogo currency0={MKR} currency1={ETHER} size={20} />{' '}
|
||||
// <TYPE.main fontSize="20px" color="white" ml="10px">
|
||||
// ETH / MKR
|
||||
// </TYPE.main>
|
||||
// </RowFixed>
|
||||
// <Row>
|
||||
// <TYPE.main fontSize="20px" color="white">
|
||||
// {value} MKR
|
||||
// </TYPE.main>
|
||||
// <TYPE.main color="#565A69" fontSize="20px" ml="10px">
|
||||
// ($
|
||||
// {value
|
||||
// ? (value * dummyUSDPrice).toLocaleString('USD', {
|
||||
// currency: 'USD',
|
||||
// minimumFractionDigits: 2
|
||||
// })
|
||||
// : null}{' '}
|
||||
// )
|
||||
// </TYPE.main>
|
||||
// </Row>
|
||||
// </AutoColumn>
|
||||
// )
|
||||
|
||||
// return (
|
||||
// <Wrapper>
|
||||
// <LineChart data={dummyData} setValue={setValue} topLeft={<TopLeftContent />} />
|
||||
// </Wrapper>
|
||||
// )
|
||||
// }
|
||||
|
||||
// export const FullVersion = Template.bind(() => <LineChart data={dummyData} />)
|
||||
// Full.args = { data: dummyData }
|
||||
// Full.decorators = [
|
||||
// (Story: any) => {
|
||||
// return (
|
||||
// <Wrapper>
|
||||
// <LineChart data={dummyData} />
|
||||
// </Wrapper>
|
||||
// )
|
||||
// }
|
||||
// ]
|
||||
@@ -3,7 +3,7 @@ import { createChart, IChartApi } from 'lightweight-charts'
|
||||
import { darken } from 'polished'
|
||||
import { RowBetween } from 'components/Row'
|
||||
import Card from '../Card'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import useTheme from 'hooks/useTheme'
|
||||
|
||||
const Wrapper = styled(Card)`
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import useHttpLocations from '../../hooks/useHttpLocations'
|
||||
|
||||
import Logo from '../Logo'
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import React from 'react'
|
||||
|
||||
import styled, { keyframes } from 'styled-components'
|
||||
|
||||
const rotate = keyframes`
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState } from 'react'
|
||||
import { useState } from 'react'
|
||||
import { Slash } from 'react-feather'
|
||||
import { ImageProps } from 'rebass'
|
||||
import useTheme from '../../hooks/useTheme'
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
import { Story } from '@storybook/react/types-6-0'
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
import Component from './index'
|
||||
|
||||
const Wrapper = styled.div`
|
||||
max-width: 150px;
|
||||
`
|
||||
export default {
|
||||
title: 'Menu',
|
||||
decorators: [
|
||||
() => (
|
||||
<Wrapper>
|
||||
<Component />
|
||||
</Wrapper>
|
||||
),
|
||||
],
|
||||
}
|
||||
|
||||
const Template: Story<any> = (args) => <Component {...args} />
|
||||
|
||||
export const Menu = Template.bind({})
|
||||
Menu.args = {}
|
||||
@@ -3,10 +3,11 @@ import { BookOpen, Code, Info, MessageCircle, PieChart } from 'react-feather'
|
||||
import { Link } from 'react-router-dom'
|
||||
import styled, { css } from 'styled-components'
|
||||
import { ReactComponent as MenuIcon } from '../../assets/images/menu.svg'
|
||||
import { useActiveWeb3React } from '../../hooks'
|
||||
import { useActiveWeb3React } from '../../hooks/web3'
|
||||
import { useOnClickOutside } from '../../hooks/useOnClickOutside'
|
||||
import { ApplicationModal } from '../../state/application/actions'
|
||||
import { useModalOpen, useToggleModal } from '../../state/application/hooks'
|
||||
import { Trans } from '@lingui/macro'
|
||||
|
||||
import { ExternalLink } from '../../theme'
|
||||
import { ButtonPrimary } from '../Button'
|
||||
@@ -142,27 +143,37 @@ export default function Menu() {
|
||||
<MenuFlyout>
|
||||
<MenuItem href="https://uniswap.org/">
|
||||
<Info size={14} />
|
||||
<div>About</div>
|
||||
<div>
|
||||
<Trans>About</Trans>
|
||||
</div>
|
||||
</MenuItem>
|
||||
<MenuItem href="https://docs.uniswap.org/">
|
||||
<BookOpen size={14} />
|
||||
<div>Docs</div>
|
||||
<div>
|
||||
<Trans>Docs</Trans>
|
||||
</div>
|
||||
</MenuItem>
|
||||
<MenuItem href={CODE_LINK}>
|
||||
<Code size={14} />
|
||||
<div>Code</div>
|
||||
<div>
|
||||
<Trans>Code</Trans>
|
||||
</div>
|
||||
</MenuItem>
|
||||
<MenuItem href="https://discord.gg/FCfyBSbCU5">
|
||||
<MessageCircle size={14} />
|
||||
<div>Discord</div>
|
||||
<div>
|
||||
<Trans>Discord</Trans>
|
||||
</div>
|
||||
</MenuItem>
|
||||
<MenuItem href="https://info.uniswap.org/">
|
||||
<PieChart size={14} />
|
||||
<div>Analytics</div>
|
||||
<div>
|
||||
<Trans>Analytics</Trans>
|
||||
</div>
|
||||
</MenuItem>
|
||||
{account && (
|
||||
<UNIbutton onClick={openClaimModal} padding="8px 16px" width="100%" borderRadius="12px" mt="0.5rem">
|
||||
Claim UNI
|
||||
<Trans>Claim UNI</Trans>
|
||||
</UNIbutton>
|
||||
)}
|
||||
</MenuFlyout>
|
||||
|
||||
@@ -3,7 +3,6 @@ import styled, { css } from 'styled-components'
|
||||
import { animated, useTransition, useSpring } from 'react-spring'
|
||||
import { DialogOverlay, DialogContent } from '@reach/dialog'
|
||||
import { isMobile } from 'react-device-detect'
|
||||
import '@reach/dialog/styles.css'
|
||||
import { transparentize } from 'polished'
|
||||
import { useGesture } from 'react-use-gesture'
|
||||
|
||||
@@ -31,7 +30,7 @@ const StyledDialogContent = styled(({ minHeight, maxHeight, mobile, isOpen, ...r
|
||||
)).attrs({
|
||||
'aria-label': 'dialog',
|
||||
})`
|
||||
overflow-y: ${({ mobile }) => (mobile ? 'scroll' : 'hidden')};
|
||||
overflow-y: auto;
|
||||
|
||||
&[data-reach-dialog-content] {
|
||||
margin: 0 0 2rem 0;
|
||||
@@ -40,7 +39,7 @@ const StyledDialogContent = styled(({ minHeight, maxHeight, mobile, isOpen, ...r
|
||||
box-shadow: 0 4px 8px 0 ${({ theme }) => transparentize(0.95, theme.shadow1)};
|
||||
padding: 0px;
|
||||
width: 50vw;
|
||||
overflow-y: ${({ mobile }) => (mobile ? 'scroll' : 'hidden')};
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
|
||||
align-self: ${({ mobile }) => (mobile ? 'flex-end' : 'center')};
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import React, { useContext } from 'react'
|
||||
import { useActiveWeb3React } from '../../hooks'
|
||||
import { useContext } from 'react'
|
||||
import { useActiveWeb3React } from '../../hooks/web3'
|
||||
import { ExplorerDataType, getExplorerLink } from '../../utils/getExplorerLink'
|
||||
|
||||
import { AutoColumn, ColumnCenter } from '../Column'
|
||||
import styled, { ThemeContext } from 'styled-components'
|
||||
import { RowBetween } from '../Row'
|
||||
import { TYPE, CloseIcon, CustomLightSpinner } from '../../theme'
|
||||
import { ArrowUpCircle } from 'react-feather'
|
||||
import { Trans } from '@lingui/macro'
|
||||
|
||||
import Circle from '../../assets/images/blue-loader.svg'
|
||||
import { getEtherscanLink } from '../../utils'
|
||||
import { ExternalLink } from '../../theme/components'
|
||||
|
||||
const ConfirmOrLoadingWrapper = styled.div`
|
||||
@@ -32,7 +33,9 @@ export function LoadingView({ children, onDismiss }: { children: any; onDismiss:
|
||||
</ConfirmedIcon>
|
||||
<AutoColumn gap="100px" justify={'center'}>
|
||||
{children}
|
||||
<TYPE.subHeader>Confirm this transaction in your wallet</TYPE.subHeader>
|
||||
<TYPE.subHeader>
|
||||
<Trans>Confirm this transaction in your wallet</Trans>
|
||||
</TYPE.subHeader>
|
||||
</AutoColumn>
|
||||
</ConfirmOrLoadingWrapper>
|
||||
)
|
||||
@@ -62,8 +65,13 @@ export function SubmittedView({
|
||||
<AutoColumn gap="100px" justify={'center'}>
|
||||
{children}
|
||||
{chainId && hash && (
|
||||
<ExternalLink href={getEtherscanLink(chainId, hash, 'transaction')} style={{ marginLeft: '4px' }}>
|
||||
<TYPE.subHeader>View transaction on Etherscan</TYPE.subHeader>
|
||||
<ExternalLink
|
||||
href={getExplorerLink(chainId, hash, ExplorerDataType.TRANSACTION)}
|
||||
style={{ marginLeft: '4px' }}
|
||||
>
|
||||
<TYPE.subHeader>
|
||||
<Trans>View transaction on Explorer</Trans>
|
||||
</TYPE.subHeader>
|
||||
</ExternalLink>
|
||||
)}
|
||||
</AutoColumn>
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { darken } from 'polished'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { NavLink, Link as HistoryLink } from 'react-router-dom'
|
||||
import { Trans } from '@lingui/macro'
|
||||
import { NavLink, Link as HistoryLink, useLocation } from 'react-router-dom'
|
||||
import { Percent } from '@uniswap/sdk-core'
|
||||
|
||||
import { ArrowLeft } from 'react-feather'
|
||||
import { RowBetween } from '../Row'
|
||||
import Row, { RowBetween } from '../Row'
|
||||
import SettingsTab from '../Settings'
|
||||
import { useDispatch } from 'react-redux'
|
||||
import { AppDispatch } from 'state'
|
||||
|
||||
import { useAppDispatch } from 'state/hooks'
|
||||
import { resetMintState } from 'state/mint/actions'
|
||||
import { resetMintState as resetMintV3State } from 'state/mint/v3/actions'
|
||||
import { TYPE } from 'theme'
|
||||
@@ -60,14 +59,13 @@ const StyledArrowLeft = styled(ArrowLeft)`
|
||||
`
|
||||
|
||||
export function SwapPoolTabs({ active }: { active: 'swap' | 'pool' }) {
|
||||
const { t } = useTranslation()
|
||||
return (
|
||||
<Tabs style={{ marginBottom: '20px', display: 'none', padding: '1rem 1rem 0 1rem' }}>
|
||||
<StyledNavLink id={`swap-nav-link`} to={'/swap'} isActive={() => active === 'swap'}>
|
||||
{t('swap')}
|
||||
<Trans>Swap</Trans>
|
||||
</StyledNavLink>
|
||||
<StyledNavLink id={`pool-nav-link`} to={'/pool'} isActive={() => active === 'pool'}>
|
||||
{t('pool')}
|
||||
<Trans>Pool</Trans>
|
||||
</StyledNavLink>
|
||||
</Tabs>
|
||||
)
|
||||
@@ -80,7 +78,9 @@ export function FindPoolTabs({ origin }: { origin: string }) {
|
||||
<HistoryLink to={origin}>
|
||||
<StyledArrowLeft />
|
||||
</HistoryLink>
|
||||
<ActiveText>Import Pool</ActiveText>
|
||||
<ActiveText>
|
||||
<Trans>Import V2 Pool</Trans>
|
||||
</ActiveText>
|
||||
</RowBetween>
|
||||
</Tabs>
|
||||
)
|
||||
@@ -89,24 +89,29 @@ export function FindPoolTabs({ origin }: { origin: string }) {
|
||||
export function AddRemoveTabs({
|
||||
adding,
|
||||
creating,
|
||||
positionID,
|
||||
defaultSlippage,
|
||||
positionID,
|
||||
}: {
|
||||
adding: boolean
|
||||
creating: boolean
|
||||
positionID?: string | undefined
|
||||
defaultSlippage: Percent
|
||||
positionID?: string | undefined
|
||||
}) {
|
||||
const theme = useTheme()
|
||||
|
||||
// reset states on back
|
||||
const dispatch = useDispatch<AppDispatch>()
|
||||
const dispatch = useAppDispatch()
|
||||
const location = useLocation()
|
||||
|
||||
// detect if back should redirect to v3 or v2 pool page
|
||||
const poolLink = location.pathname.includes('add/v2')
|
||||
? '/pool/v2'
|
||||
: '/pool' + (!!positionID ? `/${positionID.toString()}` : '')
|
||||
|
||||
return (
|
||||
<Tabs>
|
||||
<RowBetween style={{ padding: '1rem 1rem 0 1rem' }}>
|
||||
<HistoryLink
|
||||
to={'/pool' + (!!positionID ? `/${positionID.toString()}` : '')}
|
||||
to={poolLink}
|
||||
onClick={() => {
|
||||
if (adding) {
|
||||
// not 100% sure both of these are needed
|
||||
@@ -118,10 +123,29 @@ export function AddRemoveTabs({
|
||||
<StyledArrowLeft stroke={theme.text2} />
|
||||
</HistoryLink>
|
||||
<TYPE.mediumHeader fontWeight={500} fontSize={20}>
|
||||
{creating ? 'Create a pair' : adding ? 'Add Liquidity' : 'Remove Liquidity'}
|
||||
{creating ? (
|
||||
<Trans>Create a pair</Trans>
|
||||
) : adding ? (
|
||||
<Trans>Add Liquidity</Trans>
|
||||
) : (
|
||||
<Trans>Remove Liquidity</Trans>
|
||||
)}
|
||||
</TYPE.mediumHeader>
|
||||
<SettingsTab placeholderSlippage={defaultSlippage} />
|
||||
</RowBetween>
|
||||
</Tabs>
|
||||
)
|
||||
}
|
||||
|
||||
export function CreateProposalTabs() {
|
||||
return (
|
||||
<Tabs>
|
||||
<Row style={{ padding: '1rem 1rem 0 1rem' }}>
|
||||
<HistoryLink to="/vote">
|
||||
<StyledArrowLeft />
|
||||
</HistoryLink>
|
||||
<ActiveText style={{ marginLeft: 'auto', marginRight: 'auto' }}>Create Proposal</ActiveText>
|
||||
</Row>
|
||||
</Tabs>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { escapeRegExp } from '../../utils'
|
||||
|
||||
const StyledInput = styled.input<{ error?: boolean; fontSize?: string; align?: string }>`
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Placement } from '@popperjs/core'
|
||||
import { transparentize } from 'polished'
|
||||
import React, { useCallback, useState } from 'react'
|
||||
import { usePopper } from 'react-popper'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import useInterval from '../../hooks/useInterval'
|
||||
import Portal from '@reach/portal'
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { TokenAmount } from '@uniswap/sdk-core'
|
||||
import React, { useEffect } from 'react'
|
||||
import { X } from 'react-feather'
|
||||
import { Trans } from '@lingui/macro'
|
||||
import { CurrencyAmount, Token } from '@uniswap/sdk-core'
|
||||
import { useCallback, useEffect } from 'react'
|
||||
import ReactGA from 'react-ga'
|
||||
import { Heart, X } from 'react-feather'
|
||||
import styled, { keyframes } from 'styled-components'
|
||||
import tokenLogo from '../../assets/images/token-logo.png'
|
||||
import { ButtonPrimary } from '../../components/Button'
|
||||
import { useActiveWeb3React } from '../../hooks'
|
||||
import { useActiveWeb3React } from '../../hooks/web3'
|
||||
import { ApplicationModal } from '../../state/application/actions'
|
||||
import {
|
||||
useModalOpen,
|
||||
@@ -62,14 +64,25 @@ export default function ClaimPopup() {
|
||||
// toggle for showing this modal
|
||||
const showClaimModal = useModalOpen(ApplicationModal.SELF_CLAIM)
|
||||
const toggleSelfClaimModal = useToggleSelfClaimModal()
|
||||
const handleToggleSelfClaimModal = useCallback(() => {
|
||||
ReactGA.event({
|
||||
category: 'MerkleDrop',
|
||||
action: 'Toggle self claim modal',
|
||||
})
|
||||
toggleSelfClaimModal()
|
||||
}, [toggleSelfClaimModal])
|
||||
|
||||
// const userHasAvailableclaim = useUserHasAvailableClaim()
|
||||
const userHasAvailableclaim: boolean = useUserHasAvailableClaim(account)
|
||||
const unclaimedAmount: TokenAmount | undefined = useUserUnclaimedAmount(account)
|
||||
const unclaimedAmount: CurrencyAmount<Token> | undefined = useUserUnclaimedAmount(account)
|
||||
|
||||
// listen for available claim and show popup if needed
|
||||
useEffect(() => {
|
||||
if (userHasAvailableclaim) {
|
||||
ReactGA.event({
|
||||
category: 'MerkleDrop',
|
||||
action: 'Show claim popup',
|
||||
})
|
||||
toggleShowClaimPopup()
|
||||
}
|
||||
// the toggleShowClaimPopup function changes every time the popup changes, so this will cause an infinite loop.
|
||||
@@ -92,18 +105,20 @@ export default function ClaimPopup() {
|
||||
<span role="img" aria-label="party">
|
||||
🎉
|
||||
</span>{' '}
|
||||
UNI has arrived{' '}
|
||||
<Trans>UNI has arrived</Trans>{' '}
|
||||
<span role="img" aria-label="party">
|
||||
🎉
|
||||
</span>
|
||||
</TYPE.white>
|
||||
<TYPE.subHeader style={{ paddingTop: '0.5rem', textAlign: 'center' }} color="white">
|
||||
{`Thanks for being part of the Uniswap community <3`}
|
||||
<Trans>
|
||||
Thanks for being part of the Uniswap community <Heart size={12} />
|
||||
</Trans>
|
||||
</TYPE.subHeader>
|
||||
</AutoColumn>
|
||||
<AutoColumn style={{ zIndex: 10 }} justify="center">
|
||||
<ButtonPrimary padding="8px" borderRadius="8px" width={'fit-content'} onClick={toggleSelfClaimModal}>
|
||||
Claim your UNI tokens
|
||||
<ButtonPrimary padding="8px" borderRadius="8px" width={'fit-content'} onClick={handleToggleSelfClaimModal}>
|
||||
<Trans>Claim your UNI tokens</Trans>
|
||||
</ButtonPrimary>
|
||||
</AutoColumn>
|
||||
</StyledClaimPopup>
|
||||
|
||||
@@ -1,112 +0,0 @@
|
||||
import { diffTokenLists, TokenList } from '@uniswap/token-lists'
|
||||
import React, { useCallback, useMemo } from 'react'
|
||||
import ReactGA from 'react-ga'
|
||||
import { useDispatch } from 'react-redux'
|
||||
import { Text } from 'rebass'
|
||||
import styled from 'styled-components'
|
||||
import { AppDispatch } from '../../state'
|
||||
import { useRemovePopup } from '../../state/application/hooks'
|
||||
import { acceptListUpdate } from '../../state/lists/actions'
|
||||
import { TYPE } from '../../theme'
|
||||
import listVersionLabel from '../../utils/listVersionLabel'
|
||||
import { ButtonSecondary } from '../Button'
|
||||
import { AutoColumn } from '../Column'
|
||||
import { AutoRow } from '../Row'
|
||||
|
||||
export const ChangesList = styled.ul`
|
||||
max-height: 400px;
|
||||
overflow: auto;
|
||||
`
|
||||
|
||||
export default function ListUpdatePopup({
|
||||
popKey,
|
||||
listUrl,
|
||||
oldList,
|
||||
newList,
|
||||
auto,
|
||||
}: {
|
||||
popKey: string
|
||||
listUrl: string
|
||||
oldList: TokenList
|
||||
newList: TokenList
|
||||
auto: boolean
|
||||
}) {
|
||||
const removePopup = useRemovePopup()
|
||||
const removeThisPopup = useCallback(() => removePopup(popKey), [popKey, removePopup])
|
||||
const dispatch = useDispatch<AppDispatch>()
|
||||
|
||||
const handleAcceptUpdate = useCallback(() => {
|
||||
if (auto) return
|
||||
ReactGA.event({
|
||||
category: 'Lists',
|
||||
action: 'Update List from Popup',
|
||||
label: listUrl,
|
||||
})
|
||||
dispatch(acceptListUpdate(listUrl))
|
||||
removeThisPopup()
|
||||
}, [auto, dispatch, listUrl, removeThisPopup])
|
||||
|
||||
const { added: tokensAdded, changed: tokensChanged, removed: tokensRemoved } = useMemo(() => {
|
||||
return diffTokenLists(oldList.tokens, newList.tokens)
|
||||
}, [newList.tokens, oldList.tokens])
|
||||
const numTokensChanged = useMemo(
|
||||
() =>
|
||||
Object.keys(tokensChanged).reduce((memo, chainId: any) => memo + Object.keys(tokensChanged[chainId]).length, 0),
|
||||
[tokensChanged]
|
||||
)
|
||||
|
||||
return (
|
||||
<AutoRow>
|
||||
<AutoColumn style={{ flex: '1' }} gap="8px">
|
||||
{auto ? (
|
||||
<TYPE.body fontWeight={500}>
|
||||
The token list "{oldList.name}" has been updated to{' '}
|
||||
<strong>{listVersionLabel(newList.version)}</strong>.
|
||||
</TYPE.body>
|
||||
) : (
|
||||
<>
|
||||
<div>
|
||||
<Text>
|
||||
An update is available for the token list "{oldList.name}" (
|
||||
{listVersionLabel(oldList.version)} to {listVersionLabel(newList.version)}).
|
||||
</Text>
|
||||
<ChangesList>
|
||||
{tokensAdded.length > 0 ? (
|
||||
<li>
|
||||
{tokensAdded.map((token, i) => (
|
||||
<React.Fragment key={`${token.chainId}-${token.address}`}>
|
||||
<strong title={token.address}>{token.symbol}</strong>
|
||||
{i === tokensAdded.length - 1 ? null : ', '}
|
||||
</React.Fragment>
|
||||
))}{' '}
|
||||
added
|
||||
</li>
|
||||
) : null}
|
||||
{tokensRemoved.length > 0 ? (
|
||||
<li>
|
||||
{tokensRemoved.map((token, i) => (
|
||||
<React.Fragment key={`${token.chainId}-${token.address}`}>
|
||||
<strong title={token.address}>{token.symbol}</strong>
|
||||
{i === tokensRemoved.length - 1 ? null : ', '}
|
||||
</React.Fragment>
|
||||
))}{' '}
|
||||
removed
|
||||
</li>
|
||||
) : null}
|
||||
{numTokensChanged > 0 ? <li>{numTokensChanged} tokens updated</li> : null}
|
||||
</ChangesList>
|
||||
</div>
|
||||
<AutoRow>
|
||||
<div style={{ flexGrow: 1, marginRight: 12 }}>
|
||||
<ButtonSecondary onClick={handleAcceptUpdate}>Accept update</ButtonSecondary>
|
||||
</div>
|
||||
<div style={{ flexGrow: 1 }}>
|
||||
<ButtonSecondary onClick={removeThisPopup}>Dismiss</ButtonSecondary>
|
||||
</div>
|
||||
</AutoRow>
|
||||
</>
|
||||
)}
|
||||
</AutoColumn>
|
||||
</AutoRow>
|
||||
)
|
||||
}
|
||||
@@ -1,11 +1,10 @@
|
||||
import React, { useCallback, useContext, useEffect } from 'react'
|
||||
import { useCallback, useContext, useEffect } from 'react'
|
||||
import { X } from 'react-feather'
|
||||
import { useSpring } from 'react-spring/web'
|
||||
import styled, { ThemeContext } from 'styled-components'
|
||||
import { animated } from 'react-spring'
|
||||
import { PopupContent } from '../../state/application/actions'
|
||||
import { useRemovePopup } from '../../state/application/hooks'
|
||||
import ListUpdatePopup from './ListUpdatePopup'
|
||||
import TransactionPopup from './TransactionPopup'
|
||||
|
||||
export const StyledClose = styled(X)`
|
||||
@@ -77,11 +76,6 @@ export default function PopupItem({
|
||||
txn: { hash, success, summary },
|
||||
} = content
|
||||
popupContent = <TransactionPopup hash={hash} success={success} summary={summary} />
|
||||
} else if ('listUpdate' in content) {
|
||||
const {
|
||||
listUpdate: { listUrl, oldList, newList, auto },
|
||||
} = content
|
||||
popupContent = <ListUpdatePopup popKey={popKey} listUrl={listUrl} oldList={oldList} newList={newList} auto={auto} />
|
||||
}
|
||||
|
||||
const faderStyle = useSpring({
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import React, { useContext } from 'react'
|
||||
import { useContext } from 'react'
|
||||
import { AlertCircle, CheckCircle } from 'react-feather'
|
||||
import styled, { ThemeContext } from 'styled-components'
|
||||
import { useActiveWeb3React } from '../../hooks'
|
||||
import { useActiveWeb3React } from '../../hooks/web3'
|
||||
import { TYPE } from '../../theme'
|
||||
import { ExternalLink } from '../../theme/components'
|
||||
import { getEtherscanLink } from '../../utils'
|
||||
import { ExplorerDataType, getExplorerLink } from '../../utils/getExplorerLink'
|
||||
import { AutoColumn } from '../Column'
|
||||
import { AutoRow } from '../Row'
|
||||
|
||||
@@ -33,7 +33,9 @@ export default function TransactionPopup({
|
||||
<AutoColumn gap="8px">
|
||||
<TYPE.body fontWeight={500}>{summary ?? 'Hash: ' + hash.slice(0, 8) + '...' + hash.slice(58, 65)}</TYPE.body>
|
||||
{chainId && (
|
||||
<ExternalLink href={getEtherscanLink(chainId, hash, 'transaction')}>View on Etherscan</ExternalLink>
|
||||
<ExternalLink href={getExplorerLink(chainId, hash, ExplorerDataType.TRANSACTION)}>
|
||||
View on Explorer
|
||||
</ExternalLink>
|
||||
)}
|
||||
</AutoColumn>
|
||||
</RowNoFlex>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { useActivePopups } from '../../state/application/hooks'
|
||||
import { AutoColumn } from '../Column'
|
||||
import PopupItem from './PopupItem'
|
||||
@@ -33,7 +32,7 @@ const MobilePopupInner = styled.div`
|
||||
|
||||
const FixedPopupColumn = styled(AutoColumn)<{ extraPadding: boolean }>`
|
||||
position: fixed;
|
||||
top: ${({ extraPadding }) => (extraPadding ? '72px' : '88px')};
|
||||
top: ${({ extraPadding }) => (extraPadding ? '80px' : '88px')};
|
||||
right: 1rem;
|
||||
max-width: 355px !important;
|
||||
width: 100%;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import React from 'react'
|
||||
import { Token } from '@uniswap/sdk-core'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { Text } from 'rebass'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { Trans } from '@lingui/macro'
|
||||
|
||||
import { unwrappedToken } from '../../utils/wrappedCurrency'
|
||||
import { unwrappedToken } from '../../utils/unwrappedToken'
|
||||
import { ButtonEmpty } from '../Button'
|
||||
import { transparentize } from 'polished'
|
||||
import { CardNoise } from '../earn/styled'
|
||||
@@ -48,7 +48,13 @@ export default function SushiPositionCard({ tokenA, tokenB, liquidityToken, bord
|
||||
<AutoRow gap="8px">
|
||||
<DoubleCurrencyLogo currency0={currency0} currency1={currency1} size={20} />
|
||||
<Text fontWeight={500} fontSize={20}>
|
||||
{!currency0 || !currency1 ? <Dots>Loading</Dots> : `${currency0.symbol}/${currency1.symbol}`}
|
||||
{!currency0 || !currency1 ? (
|
||||
<Dots>
|
||||
<Trans>Loading</Trans>
|
||||
</Dots>
|
||||
) : (
|
||||
`${currency0.symbol}/${currency1.symbol}`
|
||||
)}
|
||||
</Text>
|
||||
|
||||
<Badge variant={BadgeVariant.WARNING}>Sushi</Badge>
|
||||
@@ -61,7 +67,7 @@ export default function SushiPositionCard({ tokenA, tokenB, liquidityToken, bord
|
||||
as={Link}
|
||||
to={`/migrate/v2/${liquidityToken.address}`}
|
||||
>
|
||||
Migrate
|
||||
<Trans>Migrate</Trans>
|
||||
</ButtonEmpty>
|
||||
</RowFixed>
|
||||
</FixedHeightRow>
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
import React, { useState } from 'react'
|
||||
import { Percent, TokenAmount } from '@uniswap/sdk-core'
|
||||
import { JSBI, Pair } from '@uniswap/v2-sdk'
|
||||
import JSBI from 'jsbi'
|
||||
import { useState } from 'react'
|
||||
import { Percent, CurrencyAmount, Token } from '@uniswap/sdk-core'
|
||||
import { Pair } from '@uniswap/v2-sdk'
|
||||
import { ChevronDown, ChevronUp } from 'react-feather'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { Text } from 'rebass'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { useTotalSupply } from '../../hooks/useTotalSupply'
|
||||
import { Trans } from '@lingui/macro'
|
||||
|
||||
import { useActiveWeb3React } from '../../hooks'
|
||||
import { useActiveWeb3React } from '../../hooks/web3'
|
||||
import { useTokenBalance } from '../../state/wallet/hooks'
|
||||
import { currencyId } from '../../utils/currencyId'
|
||||
import { unwrappedToken } from '../../utils/wrappedCurrency'
|
||||
import { unwrappedToken } from '../../utils/unwrappedToken'
|
||||
import { ButtonPrimary, ButtonSecondary, ButtonEmpty } from '../Button'
|
||||
import { transparentize } from 'polished'
|
||||
import { CardNoise } from '../earn/styled'
|
||||
@@ -23,7 +25,7 @@ import CurrencyLogo from '../CurrencyLogo'
|
||||
import DoubleCurrencyLogo from '../DoubleLogo'
|
||||
import { RowBetween, RowFixed, AutoRow } from '../Row'
|
||||
import { Dots } from '../swap/styleds'
|
||||
import { BIG_INT_ZERO } from '../../constants'
|
||||
import { BIG_INT_ZERO } from '../../constants/misc'
|
||||
import { FixedHeightRow } from '.'
|
||||
|
||||
const StyledPositionCard = styled(LightCard)<{ bgColor: any }>`
|
||||
@@ -38,7 +40,7 @@ interface PositionCardProps {
|
||||
pair: Pair
|
||||
showUnwrapped?: boolean
|
||||
border?: string
|
||||
stakedBalance?: TokenAmount // optional balance to indicate that liquidity is deposited in mining pool
|
||||
stakedBalance?: CurrencyAmount<Token> // optional balance to indicate that liquidity is deposited in mining pool
|
||||
}
|
||||
|
||||
export default function V2PositionCard({ pair, border, stakedBalance }: PositionCardProps) {
|
||||
@@ -56,8 +58,10 @@ export default function V2PositionCard({ pair, border, stakedBalance }: Position
|
||||
const userPoolBalance = stakedBalance ? userDefaultPoolBalance?.add(stakedBalance) : userDefaultPoolBalance
|
||||
|
||||
const poolTokenPercentage =
|
||||
!!userPoolBalance && !!totalPoolTokens && JSBI.greaterThanOrEqual(totalPoolTokens.raw, userPoolBalance.raw)
|
||||
? new Percent(userPoolBalance.raw, totalPoolTokens.raw)
|
||||
!!userPoolBalance &&
|
||||
!!totalPoolTokens &&
|
||||
JSBI.greaterThanOrEqual(totalPoolTokens.quotient, userPoolBalance.quotient)
|
||||
? new Percent(userPoolBalance.quotient, totalPoolTokens.quotient)
|
||||
: undefined
|
||||
|
||||
const [token0Deposited, token1Deposited] =
|
||||
@@ -65,7 +69,7 @@ export default function V2PositionCard({ pair, border, stakedBalance }: Position
|
||||
!!totalPoolTokens &&
|
||||
!!userPoolBalance &&
|
||||
// this condition is a short-circuit in the case where useTokenBalance updates sooner than useTotalSupply
|
||||
JSBI.greaterThanOrEqual(totalPoolTokens.raw, userPoolBalance.raw)
|
||||
JSBI.greaterThanOrEqual(totalPoolTokens.quotient, userPoolBalance.quotient)
|
||||
? [
|
||||
pair.getLiquidityValue(pair.token0, totalPoolTokens, userPoolBalance, false),
|
||||
pair.getLiquidityValue(pair.token1, totalPoolTokens, userPoolBalance, false),
|
||||
@@ -82,7 +86,13 @@ export default function V2PositionCard({ pair, border, stakedBalance }: Position
|
||||
<AutoRow gap="8px">
|
||||
<DoubleCurrencyLogo currency0={currency0} currency1={currency1} size={20} />
|
||||
<Text fontWeight={500} fontSize={20}>
|
||||
{!currency0 || !currency1 ? <Dots>Loading</Dots> : `${currency0.symbol}/${currency1.symbol}`}
|
||||
{!currency0 || !currency1 ? (
|
||||
<Dots>
|
||||
<Trans>Loading</Trans>
|
||||
</Dots>
|
||||
) : (
|
||||
`${currency0.symbol}/${currency1.symbol}`
|
||||
)}
|
||||
</Text>
|
||||
</AutoRow>
|
||||
<RowFixed gap="8px">
|
||||
@@ -94,12 +104,12 @@ export default function V2PositionCard({ pair, border, stakedBalance }: Position
|
||||
>
|
||||
{showMore ? (
|
||||
<>
|
||||
Manage
|
||||
<Trans>Manage</Trans>
|
||||
<ChevronUp size="20" style={{ marginLeft: '10px' }} />
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
Manage
|
||||
<Trans>Manage</Trans>
|
||||
<ChevronDown size="20" style={{ marginLeft: '10px' }} />
|
||||
</>
|
||||
)}
|
||||
@@ -111,7 +121,7 @@ export default function V2PositionCard({ pair, border, stakedBalance }: Position
|
||||
<AutoColumn gap="8px">
|
||||
<FixedHeightRow>
|
||||
<Text fontSize={16} fontWeight={500}>
|
||||
Your total pool tokens:
|
||||
<Trans>Your total pool tokens:</Trans>
|
||||
</Text>
|
||||
<Text fontSize={16} fontWeight={500}>
|
||||
{userPoolBalance ? userPoolBalance.toSignificant(4) : '-'}
|
||||
@@ -120,7 +130,7 @@ export default function V2PositionCard({ pair, border, stakedBalance }: Position
|
||||
{stakedBalance && (
|
||||
<FixedHeightRow>
|
||||
<Text fontSize={16} fontWeight={500}>
|
||||
Pool tokens in rewards pool:
|
||||
<Trans>Pool tokens in rewards pool:</Trans>
|
||||
</Text>
|
||||
<Text fontSize={16} fontWeight={500}>
|
||||
{stakedBalance.toSignificant(4)}
|
||||
@@ -130,7 +140,7 @@ export default function V2PositionCard({ pair, border, stakedBalance }: Position
|
||||
<FixedHeightRow>
|
||||
<RowFixed>
|
||||
<Text fontSize={16} fontWeight={500}>
|
||||
Pooled {currency0.symbol}:
|
||||
<Trans>Pooled {currency0.symbol}:</Trans>
|
||||
</Text>
|
||||
</RowFixed>
|
||||
{token0Deposited ? (
|
||||
@@ -148,7 +158,7 @@ export default function V2PositionCard({ pair, border, stakedBalance }: Position
|
||||
<FixedHeightRow>
|
||||
<RowFixed>
|
||||
<Text fontSize={16} fontWeight={500}>
|
||||
Pooled {currency1.symbol}:
|
||||
<Trans>Pooled {currency1.symbol}:</Trans>
|
||||
</Text>
|
||||
</RowFixed>
|
||||
{token1Deposited ? (
|
||||
@@ -165,7 +175,7 @@ export default function V2PositionCard({ pair, border, stakedBalance }: Position
|
||||
|
||||
<FixedHeightRow>
|
||||
<Text fontSize={16} fontWeight={500}>
|
||||
Your pool share:
|
||||
<Trans>Your pool share:</Trans>
|
||||
</Text>
|
||||
<Text fontSize={16} fontWeight={500}>
|
||||
{poolTokenPercentage
|
||||
@@ -174,7 +184,7 @@ export default function V2PositionCard({ pair, border, stakedBalance }: Position
|
||||
</Text>
|
||||
</FixedHeightRow>
|
||||
|
||||
{userDefaultPoolBalance && JSBI.greaterThan(userDefaultPoolBalance.raw, BIG_INT_ZERO) && (
|
||||
{userDefaultPoolBalance && JSBI.greaterThan(userDefaultPoolBalance.quotient, BIG_INT_ZERO) && (
|
||||
<RowBetween marginTop="10px">
|
||||
<ButtonPrimary
|
||||
padding="8px"
|
||||
@@ -183,7 +193,7 @@ export default function V2PositionCard({ pair, border, stakedBalance }: Position
|
||||
to={`/migrate/v2/${pair.liquidityToken.address}`}
|
||||
width="64%"
|
||||
>
|
||||
Migrate
|
||||
<Trans>Migrate</Trans>
|
||||
</ButtonPrimary>
|
||||
<ButtonSecondary
|
||||
padding="8px"
|
||||
@@ -192,7 +202,7 @@ export default function V2PositionCard({ pair, border, stakedBalance }: Position
|
||||
width="32%"
|
||||
to={`/remove/v2/${currencyId(currency0)}/${currencyId(currency1)}`}
|
||||
>
|
||||
Remove
|
||||
<Trans>Remove</Trans>
|
||||
</ButtonSecondary>
|
||||
</RowBetween>
|
||||
)}
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
import { Percent, TokenAmount } from '@uniswap/sdk-core'
|
||||
import { JSBI, Pair } from '@uniswap/v2-sdk'
|
||||
import JSBI from 'jsbi'
|
||||
import { Percent, CurrencyAmount, Token } from '@uniswap/sdk-core'
|
||||
import { Pair } from '@uniswap/v2-sdk'
|
||||
import { darken } from 'polished'
|
||||
import React, { useState } from 'react'
|
||||
import { useState } from 'react'
|
||||
import { ChevronDown, ChevronUp } from 'react-feather'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { Text } from 'rebass'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { useTotalSupply } from '../../hooks/useTotalSupply'
|
||||
import { Trans } from '@lingui/macro'
|
||||
|
||||
import { useActiveWeb3React } from '../../hooks'
|
||||
import { useActiveWeb3React } from '../../hooks/web3'
|
||||
import { useTokenBalance } from '../../state/wallet/hooks'
|
||||
import { ExternalLink, TYPE } from '../../theme'
|
||||
import { currencyId } from '../../utils/currencyId'
|
||||
import { unwrappedToken } from '../../utils/wrappedCurrency'
|
||||
import { unwrappedToken } from '../../utils/unwrappedToken'
|
||||
import { ButtonPrimary, ButtonSecondary, ButtonEmpty } from '../Button'
|
||||
import { transparentize } from 'polished'
|
||||
import { CardNoise } from '../earn/styled'
|
||||
@@ -25,7 +27,7 @@ import CurrencyLogo from '../CurrencyLogo'
|
||||
import DoubleCurrencyLogo from '../DoubleLogo'
|
||||
import { RowBetween, RowFixed, AutoRow } from '../Row'
|
||||
import { Dots } from '../swap/styleds'
|
||||
import { BIG_INT_ZERO } from '../../constants'
|
||||
import { BIG_INT_ZERO } from '../../constants/misc'
|
||||
|
||||
export const FixedHeightRow = styled(RowBetween)`
|
||||
height: 24px;
|
||||
@@ -49,7 +51,7 @@ interface PositionCardProps {
|
||||
pair: Pair
|
||||
showUnwrapped?: boolean
|
||||
border?: string
|
||||
stakedBalance?: TokenAmount // optional balance to indicate that liquidity is deposited in mining pool
|
||||
stakedBalance?: CurrencyAmount<Token> // optional balance to indicate that liquidity is deposited in mining pool
|
||||
}
|
||||
|
||||
export function MinimalPositionCard({ pair, showUnwrapped = false, border }: PositionCardProps) {
|
||||
@@ -64,8 +66,10 @@ export function MinimalPositionCard({ pair, showUnwrapped = false, border }: Pos
|
||||
const totalPoolTokens = useTotalSupply(pair.liquidityToken)
|
||||
|
||||
const poolTokenPercentage =
|
||||
!!userPoolBalance && !!totalPoolTokens && JSBI.greaterThanOrEqual(totalPoolTokens.raw, userPoolBalance.raw)
|
||||
? new Percent(userPoolBalance.raw, totalPoolTokens.raw)
|
||||
!!userPoolBalance &&
|
||||
!!totalPoolTokens &&
|
||||
JSBI.greaterThanOrEqual(totalPoolTokens.quotient, userPoolBalance.quotient)
|
||||
? new Percent(userPoolBalance.quotient, totalPoolTokens.quotient)
|
||||
: undefined
|
||||
|
||||
const [token0Deposited, token1Deposited] =
|
||||
@@ -73,7 +77,7 @@ export function MinimalPositionCard({ pair, showUnwrapped = false, border }: Pos
|
||||
!!totalPoolTokens &&
|
||||
!!userPoolBalance &&
|
||||
// this condition is a short-circuit in the case where useTokenBalance updates sooner than useTotalSupply
|
||||
JSBI.greaterThanOrEqual(totalPoolTokens.raw, userPoolBalance.raw)
|
||||
JSBI.greaterThanOrEqual(totalPoolTokens.quotient, userPoolBalance.quotient)
|
||||
? [
|
||||
pair.getLiquidityValue(pair.token0, totalPoolTokens, userPoolBalance, false),
|
||||
pair.getLiquidityValue(pair.token1, totalPoolTokens, userPoolBalance, false),
|
||||
@@ -82,13 +86,13 @@ export function MinimalPositionCard({ pair, showUnwrapped = false, border }: Pos
|
||||
|
||||
return (
|
||||
<>
|
||||
{userPoolBalance && JSBI.greaterThan(userPoolBalance.raw, JSBI.BigInt(0)) ? (
|
||||
{userPoolBalance && JSBI.greaterThan(userPoolBalance.quotient, JSBI.BigInt(0)) ? (
|
||||
<GreyCard border={border}>
|
||||
<AutoColumn gap="12px">
|
||||
<FixedHeightRow>
|
||||
<RowFixed>
|
||||
<Text fontWeight={500} fontSize={16}>
|
||||
Your position
|
||||
<Trans>Your position</Trans>
|
||||
</Text>
|
||||
</RowFixed>
|
||||
</FixedHeightRow>
|
||||
@@ -108,7 +112,7 @@ export function MinimalPositionCard({ pair, showUnwrapped = false, border }: Pos
|
||||
<AutoColumn gap="4px">
|
||||
<FixedHeightRow>
|
||||
<Text fontSize={16} fontWeight={500}>
|
||||
Your pool share:
|
||||
<Trans>Your pool share:</Trans>
|
||||
</Text>
|
||||
<Text fontSize={16} fontWeight={500}>
|
||||
{poolTokenPercentage ? poolTokenPercentage.toFixed(6) + '%' : '-'}
|
||||
@@ -151,8 +155,10 @@ export function MinimalPositionCard({ pair, showUnwrapped = false, border }: Pos
|
||||
<span role="img" aria-label="wizard-icon">
|
||||
⭐️
|
||||
</span>{' '}
|
||||
By adding liquidity you'll earn 0.3% of all trades on this pair proportional to your share of the pool.
|
||||
Fees are added to the pool, accrue in real time and can be claimed by withdrawing your liquidity.
|
||||
<Trans>
|
||||
By adding liquidity you'll earn 0.3% of all trades on this pair proportional to your share of the
|
||||
pool. Fees are added to the pool, accrue in real time and can be claimed by withdrawing your liquidity.
|
||||
</Trans>{' '}
|
||||
</TYPE.subHeader>
|
||||
</LightCard>
|
||||
)}
|
||||
@@ -175,8 +181,10 @@ export default function FullPositionCard({ pair, border, stakedBalance }: Positi
|
||||
const userPoolBalance = stakedBalance ? userDefaultPoolBalance?.add(stakedBalance) : userDefaultPoolBalance
|
||||
|
||||
const poolTokenPercentage =
|
||||
!!userPoolBalance && !!totalPoolTokens && JSBI.greaterThanOrEqual(totalPoolTokens.raw, userPoolBalance.raw)
|
||||
? new Percent(userPoolBalance.raw, totalPoolTokens.raw)
|
||||
!!userPoolBalance &&
|
||||
!!totalPoolTokens &&
|
||||
JSBI.greaterThanOrEqual(totalPoolTokens.quotient, userPoolBalance.quotient)
|
||||
? new Percent(userPoolBalance.quotient, totalPoolTokens.quotient)
|
||||
: undefined
|
||||
|
||||
const [token0Deposited, token1Deposited] =
|
||||
@@ -184,7 +192,7 @@ export default function FullPositionCard({ pair, border, stakedBalance }: Positi
|
||||
!!totalPoolTokens &&
|
||||
!!userPoolBalance &&
|
||||
// this condition is a short-circuit in the case where useTokenBalance updates sooner than useTotalSupply
|
||||
JSBI.greaterThanOrEqual(totalPoolTokens.raw, userPoolBalance.raw)
|
||||
JSBI.greaterThanOrEqual(totalPoolTokens.quotient, userPoolBalance.quotient)
|
||||
? [
|
||||
pair.getLiquidityValue(pair.token0, totalPoolTokens, userPoolBalance, false),
|
||||
pair.getLiquidityValue(pair.token1, totalPoolTokens, userPoolBalance, false),
|
||||
@@ -201,19 +209,25 @@ export default function FullPositionCard({ pair, border, stakedBalance }: Positi
|
||||
<AutoRow gap="8px" style={{ marginLeft: '8px' }}>
|
||||
<DoubleCurrencyLogo currency0={currency0} currency1={currency1} size={20} />
|
||||
<Text fontWeight={500} fontSize={20}>
|
||||
{!currency0 || !currency1 ? <Dots>Loading</Dots> : `${currency0.symbol}/${currency1.symbol}`}
|
||||
{!currency0 || !currency1 ? (
|
||||
<Dots>
|
||||
<Trans>Loading</Trans>
|
||||
</Dots>
|
||||
) : (
|
||||
`${currency0.symbol}/${currency1.symbol}`
|
||||
)}
|
||||
</Text>
|
||||
</AutoRow>
|
||||
<RowFixed gap="8px" style={{ marginRight: '4px' }}>
|
||||
<ButtonEmpty padding="6px 8px" borderRadius="12px" width="100%" onClick={() => setShowMore(!showMore)}>
|
||||
{showMore ? (
|
||||
<>
|
||||
Manage
|
||||
<Trans>Manage</Trans>
|
||||
<ChevronUp size="20" style={{ marginLeft: '8px', height: '20px', minWidth: '20px' }} />
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
Manage
|
||||
<Trans>Manage</Trans>
|
||||
<ChevronDown size="20" style={{ marginLeft: '8px', height: '20px', minWidth: '20px' }} />
|
||||
</>
|
||||
)}
|
||||
@@ -225,7 +239,7 @@ export default function FullPositionCard({ pair, border, stakedBalance }: Positi
|
||||
<AutoColumn gap="8px">
|
||||
<FixedHeightRow>
|
||||
<Text fontSize={16} fontWeight={500}>
|
||||
Your total pool tokens:
|
||||
<Trans>Your total pool tokens:</Trans>
|
||||
</Text>
|
||||
<Text fontSize={16} fontWeight={500}>
|
||||
{userPoolBalance ? userPoolBalance.toSignificant(4) : '-'}
|
||||
@@ -234,7 +248,7 @@ export default function FullPositionCard({ pair, border, stakedBalance }: Positi
|
||||
{stakedBalance && (
|
||||
<FixedHeightRow>
|
||||
<Text fontSize={16} fontWeight={500}>
|
||||
Pool tokens in rewards pool:
|
||||
<Trans>Pool tokens in rewards pool:</Trans>
|
||||
</Text>
|
||||
<Text fontSize={16} fontWeight={500}>
|
||||
{stakedBalance.toSignificant(4)}
|
||||
@@ -244,7 +258,7 @@ export default function FullPositionCard({ pair, border, stakedBalance }: Positi
|
||||
<FixedHeightRow>
|
||||
<RowFixed>
|
||||
<Text fontSize={16} fontWeight={500}>
|
||||
Pooled {currency0.symbol}:
|
||||
<Trans>Pooled {currency0.symbol}:</Trans>
|
||||
</Text>
|
||||
</RowFixed>
|
||||
{token0Deposited ? (
|
||||
@@ -262,7 +276,7 @@ export default function FullPositionCard({ pair, border, stakedBalance }: Positi
|
||||
<FixedHeightRow>
|
||||
<RowFixed>
|
||||
<Text fontSize={16} fontWeight={500}>
|
||||
Pooled {currency1.symbol}:
|
||||
<Trans>Pooled {currency1.symbol}:</Trans>
|
||||
</Text>
|
||||
</RowFixed>
|
||||
{token1Deposited ? (
|
||||
@@ -279,12 +293,16 @@ export default function FullPositionCard({ pair, border, stakedBalance }: Positi
|
||||
|
||||
<FixedHeightRow>
|
||||
<Text fontSize={16} fontWeight={500}>
|
||||
Your pool share:
|
||||
<Trans>Your pool share:</Trans>
|
||||
</Text>
|
||||
<Text fontSize={16} fontWeight={500}>
|
||||
{poolTokenPercentage
|
||||
? (poolTokenPercentage.toFixed(2) === '0.00' ? '<0.01' : poolTokenPercentage.toFixed(2)) + '%'
|
||||
: '-'}
|
||||
{poolTokenPercentage ? (
|
||||
<Trans>
|
||||
{poolTokenPercentage.toFixed(2) === '0.00' ? '<0.01' : poolTokenPercentage.toFixed(2)} %
|
||||
</Trans>
|
||||
) : (
|
||||
'-'
|
||||
)}
|
||||
</Text>
|
||||
</FixedHeightRow>
|
||||
|
||||
@@ -293,10 +311,12 @@ export default function FullPositionCard({ pair, border, stakedBalance }: Positi
|
||||
style={{ width: '100%', textAlign: 'center' }}
|
||||
href={`https://v2.info.uniswap.org/account/${account}`}
|
||||
>
|
||||
View accrued fees and analytics<span style={{ fontSize: '11px' }}>↗</span>
|
||||
<Trans>
|
||||
View accrued fees and analytics<span style={{ fontSize: '11px' }}>↗</span>
|
||||
</Trans>
|
||||
</ExternalLink>
|
||||
</ButtonSecondary>
|
||||
{userDefaultPoolBalance && JSBI.greaterThan(userDefaultPoolBalance.raw, BIG_INT_ZERO) && (
|
||||
{userDefaultPoolBalance && JSBI.greaterThan(userDefaultPoolBalance.quotient, BIG_INT_ZERO) && (
|
||||
<RowBetween marginTop="10px">
|
||||
<ButtonPrimary
|
||||
padding="8px"
|
||||
@@ -305,7 +325,7 @@ export default function FullPositionCard({ pair, border, stakedBalance }: Positi
|
||||
to={`/migrate/v2/${pair.liquidityToken.address}`}
|
||||
width="32%"
|
||||
>
|
||||
Migrate
|
||||
<Trans>Migrate</Trans>
|
||||
</ButtonPrimary>
|
||||
<ButtonPrimary
|
||||
padding="8px"
|
||||
@@ -314,7 +334,7 @@ export default function FullPositionCard({ pair, border, stakedBalance }: Positi
|
||||
to={`/add/v2/${currencyId(currency0)}/${currencyId(currency1)}`}
|
||||
width="32%"
|
||||
>
|
||||
Add
|
||||
<Trans>Add</Trans>
|
||||
</ButtonPrimary>
|
||||
<ButtonPrimary
|
||||
padding="8px"
|
||||
@@ -323,11 +343,11 @@ export default function FullPositionCard({ pair, border, stakedBalance }: Positi
|
||||
width="32%"
|
||||
to={`/remove/v2/${currencyId(currency0)}/${currencyId(currency1)}`}
|
||||
>
|
||||
Remove
|
||||
<Trans>Remove</Trans>
|
||||
</ButtonPrimary>
|
||||
</RowBetween>
|
||||
)}
|
||||
{stakedBalance && JSBI.greaterThan(stakedBalance.raw, BIG_INT_ZERO) && (
|
||||
{stakedBalance && JSBI.greaterThan(stakedBalance.quotient, BIG_INT_ZERO) && (
|
||||
<ButtonPrimary
|
||||
padding="8px"
|
||||
borderRadius="8px"
|
||||
@@ -335,7 +355,7 @@ export default function FullPositionCard({ pair, border, stakedBalance }: Positi
|
||||
to={`/uni/${currencyId(currency0)}/${currencyId(currency1)}`}
|
||||
width="100%"
|
||||
>
|
||||
Manage Liquidity in Rewards Pool
|
||||
<Trans>Manage Liquidity in Rewards Pool</Trans>
|
||||
</ButtonPrimary>
|
||||
)}
|
||||
</AutoColumn>
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
// import { Story } from '@storybook/react/types-6-0'
|
||||
// import React from 'react'
|
||||
// import { Position } from 'types/position'
|
||||
// import { basisPointsToPercent } from 'utils'
|
||||
// import { DAI, WBTC } from '../../constants'
|
||||
// import Component, { PositionListProps } from './index'
|
||||
// import { TokenAmount } from '@uniswap/sdk-core'
|
||||
// import JSBI from 'jsbi'
|
||||
|
||||
// const FEE_BIPS = {
|
||||
// FIVE: basisPointsToPercent(5),
|
||||
// THIRTY: basisPointsToPercent(30),
|
||||
// ONE_HUNDRED: basisPointsToPercent(100),
|
||||
// }
|
||||
// const daiAmount = new TokenAmount(DAI, JSBI.BigInt(500 * 10 ** 18))
|
||||
// const wbtcAmount = new TokenAmount(WBTC, JSBI.BigInt(10 ** 7))
|
||||
// const positions = [
|
||||
// {
|
||||
// feesEarned: {
|
||||
// DAI: 1000,
|
||||
// WBTC: 0.005,
|
||||
// },
|
||||
// feeLevel: FEE_BIPS.FIVE,
|
||||
// tokenAmount0: daiAmount,
|
||||
// tokenAmount1: wbtcAmount,
|
||||
// tickLower: 40000,
|
||||
// tickUpper: 60000,
|
||||
// },
|
||||
// {
|
||||
// feesEarned: {
|
||||
// DAI: 1000,
|
||||
// WBTC: 0.005,
|
||||
// },
|
||||
// feeLevel: FEE_BIPS.THIRTY,
|
||||
// tokenAmount0: daiAmount,
|
||||
// tokenAmount1: wbtcAmount,
|
||||
// tickLower: 45000,
|
||||
// tickUpper: 55000,
|
||||
// },
|
||||
// ]
|
||||
// const positions: Position[] = []
|
||||
|
||||
export default {
|
||||
title: 'PositionList',
|
||||
}
|
||||
|
||||
// const Template: Story<PositionListProps> = (args) => <Component {...args} />
|
||||
|
||||
// export const PositionList = Template.bind({})
|
||||
// PositionList.args = {
|
||||
// positions,
|
||||
// showUnwrapped: true,
|
||||
// }
|
||||
@@ -1,7 +1,7 @@
|
||||
import PositionListItem from 'components/PositionListItem'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import styled from 'styled-components'
|
||||
import { Trans } from '@lingui/macro'
|
||||
import styled from 'styled-components/macro'
|
||||
import { MEDIA_WIDTHS } from 'theme'
|
||||
import { PositionDetails } from 'types/position'
|
||||
|
||||
@@ -39,18 +39,20 @@ export type PositionListProps = React.PropsWithChildren<{
|
||||
}>
|
||||
|
||||
export default function PositionList({ positions }: PositionListProps) {
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<>
|
||||
<DesktopHeader>
|
||||
<div>
|
||||
{t('Your positions')}
|
||||
<Trans>Your positions</Trans>
|
||||
{positions && ' (' + positions.length + ')'}
|
||||
</div>
|
||||
<div>{t('Price range')}</div>
|
||||
<div>
|
||||
<Trans>Price range</Trans>
|
||||
</div>
|
||||
</DesktopHeader>
|
||||
<MobileHeader>Your positions</MobileHeader>
|
||||
<MobileHeader>
|
||||
<Trans>Your positions</Trans>
|
||||
</MobileHeader>
|
||||
{positions.map((p) => {
|
||||
return <PositionListItem key={p.tokenId.toString()} positionDetails={p} />
|
||||
})}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
// import { Story } from '@storybook/react/types-6-0'
|
||||
// import { FeeAmount, MAX_TICK, MIN_TICK, TICK_SPACINGS } from '@uniswap/v3-sdk'
|
||||
// import { BigNumber } from 'ethers'
|
||||
// import React from 'react'
|
||||
// import { Position } from 'types/position'
|
||||
// import Component, { PositionListItemProps } from './index'
|
||||
|
||||
// const position: Position = {
|
||||
// nonce: BigNumber.from(0),
|
||||
// operator: '',
|
||||
// token0: '',
|
||||
// token1: '',
|
||||
// fee: FeeAmount.LOW,
|
||||
// tickLower: MIN_TICK(TICK_SPACINGS[FeeAmount.LOW]),
|
||||
// tickUpper: MAX_TICK(TICK_SPACINGS[FeeAmount.LOW]),
|
||||
// liquidity,
|
||||
// feeGrowthInside0LastX128fee
|
||||
// feeGrowthInside0LastX128
|
||||
// feeGrowthInside1LastX128
|
||||
// tokensOwed0
|
||||
// tokensOwed1
|
||||
// }
|
||||
|
||||
export default {
|
||||
title: 'PositionListItem',
|
||||
}
|
||||
|
||||
// const Template: Story<PositionListItemProps> = (args) => <Component {...args} />
|
||||
|
||||
// export const PositionListItem = Template.bind({})
|
||||
// PositionListItem.args = {position}
|
||||
@@ -1,26 +1,29 @@
|
||||
import React, { useMemo, useState } from 'react'
|
||||
import { useMemo } from 'react'
|
||||
import { Position } from '@uniswap/v3-sdk'
|
||||
import Badge from 'components/Badge'
|
||||
import DoubleCurrencyLogo from 'components/DoubleLogo'
|
||||
import { usePool } from 'hooks/usePools'
|
||||
import { useToken } from 'hooks/Tokens'
|
||||
import { Link } from 'react-router-dom'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { HideSmall, MEDIA_WIDTHS, SmallOnly } from 'theme'
|
||||
import { PositionDetails } from 'types/position'
|
||||
import { WETH9, Price, Token, Percent } from '@uniswap/sdk-core'
|
||||
import { formatPrice } from 'utils/formatTokenAmount'
|
||||
import { Price, Token, Percent } from '@uniswap/sdk-core'
|
||||
import { formatPrice } from 'utils/formatCurrencyAmount'
|
||||
import Loader from 'components/Loader'
|
||||
import { unwrappedToken } from 'utils/wrappedCurrency'
|
||||
import { DAI, USDC, USDT, WBTC } from '../../constants'
|
||||
import { unwrappedToken } from 'utils/unwrappedToken'
|
||||
import RangeBadge from 'components/Badge/RangeBadge'
|
||||
import { RowFixed } from 'components/Row'
|
||||
import HoverInlineText from 'components/HoverInlineText'
|
||||
import { DAI, USDC, USDT, WBTC, WETH9_EXTENDED } from '../../constants/tokens'
|
||||
import { Trans } from '@lingui/macro'
|
||||
|
||||
const Row = styled(Link)`
|
||||
const LinkRow = styled(Link)`
|
||||
align-items: center;
|
||||
border-radius: 20px;
|
||||
display: flex;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
justify-content: space-between;
|
||||
color: ${({ theme }) => theme.text1};
|
||||
margin: 8px 0;
|
||||
@@ -50,6 +53,7 @@ const Row = styled(Link)`
|
||||
row-gap: 24px;
|
||||
`};
|
||||
`
|
||||
|
||||
const BadgeText = styled.div`
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
@@ -65,7 +69,6 @@ const DataLineItem = styled.div`
|
||||
const RangeLineItem = styled(DataLineItem)`
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
cursor: pointer;
|
||||
align-items: center;
|
||||
justify-self: flex-end;
|
||||
|
||||
@@ -118,11 +121,9 @@ export interface PositionListItemProps {
|
||||
positionDetails: PositionDetails
|
||||
}
|
||||
|
||||
export function getPriceOrderingFromPositionForUI(
|
||||
position?: Position
|
||||
): {
|
||||
priceLower?: Price
|
||||
priceUpper?: Price
|
||||
export function getPriceOrderingFromPositionForUI(position?: Position): {
|
||||
priceLower?: Price<Token, Token>
|
||||
priceUpper?: Price<Token, Token>
|
||||
quote?: Token
|
||||
base?: Token
|
||||
} {
|
||||
@@ -130,8 +131,8 @@ export function getPriceOrderingFromPositionForUI(
|
||||
return {}
|
||||
}
|
||||
|
||||
const token0 = position.amount0.token
|
||||
const token1 = position.amount1.token
|
||||
const token0 = position.amount0.currency
|
||||
const token1 = position.amount1.currency
|
||||
|
||||
// if token0 is a dollar-stable asset, set it as the quote token
|
||||
const stables = [DAI, USDC, USDT]
|
||||
@@ -145,7 +146,7 @@ export function getPriceOrderingFromPositionForUI(
|
||||
}
|
||||
|
||||
// if token1 is an ETH-/BTC-stable asset, set it as the base token
|
||||
const bases = [...Object.values(WETH9), WBTC]
|
||||
const bases = [...Object.values(WETH9_EXTENDED), WBTC]
|
||||
if (bases.some((base) => base.equals(token1))) {
|
||||
return {
|
||||
priceLower: position.token0PriceUpper.invert(),
|
||||
@@ -201,25 +202,20 @@ export default function PositionListItem({ positionDetails }: PositionListItemPr
|
||||
}, [liquidity, pool, tickLower, tickUpper])
|
||||
|
||||
// prices
|
||||
let { priceLower, priceUpper, base, quote } = getPriceOrderingFromPositionForUI(position)
|
||||
const inverted = token1 ? base?.equals(token1) : undefined
|
||||
const currencyQuote = inverted ? currency1 : currency0
|
||||
const currencyBase = inverted ? currency0 : currency1
|
||||
const { priceLower, priceUpper, quote, base } = getPriceOrderingFromPositionForUI(position)
|
||||
|
||||
const currencyQuote = quote && unwrappedToken(quote)
|
||||
const currencyBase = base && unwrappedToken(base)
|
||||
|
||||
// check if price is within range
|
||||
const outOfRange: boolean = pool ? pool.tickCurrent < tickLower || pool.tickCurrent >= tickUpper : false
|
||||
|
||||
const positionSummaryLink = '/pool/' + positionDetails.tokenId
|
||||
|
||||
const [manuallyInverted, setManuallyInverted] = useState(true)
|
||||
if (manuallyInverted) {
|
||||
;[priceLower, priceUpper, base, quote] = [priceUpper?.invert(), priceLower?.invert(), quote, base]
|
||||
}
|
||||
|
||||
const removed = liquidity?.eq(0)
|
||||
|
||||
return (
|
||||
<Row to={positionSummaryLink}>
|
||||
<LinkRow to={positionSummaryLink}>
|
||||
<RowFixed>
|
||||
<PrimaryPositionIdData>
|
||||
<DoubleCurrencyLogo currency0={currencyBase} currency1={currencyQuote} size={18} margin />
|
||||
@@ -228,49 +224,44 @@ export default function PositionListItem({ positionDetails }: PositionListItemPr
|
||||
</DataText>
|
||||
|
||||
<Badge>
|
||||
<BadgeText>{new Percent(feeAmount, 1_000_000).toSignificant()}%</BadgeText>
|
||||
<BadgeText>
|
||||
<Trans>{new Percent(feeAmount, 1_000_000).toSignificant()}%</Trans>
|
||||
</BadgeText>
|
||||
</Badge>
|
||||
</PrimaryPositionIdData>
|
||||
<RangeBadge removed={removed} inRange={!outOfRange} />
|
||||
</RowFixed>
|
||||
|
||||
{priceLower && priceUpper ? (
|
||||
<>
|
||||
<RangeLineItem
|
||||
onClick={(e) => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
setManuallyInverted(!manuallyInverted)
|
||||
}}
|
||||
>
|
||||
<RangeText>
|
||||
<ExtentsText>Min: </ExtentsText>
|
||||
{formatPrice(priceLower, 5)}{' '}
|
||||
<HoverInlineText text={manuallyInverted ? currencyQuote?.symbol ?? '' : currencyBase?.symbol ?? ''} />{' '}
|
||||
{' per '}{' '}
|
||||
<HoverInlineText text={manuallyInverted ? currencyBase?.symbol ?? '' : currencyQuote?.symbol ?? ''} />
|
||||
</RangeText>{' '}
|
||||
<HideSmall>
|
||||
<DoubleArrow>⟷</DoubleArrow>{' '}
|
||||
</HideSmall>
|
||||
<SmallOnly>
|
||||
<DoubleArrow>↕</DoubleArrow>{' '}
|
||||
</SmallOnly>
|
||||
<RangeText>
|
||||
<ExtentsText>Max:</ExtentsText>
|
||||
{formatPrice(priceUpper, 5)}{' '}
|
||||
<HoverInlineText text={manuallyInverted ? currencyQuote?.symbol ?? '' : currencyBase?.symbol ?? ''} />{' '}
|
||||
{' per '}{' '}
|
||||
<HoverInlineText
|
||||
maxCharacters={10}
|
||||
text={manuallyInverted ? currencyBase?.symbol ?? '' : currencyQuote?.symbol ?? ''}
|
||||
/>
|
||||
</RangeText>{' '}
|
||||
</RangeLineItem>
|
||||
</>
|
||||
<RangeLineItem>
|
||||
<RangeText>
|
||||
<ExtentsText>
|
||||
<Trans>Min: </Trans>
|
||||
</ExtentsText>
|
||||
<Trans>
|
||||
{formatPrice(priceLower, 5)} <HoverInlineText text={currencyQuote?.symbol} /> per{' '}
|
||||
<HoverInlineText text={currencyBase?.symbol ?? ''} />
|
||||
</Trans>
|
||||
</RangeText>{' '}
|
||||
<HideSmall>
|
||||
<DoubleArrow>⟷</DoubleArrow>{' '}
|
||||
</HideSmall>
|
||||
<SmallOnly>
|
||||
<DoubleArrow>↕</DoubleArrow>{' '}
|
||||
</SmallOnly>
|
||||
<RangeText>
|
||||
<ExtentsText>
|
||||
<Trans>Max:</Trans>
|
||||
</ExtentsText>
|
||||
<Trans>
|
||||
{formatPrice(priceUpper, 5)} <HoverInlineText text={currencyQuote?.symbol} /> per{' '}
|
||||
<HoverInlineText maxCharacters={10} text={currencyBase?.symbol} />
|
||||
</Trans>
|
||||
</RangeText>
|
||||
</RangeLineItem>
|
||||
) : (
|
||||
<Loader />
|
||||
)}
|
||||
</Row>
|
||||
</LinkRow>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import React, { useState, useCallback, useContext } from 'react'
|
||||
import { useState, useCallback, useContext, ReactNode } from 'react'
|
||||
import { Position } from '@uniswap/v3-sdk'
|
||||
import { LightCard } from 'components/Card'
|
||||
import { AutoColumn } from 'components/Column'
|
||||
import { TYPE } from 'theme'
|
||||
import { RowBetween, RowFixed } from 'components/Row'
|
||||
import CurrencyLogo from 'components/CurrencyLogo'
|
||||
import { unwrappedToken } from 'utils/wrappedCurrency'
|
||||
import { unwrappedToken } from 'utils/unwrappedToken'
|
||||
import { Break } from 'components/earn/styled'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Trans } from '@lingui/macro'
|
||||
import { Currency } from '@uniswap/sdk-core'
|
||||
import RateToggle from 'components/RateToggle'
|
||||
import DoubleCurrencyLogo from 'components/DoubleLogo'
|
||||
import RangeBadge from 'components/Badge/RangeBadge'
|
||||
import { ThemeContext } from 'styled-components'
|
||||
import { JSBI } from '@uniswap/v2-sdk'
|
||||
import JSBI from 'jsbi'
|
||||
|
||||
export const PositionPreview = ({
|
||||
position,
|
||||
@@ -22,12 +22,10 @@ export const PositionPreview = ({
|
||||
baseCurrencyDefault,
|
||||
}: {
|
||||
position: Position
|
||||
title?: string
|
||||
title?: ReactNode
|
||||
inRange: boolean
|
||||
baseCurrencyDefault?: Currency | undefined
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const theme = useContext(ThemeContext)
|
||||
|
||||
const currency0 = unwrappedToken(position.pool.token0)
|
||||
@@ -97,8 +95,12 @@ export const PositionPreview = ({
|
||||
</RowBetween>
|
||||
<Break />
|
||||
<RowBetween>
|
||||
<TYPE.label>{t('feeTier')}</TYPE.label>
|
||||
<TYPE.label>{position?.pool?.fee / 10000}%</TYPE.label>
|
||||
<TYPE.label>
|
||||
<Trans>Fee Tier</Trans>
|
||||
</TYPE.label>
|
||||
<TYPE.label>
|
||||
<Trans>{position?.pool?.fee / 10000}%</Trans>
|
||||
</TYPE.label>
|
||||
</RowBetween>
|
||||
</AutoColumn>
|
||||
</LightCard>
|
||||
@@ -116,40 +118,49 @@ export const PositionPreview = ({
|
||||
<RowBetween>
|
||||
<LightCard width="48%" padding="8px">
|
||||
<AutoColumn gap="4px" justify="center">
|
||||
<TYPE.main fontSize="12px">Min Price</TYPE.main>
|
||||
<TYPE.main fontSize="12px">
|
||||
<Trans>Min Price</Trans>
|
||||
</TYPE.main>
|
||||
<TYPE.mediumHeader textAlign="center">{`${priceLower.toSignificant(5)}`}</TYPE.mediumHeader>
|
||||
<TYPE.main
|
||||
textAlign="center"
|
||||
fontSize="12px"
|
||||
>{` ${quoteCurrency.symbol}/${baseCurrency.symbol}`}</TYPE.main>
|
||||
<TYPE.main textAlign="center" fontSize="12px">
|
||||
<Trans>
|
||||
{quoteCurrency.symbol} per {baseCurrency.symbol}
|
||||
</Trans>
|
||||
</TYPE.main>
|
||||
<TYPE.small textAlign="center" color={theme.text3} style={{ marginTop: '4px' }}>
|
||||
Your position will be 100% composed of {baseCurrency?.symbol} at this price
|
||||
<Trans>Your position will be 100% composed of {baseCurrency?.symbol} at this price</Trans>
|
||||
</TYPE.small>
|
||||
</AutoColumn>
|
||||
</LightCard>
|
||||
|
||||
<LightCard width="48%" padding="8px">
|
||||
<AutoColumn gap="4px" justify="center">
|
||||
<TYPE.main fontSize="12px">Max Price</TYPE.main>
|
||||
<TYPE.main fontSize="12px">
|
||||
<Trans>Max Price</Trans>
|
||||
</TYPE.main>
|
||||
<TYPE.mediumHeader textAlign="center">{`${priceUpper.toSignificant(5)}`}</TYPE.mediumHeader>
|
||||
<TYPE.main
|
||||
textAlign="center"
|
||||
fontSize="12px"
|
||||
>{` ${quoteCurrency.symbol} per ${baseCurrency.symbol}`}</TYPE.main>
|
||||
<TYPE.main textAlign="center" fontSize="12px">
|
||||
<Trans>
|
||||
{quoteCurrency.symbol} per {baseCurrency.symbol}
|
||||
</Trans>
|
||||
</TYPE.main>
|
||||
<TYPE.small textAlign="center" color={theme.text3} style={{ marginTop: '4px' }}>
|
||||
Your position will be 100% composed of {quoteCurrency?.symbol} at this price
|
||||
<Trans>Your position will be 100% composed of {quoteCurrency?.symbol} at this price</Trans>
|
||||
</TYPE.small>
|
||||
</AutoColumn>
|
||||
</LightCard>
|
||||
</RowBetween>
|
||||
<LightCard padding="12px ">
|
||||
<AutoColumn gap="4px" justify="center">
|
||||
<TYPE.main fontSize="12px">Current price</TYPE.main>
|
||||
<TYPE.main fontSize="12px">
|
||||
<Trans>Current price</Trans>
|
||||
</TYPE.main>
|
||||
<TYPE.mediumHeader>{`${price.toSignificant(5)} `}</TYPE.mediumHeader>
|
||||
<TYPE.main
|
||||
textAlign="center"
|
||||
fontSize="12px"
|
||||
>{` ${quoteCurrency.symbol} per ${baseCurrency.symbol}`}</TYPE.main>
|
||||
<TYPE.main textAlign="center" fontSize="12px">
|
||||
<Trans>
|
||||
{quoteCurrency.symbol} per {baseCurrency.symbol}
|
||||
</Trans>
|
||||
</TYPE.main>
|
||||
</AutoColumn>
|
||||
</LightCard>
|
||||
</AutoColumn>
|
||||
|
||||