Compare commits

..

29 Commits

Author SHA1 Message Date
Moody Salem
5c10a7f61d move environment variables to the .env files 2020-05-26 20:06:18 -04:00
Noah Zinsmeister
97079055b4 add OPQ to broken tokens list 2020-05-18 17:26:00 -04:00
Callil Capuozzo
648f30be9b Update title 2020-05-18 10:27:52 -04:00
Callil Capuozzo
121d862fd0 Tweak banner links and copy 2020-05-18 09:59:35 -04:00
Noah Zinsmeister
c3fcffff4c Merge branch 'prod' into beta 2020-05-12 23:46:49 -04:00
Noah Zinsmeister
8fd0747a0b add tokens, remove UNI-V1:SAI (#758) 2020-05-12 23:45:04 -04:00
Kartik Talwar
9a8edc2c26 Update local env setup documentation (#706)
Updated the variable name from `REACT_APP_NETWORK_ID` to `REACT_APP_CHAIN_ID` in the setup docs to reflect the latest env variable names from PR #621
2020-05-04 20:32:07 -04:00
Ian Lapham
d720d4490c add SENT to broken tokens (#697) 2020-04-27 20:36:30 -04:00
Ian Lapham
6f505e45cc add SENT to broken token list (return bug) (#694) 2020-04-27 20:04:25 -04:00
Ian Lapham
cb2fcf3538 allow solo ETH output in query params (#690) (#693) 2020-04-27 12:38:00 -04:00
Ian Lapham
608421453b allow solo ETH output in query params (#690) 2020-04-27 12:32:44 -04:00
Micah Zoltu
b825900a1f Adds warning about ERC-777 tokens and the like. (#686) 2020-04-20 10:18:07 -04:00
Ian Lapham
10510cf975 Disable adding for ERC-777 tokens (#684) 2020-04-19 19:57:51 -04:00
Noah Zinsmeister
8fe0eb6bfe remove imBTC 2020-04-18 03:51:32 -04:00
Noah Zinsmeister
b54c20d56b add BTC++ 2020-04-14 10:56:09 -04:00
Noah Zinsmeister
bcfa2ed6ce add UBT 2020-04-14 10:54:39 -04:00
Chaitanya Potti
18b4c487f8 Integrate Torus (#554)
* torus integration done

* add torus-connector

* bump torus connector
2020-04-08 13:56:35 -04:00
Noah Zinsmeister
40491d5e39 Merge branch 'alekskuzmin-add-translations' into beta 2020-03-23 12:35:20 -04:00
Noah Zinsmeister
d6b2066d33 fix lint error 2020-03-23 12:34:08 -04:00
Noah Zinsmeister
e709779de2 Merge branch 'add-translations' of https://github.com/alekskuzmin/uniswap-frontend into alekskuzmin-add-translations 2020-03-23 12:31:33 -04:00
dependabot[bot]
90213bda78 Bump acorn from 5.7.3 to 5.7.4 (#656)
Bumps [acorn](https://github.com/acornjs/acorn) from 5.7.3 to 5.7.4.
- [Release notes](https://github.com/acornjs/acorn/releases)
- [Commits](https://github.com/acornjs/acorn/compare/5.7.3...5.7.4)

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-03-23 10:47:09 -04:00
Ian Lapham
0f107ebad5 Add extra warning text on add liquidity page (#655)
* add extra warning text on add liquidity
2020-03-23 10:44:48 -04:00
ianlapham
b907055402 hide ETH on remove page 2020-03-23 10:44:47 -04:00
Noah Zinsmeister
72ffd5c78e add missing optional chaining operators 2020-03-03 11:12:58 -05:00
Noah Zinsmeister
ffee859741 Balances (#650)
* improve balances context

add ts

* invalidate caches after timeout
2020-03-03 11:07:13 -05:00
Noah Zinsmeister
218e3567f5 add SXP (#651)
add TRB (closes #541)

add KEY

add USDx (closes #643)

add HEDG

add MCX

add CEL

add FXC
2020-03-02 19:06:46 -05:00
Gregory Markou
8dc763f82b Prioritize exact token symbol matches (#631)
* add dai prioritiy

* remove log

* ran linter

* fix comments

* fix lint

* preserve previous sort
2020-02-19 11:29:31 -07:00
Alex Kuzmin
aae42b9fca Fix formatting with Prettier 2020-02-17 12:38:19 +03:00
Alex Kuzmin
b861101a8f Replace hardcoded strings with translations 2020-02-17 11:53:02 +03:00
1056 changed files with 21406 additions and 197645 deletions

16
.env
View File

@@ -1,12 +1,4 @@
# These API keys are intentionally public. Please do not report them - thank you for your concern.
REACT_APP_AMPLITUDE_PROXY_URL="https://api.uniswap.org/v1/amplitude-proxy"
REACT_APP_AWS_API_REGION="us-east-2"
REACT_APP_AWS_API_ENDPOINT="https://beta.api.uniswap.org/v1/graphql"
REACT_APP_TEMP_API_URL="https://temp.api.uniswap.org/v1"
REACT_APP_SENTRY_DSN="https://a3c62e400b8748b5a8d007150e2f38b7@o1037921.ingest.sentry.io/4504255148851200"
REACT_APP_SENTRY_ENABLED=false
ESLINT_NO_DEV_ERRORS=true
REACT_APP_INFURA_KEY="4bf032f2d38a4ed6bb975b80d6340847"
REACT_APP_MOONPAY_API="https://api.moonpay.com"
REACT_APP_MOONPAY_LINK="https://us-central1-uniswap-mobile.cloudfunctions.net/signMoonpayLinkStaging?platform=web"
REACT_APP_MOONPAY_PUBLISHABLE_KEY="pk_test_DycfESRid31UaSxhI5yWKe1r5E5kKSz"
REACT_APP_CHAIN_ID="1"
REACT_APP_NETWORK_URL="https://mainnet.infura.io/v3/b8800ce81b8c451698081d269b86692b"
REACT_APP_PORTIS_ID=""
REACT_APP_FORTMATIC_KEY=""

View File

@@ -1,11 +1,4 @@
REACT_APP_AMPLITUDE_PROXY_URL="https://api.uniswap.org/v1/amplitude-proxy"
REACT_APP_AWS_API_ENDPOINT="https://api.uniswap.org/v1/graphql"
REACT_APP_FORTMATIC_KEY="pk_live_F937DF033A1666BF"
REACT_APP_GOOGLE_ANALYTICS_ID="G-KDP9B6W4H8"
REACT_APP_INFURA_KEY="099fc58e0de9451d80b18d7c74caa7c1"
REACT_APP_MOONPAY_API="https://api.moonpay.com"
REACT_APP_MOONPAY_LINK="https://us-central1-uniswap-mobile.cloudfunctions.net/signMoonpayLink?platform=web"
REACT_APP_MOONPAY_PUBLISHABLE_KEY="pk_live_uQG4BJC4w3cxnqpcSqAfohdBFDTsY6E"
REACT_APP_FIREBASE_KEY="AIzaSyBcZWwTcTJHj_R6ipZcrJkXdq05PuX0Rs0"
THE_GRAPH_SCHEMA_ENDPOINT="https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v3"
REACT_APP_SENTRY_ENABLED=false
REACT_APP_CHAIN_ID="1"
REACT_APP_NETWORK_URL="https://mainnet.infura.io/v3/2acb2baa4c06402792e0c701a3697d10"
REACT_APP_PORTIS_ID="c0e2bf01-4b08-4fd5-ac7b-8e26b58cd236"
REACT_APP_FORTMATIC_KEY="pk_live_F937DF033A1666BF"

View File

@@ -1,5 +0,0 @@
*.config.ts
*.d.ts
/src/graphql/data/__generated__/types-and-hooks.ts
/src/graphql/thegraph/__generated__/types-and-hooks.ts
/src/schema/schema.graphql

View File

@@ -1,7 +0,0 @@
/* eslint-env node */
require('@uniswap/eslint-config/load')
module.exports = {
extends: '@uniswap/eslint-config/react',
}

1
.github/CODEOWNERS vendored
View File

@@ -1 +0,0 @@
@uniswap/web

View File

@@ -1,19 +1,19 @@
---
name: Bug Report
about: Describe an issue in the Uniswap Interface
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''
---
**Bug Description**
A clear and concise description of the bug.
A clear and concise description of what the bug is.
**Steps to Reproduce**
1. Go to ...
2. Click on ...
...
...
**Expected Behavior**
A clear and concise description of what you expected to happen.

View File

@@ -1,8 +0,0 @@
blank_issues_enabled: true
contact_links:
- name: Support
url: https://discord.gg/FCfyBSbCU5
about: Please ask and answer questions here
- name: List a token
url: https://github.com/Uniswap/default-token-list#adding-a-token
about: Any requests to add a token to Uniswap should go here

View File

@@ -1,9 +1,10 @@
---
name: Feature Request
about: Suggest an idea for improving the UX of the Uniswap Interface
about: Suggest an idea for this project
title: ''
labels: 'improvement'
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**

View File

@@ -0,0 +1,10 @@
---
name: Something Else
about: Tell us something else
title: ''
labels: ''
assignees: ''
---

30
.github/ISSUE_TEMPLATE/token-request.md vendored Normal file
View File

@@ -0,0 +1,30 @@
---
name: Token Request
about: Request a token addition
title: ''
labels: token request
assignees: ''
---
**Please provide the following information for your token.**
Token Address:
Token Name (from contract):
Token Decimals (from contract):
Token Symbol (from contract):
Uniswap Exchange Address of Token:
Link to the official homepage of token:
Link to CoinMarketCap or CoinGecko page of token:
Some tokens (e.g. BNB) do not work with Uniswap v1. In order to assess if your token works correctly, please complete small-value transactions of each of the types below, and submit the Etherscan transaction links for our review.
Test `addLiquidity` transaction:
Test `swap` transaction:
Test `removeLiquidity` transaction:
Are you willing to add liquidity to the liquidity pool for this token? (Y/N):
If so, how much liquidity are you willing to add?:
# WARNING
Uniswap v1 is not compatible with any token that issues untrusted callbacks as part of a token transfer! This includes all ERC-777 tokens. Such a token will appear to work, but it will be suseptible to theft by attackers.

View File

@@ -1,21 +0,0 @@
name: Setup
runs:
using: composite
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 14
registry-url: https://registry.npmjs.org
cache: yarn
- uses: actions/cache@v3
id: install-cache
with:
path: node_modules/
key: ${{ runner.os }}-install-${{ hashFiles('**/yarn.lock') }}
- if: steps.install-cache.outputs.cache-hit != 'true'
run: yarn install --frozen-lockfile --ignore-scripts
shell: bash

View File

@@ -1,11 +0,0 @@
version: 2
updates:
- package-ecosystem: npm
# Files stored in repository root
directory: '/'
schedule:
interval: 'daily'
allow:
- dependency-name: '@uniswap/default-token-list'
- dependency-name: '@uniswap/token-lists'
- dependency-name: '@uniswap/widgets'

View File

@@ -1,24 +1,3 @@
Your PR title must follow [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/#summary), and should start with one of the following [types](https://github.com/angular/angular/blob/22b96b9/CONTRIBUTING.md#type):
**PLEASE DO NOT SUBMIT TOKEN ADDITIONS AS PULL REQUESTS**
- build: Changes that affect the build system or external dependencies (example scopes: yarn, eslint, typescript)
- ci: Changes to our CI configuration files and scripts (example scopes: vercel, github, cypress)
- docs: Documentation only changes
- feat: A new feature
- fix: A bug fix
- perf: A code change that improves performance
- refactor: A code change that neither fixes a bug nor adds a feature
- style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
- test: Adding missing tests or correcting existing tests
Example commit messages:
- feat: adds support for gnosis safe wallet
- fix: removes a polling memory leak
- chore: bumps redux version
Other things to note:
- Please describe the change using verb statements (ex: Removes X from Y)
- PRs with multiple changes should use a list of verb statements
- Add any relevant unit / integration tests
- Changes will be previewable via vercel. Non-obvious changes should include instructions for how to reproduce them
All token requests should be made via an issue.

View File

@@ -1,17 +0,0 @@
name: Check PR Title
on:
pull_request_target:
types:
- opened
- edited
- synchronize
jobs:
# Ensures that the PR title adheres to [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/).
conventional-commit:
runs-on: ubuntu-latest
steps:
- uses: amannn/action-semantic-pull-request@v3.4.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -1,33 +0,0 @@
name: Crowdin Download
on:
schedule:
# Download translations every hour.
# This is not done as part of the build so that builds remain reproducible.
- cron: '0 * * * *'
# manual trigger
workflow_dispatch:
jobs:
download-translations:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/setup
- run: yarn i18n:extract
- name: Download Crowdin translations
uses: crowdin/github-action@1.4.9
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: true
pull_request_title: 'chore(i18n): new Crowdin translations'
localization_branch_name: l10n_crowdin
commit_message: 'chore(i18n): synchronize translations from crowdin [skip ci]'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -1,26 +0,0 @@
name: Crowdin Upload
on:
push:
branches:
- main
jobs:
upload-sources:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/setup
- run: yarn i18n:extract
- name: Upload Crowdin sources
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 }}

View File

@@ -1,124 +1,52 @@
name: Release
on:
schedule:
- cron: '0 12 * * 2-4' # every day 12:00 UTC Monday-Thursday
# manual trigger
workflow_dispatch:
push:
# Sequence of patterns matched against refs/tags
tags:
- 'v*'
name: Build and Release
jobs:
wait-on-tests:
runs-on: ubuntu-latest
build:
name: Global Job
strategy:
matrix:
node: ['10.x']
os: [ubuntu-latest]
runs-on: ${{ matrix.os }}
steps:
- id: unit-tests
uses: fountainhead/action-wait-for-check@v1.0.0
- name: Checkout code
uses: actions/checkout@master
- name: Create production build
uses: actions/setup-node@master
with:
token: ${{ secrets.GITHUB_TOKEN }}
checkName: unit-tests
- id: cypress-tests
uses: fountainhead/action-wait-for-check@v1.0.0
with:
token: ${{ secrets.GITHUB_TOKEN }}
checkName: cypress-tests
- if: steps.unit-tests.outputs.conclusion != 'success' || steps.cypress-tests.outputs.conclusion != 'success'
run: exit 1
tag:
needs: wait-on-tests
runs-on: ubuntu-latest
outputs:
new_tag: ${{ steps.github-tag-action.outputs.new_tag }}
changelog: ${{ steps.github-tag-action.outputs.changelog }}
steps:
- uses: actions/checkout@v3
- name: Bump and tag
id: github-tag-action
uses: mathieudutour/github-tag-action@v6.0
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
release_branches: .*
default_bump: patch
release:
needs: tag
if: ${{ needs.tag.outputs.new_tag != null }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/setup
- run: yarn prepare
node-version: ${{ matrix.node }}
- run: npm install -g yarn
- run: yarn
- run: yarn build
- name: Pin to IPFS
id: pinata
uses: anantaramdas/ipfs-pinata-deploy-action@39bbda1ce1fe24c69c6f57861b8038278d53688d
with:
pin-name: Uniswap ${{ needs.tag.outputs.new_tag }}
path: './build'
pinata-api-key: ${{ secrets.PINATA_API_KEY }}
pinata-secret-api-key: ${{ secrets.PINATA_API_SECRET_KEY }}
- name: Pin to Crust
uses: crustio/ipfs-crust-action@v2.0.3
continue-on-error: true
timeout-minutes: 2
with:
cid: ${{ steps.upload.outputs.hash }}
seeds: ${{ secrets.CRUST_SEEDS }}
- name: Convert CIDv0 to CIDv1
id: convert-cidv0
uses: uniswap/convert-cidv0-cidv1@v1.0.0
with:
cidv0: ${{ steps.pinata.outputs.hash }}
- name: Release
uses: actions/create-release@v1.1.0
env:
REACT_APP_NETWORK_ID: ${{ secrets.REACT_APP_NETWORK_ID }}
- name: Create Release
id: create_release
uses: actions/create-release@v1.0.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ needs.tag.outputs.new_tag }}
release_name: Release ${{ needs.tag.outputs.new_tag }}
body: |
IPFS hash of the deployment:
- CIDv0: `${{ steps.pinata.outputs.hash }}`
- CIDv1: `${{ steps.convert-cidv0.outputs.cidv1 }}`
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.
**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.
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.pinata.outputs.hash }}/)
${{ needs.tag.outputs.changelog }}
- name: Setup node@16 (required by Cloudflare Pages)
uses: actions/setup-node@v3
tag_name: ${{ github.ref }}
release_name: Release ${{ github.ref }}
draft: false
prerelease: false
- name: Zip the build
uses: thedoctor0/zip-release@master
with:
node-version: 16
- name: Update Cloudflare Pages deployment
uses: cloudflare/pages-action@364c7ca09a4b57837c5967871d64a2c31adb8c0d
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
projectName: ${{ secrets.CLOUDFLARE_PROJECT_NAME }}
directory: build
githubToken: ${{ secrets.GITHUB_TOKEN }}
- name: Upload source maps to Sentry
uses: getsentry/action-release@bd5f874fcda966ba48139b0140fb3ec0cb3aabdd
continue-on-error: true
filename: 'build.zip'
path: './build'
exclusions: 'x'
- name: Upload Build
id: build-asset
uses: actions/upload-release-asset@v1.0.1
env:
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
environment: production
sourcemaps: './build/static/js'
url_prefix: '~/static/js'
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: build.zip
asset_name: build.zip
asset_content_type: application/zip

View File

@@ -1,27 +0,0 @@
name: Revert
on:
# manual trigger
workflow_dispatch:
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/setup
- run: yarn prepare
- run: yarn build
- name: Setup node@16 (required by Cloudflare Pages)
uses: actions/setup-node@v3
with:
node-version: 16
- name: Update Cloudflare Pages deployment
uses: cloudflare/pages-action@364c7ca09a4b57837c5967871d64a2c31adb8c0d
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
projectName: ${{ secrets.CLOUDFLARE_PROJECT_NAME }}
directory: build
githubToken: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -1,97 +0,0 @@
name: Test
on:
push:
branches:
- main
pull_request:
# manual trigger
workflow_dispatch:
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/setup
- run: yarn lint
deps-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/setup
- run: yarn yarn-deduplicate --strategy=highest --list --fail
unit-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/setup
- run: yarn prepare
- run: yarn test
cypress-build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/setup
- run: yarn prepare
- run: yarn build
- uses: actions/upload-artifact@v2
with:
name: build
path: build
if-no-files-found: error
- uses: actions/cache@v3
id: cypress-cache
with:
path: /home/runner/.cache/Cypress
key: ${{ runner.os }}-cypress-${{ hashFiles('node_modules/cypress') }}
- if: steps.cypress-cache.outputs.cache-hit != 'true'
run: yarn cypress install
cypress-test-matrix:
needs: cypress-build
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
containers: [1, 2, 3, 4]
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/setup
- uses: actions/download-artifact@v2
with:
name: build
path: build
- uses: actions/cache@v3
id: cypress-cache
with:
path: /home/runner/.cache/Cypress
key: ${{ runner.os }}-cypress-${{ hashFiles('node_modules/cypress') }}
- if: steps.cypress-cache.outputs.cache-hit != 'true'
run: yarn cypress install
- uses: cypress-io/github-action@v4
with:
install: false
start: yarn serve
wait-on: 'http://localhost:3000'
browser: chrome
record: true
parallel: true
env:
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Included as a single job to check against for cypress test success, as cypress runs in a matrix.
cypress-tests:
needs: cypress-test-matrix
runs-on: ubuntu-latest
steps:
- run: echo 'Finished cypress tests https\://dashboard.cypress.io/projects/yp82ef'

21
.gitignore vendored
View File

@@ -1,25 +1,13 @@
# See https://help.github.com/ignore-files/ for more about ignoring files.
# generated contract types
/src/types/v3
/src/abis/types
/src/locales/**/*.js
/src/locales/**/en-US.po
/src/locales/**/pseudo.po
# generated graphql types
schema.graphql
# dependencies
/node_modules
# testing
/coverage
# builds
# production
/build
/dts
# misc
.DS_Store
@@ -37,9 +25,6 @@ yarn-error.log*
notes.txt
.idea/
package-lock.json
.vscode/
cypress/videos
cypress/screenshots
.vercel
package-lock.json

1
.npmrc
View File

@@ -1 +0,0 @@
engine-strict = true

1
.nvmrc
View File

@@ -1 +0,0 @@
14.20.0

5
.prettierrc Normal file
View File

@@ -0,0 +1,5 @@
{
"semi": false,
"singleQuote": true,
"printWidth": 120
}

25
.snyk
View File

@@ -1,25 +0,0 @@
# Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities.
version: v1.25.0
# ignores vulnerabilities until expiry date; change duration by modifying expiry date
ignore:
SNYK-JS-OPENZEPPELINCONTRACTS-2964946:
- '*':
reason: None Given
expires: 2099-01-01T00:00:00.000Z
created: 2022-12-08T16:25:57.347Z
SNYK-JS-OPENZEPPELINCONTRACTS-2958047:
- '*':
reason: None Given
expires: 2099-01-01T00:00:00.000Z
created: 2022-12-08T16:26:09.720Z
SNYK-JS-OPENZEPPELINCONTRACTS-2958050:
- '*':
reason: None Given
expires: 2099-01-01T00:00:00.000Z
created: 2022-12-08T16:26:17.702Z
SNYK-JS-OPENZEPPELINCONTRACTS-2965580:
- '*':
reason: None Given
expires: 2099-01-01T00:00:00.000Z
created: 2022-12-08T16:26:34.283Z
patch: {}

13
.travis.yml Normal file
View File

@@ -0,0 +1,13 @@
branches:
except:
- master
language: node_js
node_js:
- '10'
cache:
directories:
- node_modules
install: yarn
script:
- yarn check:all
- yarn build

View File

@@ -1,6 +0,0 @@
{
"recommendations": [
"dbaeumer.vscode-eslint"
],
"unwantedRecommendations": []
}

16
.vscode/settings.json vendored
View File

@@ -1,16 +0,0 @@
{
"npm.packageManager": "yarn",
"typescript.updateImportsOnFileMove.enabled": "always",
"javascript.updateImportsOnFileMove.enabled": "always",
"editor.formatOnSaveMode": "file",
"editor.tabCompletion": "on",
"editor.tabSize": 2,
"editor.formatOnSave": false,
"editor.inlineSuggest.enabled": true,
"editor.codeActionsOnSave": {
"source.fixAll": true
},
"files.eol": "\n",
"eslint.enable": true,
"eslint.debug": true
}

View File

@@ -1,125 +0,0 @@
# Contributing
Thank you for your interest in contributing to the Uniswap interface! 🦄
# Development
Before running anything, you'll need to install the dependencies:
```
yarn install
```
## Running the interface locally
```
yarn start
```
The interface should automatically open. If it does not, navigate to [http://localhost:3000].
## Creating a production build
```
yarn build
```
To serve the production build:
```
yarn serve
```
Then, navigate to [http://localhost:3000] to see it.
## Running unit tests
```
yarn test
```
By default, this runs only unit tests that have been affected since the last commit. To run _all_ unit tests:
```
yarn test --watchAll
```
## Running integration tests (cypress)
Integration tests require a server to be running. In order to see your changes quickly, run `start` in its own tab/window:
```
yarn start
```
Integration tests are run using `cypress`. When developing locally, use `cypress:open` for an interactive UI, and to inspect the rendered page:
```
yarn cypress:open
```
To run _all_ cypress integration tests _from the command line_:
```
yarn cypress:run
```
## Engineering standards
Code merged into the `main` branch of this repository should adhere to high standards of correctness and maintainability.
Use your best judgment when applying these standards. If code is in the critical path, will be frequently visited, or
makes large architectural changes, consider following all the standards.
- Have at least one engineer approve of large code refactorings
- At least manually test small code changes, prefer automated tests
- Thoroughly unit test when code is not obviously correct
- If something breaks, add automated tests so it doesn't break again
- Add integration tests for new pages or flows
- Verify that all CI checks pass before merging
- Have at least one product manager or designer approve of any significant UX changes
## Guidelines
The following points should help guide your development:
- Security: the interface is safe to use
- Avoid adding unnecessary dependencies due to [supply chain risk](https://github.com/LavaMoat/lavamoat#further-reading-on-software-supplychain-security)
- Reproducibility: anyone can build the interface
- Avoid adding steps to the development/build processes
- The build must be deterministic, i.e. a particular commit hash always produces the same build
- Decentralization: anyone can run the interface
- An Ethereum node should be the only critical dependency
- All other external dependencies should only enhance the UX ([graceful degradation](https://developer.mozilla.org/en-US/docs/Glossary/Graceful_degradation))
- Accessibility: anyone can use the interface
- The interface should be responsive, small and also run well on low performance devices (majority of swaps on mobile!)
## Release process
Releases are cut automatically from the `main` branch Monday-Thursday in the morning according to the [release workflow](./.github/workflows/release.yaml).
Fix pull requests should be merged whenever ready and tested.
If a fix is urgently needed in production, releases can be manually triggered on [GitHub](https://github.com/Uniswap/uniswap-interface/actions/workflows/release.yaml)
after the fix is merged into `main`.
Features should not be merged into `main` until they are ready for users.
When building larger features or collaborating with other developers, create a new branch from `main` to track its development.
Use the automatic Vercel preview for sharing the feature to collect feedback.
When the feature is ready for review, create a new pull request from the feature branch into `main` and request reviews from
the appropriate UX reviewers (PMs or designers).
## 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).
# Translations
Uniswap uses [Crowdin](https://crowdin.com/project/uniswap-interface) for managing translations.
[This workflow](./.github/workflows/crowdin.yaml) uploads new strings for translation to the Crowdin project whenever code using the [lingui translation macros](https://lingui.js.org/ref/macro.html) is merged into `main`.
Every hour, translations are synced back down from Crowdin to the repository in [this other workflow](./.github/workflows/crowdin-sync.yaml).
We sync to the repository on a schedule, rather than download translations at build time, so that builds are always reproducible.
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!!

View File

@@ -1,51 +1,49 @@
# Uniswap Labs Interface
# Uniswap Frontend
[![Unit Tests](https://github.com/Uniswap/interface/actions/workflows/unit-tests.yaml/badge.svg)](https://github.com/Uniswap/interface/actions/workflows/unit-tests.yaml)
[![Integration Tests](https://github.com/Uniswap/interface/actions/workflows/integration-tests.yaml/badge.svg)](https://github.com/Uniswap/interface/actions/workflows/integration-tests.yaml)
[![Lint](https://github.com/Uniswap/interface/actions/workflows/lint.yml/badge.svg)](https://github.com/Uniswap/interface/actions/workflows/lint.yml)
[![Release](https://github.com/Uniswap/interface/actions/workflows/release.yaml/badge.svg)](https://github.com/Uniswap/interface/actions/workflows/release.yaml)
[![Crowdin](https://badges.crowdin.net/uniswap-interface/localized.svg)](https://crowdin.com/project/uniswap-interface)
[![Netlify Status](https://api.netlify.com/api/v1/badges/fa110555-b3c7-4eeb-b840-88a835009c62/deploy-status)](https://app.netlify.com/sites/uniswap/deploys)
[![Build Status](https://travis-ci.org/Uniswap/uniswap-frontend.svg)](https://travis-ci.org/Uniswap/uniswap-frontend)
[![Styled With Prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://prettier.io/)
An open source interface for Uniswap -- a protocol for decentralized exchange of Ethereum tokens.
This an 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://docs.uniswap.org/)
- 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)
- Whitepapers:
- [V1](https://hackmd.io/C-DvwDSfSxuh-Gd4WKE_ig)
- [V2](https://uniswap.org/whitepaper.pdf)
- [V3](https://uniswap.org/whitepaper-v3.pdf)
- Website: [uniswap.io](https://uniswap.io/)
- Docs: [docs.uniswap.io](https://docs.uniswap.io/)
- Twitter: [@UniswapExchange](https://twitter.com/UniswapExchange)
- Reddit: [/r/Uniswap](https://www.reddit.com/r/UniSwap/)
- Email: [contact@uniswap.io](mailto:contact@uniswap.io)
- Discord: [Uniswap](https://discord.gg/Y7TF6QA)
- Whitepaper: [Link](https://hackmd.io/C-DvwDSfSxuh-Gd4WKE_ig)
## Run Uniswap Locally
1. Download and unzip the `build.zip` file from the latest release in the [Releases tab](https://github.com/Uniswap/uniswap-frontend/releases/latest).
## Accessing the Uniswap Interface
2. Serve the `build/` folder locally, and access the application via a browser.
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).
For more information on running a local server see [https://developer.mozilla.org/en-US/docs/Learn/Common_questions/set_up_a_local_testing_server](https://developer.mozilla.org/en-US/docs/Learn/Common_questions/set_up_a_local_testing_server). This simple approach has one downside: refreshing the page will give a `404` because of how React handles client-side routing. To fix this issue, consider running `serve -s` courtesy of the [serve](https://github.com/zeit/serve) package.
## Develop Uniswap Locally
## Unsupported tokens
### Install Dependencies
Check out `useUnsupportedTokenList()` in [src/state/lists/hooks.ts](./src/state/lists/hooks.ts) for blocking tokens in your instance of the interface.
```bash
yarn
```
You can block an entire list of tokens by passing in a tokenlist like [here](./src/constants/lists.ts)
### Configure Environment
Rename `.env.local.example` to `.env.local` and fill in the appropriate variables.
### Run
```bash
yarn start
```
To run on a testnet, make a copy of `.env.local.example` named `.env.local`, change `REACT_APP_CHAIN_ID` to `"{yourChainId}"`, and change `REACT_APP_NETWORK_URL` to e.g. `"https://{yourNetwork}.infura.io/v3/{yourKey}"`.
If deploying with Github Pages, be aware that there's some [tricky client-side routing behavior with `create-react-app`](https://create-react-app.dev/docs/deployment#notes-on-client-side-routing).
## Contributions
For steps on local deployment, development, and code contribution, please see [CONTRIBUTING](./CONTRIBUTING.md).
## Accessing Uniswap V2
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).
**Please open all pull requests against the `beta` branch.** CI checks will run against all PRs. To ensure that your changes will pass, run `yarn check:all` before pushing. If this command fails, you can try to automatically fix problems with `yarn fix:all`, or do it manually.

View File

@@ -1,25 +0,0 @@
/* eslint-env node */
import type { CodegenConfig } from '@graphql-codegen/cli'
// Generates TS objects from the schemas returned by graphql queries
// To learn more: https://www.apollographql.com/docs/react/development-testing/static-typing/#setting-up-your-project
const config: CodegenConfig = {
overwrite: true,
schema: './src/graphql/data/schema.graphql',
documents: ['./src/graphql/data/**', '!./src/graphql/data/__generated__/**', '!**/thegraph/**'],
generates: {
'src/graphql/data/__generated__/types-and-hooks.ts': {
plugins: ['typescript', 'typescript-operations', 'typescript-react-apollo'],
config: {
withHooks: true,
// This avoid all generated schemas being wrapped in Maybe https://the-guild.dev/graphql/codegen/plugins/typescript/typescript#maybevalue-string-default-value-t--null
maybeValue: 'T',
},
},
},
}
// This is used in package.json when generating apollo schemas however the linter stills flags this as unused
// eslint-disable-next-line import/no-unused-modules
export default config

View File

@@ -1,25 +0,0 @@
/* eslint-env node */
import type { CodegenConfig } from '@graphql-codegen/cli'
// Generates TS objects from the schemas returned by graphql queries
// To learn more: https://www.apollographql.com/docs/react/development-testing/static-typing/#setting-up-your-project
const config: CodegenConfig = {
overwrite: true,
schema: './src/graphql/thegraph/schema.graphql',
documents: ['!./src/graphql/data/**', '!./src/graphql/thegraph/__generated__/**', './src/graphql/thegraph/**'],
generates: {
'src/graphql/thegraph/__generated__/types-and-hooks.ts': {
plugins: ['typescript', 'typescript-operations', 'typescript-react-apollo'],
config: {
withHooks: true,
// This avoid all generated schemas being wrapped in Maybe https://the-guild.dev/graphql/codegen/plugins/typescript/typescript#maybevalue-string-default-value-t--null
maybeValue: 'T',
},
},
},
}
// This is used in package.json when generating apollo schemas however the linter stills flags this as unused
// eslint-disable-next-line import/no-unused-modules
export default config

View File

@@ -1,10 +0,0 @@
/* eslint-env node */
const isDev = process.env.NODE_ENV === 'development'
module.exports = {
styledComponents: {
fileName: isDev,
displayName: isDev,
},
}

View File

@@ -1,6 +0,0 @@
overrideExisting: true
schema: 'https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v3'
generates:
./src/graphql/thegraph/schema/schema.graphql:
plugins:
- schema-ast

View File

@@ -1,47 +0,0 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const { VanillaExtractPlugin } = require('@vanilla-extract/webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const { DefinePlugin } = require('webpack')
const commitHash = require('child_process').execSync('git rev-parse HEAD')
module.exports = {
babel: {
plugins: ['@vanilla-extract/babel-plugin'],
},
jest: {
configure(jestConfig) {
return Object.assign({}, jestConfig, {
transformIgnorePatterns: ['@uniswap/conedison/format'],
moduleNameMapper: {
'@uniswap/conedison/format': '@uniswap/conedison/dist/format',
},
})
},
},
webpack: {
plugins: [
new VanillaExtractPlugin(),
new DefinePlugin({
'process.env.REACT_APP_GIT_COMMIT_HASH': JSON.stringify(commitHash.toString()),
}),
],
configure: (webpackConfig) => {
const instanceOfMiniCssExtractPlugin = webpackConfig.plugins.find(
(plugin) => plugin instanceof MiniCssExtractPlugin
)
if (instanceOfMiniCssExtractPlugin !== undefined) instanceOfMiniCssExtractPlugin.options.ignoreOrder = true
// We're currently on Webpack 4.x that doesn't support the `exports` field in package.json.
// See https://github.com/webpack/webpack/issues/9509.
//
// In case you need to add more modules, make sure to remap them to the correct path.
//
// Map @uniswap/conedison to its dist folder.
// This is required because conedison uses * to redirect all imports to its dist.
webpackConfig.resolve.alias['@uniswap/conedison'] = '@uniswap/conedison/dist'
return webpackConfig
},
},
}

View File

@@ -1,20 +0,0 @@
import { defineConfig } from 'cypress'
export default defineConfig({
projectId: 'yp82ef',
videoUploadOnPasses: false,
defaultCommandTimeout: 24000, // 2x average block time
chromeWebSecurity: false,
e2e: {
setupNodeEvents(on, config) {
return {
...config,
// Only enable Chrome.
// Electron (the default) has issues injecting window.ethereum before pageload, so it is not viable.
browsers: config.browsers.filter(({ name }) => name === 'chrome'),
}
},
baseUrl: 'http://localhost:3000',
specPattern: 'cypress/e2e/**/*.{js,jsx,ts,tsx}',
},
})

View File

@@ -1,8 +0,0 @@
import { defineConfig } from 'cypress'
export default defineConfig({
projectId: 'yp82ef',
e2e: {
specPattern: 'cypress/release.ts',
},
})

View File

@@ -1,64 +0,0 @@
import { CyHttpMessages } from 'cypress/types/net-stubbing'
import { aliasQuery, hasQuery } from '../utils/graphql-test-utils'
describe('Add Liquidity', () => {
beforeEach(() => {
cy.intercept('POST', '/subgraphs/name/uniswap/uniswap-v3', (req) => {
aliasQuery(req, 'feeTierDistribution')
})
})
it('loads the two correct tokens', () => {
cy.visit('/add/0xF9bA5210F91D0474bd1e1DcDAeC4C58E359AaD85/0xc778417E063141139Fce010982780140Aa0cD5Ab/500')
cy.get('#add-liquidity-input-tokena .token-symbol-container').should('contain.text', 'MKR')
cy.get('#add-liquidity-input-tokenb .token-symbol-container').should('contain.text', 'ETH')
})
it('does not crash if ETH is duplicated', () => {
cy.visit('/add/0xc778417E063141139Fce010982780140Aa0cD5Ab/0xc778417E063141139Fce010982780140Aa0cD5Ab')
cy.get('#add-liquidity-input-tokena .token-symbol-container').should('contain.text', 'ETH')
cy.get('#add-liquidity-input-tokenb .token-symbol-container').should('not.contain.text', 'ETH')
})
it.skip('token not in storage is loaded', () => {
cy.visit('/add/0xb290b2f9f8f108d03ff2af3ac5c8de6de31cdf6d/0xF9bA5210F91D0474bd1e1DcDAeC4C58E359AaD85')
cy.get('#add-liquidity-input-tokena .token-symbol-container').should('contain.text', 'SKL')
cy.get('#add-liquidity-input-tokenb .token-symbol-container').should('contain.text', 'MKR')
})
it.skip('single token can be selected', () => {
cy.visit('/add/0xb290b2f9f8f108d03ff2af3ac5c8de6de31cdf6d')
cy.get('#add-liquidity-input-tokena .token-symbol-container').should('contain.text', 'SKL')
cy.visit('/add/0xF9bA5210F91D0474bd1e1DcDAeC4C58E359AaD85')
cy.get('#add-liquidity-input-tokena .token-symbol-container').should('contain.text', 'MKR')
})
it.skip('loads fee tier distribution', () => {
cy.fixture('feeTierDistribution.json').then((feeTierDistribution) => {
cy.intercept('POST', '/subgraphs/name/uniswap/uniswap-v3', (req: CyHttpMessages.IncomingHttpRequest) => {
if (hasQuery(req, 'FeeTierDistributionQuery')) {
req.alias = 'FeeTierDistributionQuery'
req.reply({
body: {
data: {
...feeTierDistribution,
},
},
headers: {
'access-control-allow-origin': '*',
},
})
}
})
cy.visit('/add/0xF9bA5210F91D0474bd1e1DcDAeC4C58E359AaD85/0xc778417E063141139Fce010982780140Aa0cD5Ab')
cy.wait('@FeeTierDistributionQuery')
cy.get('#add-liquidity-selected-fee .selected-fee-label').should('contain.text', '0.3% fee tier')
cy.get('#add-liquidity-selected-fee .selected-fee-percentage').should('contain.text', '40%')
})
})
})

View File

@@ -1,31 +0,0 @@
import { getTestSelector } from '../utils'
describe('Landing Page', () => {
it('shows landing page when no selectedWallet', () => {
cy.visit('/', { noWallet: true })
cy.get(getTestSelector('landing-page'))
cy.screenshot()
})
it('redirects to swap page when selectedWallet is INJECTED', () => {
cy.visit('/', { selectedWallet: 'INJECTED' })
cy.get('#swap-page')
cy.url().should('include', '/swap')
cy.screenshot()
})
it('shows landing page when selectedWallet is INJECTED and ?intro=true is in query', () => {
cy.visit('/?intro=true', { selectedWallet: 'INJECTED' })
cy.get(getTestSelector('landing-page'))
})
it('shows landing page when the unicorn icon in nav is selected', () => {
cy.get(getTestSelector('uniswap-logo')).click()
cy.get(getTestSelector('landing-page'))
})
it('allows navigation to pool', () => {
cy.get('#pool-nav-link').click()
cy.url().should('include', '/pool')
})
})

View File

@@ -1,8 +0,0 @@
// see https://github.com/Uniswap/interface/pull/4115
describe('Link', () => {
it('should update route', () => {
cy.visit('/')
cy.contains('Pool').click()
cy.get('[data-cy="join-pool-button"]').should('exist')
})
})

View File

@@ -1,51 +0,0 @@
import { getTestSelector } from '../utils'
const COLLECTION_ADDRESS = '0xbd3531da5cf5857e7cfaa92426877b022e612cf8'
describe('Testing nfts', () => {
beforeEach(() => {
cy.visit('/')
cy.get(getTestSelector('FiatOnrampAnnouncement-close')).first().click()
})
it('should load nft leaderboard', () => {
cy.get(getTestSelector('nft-nav')).first().click()
cy.get(getTestSelector('nft-nav')).first().should('exist')
cy.get(getTestSelector('nft-nav')).first().click()
cy.get(getTestSelector('nft-trending-collection')).its('length').should('be.gte', 25)
})
it('should load pudgy penguin collection page', () => {
cy.visit(`/#/nfts/collection/${COLLECTION_ADDRESS}`)
cy.get(getTestSelector('nft-collection-asset')).should('exist')
cy.get(getTestSelector('nft-collection-filter-buy-now')).should('not.exist')
cy.get(getTestSelector('nft-filter')).first().click()
cy.get(getTestSelector('nft-collection-filter-buy-now')).should('exist')
})
it('should be able to navigate to activity', () => {
cy.visit(`/#/nfts/collection/${COLLECTION_ADDRESS}`)
cy.get(getTestSelector('nft-activity')).first().click()
cy.get(getTestSelector('nft-activity-row')).should('exist')
})
it('should go to the details page', () => {
cy.visit(`/#/nfts/collection/${COLLECTION_ADDRESS}`)
cy.get(getTestSelector('nft-filter')).first().click()
cy.get(getTestSelector('nft-collection-filter-buy-now')).click()
cy.get(getTestSelector('nft-details-link')).first().click()
cy.get(getTestSelector('nft-details-traits')).should('exist')
cy.get(getTestSelector('nft-details-activity')).should('exist')
cy.get(getTestSelector('nft-details-description')).should('exist')
cy.get(getTestSelector('nft-details-asset-details')).should('exist')
})
it('should toggle buy now on details page', () => {
cy.visit(`#/nfts/asset/${COLLECTION_ADDRESS}/2043`)
cy.get(getTestSelector('nft-details-description-text')).should('exist')
cy.get(getTestSelector('nft-details-description')).click()
cy.get(getTestSelector('nft-details-description-text')).should('not.exist')
cy.get(getTestSelector('nft-details-toggle-bag')).eq(1).click()
cy.get(getTestSelector('nft-bag')).should('exist')
})
})

View File

@@ -1,11 +0,0 @@
import { getTestSelector } from '../utils'
describe('Pool', () => {
beforeEach(() => cy.visit('/pool'))
it('add liquidity links to /add/ETH', () => {
cy.get(getTestSelector('FiatOnrampAnnouncement-close')).first().click()
cy.get('#join-pool-button').click()
cy.url().should('contain', '/add/ETH')
})
})

View File

@@ -1,10 +0,0 @@
describe('Redirect', () => {
it('should redirect to /vote/create-proposal when visiting /create-proposal', () => {
cy.visit('/create-proposal')
cy.url().should('match', /\/vote\/create-proposal/)
})
it('should redirect to /not-found when visiting nonexist url', () => {
cy.visit('/none-exist-url')
cy.url().should('match', /\/not-found/)
})
})

View File

@@ -1,25 +0,0 @@
describe('Remove Liquidity', () => {
it('eth remove', () => {
cy.visit('/remove/v2/ETH/0xF9bA5210F91D0474bd1e1DcDAeC4C58E359AaD85')
cy.get('#remove-liquidity-tokena-symbol').should('contain.text', 'ETH')
cy.get('#remove-liquidity-tokenb-symbol').should('contain.text', 'MKR')
})
it('eth remove swap order', () => {
cy.visit('/remove/v2/0xF9bA5210F91D0474bd1e1DcDAeC4C58E359AaD85/ETH')
cy.get('#remove-liquidity-tokena-symbol').should('contain.text', 'MKR')
cy.get('#remove-liquidity-tokenb-symbol').should('contain.text', 'ETH')
})
it('loads the two correct tokens', () => {
cy.visit('/remove/v2/0xc778417E063141139Fce010982780140Aa0cD5Ab/0xF9bA5210F91D0474bd1e1DcDAeC4C58E359AaD85')
cy.get('#remove-liquidity-tokena-symbol').should('contain.text', 'WETH')
cy.get('#remove-liquidity-tokenb-symbol').should('contain.text', 'MKR')
})
it('does not crash if ETH is duplicated', () => {
cy.visit('/remove/v2/0xc778417E063141139Fce010982780140Aa0cD5Ab/0xc778417E063141139Fce010982780140Aa0cD5Ab')
cy.get('#remove-liquidity-tokena-symbol').should('contain.text', 'WETH')
cy.get('#remove-liquidity-tokenb-symbol').should('contain.text', 'WETH')
})
})

View File

@@ -1,11 +0,0 @@
describe('Send', () => {
it('should redirect', () => {
cy.visit('/send')
cy.url().should('include', '/swap')
})
it('should redirect with url params', () => {
cy.visit('/send?outputCurrency=ETH&recipient=bob.argent.xyz')
cy.url().should('contain', '/swap?outputCurrency=ETH&recipient=bob.argent.xyz')
})
})

View File

@@ -1,84 +0,0 @@
import assert = require('assert')
describe('Service Worker', () => {
before(() => {
// Fail fast if there is no Service Worker on this build.
cy.request({ url: '/service-worker.js', headers: { 'Service-Worker': 'script' } }).then((response) => {
const isValid = isValidServiceWorker(response)
if (!isValid) {
throw new Error(
'\n' +
'Service Worker tests must be run on a production-like build\n' +
'To test, build with `yarn build:e2e` and serve with `yarn serve`'
)
}
})
function isValidServiceWorker(response: Cypress.Response<any>) {
const contentType = response.headers['content-type']
return !(response.status === 404 || (contentType != null && contentType.indexOf('javascript') === -1))
}
})
function unregister() {
return cy.log('unregister service worker').then(async () => {
const cacheKeys = await window.caches.keys()
const cacheKey = cacheKeys.find((key) => key.match(/precache/))
if (cacheKey) {
await window.caches.delete(cacheKey)
}
const sw = await window.navigator.serviceWorker.getRegistration(Cypress.config().baseUrl ?? undefined)
await sw?.unregister()
})
}
before(unregister)
after(unregister)
beforeEach(() => {
cy.intercept({ hostname: 'www.google-analytics.com' }, (req) => {
const body = req.body.toString()
if (req.query['ep.event_category'] === 'Service Worker' || body.includes('Service%20Worker')) {
if (req.query['en'] === 'Not Installed' || body.includes('Not%20Installed')) {
req.alias = 'NotInstalled'
} else if (req.query['en'] === 'Cache Hit' || body.includes('Cache%20Hit')) {
req.alias = 'CacheHit'
} else if (req.query['en'] === 'Cache Miss' || body.includes('Cache%20Miss')) {
req.alias = 'CacheMiss'
}
}
})
})
it('installs a ServiceWorker', () => {
cy.visit('/', { serviceWorker: true })
.get('#swap-page')
.wait('@NotInstalled', { timeout: 20000 })
.window({ timeout: 20000 })
.and((win) => {
expect(win.navigator.serviceWorker.controller?.state).to.equal('activated')
})
})
it('records a cache hit', () => {
cy.visit('/', { serviceWorker: true }).get('#swap-page').wait('@CacheHit', { timeout: 20000 })
})
it('records a cache miss', () => {
cy.then(async () => {
const cacheKeys = await window.caches.keys()
const cacheKey = cacheKeys.find((key) => key.match(/precache/))
assert(cacheKey)
const cache = await window.caches.open(cacheKey)
const keys = await cache.keys()
const key = keys.find((key) => key.url.match(/index/))
assert(key)
await cache.put(key, new Response())
})
.visit('/', { serviceWorker: true })
.get('#swap-page')
.wait('@CacheMiss', { timeout: 20000 })
})
})

View File

@@ -1,53 +0,0 @@
describe('Swap', () => {
before(() => {
cy.visit('/swap')
})
it('starts with ETH selected by default', () => {
cy.get('#swap-currency-input .token-amount-input').should('have.value', '')
cy.get('#swap-currency-input .token-symbol-container').should('contain.text', 'ETH')
cy.get('#swap-currency-output .token-amount-input').should('not.have.value')
cy.get('#swap-currency-output .token-symbol-container').should('contain.text', 'Select token')
})
it('can enter an amount into input', () => {
cy.get('#swap-currency-input .token-amount-input').clear().type('0.001').should('have.value', '0.001')
})
it('zero swap amount', () => {
cy.get('#swap-currency-input .token-amount-input').clear().type('0.0').should('have.value', '0.0')
})
it('invalid swap amount', () => {
cy.get('#swap-currency-input .token-amount-input').clear().type('\\').should('have.value', '')
})
it('can enter an amount into output', () => {
cy.get('#swap-currency-output .token-amount-input').clear().type('0.001').should('have.value', '0.001')
})
it('zero output amount', () => {
cy.get('#swap-currency-output .token-amount-input').clear().type('0.0').should('have.value', '0.0')
})
it.skip('can swap ETH for DAI', () => {
cy.get('#swap-currency-output .open-currency-select-button').click()
cy.get('.token-item-0xc7AD46e0b8a400Bb3C915120d284AafbA8fc4735').click()
cy.get('#swap-currency-input .token-amount-input').clear().type('0.0000001')
cy.get('#swap-currency-output .token-amount-input').should('not.equal', '')
cy.get('#swap-button').click()
cy.get('#confirm-swap-or-send').should('contain', 'Confirm Swap')
cy.get('[data-cy="confirmation-close-icon"]').click()
})
it('add a recipient does not exist unless in expert mode', () => {
cy.get('#add-recipient-button').should('not.exist')
})
it.skip('ETH to wETH is same value (wrapped swaps have no price impact)', () => {
cy.get('#swap-currency-output .open-currency-select-button').click()
cy.get('.token-item-0xc778417E063141139Fce010982780140Aa0cD5Ab').click()
cy.get('#swap-currency-input .token-amount-input').clear().type('0.01')
cy.get('#swap-currency-output .token-amount-input').should('have.value', '0.01')
})
})

View File

@@ -1,74 +0,0 @@
import { getTestSelector, getTestSelectorStartsWith } from '../utils'
describe('Token explore', () => {
before(() => {
cy.visit('/')
})
it('should load token leaderboard', () => {
cy.visit('/tokens/ethereum')
cy.get(getTestSelectorStartsWith('token-table')).its('length').should('be.eq', 100)
// check sorted svg icon is present in volume cell, since tokens are sorted by volume by default
cy.get(getTestSelector('header-row')).find(getTestSelector('volume-cell')).find('svg').should('exist')
cy.get(getTestSelector('token-table-row-ETH')).find(getTestSelector('name-cell')).should('include.text', 'Ether')
cy.get(getTestSelector('token-table-row-ETH')).find(getTestSelector('volume-cell')).should('include.text', '$')
cy.get(getTestSelector('token-table-row-ETH')).find(getTestSelector('price-cell')).should('include.text', '$')
cy.get(getTestSelector('token-table-row-ETH')).find(getTestSelector('tvl-cell')).should('include.text', '$')
cy.get(getTestSelector('token-table-row-ETH'))
.find(getTestSelector('percent-change-cell'))
.should('include.text', '%')
cy.get(getTestSelector('header-row')).find(getTestSelector('price-cell')).click()
cy.get(getTestSelector('header-row')).find(getTestSelector('price-cell')).find('svg').should('exist')
})
it('should update when time window toggled', () => {
cy.visit('/tokens/ethereum')
cy.get(getTestSelector('time-selector')).should('contain', '1D')
cy.get(getTestSelector('token-table-row-ETH'))
.find(getTestSelector('volume-cell'))
.then(function ($elem) {
cy.wrap($elem.text()).as('dailyEthVol')
})
cy.get(getTestSelector('time-selector')).click()
cy.get(getTestSelector('1Y')).click()
cy.get(getTestSelector('token-table-row-ETH'))
.find(getTestSelector('volume-cell'))
.then(function ($elem) {
cy.wrap($elem.text()).as('yearlyEthVol')
})
expect(cy.get('@dailyEthVol')).to.not.equal(cy.get('@yearlyEthVol'))
})
it('should navigate to token detail page when row clicked', () => {
cy.visit('/tokens/ethereum')
cy.get(getTestSelector('token-table-row-ETH')).click()
cy.get(getTestSelector('token-details-about-section')).should('exist')
cy.get(getTestSelector('token-details-stats')).should('exist')
cy.get(getTestSelector('token-info-container')).should('exist')
cy.get(getTestSelector('chart-container')).should('exist')
cy.contains('Ethereum is a smart contract platform that enables developers to build tokens').should('exist')
cy.contains('Etherscan').should('exist')
})
it('should update when global network changed', () => {
cy.visit('/tokens/ethereum')
cy.get(getTestSelector('tokens-network-filter-selected')).should('contain', 'Ethereum')
cy.get(getTestSelector('token-table-row-ETH')).should('exist')
// note: cannot switch global chain via UI because we cannot approve the network switch
// in metamask modal using plain cypress. this is a workaround.
cy.visit('/tokens/polygon')
cy.get(getTestSelector('tokens-network-filter-selected')).should('contain', 'Polygon')
cy.get(getTestSelector('token-table-row-MATIC')).should('exist')
})
it('should update when token explore table network changed', () => {
cy.visit('/tokens/ethereum')
cy.get(getTestSelector('tokens-network-filter-selected')).click()
cy.get(getTestSelector('tokens-network-filter-option-optimism')).click()
cy.get(getTestSelector('tokens-network-filter-selected')).should('contain', 'Optimism')
cy.reload()
cy.get(getTestSelector('tokens-network-filter-selected')).should('contain', 'Optimism')
cy.get(getTestSelector('chain-selector')).last().should('contain', 'Ethereum')
})
})

View File

@@ -1,51 +0,0 @@
import { getTestSelector } from '../utils'
describe('Wallet Dropdown', () => {
before(() => {
cy.visit('/pool')
})
it('should change the theme', () => {
cy.get(getTestSelector('web3-status-connected')).click()
cy.get(getTestSelector('wallet-select-theme')).click()
cy.get(getTestSelector('wallet-select-theme')).contains('Light theme').should('exist')
})
it('should select a language', () => {
cy.get(getTestSelector('wallet-select-language')).click()
cy.get(getTestSelector('wallet-language-item')).contains('Afrikaans').click({ force: true })
cy.get(getTestSelector('wallet-header')).should('contain', 'Taal')
cy.get(getTestSelector('wallet-language-item')).contains('English').click({ force: true })
cy.get(getTestSelector('wallet-header')).should('contain', 'Language')
cy.get(getTestSelector('wallet-back')).click()
})
it('should be able to view transactions', () => {
cy.get(getTestSelector('wallet-transactions')).click()
cy.get(getTestSelector('wallet-empty-transaction-text')).should('exist')
cy.get(getTestSelector('wallet-back')).click()
})
it('should change the theme when not connected', () => {
cy.get(getTestSelector('wallet-disconnect')).click()
cy.get(getTestSelector('wallet-select-theme')).click()
cy.get(getTestSelector('wallet-select-theme')).contains('Dark theme').should('exist')
cy.get(getTestSelector('wallet-select-theme')).click()
cy.get(getTestSelector('wallet-select-theme')).contains('Light theme').should('exist')
})
it('should select a language when not connected', () => {
cy.get(getTestSelector('wallet-select-language')).click()
cy.get(getTestSelector('wallet-language-item')).contains('Afrikaans').click({ force: true })
cy.get(getTestSelector('wallet-header')).should('contain', 'Taal')
cy.get(getTestSelector('wallet-language-item')).contains('English').click({ force: true })
cy.get(getTestSelector('wallet-header')).should('contain', 'Language')
cy.get(getTestSelector('wallet-back')).click()
})
it('should open the wallet connect modal from the drop down when not connected', () => {
cy.get(getTestSelector('wallet-connect-wallet')).click()
cy.get(getTestSelector('wallet-modal')).should('exist')
cy.get(getTestSelector('wallet-modal-close')).click()
})
})

View File

@@ -1,30 +0,0 @@
{
"_meta": {
"block": {
"number": 99999999
}
},
"asToken0": [
{
"feeTier": "100",
"totalValueLockedToken0": "0",
"totalValueLockedToken1": "3"
},
{
"feeTier": "500",
"totalValueLockedToken0": "0",
"totalValueLockedToken1": "1"
},
{
"feeTier": "3000",
"totalValueLockedToken0": "0",
"totalValueLockedToken1": "4"
},
{
"feeTier": "10000",
"totalValueLockedToken0": "0",
"totalValueLockedToken1": "2"
}
],
"asToken1": []
}

View File

@@ -1,21 +0,0 @@
const ONE_MINUTE = 60_000
describe(
'Release',
{
pageLoadTimeout: ONE_MINUTE,
retries: 30,
},
() => {
it('loads swap page', () => {
// TODO: We *must* wait in order to space out the retry attempts. Find a better way to do this.
// eslint-disable-next-line cypress/no-unnecessary-waiting
cy.wait(ONE_MINUTE)
.visit('/', {
retryOnStatusCodeFailure: true,
retryOnNetworkFailure: true,
})
.get('#swap-page')
})
}
)

View File

@@ -1,91 +0,0 @@
// ***********************************************************
// This file is processed and loaded automatically before your test files.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************
// Import commands.ts using ES2015 syntax:
import { injected } from './ethereum'
import assert = require('assert')
import { FeatureFlag } from '../../src/featureFlags/flags/featureFlags'
declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace Cypress {
interface ApplicationWindow {
ethereum: typeof injected
}
interface VisitOptions {
serviceWorker?: true
featureFlags?: Array<FeatureFlag>
selectedWallet?: string
noWallet?: boolean
}
}
}
// sets up the injected provider to be a mock ethereum provider with the given mnemonic/index
// eslint-disable-next-line no-undef
Cypress.Commands.overwrite(
'visit',
(original, url: string | Partial<Cypress.VisitOptions>, options?: Partial<Cypress.VisitOptions>) => {
assert(typeof url === 'string')
cy.intercept('/service-worker.js', options?.serviceWorker ? undefined : { statusCode: 404 }).then(() => {
original({
...options,
url: (url.startsWith('/') && url.length > 2 && !url.startsWith('/#') ? `/#${url}` : url) + '?chain=goerli',
onBeforeLoad(win) {
options?.onBeforeLoad?.(win)
win.localStorage.clear()
const userState = {
selectedWallet: options?.noWallet !== true ? options?.selectedWallet || 'INJECTED' : undefined,
fiatOnrampDismissed: true,
}
win.localStorage.setItem('redux_localstorage_simple_user', JSON.stringify(userState))
if (options?.featureFlags) {
const featureFlags = options.featureFlags.reduce(
(flags, flag) => ({
...flags,
[flag]: 'enabled',
}),
{}
)
win.localStorage.setItem('featureFlags', JSON.stringify(featureFlags))
}
win.ethereum = injected
},
})
})
}
)
beforeEach(() => {
// Infura security policies are based on Origin headers.
// These are stripped by cypress because chromeWebSecurity === false; this adds them back in.
cy.intercept(/infura.io/, (res) => {
res.headers['origin'] = 'http://localhost:3000'
res.continue()
})
// Graphql security policies are based on Origin headers.
// These are stripped by cypress because chromeWebSecurity === false; this adds them back in.
cy.intercept('https://api.uniswap.org/v1/graphql', (res) => {
res.headers['origin'] = 'https://app.uniswap.org'
res.continue()
})
cy.intercept('https://beta.api.uniswap.org/v1/graphql', (res) => {
res.headers['origin'] = 'https://app.uniswap.org'
res.continue()
})
})
Cypress.on('uncaught:exception', () => {
// returning false here prevents Cypress from failing the test
return false
})

View File

@@ -1,70 +0,0 @@
/**
* Updates cy.visit() to include an injected window.ethereum provider.
*/
import { Eip1193Bridge } from '@ethersproject/experimental/lib/eip1193-bridge'
// eslint-disable-next-line @typescript-eslint/no-restricted-imports
import { JsonRpcProvider } from '@ethersproject/providers'
import { Wallet } from '@ethersproject/wallet'
// 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
const TEST_ADDRESS_NEVER_USE = new Wallet(TEST_PRIVATE_KEY).address
const provider = new JsonRpcProvider('https://goerli.infura.io/v3/4bf032f2d38a4ed6bb975b80d6340847', 4)
const signer = new Wallet(TEST_PRIVATE_KEY, provider)
export const injected = new (class extends Eip1193Bridge {
chainId = /* GOERLI= */ 5
async sendAsync(...args: any[]) {
console.debug('sendAsync called', ...args)
return this.send(...args)
}
async send(...args: any[]) {
console.debug('send called', ...args)
const isCallbackForm = typeof args[0] === 'object' && typeof args[1] === 'function'
let callback
let method
let params
if (isCallbackForm) {
callback = args[1]
method = args[0].method
params = args[0].params
} else {
method = args[0]
params = args[1]
}
if (method === 'eth_requestAccounts' || method === 'eth_accounts') {
if (isCallbackForm) {
callback({ result: [TEST_ADDRESS_NEVER_USE] })
} else {
return Promise.resolve([TEST_ADDRESS_NEVER_USE])
}
}
if (method === 'eth_chainId') {
if (isCallbackForm) {
callback(null, { result: '0x4' })
} else {
return Promise.resolve('0x4')
}
}
try {
const result = await super.send(method, params)
console.debug('result received', method, params, result)
if (isCallbackForm) {
callback(null, { result })
} else {
return result
}
} catch (error) {
if (isCallbackForm) {
callback(error, null)
} else {
throw error
}
}
}
})(signer, provider)

View File

@@ -1,9 +0,0 @@
{
"compilerOptions": {
"strict": true,
"target": "es5",
"lib": ["es5", "dom"],
"types": ["cypress"]
},
"include": ["**/*.ts"]
}

View File

@@ -1,12 +0,0 @@
// Utility to match GraphQL mutation based on the query name
export const hasQuery = (req: any, queryName: string) => {
const { body } = req
return Object.prototype.hasOwnProperty.call(body, 'query') && body.query.includes(queryName)
}
// Alias query if queryName matches
export const aliasQuery = (req: any, queryName: string) => {
if (hasQuery(req, queryName)) {
req.alias = `${queryName}Query`
}
}

View File

@@ -1,3 +0,0 @@
export const getTestSelector = (selectorId: string) => `[data-testid=${selectorId}]`
export const getTestSelectorStartsWith = (selectorId: string) => `[data-testid^=${selectorId}]`

View File

@@ -1,23 +0,0 @@
/* eslint-env node */
require('dotenv').config({ path: '.env.production' })
const { exec } = require('child_process')
const dataConfig = require('./graphql.config')
const thegraphConfig = require('./graphql_thegraph.config')
function fetchSchema(url, outputFile) {
exec(
`get-graphql-schema --h Origin=https://app.uniswap.org ${url} | tee ${outputFile}.temp`,
(error, stdout, stderr) => {
if (error || stderr) {
console.log(`Failed to fetch schema from ${url}`)
} else if (stdout) {
exec(`mv ${outputFile}.temp ${outputFile}`)
}
}
)
}
fetchSchema(process.env.THE_GRAPH_SCHEMA_ENDPOINT, thegraphConfig.schema)
fetchSchema(process.env.REACT_APP_AWS_API_ENDPOINT, dataConfig.schema)

View File

@@ -1,8 +0,0 @@
/* eslint-env node */
module.exports = {
src: './src',
language: 'typescript',
schema: './src/graphql/data/schema.graphql',
exclude: ['**/node_modules/**', '**/__mocks__/**', '**/__generated__/**', '**/thegraph/**'],
}

View File

@@ -1,10 +0,0 @@
/* eslint-env node */
const defaultConfig = require('./graphql.config')
module.exports = {
src: defaultConfig.src,
language: defaultConfig.language,
schema: './src/graphql/thegraph/schema.graphql',
exclude: ['**/node_modules/**', '**/__mocks__/**', '**/__generated__/**', '**/data/**'],
}

View File

@@ -1,58 +0,0 @@
const linguiConfig = {
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',
'sw-TZ',
'tr-TR',
'uk-UA',
'vi-VN',
'zh-CN',
'zh-TW',
'pseudo',
],
orderBy: 'messageId',
rootDir: '.',
runtimeConfigModule: ['@lingui/core', 'i18n'],
sourceLocale: 'en-US',
pseudoLocale: 'pseudo',
}
export default linguiConfig

14
netlify.toml Normal file
View File

@@ -0,0 +1,14 @@
# block some countries
[[redirects]]
from = "/*"
to = "/451.html"
status = 451
force = true
conditions = {Country=["BY","CU","IR","IQ","CI","LR","KP","SD","SY","ZW"]}
headers = {Link="<https://uniswap.exchange>"}
# support SPA setup
[[redirects]]
from = "/*"
to = "/index.html"
status = 200

View File

@@ -1,51 +1,65 @@
{
"name": "@uniswap/interface",
"version": "1.0.7",
"description": "Uniswap Interface",
"homepage": ".",
"license": "GPL-3.0-or-later",
"scripts": {
"contracts:compile:abi": "typechain --target ethers-v5 --out-dir src/abis/types \"./src/abis/**/*.json\"",
"contracts:compile:v3": "typechain --target ethers-v5 --out-dir src/types/v3 \"./node_modules/@uniswap/**/artifacts/contracts/**/*[!dbg].json\"",
"contracts:compile": "yarn contracts:compile:abi && yarn contracts:compile:v3",
"graphql:fetch": "node fetch-schema.js",
"graphql:generate:data": "graphql-codegen --config apollo-codegen.ts",
"graphql:generate:thegraph": "graphql-codegen --config apollo-codegen_thegraph.ts",
"graphql:generate": "yarn graphql:generate:data && yarn graphql:generate:thegraph",
"prei18n:extract": "node prei18n-extract.js",
"i18n:extract": "lingui extract --locale en-US",
"i18n:compile": "yarn i18n:extract && lingui compile",
"i18n:pseudo": "lingui extract --locale pseudo && lingui compile",
"prepare": "yarn contracts:compile && yarn graphql:fetch && yarn graphql:generate && yarn i18n:compile",
"start": "craco start",
"build": "craco build",
"serve": "serve build -l 3000",
"deduplicate": "yarn-deduplicate --strategy=highest",
"lint": "yarn eslint .",
"test": "craco test --coverage",
"cypress:open": "cypress open --browser chrome --e2e",
"cypress:run": "cypress run --browser chrome --e2e",
"postinstall": "patch-package"
"name": "uniswap",
"description": "Uniswap Exchange Protocol",
"version": "0.1.0",
"homepage": "https://uniswap.exchange",
"private": true,
"dependencies": {
"@reach/dialog": "^0.2.8",
"@reach/tooltip": "^0.2.0",
"@types/jest": "^25.1.3",
"@types/node": "^13.7.4",
"@types/react": "^16.9.22",
"@types/react-dom": "^16.9.5",
"@uniswap/sdk": "^1.0.0-beta.4",
"@web3-react/core": "^6.0.2",
"@web3-react/fortmatic-connector": "^6.0.2",
"@web3-react/injected-connector": "^6.0.3",
"@web3-react/network-connector": "^6.0.4",
"@web3-react/torus-connector": "^6.0.8",
"@web3-react/portis-connector": "^6.0.2",
"@web3-react/walletconnect-connector": "^6.0.2",
"@web3-react/walletlink-connector": "^6.0.2",
"copy-to-clipboard": "^3.2.0",
"escape-string-regexp": "^2.0.0",
"ethers": "^4.0.44",
"history": "^4.9.0",
"i18next": "^15.0.9",
"i18next-browser-languagedetector": "^3.0.1",
"i18next-xhr-backend": "^2.0.1",
"jazzicon": "^1.5.0",
"polished": "^3.3.2",
"qrcode.react": "^0.9.3",
"react": "^16.8.6",
"react-device-detect": "^1.6.2",
"react-dom": "^16.8.6",
"react-feather": "^1.1.6",
"react-ga": "^2.5.7",
"react-i18next": "^10.7.0",
"react-router-dom": "^5.0.0",
"react-scripts": "^3.0.1",
"react-spring": "^8.0.27",
"react-switch": "^5.0.1",
"react-use-gesture": "^6.0.14",
"styled-components": "^4.2.0",
"typescript": "^3.8.2"
},
"jest": {
"collectCoverageFrom": [
"src/components/**/*.ts*",
"src/hooks/**/*.ts*",
"src/lib/hooks/**/*.ts*",
"src/lib/state/**/*.ts*",
"src/lib/utils/**/*.ts*",
"src/pages/**/*.ts*",
"src/state/**/*.ts*",
"src/utils/**/*.ts*"
],
"coverageThreshold": {
"global": {
"branches": 4,
"functions": 6,
"lines": 9,
"statements": 9
}
}
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject",
"lint:base": "yarn eslint './src/**/*.{js,jsx}'",
"format:base": "yarn prettier './src/**/*.{js,jsx,scss}'",
"fix:lint": "yarn lint:base --fix",
"fix:format": "yarn format:base --write",
"fix:all": "yarn fix:lint && yarn fix:format",
"check:lint": "yarn lint:base",
"check:format": "yarn format:base --check",
"check:all": "yarn check:lint && yarn check:format"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
@@ -59,187 +73,8 @@
"last 1 safari version"
]
},
"license": "GPL-3.0-or-later",
"devDependencies": {
"@craco/craco": "6.4.3",
"@ethersproject/experimental": "^5.4.0",
"@lingui/cli": "^3.9.0",
"@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^13.1",
"@typechain/ethers-v5": "^7.0.0",
"@types/array.prototype.flat": "^1.2.1",
"@types/array.prototype.flatmap": "^1.2.2",
"@types/d3": "^6.7.1",
"@types/jest": "^25.2.1",
"@types/lingui__core": "^2.7.1",
"@types/lingui__macro": "^2.7.4",
"@types/lingui__react": "^2.8.3",
"@types/ms.macro": "^2.0.0",
"@types/multicodec": "^1.0.0",
"@types/node": "^13.13.5",
"@types/qs": "^6.9.2",
"@types/react": "^18.0.15",
"@types/react-dom": "^18.0.6",
"@types/react-redux": "^7.1.24",
"@types/react-router-dom": "^5.3.3",
"@types/react-table": "^7.7.12",
"@types/react-virtualized-auto-sizer": "^1.0.0",
"@types/react-window": "^1.8.2",
"@types/rebass": "^4.0.7",
"@types/styled-components": "^5.1.25",
"@types/testing-library__cypress": "^5.0.5",
"@types/ua-parser-js": "^0.7.35",
"@types/uuid": "^8.3.4",
"@types/wcag-contrast": "^3.0.0",
"@uniswap/eslint-config": "^1.1.1",
"@vanilla-extract/babel-plugin": "^1.1.7",
"@vanilla-extract/webpack-plugin": "^2.1.11",
"cypress": "^10.3.1",
"env-cmd": "^10.1.0",
"eslint": "^7.11.0",
"jest-fetch-mock": "^3.0.3",
"jest-styled-components": "^7.0.8",
"ms.macro": "^2.0.0",
"patch-package": "^6.4.7",
"postinstall-postinstall": "^2.1.0",
"prettier": "^2.7.1",
"react-scripts": "^4.0.3",
"serve": "^11.3.2",
"ts-transform-graphql-tag": "^0.2.1",
"typechain": "^5.0.0",
"typescript": "^4.4.3",
"yarn-deduplicate": "^6.0.0"
},
"dependencies": {
"@apollo/client": "^3.7.2",
"@coinbase/wallet-sdk": "^3.3.0",
"@fontsource/ibm-plex-mono": "^4.5.1",
"@fontsource/inter": "^4.5.1",
"@graphql-codegen/cli": "^2.15.0",
"@graphql-codegen/client-preset": "^1.2.1",
"@graphql-codegen/typescript": "^2.8.3",
"@graphql-codegen/typescript-operations": "^2.5.8",
"@graphql-codegen/typescript-react-apollo": "^3.3.7",
"@graphql-codegen/typescript-resolvers": "^2.7.8",
"@lingui/core": "^3.14.0",
"@lingui/macro": "^3.14.0",
"@lingui/react": "^3.14.0",
"@looksrare/sdk": "^0.10.2",
"@metamask/jazzicon": "^2.0.0",
"@opensea/seaport-js": "^1.0.2",
"@popperjs/core": "^2.4.4",
"@reach/dialog": "^0.10.3",
"@reach/portal": "^0.10.3",
"@react-hook/window-scroll": "^1.3.0",
"@reduxjs/toolkit": "^1.6.1",
"@sentry/react": "^7.29.0",
"@types/react-window-infinite-loader": "^1.0.6",
"@uniswap/analytics": "1.2.0",
"@uniswap/analytics-events": "^2.1.0",
"@uniswap/conedison": "^1.1.1",
"@uniswap/governance": "^1.0.2",
"@uniswap/liquidity-staker": "^1.0.2",
"@uniswap/merkle-distributor": "1.0.1",
"@uniswap/permit2-sdk": "1.2.0",
"@uniswap/redux-multicall": "^1.1.8",
"@uniswap/router-sdk": "^1.3.0",
"@uniswap/sdk-core": "^3.0.1",
"@uniswap/smart-order-router": "^2.10.0",
"@uniswap/token-lists": "^1.0.0-beta.30",
"@uniswap/universal-router-sdk": "1.3.0",
"@uniswap/v2-core": "1.0.0",
"@uniswap/v2-periphery": "^1.1.0-beta.0",
"@uniswap/v2-sdk": "^3.0.1",
"@uniswap/v3-core": "1.0.0",
"@uniswap/v3-periphery": "^1.1.1",
"@uniswap/v3-sdk": "^3.9.0",
"@uniswap/widgets": "2.25.1",
"@vanilla-extract/css": "^1.7.2",
"@vanilla-extract/css-utils": "^0.1.2",
"@vanilla-extract/dynamic": "^2.0.2",
"@vanilla-extract/sprinkles": "^1.4.1",
"@visx/axis": "^2.12.2",
"@visx/event": "^2.6.0",
"@visx/glyph": "^2.10.0",
"@visx/group": "^2.10.0",
"@visx/react-spring": "^2.12.2",
"@visx/responsive": "^2.10.0",
"@visx/shape": "^2.11.1",
"@walletconnect/ethereum-provider": "^1.8.0",
"@web3-react/coinbase-wallet": "8.0.34-beta.0",
"@web3-react/core": "8.0.35-beta.0",
"@web3-react/eip1193": "8.0.26-beta.0",
"@web3-react/empty": "8.0.20-beta.0",
"@web3-react/gnosis-safe": "8.0.7-beta.0",
"@web3-react/metamask": "8.0.28-beta.0",
"@web3-react/network": "8.0.27-beta.0",
"@web3-react/types": "8.0.20-beta.0",
"@web3-react/url": "8.0.25-beta.0",
"@web3-react/walletconnect": "8.0.36-beta.0",
"array.prototype.flat": "^1.2.4",
"array.prototype.flatmap": "^1.2.4",
"cids": "^1.0.0",
"clsx": "^1.1.1",
"copy-to-clipboard": "^3.2.0",
"d3": "^7.6.1",
"ethers": "^5.1.4",
"firebase": "^9.1.3",
"focus-visible": "^5.2.0",
"get-graphql-schema": "^2.1.2",
"graphql": "^16.5.0",
"graphql-request": "^3.4.0",
"immer": "^9.0.6",
"inter-ui": "^3.13.1",
"jotai": "^1.3.7",
"jsbi": "^3.1.4",
"make-plural": "^7.0.0",
"multicodec": "^3.0.1",
"multihashes": "^4.0.2",
"node-vibrant": "^3.2.1-alpha.1",
"numbro": "^2.3.6",
"polished": "^3.3.2",
"polyfill-object.fromentries": "^1.0.1",
"popper-max-size-modifier": "^0.2.0",
"qs": "^6.9.4",
"rc-slider": "^10.0.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-feather": "^2.0.8",
"react-ga4": "^1.4.1",
"react-infinite-scroll-component": "^6.1.0",
"react-is": "^17.0.2",
"react-markdown": "^4.3.1",
"react-popper": "^2.2.3",
"react-query": "^3.39.1",
"react-redux": "^8.0.2",
"react-router-dom": "^6.3.0",
"react-spring": "^9.5.5",
"react-table": "^7.8.0",
"react-use-gesture": "^6.0.14",
"react-virtualized-auto-sizer": "^1.0.2",
"react-window": "^1.8.5",
"react-window-infinite-loader": "^1.0.8",
"rebass": "^4.0.7",
"redux": "^4.1.2",
"redux-localstorage-simple": "^2.3.1",
"setimmediate": "^1.0.5",
"styled-components": "^5.3.5",
"tiny-invariant": "^1.2.0",
"ua-parser-js": "^0.7.28",
"use-count-up": "^2.2.5",
"use-resize-observer": "^9.0.2",
"uuid": "^8.3.2",
"video-extensions": "^1.2.0",
"wcag-contrast": "^3.0.0",
"web-vitals": "^2.1.0",
"workbox-core": "^6.1.0",
"workbox-navigation-preload": "^6.1.0",
"workbox-precaching": "^6.1.0",
"workbox-routing": "^6.1.0",
"zustand": "^4.0.0-rc.1"
},
"engines": {
"npm": "please-use-yarn",
"node": "14",
"yarn": ">=1.22"
"prettier": "^1.17.0"
}
}

View File

@@ -1,22 +0,0 @@
diff --git a/node_modules/@vanilla-extract/css/dist/vanilla-extract-css.cjs.dev.js b/node_modules/@vanilla-extract/css/dist/vanilla-extract-css.cjs.dev.js
index 6e40061..10283a2 100644
--- a/node_modules/@vanilla-extract/css/dist/vanilla-extract-css.cjs.dev.js
+++ b/node_modules/@vanilla-extract/css/dist/vanilla-extract-css.cjs.dev.js
@@ -177,11 +177,13 @@ function generateIdentifier(debugId) {
var fileScopeHash = hash__default["default"](packageName ? "".concat(packageName).concat(filePath) : filePath);
var identifier = "".concat(fileScopeHash).concat(refCount);
- if (adapter_dist_vanillaExtractCssAdapter.getIdentOption() === 'debug') {
- var devPrefix = getDevPrefix(debugId);
+ if (process.env.VANILLA_EXTRACT_DEV_PREFIX) {
+ if (adapter_dist_vanillaExtractCssAdapter.getIdentOption() === 'debug') {
+ var devPrefix = getDevPrefix(debugId);
- if (devPrefix) {
- identifier = "".concat(devPrefix, "__").concat(identifier);
+ if (devPrefix) {
+ identifier = "".concat(devPrefix, "__").concat(identifier);
+ }
}
}

View File

@@ -1,10 +0,0 @@
/* eslint-env node */
const { exec } = require('child_process')
const isWindows = process.platform === 'win32' || /^(msys|cygwin)$/.test(process.env.OSTYPE)
if (isWindows) {
exec(`type nul > src/locales/en-US.po`)
} else {
exec(`touch src/locales/en-US.po`)
}

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

View File

@@ -1,11 +0,0 @@
<svg width="257" height="256" viewBox="0 0 257 256" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M96.4347 60.2768C94.3434 59.9524 94.2552 59.9143 95.2394 59.7631C97.1254 59.473 101.579 59.8683 104.648 60.5981C111.812 62.3011 118.331 66.6637 125.29 74.4117L127.139 76.4701L129.784 76.0449C140.926 74.2544 152.26 75.6774 161.741 80.057C164.349 81.2619 168.461 83.6603 168.975 84.2766C169.138 84.473 169.439 85.7374 169.642 87.0866C170.347 91.7544 169.994 95.3323 168.567 98.0046C167.79 99.4588 167.746 99.9197 168.268 101.164C168.686 102.157 169.848 102.892 170.999 102.891C173.355 102.888 175.891 99.0791 177.066 93.78L177.532 91.6751L178.457 92.7224C183.528 98.4681 187.512 106.304 188.196 111.881L188.374 113.336L187.522 112.014C186.054 109.739 184.58 108.19 182.693 106.941C179.29 104.69 175.693 103.923 166.164 103.421C157.559 102.968 152.689 102.233 147.859 100.658C139.643 97.9792 135.501 94.4114 125.74 81.6059C121.405 75.918 118.726 72.7711 116.06 70.2368C110.004 64.4784 104.053 61.4584 96.4347 60.2768Z" fill="#FF007A"/>
<path d="M170.916 72.9763C171.132 69.1649 171.649 66.651 172.688 64.3552C173.099 63.4465 173.485 62.7027 173.544 62.7027C173.604 62.7027 173.425 63.3735 173.147 64.1931C172.391 66.4212 172.267 69.4687 172.788 73.0144C173.448 77.5132 173.824 78.1623 178.579 83.022C180.809 85.3014 183.403 88.1762 184.344 89.4105L186.054 91.6547L184.344 90.0508C182.253 88.0895 177.444 84.2644 176.381 83.7176C175.669 83.3509 175.563 83.3573 175.124 83.7946C174.719 84.1975 174.634 84.803 174.577 87.6654C174.49 92.1267 173.882 94.9901 172.414 97.8533C171.621 99.4019 171.495 99.0714 172.214 97.3235C172.75 96.0184 172.805 95.4446 172.801 91.1259C172.792 82.4485 171.762 80.3624 165.721 76.7887C164.19 75.8834 161.668 74.5778 160.117 73.8872C158.565 73.1965 157.333 72.595 157.378 72.5501C157.549 72.3798 163.441 74.0995 165.812 75.0117C169.339 76.3686 169.922 76.5444 170.35 76.3807C170.637 76.271 170.776 75.4347 170.916 72.9763Z" fill="#FF007A"/>
<path d="M100.497 87.8209C96.2514 81.9758 93.6246 73.0138 94.1933 66.3144L94.3691 64.2413L95.3355 64.4176C97.1504 64.7486 100.28 65.9133 101.745 66.8033C105.766 69.2453 107.506 72.4605 109.277 80.7164C109.796 83.1346 110.477 85.8712 110.79 86.7976C111.294 88.2889 113.199 91.7721 114.748 94.0343C115.864 95.6636 115.123 96.4356 112.657 96.213C108.89 95.873 103.788 92.3519 100.497 87.8209Z" fill="#FF007A"/>
<path d="M165.766 131.323C145.925 123.335 138.937 116.4 138.937 104.7C138.937 102.979 138.996 101.57 139.068 101.57C139.14 101.57 139.908 102.138 140.774 102.833C144.797 106.06 149.303 107.438 161.776 109.258C169.115 110.328 173.245 111.193 177.056 112.457C189.166 116.473 196.658 124.624 198.445 135.725C198.964 138.951 198.66 145 197.818 148.188C197.153 150.706 195.125 155.245 194.588 155.419C194.439 155.468 194.292 154.896 194.254 154.118C194.05 149.95 191.943 145.891 188.406 142.851C184.383 139.395 178.979 136.643 165.766 131.323Z" fill="#FF007A"/>
<path d="M151.837 134.642C151.588 133.163 151.157 131.273 150.879 130.444L150.372 128.935L151.313 129.991C152.614 131.451 153.642 133.32 154.514 135.81C155.179 137.71 155.254 138.275 155.249 141.362C155.244 144.393 155.161 145.029 154.546 146.739C153.578 149.436 152.376 151.348 150.359 153.4C146.735 157.089 142.075 159.131 135.351 159.978C134.182 160.125 130.775 160.373 127.78 160.529C120.232 160.922 115.264 161.733 110.801 163.3C110.159 163.525 109.586 163.662 109.528 163.604C109.347 163.425 112.386 161.613 114.897 160.404C118.436 158.699 121.96 157.768 129.854 156.454C133.754 155.804 137.781 155.016 138.804 154.702C148.461 151.741 153.426 144.1 151.837 134.642Z" fill="#FF007A"/>
<path d="M160.932 150.795C158.296 145.128 157.691 139.657 159.135 134.554C159.289 134.009 159.538 133.562 159.687 133.562C159.837 133.562 160.459 133.899 161.07 134.31C162.284 135.127 164.721 136.505 171.212 140.044C179.311 144.46 183.929 147.879 187.07 151.786C189.82 155.208 191.522 159.104 192.341 163.856C192.805 166.548 192.533 173.024 191.843 175.735C189.665 184.281 184.604 190.993 177.385 194.911C176.327 195.484 175.377 195.955 175.275 195.958C175.172 195.96 175.557 194.98 176.131 193.78C178.56 188.703 178.836 183.765 177 178.269C175.876 174.904 173.584 170.797 168.956 163.857C163.575 155.788 162.256 153.641 160.932 150.795Z" fill="#FF007A"/>
<path d="M86.4067 181.371C93.7696 175.154 102.931 170.738 111.276 169.382C114.872 168.798 120.864 169.03 124.194 169.882C129.532 171.248 134.307 174.308 136.791 177.954C139.218 181.517 140.259 184.622 141.343 191.53C141.771 194.255 142.236 196.992 142.377 197.611C143.191 201.192 144.775 204.054 146.739 205.491C149.857 207.773 155.227 207.915 160.509 205.855C161.405 205.505 162.184 205.263 162.238 205.318C162.43 205.508 159.77 207.288 157.894 208.226C155.369 209.487 153.361 209.975 150.693 209.975C145.855 209.975 141.839 207.514 138.487 202.495C137.828 201.508 136.346 198.55 135.193 195.922C131.655 187.851 129.907 185.393 125.799 182.702C122.223 180.361 117.612 179.941 114.143 181.642C109.586 183.876 108.315 189.699 111.579 193.39C112.876 194.856 115.295 196.121 117.273 196.367C120.973 196.828 124.153 194.013 124.153 190.277C124.153 187.851 123.221 186.467 120.873 185.407C117.668 183.961 114.222 185.652 114.238 188.663C114.245 189.947 114.805 190.754 116.092 191.336C116.918 191.71 116.937 191.74 116.263 191.6C113.322 190.99 112.633 187.444 114.998 185.09C117.837 182.264 123.709 183.511 125.725 187.368C126.572 188.988 126.67 192.215 125.932 194.164C124.279 198.525 119.46 200.819 114.571 199.571C111.243 198.721 109.887 197.801 105.874 193.667C98.9012 186.484 96.1941 185.092 86.141 183.523L84.2146 183.222L86.4067 181.371Z" fill="#FF007A"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M33.8241 20.4645C57.1114 48.7285 93.0139 92.734 94.7963 95.1977C96.2679 97.232 95.7141 99.0609 93.1929 100.494C91.7909 101.291 88.9084 102.099 87.4652 102.099C85.8329 102.099 83.9939 101.313 82.6548 100.042C81.7084 99.1447 77.8882 93.4402 69.0694 79.7566C62.3216 69.2863 56.6747 60.6007 56.5206 60.4553C56.1644 60.119 56.1705 60.1303 68.3813 81.9787C76.0487 95.6979 78.6371 100.548 78.6371 101.197C78.6371 102.516 78.2771 103.21 76.6495 105.025C73.9363 108.052 72.7235 111.453 71.8479 118.492C70.8664 126.382 68.1064 131.955 60.4577 141.494C55.9803 147.078 55.2477 148.102 54.118 150.352C52.695 153.187 52.3037 154.774 52.1451 158.353C51.9775 162.137 52.3039 164.581 53.46 168.199C54.4721 171.366 55.5285 173.458 58.2292 177.641C60.5599 181.251 61.9019 183.933 61.9019 184.983C61.9019 185.818 62.0613 185.819 65.6729 185.003C74.316 183.052 81.3341 179.619 85.2812 175.412C87.724 172.808 88.2975 171.371 88.3161 167.802C88.3283 165.469 88.2462 164.98 87.6153 163.637C86.5884 161.452 84.7188 159.635 80.5983 156.818C75.1992 153.127 72.8932 150.156 72.2562 146.07C71.7337 142.717 72.3399 140.351 75.3267 134.091C78.4182 127.612 79.1843 124.85 79.7025 118.319C80.0372 114.1 80.5008 112.435 81.7131 111.1C82.9776 109.707 84.1158 109.235 87.245 108.808C92.3466 108.111 95.5951 106.791 98.2652 104.33C100.582 102.196 101.551 100.139 101.7 97.0427L101.813 94.6959L100.518 93.1867C95.8304 87.7209 30.6848 16.168 30.3963 16.168C30.3347 16.168 31.8773 18.1015 33.8241 20.4645ZM64.5333 162.634C65.5932 160.757 65.0301 158.344 63.2572 157.166C61.5821 156.052 58.9799 156.576 58.9799 158.028C58.9799 158.471 59.2248 158.793 59.7768 159.077C60.7063 159.555 60.7738 160.093 60.0425 161.192C59.3019 162.306 59.3616 163.284 60.2111 163.949C61.5802 165.021 63.5183 164.432 64.5333 162.634Z" fill="#FF007A"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M105.032 110.039C102.637 110.774 100.309 113.312 99.5884 115.974C99.1487 117.598 99.3982 120.446 100.057 121.325C101.121 122.746 102.149 123.12 104.935 123.101C110.389 123.063 115.131 120.724 115.682 117.799C116.134 115.402 114.051 112.08 111.183 110.622C109.703 109.87 106.555 109.571 105.032 110.039ZM111.408 115.024C112.249 113.829 111.881 112.537 110.451 111.664C107.726 110 103.607 111.377 103.607 113.95C103.607 115.231 105.755 116.629 107.724 116.629C109.035 116.629 110.829 115.847 111.408 115.024Z" fill="#FF007A"/>
</svg>

Before

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 378 KiB

View File

@@ -1,122 +1,39 @@
<!DOCTYPE html>
<html translate="no">
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Uniswap Interface</title>
<meta name="description" content="Swap or provide liquidity on the Uniswap Protocol" />
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta name="fortmatic-site-verification" content="j93LgcVZk79qcgyo" />
<!--
%PUBLIC_URL% will be replaced with the URL of the `public` folder during build.
Only files inside the `public` folder can be referenced from the HTML.
-->
<link rel="shortcut icon" type="image/png" href="%PUBLIC_URL%/favicon.png" />
<link rel="apple-touch-icon" sizes="192x192" href="%PUBLIC_URL%/images/192x192_App_Icon.png" />
<link rel="apple-touch-icon" sizes="512x512" href="%PUBLIC_URL%/images/512x512_App_Icon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<meta name="theme-color" content="#FC72FF" />
<meta
http-equiv="Content-Security-Policy"
content="script-src 'self' https://www.google-analytics.com https://www.googletagmanager.com 'unsafe-inline'"
/>
<!--
manifest.json provides metadata used when the app is installed as a PWA.
See https://developers.google.com/web/fundamentals/web-app-manifest/
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
<link rel="preconnect" href="https://www.google-analytics.com/" />
<link rel="preload" href="%PUBLIC_URL%/fonts/Inter-roman.var.woff2" as="font" type="font/woff2" crossorigin />
<style>
* {
font-family: 'Inter', sans-serif;
box-sizing: border-box;
}
/**
Explicitly load Inter var from public/ so it does not block LCP's critical path.
*/
@font-face {
font-family: 'Inter custom';
font-weight: 100 900;
font-style: normal;
font-display: block;
font-named-instance: 'Regular';
src: url(%PUBLIC_URL%/fonts/Inter-roman.var.woff2) format('woff2 supports variations(gvar)'),
url(%PUBLIC_URL%/fonts/Inter-roman.var.woff2) format('woff2-variations'),
url(%PUBLIC_URL%/fonts/Inter-roman.var.woff2) format('woff2');
}
@supports (font-variation-settings: normal) {
* {
font-family: 'Inter custom', sans-serif;
}
}
html,
body {
margin: 0;
padding: 0;
}
button {
user-select: none;
}
html {
font-size: 16px;
font-variant: none;
font-smooth: always;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
/* Use this to apply network-specific gradient backgrounds, in RadialGradientByChainUpdater.ts */
#background-radial-gradient {
position: fixed;
top: 0;
left: 0;
right: 0;
pointer-events: none;
width: 200vw;
height: 200vh;
transform: translate(-50vw, -100vh);
z-index: -1;
}
html,
body,
#root {
min-height: 100%;
}
@media (prefers-color-scheme: dark) {
html {
background: linear-gradient(180deg, #202738 0%, #070816 100%);
}
}
@media (prefers-color-scheme: light) {
html {
background: radial-gradient(100% 100% at 50% 0%, rgba(255, 184, 226, 0.51) 0%, rgba(255, 255, 255, 0) 100%), #FFFFFF
}
}
</style>
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>Uniswap V1 Interface</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root" />
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
<div id="root">
<!-- Triggers the font to load immediately and then is replaced by the app -->
<div>&emsp;</div>
</div>
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
<div id="background-radial-gradient"></div>
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>

89
public/locales/de.json Normal file
View File

@@ -0,0 +1,89 @@
{
"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!"
}

91
public/locales/en.json Normal file
View File

@@ -0,0 +1,91 @@
{
"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",
"connectToWallet": "Connect to a Wallet",
"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",
"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. ",
"initialWarning": "A few improperly implemented ERC20 tokens have caused the remove liquidity function to break, permanently locking funds. As the first liquidity provider we recommend testing both add and remove with small amounts before adding a large amounts.",
"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.",
"broken777": "ERC-777 tokens are not supported in Uniswap V1."
}

75
public/locales/es-AR.json Normal file
View File

@@ -0,0 +1,75 @@
{
"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"
}

75
public/locales/es-US.json Normal file
View File

@@ -0,0 +1,75 @@
{
"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"
}

87
public/locales/it-IT.json Normal file
View File

@@ -0,0 +1,87 @@
{
"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 "
}

75
public/locales/ro.json Normal file
View File

@@ -0,0 +1,75 @@
{
"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": "Schimba",
"send": "Trimite",
"pool": "Extrage",
"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": "Deschide",
"pending": "În Așteptare",
"selectToken": "Selectează un token",
"searchOrPaste": "Caută Token sau Setează Adresă",
"noExchange": "Niciun Exchange Găsit",
"exchangeRate": "Curs Valutar",
"enterValueCont": "Setează o valoare pentru {{ missingCurrencyValue }} pentru a continua.",
"selectTokenCont": "Selectează un token pentru a continua.",
"noLiquidity": "Lichiditate Inexistentă.",
"unlockTokenCont": "Te rog deblochează tokenul pentru a continua.",
"transactionDetails": "Detalii Tranzacții",
"hideDetails": "Ascunde Detaili",
"youAreSelling": "Vinzi",
"orTransFail": "sau tranzacția va eșua.",
"youWillReceive": "Vei primi cel puțin",
"youAreBuying": "Cumperi",
"itWillCost": "Va costa cel mult",
"insufficientBalance": "Balanță Insuficientă",
"inputNotValid": "Valoarea setată nu este validă",
"differentToken": "Trebuie să fie un token diferit.",
"noRecipient": "Setează o adresă de portofel pentru destinatar.",
"invalidRecipient": "Te rog setează o adresă de portofel validă pentru destinatar.",
"recipientAddress": "Adresa Destinatarului",
"youAreSending": "Trimiți",
"willReceive": "vei primi cel puțin",
"to": "spre",
"addLiquidity": "Crește Lichiditatea",
"deposit": "Depozitează",
"currentPoolSize": "Mărimea Actualului Fond Comun",
"yourPoolShare": "Partea Ta Din Fond Comun",
"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": "Adaugi între",
"and": "și",
"intoPool": "în fondul comun de lichidatate.",
"outPool": "din fondul comun de lichiditate.",
"youWillMint": "Vei printa",
"liquidityTokens": "tokene disponibile.",
"totalSupplyIs": "Actuala ofertă totală de tokene disponibile este",
"youAreSettingExRate": "Setezi cursul valutar inițial la",
"totalSupplyIs0": "Actuala ofertă totală de tokene disponibile este 0.",
"tokenWorth": "La acest schimb valutar, fiecare token disponibil este estimată la",
"firstLiquidity": "Ești prima persoană care aduce lichiditate!",
"initialExchangeRate": "Schimbul valutar inițial va fi setat în funcție de depozitul tău. Te rog asigură-te că depoziturile ETH și {{ label }} pe care le-ai făcut au aceeași valoare în monezi naționale.",
"removeLiquidity": "Elimină Lichiditate",
"poolTokens": "Extrage Tokene",
"enterLabelCont": "Setează o valoare pentru {{ label }} pentru a continua.",
"youAreRemoving": "Elimini între",
"youWillRemove": "Vei elimina",
"createExchange": "Creează Exchange",
"invalidTokenAddress": "Adresă de token nu este validă",
"exchangeExists": "{{ label }} Exchange există deja!",
"invalidSymbol": "Simbol invalid!",
"invalidDecimals": "Zecimale invalidate",
"tokenAddress": "Adresă Token",
"label": "Denumire",
"decimals": "Zecimale",
"enterTokenCont": "Setează o adresă de token pentru a continua"
}

76
public/locales/ru.json Normal file
View File

@@ -0,0 +1,76 @@
{
"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": "Чтобы продолжить, введите адрес токена",
"connectToWallet": "Подключиться к кошельку"
}

87
public/locales/vi.json Normal file
View File

@@ -0,0 +1,87 @@
{
"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": "Che giấu 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": "dồ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 "
}

75
public/locales/zh-CN.json Normal file
View File

@@ -0,0 +1,75 @@
{
"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": "输入通证地址并继续"
}

75
public/locales/zh-TW.json Normal file
View File

@@ -0,0 +1,75 @@
{
"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": "輸入代幣地址"
}

View File

@@ -1,30 +1,15 @@
{
"background_color": "#fff",
"display": "standalone",
"homepage_url": "https://app.uniswap.org",
"providedBy": {
"name": "Uniswap",
"url": "https://uniswap.org"
},
"short_name": "Uniswap",
"name": "Uniswap Exchange",
"icons": [
{
"src": "./images/192x192_App_Icon.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any maskable"
},
{
"src": "./images/512x512_App_Icon.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any maskable"
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
}
],
"orientation": "portrait",
"name": "Uniswap",
"description": "Swap or provide liquidity on the Uniswap Protocol",
"iconPath": "./images/256x256_App_Icon_Pink.svg",
"short_name": "Uniswap",
"start_url": ".",
"theme_color": "#FC72FF"
}
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 245 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 169 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

View File

@@ -1,3 +0,0 @@
<svg width="29" height="28" viewBox="0 0 29 28" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6.74219 20.29C6.74219 22.1885 7.71777 23.1729 9.59863 23.1729H18.959C20.8398 23.1729 21.8154 22.1885 21.8154 20.29V7.02734C21.8154 5.1377 20.8398 4.14453 18.959 4.14453H9.59863C7.71777 4.14453 6.74219 5.1377 6.74219 7.02734V20.29ZM8.46484 20.1846V7.13281C8.46484 6.31543 8.88672 5.86719 9.73926 5.86719H18.8096C19.6621 5.86719 20.0928 6.31543 20.0928 7.13281V20.1846C20.0928 21.002 19.6621 21.4502 18.8096 21.4502H9.73926C8.88672 21.4502 8.46484 21.002 8.46484 20.1846ZM10.5391 9.16309C10.9961 9.16309 11.3564 8.79395 11.3564 8.3457C11.3564 7.88867 10.9961 7.52832 10.5391 7.52832C10.0908 7.52832 9.72168 7.89746 9.72168 8.3457C9.72168 8.79395 10.0908 9.16309 10.5391 9.16309ZM12.9561 8.91699H18.2646C18.5811 8.91699 18.8359 8.66211 18.8359 8.3457C18.8359 8.0293 18.5811 7.77441 18.2646 7.77441H12.9561C12.6396 7.77441 12.3848 8.0293 12.3848 8.3457C12.3848 8.66211 12.6396 8.91699 12.9561 8.91699ZM10.5391 11.7822C10.9961 11.7822 11.3564 11.4131 11.3564 10.9648C11.3564 10.5078 10.9961 10.1562 10.5391 10.1562C10.082 10.1562 9.72168 10.5166 9.72168 10.9648C9.72168 11.4131 10.082 11.7822 10.5391 11.7822ZM12.9561 11.5361H18.2646C18.5898 11.5361 18.8359 11.2812 18.8359 10.9648C18.8359 10.6484 18.5898 10.4023 18.2646 10.4023H12.9561C12.6309 10.4023 12.3848 10.6484 12.3848 10.9648C12.3848 11.2812 12.6309 11.5361 12.9561 11.5361ZM10.5391 14.5332C10.9961 14.5332 11.3564 14.1641 11.3564 13.7158C11.3564 13.2588 10.9961 12.8896 10.5391 12.8896C10.0908 12.8896 9.72168 13.2676 9.72168 13.7158C9.72168 14.1553 10.0908 14.5332 10.5391 14.5332ZM12.9561 14.2871H18.2646C18.5811 14.2871 18.8359 14.0234 18.8359 13.7158C18.8359 13.3994 18.5898 13.1445 18.2646 13.1445H12.9561C12.6309 13.1445 12.3848 13.3994 12.3848 13.7158C12.3848 14.0234 12.6396 14.2871 12.9561 14.2871Z" fill="#0A0A3B"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

View File

@@ -1,4 +0,0 @@
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9.57471 23.4444H20.6489C22.4664 23.4444 23.5211 22.3897 23.5211 20.3745V10.6281C23.5211 8.61286 22.457 7.55818 20.4229 7.55818H19.0951C19.0481 5.4488 17.2494 3.69727 14.9988 3.69727C12.7576 3.69727 10.9496 5.4488 10.9025 7.55818H9.57471C7.54067 7.55818 6.47656 8.61286 6.47656 10.6281V20.3745C6.47656 22.3897 7.54067 23.4444 9.57471 23.4444ZM14.9988 5.36405C16.2889 5.36405 17.24 6.33398 17.2777 7.55818H12.7199C12.7576 6.33398 13.7087 5.36405 14.9988 5.36405Z" fill="#4673FA"/>
<path d="M14.4407 20.3577C14.057 20.3577 13.744 20.1936 13.4613 19.814L10.9875 16.757C10.8057 16.5313 10.7148 16.2851 10.7148 16.0287C10.7148 15.5055 11.1187 15.0746 11.6438 15.0746C11.9568 15.0746 12.1991 15.1977 12.4516 15.526L14.4003 18.0393L18.5806 11.2483C18.7926 10.8995 19.0854 10.7148 19.3985 10.7148C19.9033 10.7148 20.3577 11.0739 20.3577 11.6073C20.3577 11.8433 20.2466 12.0997 20.0952 12.3357L15.3697 19.814C15.1475 20.173 14.8143 20.3577 14.4407 20.3577Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24">
<path fill="#4673FA" d="M11.783 18.094c-.315.489-.78.763-1.32.763-.554 0-.988-.229-1.393-.763l-3.537-4.393c-.255-.32-.39-.656-.39-1.022 0-.763.57-1.358 1.304-1.358.45 0 .81.168 1.17.64l2.787 3.616 5.92-9.671c.315-.519.72-.763 1.17-.763.704 0 1.363.503 1.363 1.25 0 .352-.18.718-.374 1.038l-6.7 10.663z"/>
</svg>

Before

Width:  |  Height:  |  Size: 410 B

View File

@@ -1,3 +0,0 @@
<svg width="28" height="28" viewBox="0 0 28 28" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12.7783 21.1514C12.9805 21.3447 13.2266 21.4502 13.5078 21.4502C14.0967 21.4502 14.5537 20.9932 14.5537 20.4131C14.5537 20.123 14.4395 19.8594 14.2373 19.6572L8.08496 13.6455L14.2373 7.65137C14.4395 7.44922 14.5537 7.17676 14.5537 6.89551C14.5537 6.31543 14.0967 5.8584 13.5078 5.8584C13.2266 5.8584 12.9805 5.96387 12.7871 6.15723L5.94922 12.8369C5.70312 13.0654 5.58008 13.3467 5.58008 13.6543C5.58008 13.9619 5.70312 14.2256 5.94043 14.4629L12.7783 21.1514ZM20.6357 21.1514C20.8379 21.3447 21.0752 21.4502 21.3652 21.4502C21.9541 21.4502 22.4111 20.9932 22.4111 20.4131C22.4111 20.123 22.2881 19.8594 22.0947 19.6572L15.9336 13.6455L22.0947 7.65137C22.2969 7.44922 22.4111 7.17676 22.4111 6.89551C22.4111 6.31543 21.9541 5.8584 21.3652 5.8584C21.0752 5.8584 20.8379 5.96387 20.6357 6.15723L13.7979 12.8369C13.5605 13.0654 13.4375 13.3467 13.4287 13.6543C13.4287 13.9619 13.5518 14.2256 13.7979 14.4629L20.6357 21.1514Z" fill="currentColor"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -1,10 +0,0 @@
<svg width="29" height="28" viewBox="0 0 29 28" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_564_11230)">
<path d="M7.2207 16.0615L13.9092 9.22363C14.1377 8.97754 14.4102 8.86328 14.7178 8.86328C15.0254 8.86328 15.3066 8.98633 15.5352 9.22363L22.2148 16.0615C22.4082 16.2549 22.5137 16.501 22.5137 16.791C22.5137 17.3799 22.0566 17.8369 21.4766 17.8369C21.1953 17.8369 20.9229 17.7314 20.7207 17.5205L14.7266 11.3594L8.71484 17.5205C8.52148 17.7227 8.24902 17.8369 7.95898 17.8369C7.37891 17.8369 6.92188 17.3799 6.92188 16.791C6.92188 16.5098 7.02734 16.2549 7.2207 16.0615Z" fill="currentColor"/>
</g>
<defs>
<clipPath id="clip0_564_11230">
<rect width="28" height="28" fill="white" transform="translate(0.716797)"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 774 B

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