Compare commits

...

777 Commits

Author SHA1 Message Date
e2d5f85ce0 no need actions 2024-01-05 17:28:30 +00:00
9ee5aa173f rpcs
Some checks failed
Crowdin Upload / upload-sources (push) Has been cancelled
Test / lint (push) Has been cancelled
Test / typecheck (push) Has been cancelled
Test / deps-tests (push) Has been cancelled
Test / unit-tests (push) Has been cancelled
Test / build (push) Has been cancelled
Test / cypress-typecheck (push) Has been cancelled
Test / cypress-rerun (push) Has been cancelled
Test / cloud-typecheck (push) Has been cancelled
Test / cloud-tests (push) Has been cancelled
Test / pre (push) Has been cancelled
Test / cypress-test-matrix (1) (push) Has been cancelled
Test / cypress-test-matrix (2) (push) Has been cancelled
Test / cypress-test-matrix (3) (push) Has been cancelled
Test / cypress-test-matrix (4) (push) Has been cancelled
Test / hardhat-cache (push) Has been cancelled
Test / post (push) Has been cancelled
2024-01-05 17:25:52 +00:00
f99f20fe18 fuck telemetry 2024-01-05 17:25:33 +00:00
fb0108196c add torn to default tokens list
Some checks failed
Crowdin Upload / upload-sources (push) Has been cancelled
Test / lint (push) Has been cancelled
Test / typecheck (push) Has been cancelled
Test / deps-tests (push) Has been cancelled
Test / unit-tests (push) Has been cancelled
Test / build (push) Has been cancelled
Test / cypress-typecheck (push) Has been cancelled
Test / cypress-rerun (push) Has been cancelled
Test / cloud-typecheck (push) Has been cancelled
Test / cloud-tests (push) Has been cancelled
Test / pre (push) Has been cancelled
Test / cypress-test-matrix (1) (push) Has been cancelled
Test / cypress-test-matrix (2) (push) Has been cancelled
Test / cypress-test-matrix (3) (push) Has been cancelled
Test / cypress-test-matrix (4) (push) Has been cancelled
Test / hardhat-cache (push) Has been cancelled
Test / post (push) Has been cancelled
2023-12-22 07:12:38 +00:00
986cf07391 remove warnings 2023-12-22 07:12:12 +00:00
48eb3f0005 remove prohibited & blocked lists checking
Some checks failed
Semgrep / semgrep/ci (push) Has been cancelled
Crowdin Upload / upload-sources (push) Has been cancelled
Test / lint (push) Has been cancelled
Test / typecheck (push) Has been cancelled
Test / deps-tests (push) Has been cancelled
Test / unit-tests (push) Has been cancelled
Test / build (push) Has been cancelled
Test / cypress-typecheck (push) Has been cancelled
Test / cypress-rerun (push) Has been cancelled
Test / cypress-test-matrix (1) (push) Has been cancelled
Test / cypress-test-matrix (2) (push) Has been cancelled
Test / cypress-test-matrix (3) (push) Has been cancelled
Test / cypress-test-matrix (4) (push) Has been cancelled
Test / hardhat-cache (push) Has been cancelled
Test / cloud-typecheck (push) Has been cancelled
Test / cloud-tests (push) Has been cancelled
Test / pre (push) Has been cancelled
Test / post (push) Has been cancelled
2023-12-19 17:21:56 +00:00
a95c8fab5a change mainnet rpc bcs infura blocks connections not from uni 2023-12-19 17:21:10 +00:00
1c131ee496 fix installation graphql script
Some checks are pending
Crowdin Upload / upload-sources (push) Waiting to run
Test / lint (push) Waiting to run
Test / typecheck (push) Waiting to run
Test / deps-tests (push) Waiting to run
Test / unit-tests (push) Waiting to run
Test / build (push) Waiting to run
Test / cypress-typecheck (push) Waiting to run
Test / cypress-rerun (push) Waiting to run
Test / cypress-test-matrix (1) (push) Blocked by required conditions
Test / cypress-test-matrix (2) (push) Blocked by required conditions
Test / cypress-test-matrix (3) (push) Blocked by required conditions
Test / cypress-test-matrix (4) (push) Blocked by required conditions
Test / hardhat-cache (push) Blocked by required conditions
Test / cloud-typecheck (push) Waiting to run
Test / cloud-tests (push) Waiting to run
Test / pre (push) Waiting to run
Test / post (push) Blocked by required conditions
2023-12-19 13:56:52 +00:00
911af900ed remove tokens censoring
Some checks are pending
Crowdin Upload / upload-sources (push) Waiting to run
Semgrep / semgrep/ci (push) Waiting to run
Test / lint (push) Waiting to run
Test / typecheck (push) Waiting to run
Test / deps-tests (push) Waiting to run
Test / unit-tests (push) Waiting to run
Test / build (push) Waiting to run
Test / cypress-typecheck (push) Waiting to run
Test / cypress-rerun (push) Waiting to run
Test / cypress-test-matrix (1) (push) Blocked by required conditions
Test / cypress-test-matrix (2) (push) Blocked by required conditions
Test / cypress-test-matrix (3) (push) Blocked by required conditions
Test / cypress-test-matrix (4) (push) Blocked by required conditions
Test / hardhat-cache (push) Blocked by required conditions
Test / cloud-typecheck (push) Waiting to run
Test / cloud-tests (push) Waiting to run
Test / pre (push) Waiting to run
Test / post (push) Blocked by required conditions
2023-12-19 13:16:53 +00:00
Kristie Huang
fc7ecc7e3b
feat: [info] add multi-chain balances on TDP (#7493)
* feat: wip, [info] add TDP crosschain balances

* very wip new balances

* progress on balances

* wip new balance

* add todo for native tokens

* fix bridge info caching

* fix bridge info caching & clean up

* cleanup query logic

* remove pollinginterval enum change

* fix logo flickering

* minor comment cleanup

* more minor comment cleanup

* use gqlToCurrency instead

* css changes for balance box

* css changes for mobile balance summary footer

* fix apollo client caching tokens merge

* clarify comment

* make chainId required

* comment cleanup

* fix: balance fetch caching

* fix prefetchbalancewrapper css jank

* remove padding

* delete extraneous borderRadius

* update comment

* should not show balancecard at all if no balances

* rename to multichain

* changes to mobile bar css

* use surface1 theme background

* oops add back bottom-bar

* fix cypress tests ??

* revert change

* broken apollo merge??

* remove extraneous tokens call

* remove apollo merge for portfolio>tokens

* oops fix some pr review

* load portfolio balances as it updates

* pr review

* update comment linear ticket

* remove extraneous chainId prop

* increase timeout time

* should not do symbols check

* pr review

* pr review

* refactor multichainbalances into map

* remove address native

* nit pr review

* use portfoliobalance fragment

* fix typechecking gql

* TYPES

---------

Co-authored-by: cartcrom <cartergcromer@gmail.com>
2023-11-27 13:40:19 -05:00
Kristie Huang
4a5a41c59e
fix: fix uniswapx feature flag test cleanup (#7615) 2023-11-21 14:42:40 -05:00
Kristie Huang
4bec816e6c
fix: disable fees and uniswapx tests + skip localStorage reads for bl… (#7580)
fix: disable fees and uniswapx tests + skip localStorage reads for blocked addresses (#7564)

* fix: disable fees tests

* skip uniswapx tests for now

* turn off uniswapx for classic swap test

* skip local cache reads for blocked accounts

* fix: broken pools test (#7562)

* test: update hardhat blocknumber (#7559)

* init

* fix: remove console log

* fix: add comment

---------

Co-authored-by: Tina <59578595+tinaszheng@users.noreply.github.com>
Co-authored-by: cartcrom <cartergcromer@gmail.com>
Co-authored-by: cartcrom <39385577+cartcrom@users.noreply.github.com>
2023-11-21 14:10:28 -05:00
Kristie Huang
1d1b15f4ac
fix: android banner DownloadButton onClick should not propagate up (#7611)
* android banner link - remove linktarget

* stop propagation?

* linter
2023-11-20 12:36:02 -05:00
Tina
1ffaf723de
fix: dont show USD price difference for wraps (#7610)
dont show stableconi price difference on wraps
2023-11-17 17:46:16 -05:00
Tina
dd4b2dc764
fix: only change input currency to weth after eth wrap completes for uniswapx eth input trades (#7604)
* only change input currency to weth after wrap completes

* add e2e test

* update test
2023-11-17 10:47:16 -05:00
eddie
5ded55e061
feat: x rollout cleanup (#7582)
* feat: cleanup post x rollout

* feat: remove feature flag

* fix: remove more unused styled components

* fix: delete deprecated value from redux store

* fix: lint

* fix: remove userOptedOutOfUniswapX

* fix: migrate verion in edge case, add test
2023-11-16 13:59:36 -08:00
eddie
0f4ca592f2
fix: remove /increase route (#7603)
* fix: remove /increase route

* fix: rename confusing components
2023-11-16 13:36:57 -08:00
Kristie Huang
90497dc08a
chore: refactor TDP time selector (#7600)
* feat: [info] add tdp charts toggle, WIP

* some refactoring

* remove chartType related changes after cherrypick

* nit

* remove setTransition
2023-11-16 13:46:25 -05:00
eddie
2e618fb2aa
fix: remove 3 launched feature flags (#7589)
* fix: remove 3 launched feature flags

* fix: remove unused componnent

* fix: remove another apple logo
2023-11-15 11:17:02 -08:00
cartcrom
0aa5727cdd
fix: don't format wrap input amount (#7592)
* fix: don't format wrap input amount

* lint
2023-11-15 13:58:57 -05:00
Tina
79e74e1d13
fix: disable showing approve cost for arbitrum (#7594)
disable showing approve cost for arbitrum
2023-11-15 13:24:13 -05:00
eddie
52dc441e31
feat: swap component refactor limits (#7588)
* feat: add limits tab, flag

* feat: add unit test

* fix: update snapshot
2023-11-15 09:00:03 -08:00
Tina
ff6d1cc510
feat: read token taxes from backend response (#7532)
* read token taxes from backend

* revert env changes

* upgrade router-sdk for updated price impact logic

* add tax information to trade currencies instead of directly on trade object

* consolidate getTradeCurrencies with getSwapCurrenciesWithTaxInfo

* delete feature flag for token taxes!

* run yarn dedupe again

* fix unit tests

* update logic for disabling inputs

* update snapshot again

* fix return value for uniswapx

* remove unused constants and update comment

* pr review

* re-add useSwapTaxes for token descriptor page

* add in client-side tax fetching on currency level

* revert removing newline

* typecheck....

* typecheck...

* remove inputTax, outputTax from routing-api arguments because they are now unused

* dont pass in tax info to preview trade
2023-11-15 09:57:43 -05:00
cartcrom
76157c057e
fix: portfolioLogo alignment (#7585)
* fix: portfolioLogo alignment

* fix: snapshot
2023-11-14 17:02:16 -05:00
eddie
a1bd6f5eb4
feat: update default router preference in redux (#7571) 2023-11-14 11:05:47 -08:00
Jack Short
f903eedc15
fix: redux migration to flush german locale (#7584)
* fix: redux migration to flush german locale

* lint

* my linter was not workking
2023-11-14 13:29:17 -05:00
eddie
1feeaea181
test: update e2e tests after X rollout (#7583)
test: updatea e2e tests after X rollout
2023-11-14 09:13:57 -08:00
eddie
7b10c94e4d
fix: update robots.txt file (#7570) 2023-11-14 09:13:44 -08:00
eddie
f2f59d52cb
feat: update legacy redux migration post X rollout (#7572) 2023-11-13 15:19:28 -08:00
eddie
a5034cb1c0
fix: reset token selections when changing chains on /add (#7561)
* fix: reset token selections when  changing chains on /add

* fix: tests

* fix: add e2e test

* fix: remove .only
2023-11-13 15:10:44 -08:00
eddie
2227a38276
fix: set current redux version to 3 (#7578)
* fix: set current redux version to 3

* fix: tests
2023-11-13 14:21:50 -08:00
Thomas Thachil
9f06747958
fix(): deeplink for android wc (#7573) 2023-11-13 16:46:15 -05:00
Kristie Huang
c6b44bb5c9
fix: use NativeCurrency for polygon matic (#7567)
* fix: use NativeCurrency for polygon matic

* add comment

* update snapshots??

* Revert "update snapshots??"

This reverts commit 280758be118610cc9e13afcd6e420985e8a200d2.
2023-11-13 16:11:33 -05:00
Zach Pomerantz
1d64d24d31
fix: update function tests for 404ing collections (#7575) 2023-11-13 15:39:51 -05:00
cartcrom
d8e43f0834
fix: broken pools test (#7562) 2023-11-09 19:57:01 -05:00
cartcrom
82f27186cf
test: update hardhat blocknumber (#7559)
* init

* fix: remove console log

* fix: add comment
2023-11-09 18:43:10 -05:00
Kristie Huang
876d3a1cc3
feat: [info] add new tdp nav (#7531)
* feat: [info] add new tdp nav

* tidy up code

* pr review

* nit remove unused component style

* pr review

* lol extraneous extra
2023-11-09 14:51:23 -05:00
Nate Wienert
712f82cb1a
chore: align eslint version with wallet repo (#7526) 2023-11-09 08:11:13 -10:00
Tina
682215a574
feat: use useUSDPrice hook for calculating token usd value for auto slippage (#7555) 2023-11-09 13:08:54 -05:00
Kristie Huang
395b390df6
feat: add android announcement banner (#7551)
* feat [wip]: add android announcement banner

* feat: [wip] add android announcement banner

* finish css

* remove hideBaseWallet references

* phil changes

* minor lint nit

* pr review

* growth copy
2023-11-08 16:18:16 -05:00
Tina
cee3390b71
fix: skip all quote / pricing requests if window is not visible (#7554)
* skip all quote / pricing requests if window is not visible

* add unit tests

* add ts-ignore comment
2023-11-08 15:14:50 -05:00
Jack Short
418ee08b00
chore: adds e2e test for when usd quote fetch fails (#7215)
* chore: adds e2e test for when usd quote fetch fails

* Update src/components/CurrencyInputPanel/SwapCurrencyInputPanel.tsx

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Update cypress/e2e/swap/errors.test.ts

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-11-08 13:27:10 -05:00
Charles Bachmeier
ebfcd8fbbe
refactor: move pool details components to the components folder (#7553)
* refactor: move pool details components to the components folder

* cleanup index imports

* update snapshot
2023-11-08 10:24:59 -08:00
Jack Short
c27e70b87c
chore: e2e insufficient liquidity test (#7075)
* chore: e2e insufficient liquidity test

* Update cypress/e2e/swap/errors.test.ts

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* fixing lint

* waiting for quote

* stubbing insufficient liquidity response

* req reply

* trying full url

* maybe cors

* moving before visit

* adding back timeout

* Revert "adding back timeout"

This reverts commit 89cff3afb815f5e5db005347f20812b83e047057.

* in describe block

* moving to new file

* moving to errors test file

* moving comment

* removing extra describe

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-11-08 13:11:41 -05:00
Jack Short
b4f3555600
chore: add appropriate padding and update chain selector to styled (#7549)
* chore: add appropriate padding and update chain selector to styled

* light gray on hover remove

* Update src/components/NavBar/ChainSelector.tsx

Co-authored-by: Charles Bachmeier <charles@bachmeier.io>

---------

Co-authored-by: Charles Bachmeier <charles@bachmeier.io>
2023-11-08 12:31:45 -05:00
Jack Short
0e87c38548
chore: disabling exact output for fot tokens (#7550)
* chore: disabling exact output for fot tokens

* fixing currency symbol
2023-11-08 12:28:23 -05:00
Charles Bachmeier
245d0eed06
fix: hide invalid nft collections with 0 items from search bar (#7547)
fix: hide invalid collecitons with 0 items
2023-11-08 12:21:14 -05:00
Kristie Huang
46c8caa09c
feat: update app download tracking for Android launch (#7542)
* feat: change UniwalletModal android text

* very wip android WC

* adding android/ios disambiguated event names

* put analytics events in todos

* use analytics package

* use isAndroidGALaunched

* fix ternary

* add navbar menu element

* broken onelink changes

* replace utm with onelinks

* use microsite link in address redirect

* fix unit tests, no longer discriminate between platforms expected behavior

* nit lint
2023-11-07 17:24:44 -05:00
Jack Short
aa056adaf9
chore: removing check mark on token selector (#7533) 2023-11-07 15:20:49 -05:00
Charles Bachmeier
ce4df4f79e
fix: add chainId to dependency array (#7548)
fix: add chain to dependency array
2023-11-07 09:58:25 -08:00
Kristie Huang
769a7ab9b5
fix: rename WrappedTokenInfo class (#7495)
* fix: rename WrappedTokenInfo class

* delete old wrappedTokenInfo file

* rename to TokenFromList

* move back to state/lists

* appease linter

* fix nftlistrow
2023-11-06 16:15:41 -05:00
Kristie Huang
5cbc56cf65
feat: [info] add new stats box (#7522)
* feat: [info] add new stats section, wip

* add stats section

* implement fdv and market cap

* use fdv from backend gql

* code cleanup

* update cypress tests

* should only wrap if screen width <= 640

* minor design nits

* remove sitemap change

* nit pr review
2023-11-06 15:54:43 -05:00
eddie
098c7b9cbe
fix: update uniwallet wc link (#7450)
* fix: update uniwallet wc link

* fix: undo url change for redirect
2023-11-06 12:22:03 -08:00
Jack Short
a0d880cf81
fix: spam tokens showing up in currency selector (#7545)
* fix: spam tokens showing up in currency selector

* chain id check

* token chain id
2023-11-06 14:40:36 -05:00
Kristie Huang
443a00a777
fix: remove version check in redux lists update + migrate outdated USDC saved tokens (#7544)
* fix: remove version check lists update

* add migration and test

* pr review
2023-11-06 14:20:55 -05:00
Jack Short
9eaa22f644
chore: converting useStablecoinPrice to useUsdPrice in autoslippage (#7543) 2023-11-03 12:51:04 -04:00
Nate Wienert
1c92482855
fix: basel font using wrong variation settings (#7536)
* fix: basel font using wrong variation settings
2023-11-02 11:05:13 -10:00
Nate Wienert
274d79dfde
chore: align uniswap deps with wallet repo (#7527)
* chore: align uniswap deps with wallet repo
2023-11-02 11:02:09 -10:00
Charles Bachmeier
c2ca9ab93e
feat: [info] update token links (#7505)
* update pdp link styles

* dynamic link text

* move links to their own file

* border width case

* todo comments

* add explorer icon

* hide chain logos on other chain

* remove quotes

* clean up

* unused style
2023-11-02 13:53:18 -07:00
Tina
0fbc826581
feat: Remove logging whole error object for analytics (#7540) 2023-11-02 16:32:12 -04:00
Charles Bachmeier
e9f784b2bc
refactor: clean up getExplorerLink helper fn (#7537) 2023-11-02 09:11:13 -07:00
Charles Bachmeier
f9a9469523
feat: [info] Add token description to TDP (#7504)
* update token description for TDP

* add tooltip to fee

* show buy/sell fees

* remove token description from PDP

* remove unused styles

* update snapshots

* undo fee component testing

* isInfoTDPEnabled

* update explorer fn
2023-11-02 08:32:58 -07:00
Jack Short
b995f4d671
fix: fixing ugly scrollbar (#7535) 2023-11-01 14:27:07 -04:00
Kristie Huang
3f62bcf2f0
feat: add Android feature flag & change some app logos (#7524)
* fix: generalize iOS language to app, and add color app icon

* remove apple logo

* delete more apple logos

* remove learn more arrow

* update snapshots

* add feature flags to android changes
2023-11-01 14:25:15 -04:00
Jack Short
bd30721989
chore: updating nft numbers (#7351)
* format price impact

* format price

* adding confirm swap modal

* removing export

* adding export back

* half of test functions done

* format numbers tests

* formatting

* making numberFormat local

* making formatCurrencyAmount internal

* price impact

* formatSlippage

* formatTickPrice

* formatNumberOrString

* formatFiatPrice

* removing formatPreciseFloat

* formatReviewSwapCurrencyAmount

* correct active currency

* explore table

* deleting formatTickPrice

* fixing explore table

* nft assset details

* removing all instancees of ethnumberstandardformatter

* removing format wei impls

* explore table

* collectino stats

* removing almost everything from nft/numbers

* filter button

* final nft fixes

* removing put commas

* explore page

* listing page

* extraneous functions

* responding to comments

* formatEhter

* updating formatter names

* dep array

* comments

---------

Co-authored-by: John Short <john.short@CORN-Jack-899.local>
2023-11-01 12:44:45 -04:00
Jack Short
802d56231a
fix: updating currency search panel for number formatting (#7407) 2023-10-31 16:46:02 -04:00
Kristie Huang
9536df2ff1
fix: remove bridged USDC from quickselect (#7529)
* fix: remove bridged usdc from quickselect

* oops remove migrations logic

* update routing test
2023-10-31 16:26:44 -04:00
Jack Short
ff3ed31dd7
chore: cleaning up previous uk blocking functionality (#7489) 2023-10-31 13:45:26 -04:00
Jack Short
719f82c7c4
feat: pool page currency conversion (#7416) 2023-10-31 13:44:38 -04:00
mr-uniswap
0937e35095
ci: removed snyk files (#7521)
removed snyk files
2023-10-31 13:36:24 -04:00
Matthew Spector
3f9b436c86
fix: Changing some language around fees (#7492)
* fix: Changing some language around fees

* adding chain name to toolti

* lowercase network

* fixing tests
2023-10-31 09:34:04 -07:00
Kristie Huang
40afc7388a
fix: add space to migrateV2 link (#7523) 2023-10-31 01:52:36 -04:00
mr-uniswap
eff6484a10
ci: basic semgrep configuration (#7520)
* basic semgrep configuration

* only main branch
2023-10-30 16:00:40 -04:00
Kristie Huang
635875345e
fix: add native USDC to Optimism quick-select (#7499)
* fix: add native USDC to Optimism quick-select

* fix jest test
2023-10-30 13:08:28 -04:00
Kristie Huang
b670affd4c
fix: add native USDC to Polygon quick-select (#7500)
* fix: add native USDC to Polygon quick-select

* remove usdce

* pr review
2023-10-30 11:35:45 -04:00
Charles Bachmeier
6798bf3cf1
feat: [info] add PDP loading skeleton (#7494)
* initial skeleton setup

* responsive table skeleton

* correct table widht

* right side column added

* add comments

* move loading components to their corresponding component

* remove extra bubble and adjust some styles

* move table skeleton to its own file

* add shared styles and skele file

* add loading skeleton tests

* design style nits

* update tests

* bips_base

* fix regression
2023-10-20 13:11:22 -07:00
Kristie Huang
8734ee5986
fix: dedupe matic native token (#7485)
* fix: dedupe matic native token, wip

* use precompile address

* prefill swap currency with page chain, not connected chain

* fix token-explore test
2023-10-20 14:13:58 -04:00
Charles Bachmeier
226fc441a7
refactor: allow missing input for useSwapTaxes (#7498) 2023-10-20 09:54:13 -07:00
eddie
36242d14b0
feat: add temporary logging to swap_signed (#7472) 2023-10-19 13:49:13 -07:00
eddie
b02352e8bf
fix: dont try to log unserializable objects (#7497)
* fix: dont log unserializable objects to amplitude

* fix: add more fields

* fix: nits

* fix: add chainid
2023-10-19 13:38:16 -07:00
Nate Wienert
819e2f5712
fix: fix contrast on l2 network text (#7466)
* fix: fix contrast on l2 network text
2023-10-19 13:05:26 -04:00
Jack Short
5357c58ac9
chore: removing german from supported languages (#7490)
* chore: removing german from supported languages

* updating tests

* Update src/utils/formatNumbers.test.ts

Co-authored-by: Charles Bachmeier <charles@bachmeier.io>

---------

Co-authored-by: Charles Bachmeier <charles@bachmeier.io>
2023-10-18 16:01:47 -04:00
Zach Pomerantz
aada666c1a
fix: de-flake Cypress through various means (#7488)
* build: reduce retries to discourage flakes

* fix: lazy-load asset logos

* chore: simplify logging test

* fix: guard against dutch orders for pricing

* test: only stub non-pricing quotes

* fix: opt in flicker

* test: mock statsig
2023-10-18 12:44:52 -07:00
cartcrom
86fc15907a
refactor: consolidate percent formatting util (#7467)
* refactor: consolidate percent formatting util

* refactor: use generic percent formatter

* fix: add descriptive comment for formatDelta
2023-10-18 14:34:37 -04:00
Kristie Huang
c5f2df4bc0
fix: update USDbC to default USDC on Base (#7377)
* fix: update usdbc to default usdc

* add base to chainid logo lookup

* remove nit

* replace dai with usdbc
2023-10-18 14:03:55 -04:00
ksvat
71d3661b22
fix: currency balance for search token (#7471) 2023-10-18 10:54:47 -07:00
eddie
740db0fe16
fix: merge portfolio tokens w/ default token list in Currency Selector (#7479) 2023-10-17 14:00:39 -07:00
Kristie Huang
ed6afb50de
feat: [info] add explore page (#7381)
* feat: add explore page

* add explore filter options

* add search bar defocus

* use Tokens Tab state for filters

* flag-gate /tokens

* filter bar css

* remove duplicate Explore page, use flag instead

* fixes

* create tabbednav interface

* rename Tokens to Explore

* simplify routing

* nit

* padding nit

* pr review

* fix menu flyouts

* fix TDP nav

* add analytics events + ui updates + pr review

* nit

* nit

* add small comment

* menu flyout nit

* fix merge conflict

* min width expand menu flyouts

* fix redirects

* update routing snapshot

* nit css

* oops

* breakpoints

* fix tab routing

* pr review

* add better tab dynamic routing

* fix redirects

* error handle edge urls

* further fix routing

* define return val for useExploreParams

* Update snapshot
2023-10-17 15:34:34 -04:00
eddie
9d439e7f62
feat: organize sitemaps (#7475) 2023-10-17 11:07:23 -07:00
charity-sock-pacifist
6b60855362
fix: learn more url [main] (#7483)
* fix: learn more url

* fix: snapshots

---------

Co-authored-by: charity-sock-pacifist <interface-github@example.com>
2023-10-17 13:58:16 -04:00
dependabot[bot]
53b53c2207
build(deps-dev): bump @uniswap/default-token-list from 11.2.0 to 11.8.0 (#7480)
Bumps [@uniswap/default-token-list](https://github.com/Uniswap/default-token-list) from 11.2.0 to 11.8.0.
- [Release notes](https://github.com/Uniswap/default-token-list/releases)
- [Commits](https://github.com/Uniswap/default-token-list/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-17 12:12:41 -04:00
charity-sock-pacifist
2818167131
feat: swap fees [main] (#7478) 2023-10-16 19:32:39 -04:00
eddie
c2440d1080
fix: use a different ipfs gateway (#7473) 2023-10-16 14:20:44 -07:00
eddie
f556f745fb
fix: remove sitemap step from ci (#7470) 2023-10-13 13:20:10 -07:00
cartcrom
7f597c0fab
refactor: use bips base constant (#7464)
* refactor: use bips base constant

* fix: missed usage
2023-10-13 16:15:28 -04:00
Tina
cfaf5d79c1
feat: Remove local routing setting (#7462)
* remove client side router preference

* update e2e test

* fix comment
2023-10-13 14:33:47 -04:00
eddie
e9fbf61375
fix: position X opt in tooltip on TDP (#7465) 2023-10-13 10:20:10 -07:00
eddie
749c9b40ea
fix: specify canonical URLs (#7455)
* fix: app.uniswap.org canonicals

* fix: deps test

* fix: use window.location.origin
2023-10-13 09:27:15 -07:00
eddie
b553a6fcd8
feat: nfts sitemap (#7456)
* feat: add nft collections to sitemap

* feat: size check on sitemap

* fix: update generate-sitemap script
2023-10-13 09:17:57 -07:00
eddie
ad1e2c60a1
fix: delay setting user.router_preference until statsig and redux initialize (#7458) 2023-10-12 15:42:57 -07:00
eddie
7001452f89
fix: move user prop updater into statsigProvider (#7442) 2023-10-12 11:30:02 -07:00
eddie
5fee3c6fdd
fix: sitemap format (#7453) 2023-10-11 15:23:15 -07:00
eddie
40b1e40721
fix: remove bridge usdc arbitrum (#7446) 2023-10-11 12:16:15 -07:00
eddie
aee4df10a8
fix: change default tx deadline to 10m (#7451)
* fix: change deadline to 10m

* test: add unit tests

* fix: improve unit tests
2023-10-11 12:15:51 -07:00
Charles Bachmeier
82a194987a
feat: [info] Add Token Description Component (#7400)
* working token details section

* update decription styling

* different chain explorers

* remove wrap check for color extraction

* move token description to its own component, add copy, make simple project query

* rename styled components and add tests

* remove old comment

* await test fragment

* fix: update description truncation from TokenDescription (#7413)

* fix: update description truncation from TokenDescription

* fix: use better name

* fix: test if description is hidden or not (#7422)

---------

Co-authored-by: Charles Bachmeier <charles@bachmeier.io>

* make darker or lighter

* showCopy default false

* update test

* remove unused styles

---------

Co-authored-by: eddie <66155195+just-toby@users.noreply.github.com>
2023-10-11 10:32:33 -07:00
eddie
1882b14690
fix: hide slippage warning when trade is x (#7439) 2023-10-11 10:21:43 -07:00
gnewfield
d56030a920
feat: add progress_indicator_v2 flag (#7445)
* feat: add progress_indicator_v2 flag

* rename flag hook
2023-10-11 12:53:10 -04:00
Kristie Huang
b75438bc8b
fix: fix sitemaps routes test (#7441)
* fix: fix sitemaps routes test

* avoid checking all top-tokens paths
2023-10-11 12:53:01 -04:00
Thomas Thachil
9f44e48cf1
chore(): update deeplink package names (#7399) 2023-10-11 12:17:45 -04:00
cartcrom
48855f487f
feat: animated review expando (#7440)
* feat: animated review expando

* test: update snapshots

* fix: pr comments + spacing
2023-10-11 09:23:28 -04:00
eddie
f09ded1a3f
fix: user prop updater staging (#7443)
fix: move user prop updater into statsigProvider
2023-10-10 15:51:26 -07:00
cartcrom
e16348e2e0
feat: new chain logos (#7438)
* feat: new consolidated chain logos

* test: update snapshots

* refactor: simplify border radius formula

* fix: pass style prop to portofolio logo container

* lint

* fix: accessibility

* fix: pr nits'

* fix: unnused styled component
2023-10-10 18:25:50 -04:00
Kristie Huang
45c3e1dc78
feat: add dynamicconfig modal setting (#7395)
* feat: add dynamicconfig feature flags setting

* better typing

* use diff atom for configs

* fix

* add config to devflagsbox

* fix devbox intiailization

* lint
2023-10-10 15:37:47 -04:00
Charles Bachmeier
24ddace1eb
feat: [info] update color extract default and have PDP fallback (#7432)
* feat: [info] update color extract default and have a fallback

* uncomment section removed for testing

* update snapshot
2023-10-10 12:24:57 -07:00
eddie
b38ce038e6
feat: remove sitemap script from prepare step (#7437) 2023-10-10 10:41:08 -07:00
Charles Bachmeier
04bf075826
fix: broken Checkmark image for Mobile NFT Sort dropdown (#7401)
fix broken image
2023-10-10 10:02:21 -07:00
eddie
27ec2e018c
feat: add robots.txt (#7435) 2023-10-06 17:09:04 -07:00
eddie
3ffe7693cf
feat: add top token urls to sitemap and improve script (#7429)
* feat: add top token urls to sitemap and improve script

* fix: remove unnecessary header

* fix: test
2023-10-06 17:08:46 -07:00
Jack Short
2c7381ff47
fix: removing scrollbar on swap with banner (#7434) 2023-10-06 15:33:04 -04:00
Jack Short
6e4746a7fe
feat: uk disclaimer banner (#7428)
* feat: uk disclaimer banner

* bad merge with sitemap

* button

* cypress test

* intercept ordering

* comments

* sitemap was committed idk why

* font weights

* moving uk disclaimer

* removing trash
2023-10-06 14:00:07 -04:00
Kristie Huang
48379c66ce
feat: [info] remove balance summaries from TDP (#7430) 2023-10-06 13:07:29 -04:00
eddie
1b7f0d11fd
fix: override user pref in analytics (#7420) 2023-10-06 09:21:18 -07:00
Kristie Huang
db1d264ad3
fix: unhide native gas token from miniportfolio (#7374)
* fix: unhide native gas token from miniportfolio

* wip tests & gql types

* fix tests, default hide small balances

* pr review

* fix e2e hidden count
2023-10-06 12:11:44 -04:00
Connor McEwen
fd24cb890a
fix: meta tag injector uses property, not name (#7431) 2023-10-06 11:46:39 -04:00
cartcrom
932c4482d2
feat: updated rate/routing tooltips (#7412)
* feat: updated routing tooltips

* refactor: gas price formatting

* fit: boolean rendering
2023-10-05 17:25:53 -04:00
Connor McEwen
2d8dac5c15
fix: merge issue (#7427)
* fix: merge issue

* update snapshots
2023-10-05 16:30:57 -04:00
Kristie Huang
0e3d188a9a
feat: add feature flags settings overrides box (#7406)
* add feature flags settings overrides box

* cat

* useGate hook monstrosity

* pr changes

* exclude devflagsbox from code cov

* pr review

* mobile bottom bar

* nit

* initialize atom

* fix atom initialization

* remove comments

* fix devbox initialization

* nit remove diff
2023-10-05 15:48:02 -04:00
cartcrom
1be62f0bec
feat: updated slippage ui (#7409)
* feat: updated slippage ui

* fix: update settings to also have period in max slippage string

* test: update e2e test search string
2023-10-05 15:34:23 -04:00
Connor McEwen
e6519a7dd1
feat: support redirects for a list of header paths (#7411)
* add country code to meta tag

* use blocked paths header

* proper types

* add test

* Update functions/components/metaTagInjector.ts

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Update functions/components/metaTagInjector.ts

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Update src/pages/App.tsx

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* pr suggestions

* skip failing e2e

* revert test change

* take file from main

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-10-05 15:25:45 -04:00
eddie
3ced65b8a4
feat: add sitemap for app.uniswap.org (#7408)
* feat: add sitemap for app.uniswap.org

* feat: script to update lastmod

* fix: deps and snapshots

* fix: use xml2js

* fix: improve test and sitemap
2023-10-05 12:19:58 -07:00
eddie
bab8506919
fix: dont crash on invalid tokenId (#7410) 2023-10-05 12:12:34 -07:00
eddie
4a79280edc
feat: allow manual test runs (#7415) 2023-10-05 12:12:21 -07:00
eddie
53f0ca9b7e
fix: disable UniswapX opt-out in e2e tests (#7423) 2023-10-05 11:54:24 -07:00
eddie
0381200fec
fix: ignore large slices in immutable check (#7425) 2023-10-05 11:40:52 -07:00
Matthew Spector
040ebb5475
fix: Remove Minus Sign for FOT Display (#7419) 2023-10-05 11:33:28 -07:00
Charles Bachmeier
0752314d87
fix: click on test row directly (#7424) 2023-10-05 11:08:39 -07:00
Charles Bachmeier
9db5fd104a
fix: use in house token for low volume test (#7414)
* fix: use discontinued project for low volume test

* use token I created

* update comment

* no info available

* remove socials

* update comment

* checksummed address
2023-10-04 18:18:57 -07:00
cartcrom
b9db195017
feat: gas costs ui updates (#7405)
* feat: gas costs ui updates

* lint

* test: update snapshots

* test: update other snapshots
2023-10-04 16:08:00 -04:00
eddie
b6bdbcf587
test: mock http requests in jest (#7394)
* test: try no coverage for unit tests

* test: onlychanged

* test: try parallel

* fix: no http in unit tests

* fix: deduplicate

* fix: nock only

* fix: maxworkers 2

* fix: remove nock

* fix: restore nock

* fix: comment

* fix: try again with jest-offline

* fix: remove jest-offline

* test: try 2 again

* fix: 100%
2023-10-03 14:37:27 -07:00
eddie
cc325b2fbe
fix: no stale trade when otherCurrency is missing (#7403) 2023-10-03 14:33:48 -07:00
Jack Short
2694379c97
chore: currency percentages (#7358)
* formatPercent

* hook deps

* price chart

* price chart formatting

* bug bash findings

* Update src/utils/formatNumbers.ts

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* fixing merge errors

* unit tests

* special cases

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-10-03 13:29:36 -07:00
cartcrom
82aaf0784a
refactor: swap line items and tooltips decomposition (#7390)
* refactor: swap line items and tooltips decomposition

* test: test line items directly

* refactor: added tooltip prop

* refactor: preview trade logic

* fix: percentage color

* lint

* fix: exchange rate alignment

* fix: initial pr comments

* test: fix snapshots

* refactor: var naming

* fix: uneeded dep array var

* refactor: small nit
2023-10-03 15:22:07 -04:00
Jordan Frankfurt
55a509cad8
chore: update @web3-react/* (#7398)
* chore: update @web3-react/walletconnect-v2

* update remaining packages and their patches
2023-10-03 13:46:02 -05:00
Tina
463dd6fdfb
feat: Move UniswapX signature expiry back to deadline (#7402)
startTime -> deadline
2023-10-03 14:29:03 -04:00
Kristie Huang
3ad4fb6846
feat: change address screening service to Uniswap /screen API (#7339)
* change fetch url to uniswap api

* clean code + write tests

* nit updates

* nit-rename test

---------

Co-authored-by: Kristie Huang <kristie.huang@uniswap.org>
2023-10-02 13:04:30 -04:00
gnewfield
1c76277c46
feat: polish blocked, nonexistent NFT collection page (#7373)
* add pages for nonexistent and blocked NFT collections

* add padding

* fix themed text import

* update design and revise based on pr comments
2023-10-02 13:02:28 -04:00
Charles Bachmeier
f90f81b3d9
feat: add error message to wallet connect fail event (#7387) 2023-10-02 09:56:35 -07:00
Charles Bachmeier
81accd1864
feat: [info] Add Liquidity and Swap buttons on PDP (#7382)
* feat: setup initial pool details page and route

* add pool data query and call on enw page

* make query dynamic to url chainId

* Get and display Header info

* add token symbols

* split header into its own file

* add helper function to not default to eth chain

* add helper function tests

* add header component tests

* add mocked test for PDP

* use valid values

* allow unsupported BE chains supported by thegraph

* typecheck

* remove useless row

* no longer needed child

* use first and last child

* move mock consts to their own file

* skele linear task

* return null

* descriptiive pool not found bool

* modify correct logo container

* update snapshots

* instantiate all chain apollo clients

* added snapshot test

* merge main and update snapshots

* Update src/pages/PoolDetails/PoolDetailsHeader.tsx

Co-authored-by: Nate Wienert <natewienert@gmail.com>

* type feeTier

* setup init stats component

* correctly query pool data for t24, t48, and tWeek timestamps

* add comments

* sanitize pool data and update tests

* correct test data

* add todo

* lint

* show correct data

* remove logs

* use formatter

* showing colored bars

* styled graph

* get muted color

* refactor: move getColor to src

* refactor useColor to use getColor function

* remove consts

* refactor files

* 1st class var support courtesy of carter

* remove logging and adds comments

* mobile styling

* move Stats to its own file

* add test cases

* add test file

* update padding

* remove old test file

* respond to feedback

* right column wrapper

* add non-functional pdp buttons

* update tests

* add button functionality

* working tokenId for position

* split buttons in their own file

* add tests

* reduce screenshots

---------

Co-authored-by: Nate Wienert <natewienert@gmail.com>
2023-10-02 09:56:17 -07:00
eddie
524ce49fcb
feat: dynamic defaultCurrencyCode for moonpay (#7383) 2023-10-02 09:48:55 -07:00
Kristie Huang
cbec108172
feat: add chains dynamicconfig for feature flags (#7389)
* feat: add feature flags dynamic config for chains

* fix

* add better chainid error checking

* quiet linter

* refactor & should be quick_route_chains only
2023-09-29 14:53:01 -04:00
eddie
3a4dc91e49
fix: wrap/unwrap activity parsing (#7384)
* fix: add unit test

* fix: re-use swap parse logic
2023-09-29 10:26:09 -07:00
Jack Short
af80079957
feat: remove buy button and landing terminology for uk (#7386)
* feat: remove buy button and landing terminology for uk

* removing tarballs

* mocked setup

* setting compliance to gb

* turning back on defaults

* cache for user

* moving to hook and grid sizing

* fixing tests

* comments

* landinage page cards

* cypress test

* removing extra store
2023-09-29 12:32:05 -04:00
Tina
c7a8e9e5a7
feat: Quick routes (#7348)
* wip, added PreviewTrade and now amending request arg type

* updates

* update logic to progress to swap review screen

* add token tax info to preview trades

* add loading component

* add feature flag and fix analytics and perf stuff

* update debounce amount

* add latencyMs measure

* change types

* add inline comments

* actually pass in feature flags

* dep array

* fix snapshot and unit tests

* fix unit tests

* update font color for loading text

* remove all chains feature flag

* remove from feature flag modal

* dont flicker review modal when allowance is loading

* remove comment

* add snapshot tests

* triple equals

* add comment

* change cast
2023-09-29 12:20:10 -04:00
eddie
e6362212c6
feat: uniswapx deadline (#7376)
* feat: uniswapX time-to-sign

* fix: animation timing

* fix: bug

* fix: improve props and remove memo
2023-09-28 10:52:35 -07:00
Charles Bachmeier
d63bdf1887
feat: [info] Add Stats Section to PDP (#7353)
* feat: setup initial pool details page and route

* add pool data query and call on enw page

* make query dynamic to url chainId

* Get and display Header info

* add token symbols

* split header into its own file

* add helper function to not default to eth chain

* add helper function tests

* add header component tests

* add mocked test for PDP

* use valid values

* allow unsupported BE chains supported by thegraph

* typecheck

* remove useless row

* no longer needed child

* use first and last child

* move mock consts to their own file

* skele linear task

* return null

* descriptiive pool not found bool

* modify correct logo container

* update snapshots

* instantiate all chain apollo clients

* added snapshot test

* merge main and update snapshots

* Update src/pages/PoolDetails/PoolDetailsHeader.tsx

Co-authored-by: Nate Wienert <natewienert@gmail.com>

* type feeTier

* setup init stats component

* correctly query pool data for t24, t48, and tWeek timestamps

* add comments

* sanitize pool data and update tests

* correct test data

* add todo

* lint

* show correct data

* remove logs

* use formatter

* showing colored bars

* styled graph

* get muted color

* refactor: move getColor to src

* refactor useColor to use getColor function

* remove consts

* refactor files

* 1st class var support courtesy of carter

* remove logging and adds comments

* mobile styling

* move Stats to its own file

* add test cases

* add test file

* update padding

* remove old test file

* respond to feedback

* right column wrapper

* update tests

---------

Co-authored-by: Nate Wienert <natewienert@gmail.com>
2023-09-28 09:27:29 -07:00
eddie
3bb55c6b5d
fix: hide price when no amount input (#7379)
* fix: hide price when no amount input

* fix: snapshots
2023-09-27 10:47:16 -07:00
Kristie Huang
71212f7e32
fix: use sentence case for text (#7375) 2023-09-27 12:46:09 -04:00
eddie
731ff4a485
feat: user property git commit hash (#7378) 2023-09-26 13:37:08 -07:00
eddie
519ba8963a
test: unit tests for parseRemote (#7359) 2023-09-26 13:36:56 -07:00
Jack Short
ec784ccb36
chore: updating input currency panel to handle comma separator (#7336) 2023-09-26 12:33:15 -05:00
Brendan Wong
20d8404717
fix: update polygon branding (#7190)
* update polygon branding

* Update matic-token-icon.svg
2023-09-25 12:11:12 -04:00
Jordan Frankfurt
809841df0a
feat: new app provider w/ fallback behavior (#7205)
* feat: new app provider w/ fallback behavior

* progress

* update useContractX signer params

* Revert "update useContractX signer params"

This reverts commit 386d1580dff77338810a4b31be38efd039d4b138.

* extend jsonrpcprovider

* add mainnet quicknode example, use old staticJsonRpc extension

* add tests

* unit testing

* fixes to tests/tsc

* Update src/state/routing/gas.ts

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* pr review

* e2e tests should only talk to the chain via connected wallet

* Revert "e2e tests should only talk to the chain via connected wallet"

This reverts commit 0ce76eb7e4132917a52b49531db871a189448e51.

* add charlie's null nit

* fix e2e

* add feature flag

* Update cypress/support/setupTests.ts

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* pr review

* pr feedback

* fix tests

* add generic send test

* fix merge error

* add a failure rate calculation and inline comments on scoring algo w/ an example

* fix sort test

* cleaner provider creation

* simplify sort

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-09-22 14:05:27 -05:00
Tina
2dc5a6efb4
fix: Remove e2e test (#7369)
* remove now untrue test

* add test about missing stats
2023-09-22 11:35:54 -07:00
eddie
7cd72a706d
feat: show usd price with no input amount (#7328)
* feat: show usd price with no input amount

* fix: snapshots

* fix: make tokens undefined only - no null

* fix: readability

* fix: syntax improvements
2023-09-22 10:31:23 -07:00
Kristie Huang
4f8956f79a
fix: should show slippage/deadline on LP flow settings (#7367)
* fix: should show slippage/deadline on LP flow settings

* write unit tests & update

---------

Co-authored-by: Kristie Huang <kristie.huang@uniswap.org>
2023-09-22 13:12:32 -04:00
Charles Bachmeier
beef7f2d86
feat: Condense color extraction logic and improve fallback (#7347)
* refactor: move getColor to src

* refactor useColor to use getColor function

* remove consts

* refactor files

* clean up color convert fn

* move getColor test and import test images

* hardcode array buffers for images

* add invalid png
2023-09-22 10:09:05 -07:00
Zach Pomerantz
b667662b49
fix: lazy load nft profile (#7361) 2023-09-22 10:08:22 -07:00
Zach Pomerantz
ed87df6269
feat: account suspense (#7337)
* feat: eagerly connect outside of react lifecycle

* test: reflect selected wallet in localStorage

* test: spy only on portfolio balances

* feat: connectionReady

* feat: connecting state

* feat: leave space for address

* fix tests

* better meta

* fix

* fix wallet change

* add interactivity earlier

* add validation

* update localstorage key in cypress setup

* even less thrash

* load per account

* simplify, hopefully

* explanatory

* inf render

* whoopsie

* ordering
2023-09-22 09:57:35 -07:00
Charles Bachmeier
622c72d4a8
feat: [info] Migrate Historical Pool Data Queries (#7310)
* correctly query pool data for t24, t48, and tWeek timestamps

* add comments

* sanitize pool data and update tests

* correct test data

* add todo

* lint

* remove logs

* 1st class var support courtesy of carter

* remove logging and adds comments
2023-09-22 09:47:25 -07:00
eddie
df6c44d2c4
fix: use Date as a performance tracker fallback (#7349) 2023-09-22 09:40:25 -07:00
eddie
59e7a2867a
fix: ui fixes on the add liquidity flow (#7352) 2023-09-22 09:40:10 -07:00
eddie
0a31428d7a
feat: uniswapX opt-out update (#7368) 2023-09-22 09:38:47 -07:00
Zach Pomerantz
fbc7e64032
chore: prohibit barrels (#7362)
* chore: prohibit barrels

* lint

* lint

* more lint

* add motivation to eslint message
2023-09-21 19:38:17 -07:00
eddie
4a8fb760d2
fix: show common bases on mobile (#7365)
* fix: show common bases on mobile

* test: add unit tests
2023-09-21 13:26:59 -07:00
eddie
15c510b742
fix: reset LDO approvals (#7345)
* fix: reset LDO approvals

* fix: constant file, better name

* Update src/components/swap/constants.ts

Co-authored-by: Charles Bachmeier <charles@bachmeier.io>

---------

Co-authored-by: Charles Bachmeier <charles@bachmeier.io>
2023-09-21 13:03:25 -07:00
eddie
e81b0a4d1f
test: unit tests for activity tab createGroups, and update cloud test snapshots (#7364)
* test: unit tests for activity tab createGroups

* fix: update cloud test snapshots
2023-09-21 12:03:10 -07:00
Zach Pomerantz
b9fc65ec9a
feat: lazy-load safe only if iframed (#7360) 2023-09-21 11:31:38 -07:00
Zach Pomerantz
d73c368ee4
fix: defer popper style recalc until use (#7330) 2023-09-21 11:29:43 -07:00
Zach Pomerantz
5e1c430657
build: improve tree-shaking (#7325)
* build: improve tree-shaking

* dedup terser
2023-09-21 11:29:22 -07:00
eddie
d4f19e42f8
feat: log chain changed (#7350) 2023-09-20 14:58:28 -07:00
cartcrom
60593df077
refactor: price chart organization (#7304)
* refactor: implement chart model type

* refactor: move PriceChart component into charts folder

* refactor: relocate pricechart test file

* lint

* fix: pr comments

* fix: use formatter hook in price chart file
2023-09-20 15:58:41 -04:00
Nate Wienert
aeef2c2356
fix: Fix visual issues in Spore (#7240)
* feat: make meta theme-color adapt to new spore background colors

* fix: make glow behind swap modal use a blur strategy rather than box shadow for a more squared glow

* test: grainy bg

* fix: make pool liquidity add input focus border same as swap

* remove svg grain
2023-09-20 09:44:25 -10:00
Zach Pomerantz
54880d201a
feat: eagerly connect outside of react lifecycle (#7334)
* feat: eagerly connect outside of react lifecycle

* test: reflect selected wallet in localStorage

* test: spy only on portfolio balances
2023-09-20 12:31:54 -07:00
Zach Pomerantz
0f6581bf47
fix: preconnect (#7340) 2023-09-20 12:30:20 -07:00
Zach Pomerantz
37c3330897
fix: wait to fetch lists until rehydration (#7332) 2023-09-20 09:40:57 -07:00
Zach Pomerantz
7a981923f6
fix: do not re-init active locale (#7329) 2023-09-20 09:32:50 -07:00
Brendan Wong
9672c2db9a
fix: remove settings button from lp page (#7105)
remove settings button from lp page
2023-09-19 14:16:46 -07:00
Charles Bachmeier
13f57d8d73
feat: block dynamic link previews for blocked collections (#7344)
* feat: block link previews for blocked collections

* update collection test

* single invalid

* move blocklist to its own const file

* rename file to blocklist
2023-09-19 11:07:07 -07:00
Charles Bachmeier
43f4d0f1b0
chore: block requested collection (#7342) 2023-09-19 08:06:58 -07:00
Zach Pomerantz
19c83c92ab
test: spy only on portfolio balances (#7335) 2023-09-19 07:59:21 -07:00
Jack Short
91c2013522
chore: only exposing useFormatter (#7308) 2023-09-18 20:21:21 -04:00
eddie
cf09e80934
fix: fetch balances when opening token selector in LP page (#7321)
* fix: fetch balances when opening token selector in LP page

* fix: move PrefetchBalancesWrapper
2023-09-18 14:49:39 -07:00
Zach Pomerantz
ad9879b4f9
fix: avoid scrollTo on pageload (#7323) 2023-09-18 13:09:01 -07:00
Zach Pomerantz
c528c6169e
fix: block number memoization (#7331) 2023-09-18 13:08:51 -07:00
Zach Pomerantz
33c93b5ded
fix: spurious Swap re-renders (#7333) 2023-09-18 13:08:37 -07:00
Charles Bachmeier
5ba046f111
feat: remove overlay cutoff (#7322) 2023-09-18 11:59:01 -07:00
Callil Capuozzo
5414a7c7ef
fix: [Spore] polish search (#7297)
* Polish search bar styles

* fix hover state

* Change background to surface1

* update tests

* Update styles
2023-09-16 10:22:38 -04:00
Zach Pomerantz
22fd0cc7bb
build: fix sourcemap warnings (#7318) 2023-09-15 19:41:38 -07:00
Kristie Huang
784fbfe7b1
test: add remove-liquidity interface tests (#7309)
* fix: duplicate or single-token remove-liquidity routes should show error page

* use maxUint256 for nonexistent pool

* move tests back to rem-liq

* rename pooled token id

* nit: use uni address from sdk core

* nit: use maxuint256 from sdk core

* nit: use liqudityValue for doublecurrencylogo

---------

Co-authored-by: Kristie Huang <kristie.huang@uniswap.org>
2023-09-15 16:05:56 -04:00
Zach Pomerantz
f47d00be37
feat: lazy-load popups/modals/chrome (#7313)
* fix: synchronously load first page

* feat: lazy-load popups/modals/chrome
2023-09-15 12:40:19 -07:00
Tina
2eb145ab80
feat: Add intent to swap quote request (#7245)
add intent to swap quote
2023-09-15 15:30:22 -04:00
Zach Pomerantz
adaa7f1a0d
feat: lazy-load smart-order-router (#7317) 2023-09-15 12:24:00 -07:00
Zach Pomerantz
2506c95816
feat: lazy-load non-swap routes (#7315)
* feat: lazy-load non-swap routes

* retain swap nav location
2023-09-15 12:10:01 -07:00
Jack Short
6303293037
chore: updating all numbers in swap flow to be converted properly (#7301)
* format price impact

* format price

* adding confirm swap modal

* removing export

* adding export back

* correct active currency

* activeLocalCurrencyIsUSD

* fallback to usd if no conversion rate for previous
2023-09-15 14:42:30 -04:00
Matthew Spector
185cb52501
chore: Remove Hardcoded Uni Wallet Supported Chains List (#7320) 2023-09-15 11:04:32 -07:00
Zach Pomerantz
92cf5b42c0
fix: lazy-load web3-react libs (#7319) 2023-09-15 10:28:06 -07:00
Nicolas Brugneaux
ea45289460
feat: replace cMC02 by WBTC in the celo tokens (#7244) 2023-09-15 11:38:53 -05:00
Zach Pomerantz
7f81073037
fix: synchronously load first page (#7312) 2023-09-14 17:50:48 -07:00
eddie
ac9a6f0398
fix: v2 pool ui (#7316)
* fix: v2 pool ui

* fix: use one wrapper
2023-09-14 14:51:39 -07:00
eddie
172160deb5
feat: improved logging 9 12 (#7306)
* feat: add chain id and update name

* log metamask version

* fix: tests
2023-09-14 12:03:14 -07:00
Nate Wienert
7fc005024d
fix: ci added CODEOWNERS github format (#7285)
* fix: ci added CODEOWNERS github format

* Update .github/workflows/1-main-to-staging.yml

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-09-14 07:59:28 -10:00
Nate Wienert
05ba0e4a66
fix: make popups appear above drawer and near top conditionally only … (#7201)
* fix: make popups appear above drawer and near top conditionally only when drawer is open

* remove logic around top bar
2023-09-14 07:49:59 -10:00
Jordan Frankfurt
5c53d8237d
test: update cloud test snapshots (#7311)
fix: -u on cloud tests
2023-09-14 12:27:58 -05:00
cartcrom
6aaf0db78d
refactor: price chart utility functions (#7266)
* refactor: price chart utility functions

* fix: snapshot

* fix: combine useMemos

* fix: pr nits
2023-09-14 13:13:17 -04:00
eddie
1c3ce8fdb7
fix: remove GA code (#7303)
* feat: move ga events to amplitude

* fix: remove GA code
2023-09-12 13:23:49 -07:00
eddie
3e05db4b87
feat: check chain ID before all transactions (#7177)
* feat: check chain ID before all transactions

* fix: use WrongChainError

* fix: remove asyncs
2023-09-12 11:20:06 -07:00
eddie
a9b2179eab
feat: move ga events to amplitude (#7300)
* feat: move ga events to amplitude

* fix: add deets to add events
2023-09-12 10:28:12 -07:00
Callil Capuozzo
0fffff66dc
fix: [Spore] general polish items (#7302)
* Add polish notes

* Polish balances

* update gap in mini portfolio names
2023-09-11 19:37:31 -04:00
eddie
1316a45c7a
fix: zustand, migrate to createWithEqualityFn (#7220) 2023-09-11 16:06:36 -07:00
Charles Bachmeier
dcf7d29357
feat: [info] Initial Pool Details Page (#7250)
* feat: setup initial pool details page and route

* add pool data query and call on enw page

* make query dynamic to url chainId

* Get and display Header info

* add token symbols

* split header into its own file

* add helper function to not default to eth chain

* add helper function tests

* add header component tests

* add mocked test for PDP

* use valid values

* allow unsupported BE chains supported by thegraph

* typecheck

* remove useless row

* no longer needed child

* use first and last child

* move mock consts to their own file

* skele linear task

* return null

* descriptiive pool not found bool

* modify correct logo container

* update snapshots

* instantiate all chain apollo clients

* added snapshot test

* merge main and update snapshots

* Update src/pages/PoolDetails/PoolDetailsHeader.tsx

Co-authored-by: Nate Wienert <natewienert@gmail.com>

* type feeTier

---------

Co-authored-by: Nate Wienert <natewienert@gmail.com>
2023-09-11 14:48:16 -07:00
Jack Short
184d515e16
chore: formatter to use local currency price (#7273)
* chore: updating formatCurrencyAmount to handle multiple langs and currencies

* missed advanced swap details

* missed confirmed swap modal

* removing updating visual effects

* removing it from parseLocale

* chore: displaying local currency and language formatting

* making effects visible

* moving to hook

* useFormatCurrencyAmount

* moving it to useformatter hook

* exporting formatting locales

* missed one parsed remote

* initial passover of using conversion rate in formatting function

* moving hook to bottom of file

* moving to bottom

* moving to bottom

* fallback to usd

* refactors

* better fallback protection

* moving to function

* fixing typecheck
2023-09-11 14:42:48 -04:00
Jack Short
86e4dd5153
chore: updating formatCurrencyAmount to handle multiple langs and cur… (#7263)
* chore: updating formatCurrencyAmount to handle multiple langs and currencies

* missed advanced swap details

* missed confirmed swap modal

* removing updating visual effects

* removing it from parseLocale

* chore: displaying local currency and language formatting

* making effects visible

* moving to hook

* useFormatCurrencyAmount

* moving it to useformatter hook

* exporting formatting locales

* missed one parsed remote

* moving hook to bottom of file

* moving to bottom
2023-09-11 13:51:11 -04:00
cartcrom
e4d103b015
refactor: price chart timestamps (#7265)
* refactor: price chart timestamps

* fix: remove unnused file

* refactor: util file name

* fix: use correct var for axis

* refactor: use backup var instead of throwing error for timeMinute interval
2023-09-11 13:16:30 -04:00
eddie
f71c781530
fix: add tax amounts to swap quote received (#7299) 2023-09-11 10:15:02 -07:00
Jack Short
736e395cd7
chore: displaying local currency and language formatting (#7267)
* chore: displaying local currency and language formatting

* moving to hook

* moving it to useformatter hook

* moving hook to bottom of file
2023-09-11 13:13:49 -04:00
Jack Short
8021135879
chore: remove extra blocknumber from dep array (#7295) 2023-09-11 12:29:39 -04:00
Tina
acdeb402ec
feat: Log auto slippage setting for gas estimate failed event (#7231)
* log auto slippage setting for gas estimate failed

* add to dep array
2023-09-11 08:41:31 -07:00
eddie
84f5d8f94d
fix: only log swap success for swap txs (#7284) 2023-09-08 12:03:59 -07:00
cartcrom
bb28235bee
refactor: consolidate price delta components (#7268)
* refactor: move delta component out of price chart file

* refactor: remove PortfolioArrow

* refactor: search row arrow cell

* fix: svg prop + snapshots failing unit tests

* refactor: css nit
2023-09-08 14:58:39 -04:00
cartcrom
f69226c1d1
fix: use updated feature flag (#7278) 2023-09-08 14:42:03 -04:00
cartcrom
35ca1b974e
fix: remove sentry warnings for failed tax fetches (#7281) 2023-09-08 14:41:47 -04:00
Nate Wienert
fdb9d8a8c9
feat: redirect /address links to the wallet download landing page or app store (#7210) 2023-09-08 08:33:21 -10:00
Zach Pomerantz
16cefb9cdb
test: fix cloud tests (#7280) 2023-09-08 10:53:22 -07:00
Zach Pomerantz
63bf1c0ac8
feat: path-based routing (#7275) 2023-09-08 10:43:59 -07:00
Nate Wienert
44e3b87ae1
fix: CODEOWNERS to use GitHub syntax currently uses google (#7200)
* improve cypress test

* fix: CODEOWNERS uses Github syntax
2023-09-08 07:22:52 -10:00
eddie
a3fbab9163
feat: uniswapx start time buffer (#7279)
* wip

* feat: use startTimeBufferSecs from API response
2023-09-08 09:30:57 -07:00
cartcrom
1ac1002c37
fix: fot ui bug in swap details dropdown (#7277)
* init

* fix: completely hide tax rows while syncing

* test: use syncing = false for fot tests
2023-09-08 10:27:18 -04:00
eddie
08e0fb7f4b
fix: replace base rpc urls with public rpcs (#7259)
* fix: replace base rpc urls with public rpcs

* fix: designation of safe vs fallback

* fix: remove duplicate
2023-09-07 13:56:30 -07:00
eddie
24d62d9594
feat: uniswapX default feature flag (#7246)
* feat: uniswapX default feature flag

* fix: bad merge

* fix: toggle behavior and style issues

* fix: toggle behavior
2023-09-07 12:52:24 -07:00
cartcrom
28ea390863
fix: gate FOT UI (#7272)
* fix: gate FOT UI in swap component

* feat: help article
2023-09-07 14:18:04 -04:00
eddie
4ba0d8ffc0
test: unit tests for swapFlowLoggers (#7257) 2023-09-07 10:07:56 -07:00
Jordan Frankfurt
7306423192
fix: eliminate flake from account connect race condition (#7212)
* fix: reduce flake from race condition

* use interface instead of type for props

* closeMenu instead of closeModal with type

* simplify useCloseModal

* fix bug

* pr feedback

* remove unnecessary code

* fix button wrapper style

* remove ApplicationModal.WALLET

* update color for spore
2023-09-06 17:52:47 -05:00
Zach Pomerantz
147a9bcbb2
fix: move off deprecated gql fields (#7269) 2023-09-06 13:48:02 -07:00
Charles Bachmeier
652a8305c8
feat: add BNB support to Token Search and Explore (#7223) 2023-09-05 10:57:21 -07:00
Jack Short
80a77dd567
fix: typecheck failing on main (#7264) 2023-09-05 13:54:19 -04:00
Jack Short
5951d0c40c
feat: adding currency conversion hook to useUSDPrice (#7251)
* feat: adding currency conversion hook

* 5m cache policy

* conversion rate hook

* usd check in outer hook

* converting usd price to localcurrencyprice

* checking usd manually
2023-09-05 13:38:33 -04:00
Jack Short
60acc689ee
chore: updating numberFormat for other currencies and languages (#7239)
* adding currency settings option

* moving menu item to shared component

* adding supported currencies

* currency menu items

* currency url params

* currency selector e2e tests

* fixing tests

* currency icons

* removing eslint

* removing another eslint disable

* renaming to local currency

* more name changes

* design updates

* adding currencies

* changing formatter rules to formatter options

* renaming file

* fixing lint

* custom currency symbol in number formatting

* refactoring input to number formatter

* locale selection

* updating all format numbers with currency and locale

* updating portfolio

* better formatting symbols

* removing adding locale and currency

* upgrading constants to be translatable

* refactoring

* adding tests

* updating comment

* removing 0 from hardcoded input and comment
2023-09-05 12:59:43 -04:00
Charles Bachmeier
cd520a9e2c
refactor: add source to subgraph queries (#7253)
* feat: add source to subgraph queries

* update test
2023-09-05 08:44:57 -07:00
cartcrom
b6e388c68c
feat: dynamic FOT tax fetching (#7252)
* feat: disable exact_output FOT swaps

* fix: pr comments

* test: update snapshots

* feat: dynamically fetch tax rates

* remove tax constants file

* test: update useRoutingAPITrade expected args

* fix: useSwapTaxes nits

* lint: useSwapTaxes dependency array
2023-09-01 14:56:26 -04:00
cartcrom
45a138dec1
fix: detect refunds on exact_out native swaps (#7227)
* fix: detect refunds on exact_out native swaps

* fix: correct comment
2023-09-01 14:55:42 -04:00
cartcrom
26d2ab53e8
feat: disable exact_output FOT swaps (#7237)
* feat: disable exact_output FOT swaps

* fix: pr comments

* test: update snapshots
2023-09-01 14:23:21 -04:00
gnewfield
e50ecc8309
fix: un-nest translation on AddLiquidityV2 page (#7258)
fix nested translation components causing translation error
2023-09-01 13:05:49 -04:00
eddie
406d7fe964
feat: remove dead statsig flag (#7229)
* feat: remove dead statsig flag

* fix: e2e test
2023-08-30 13:08:18 -07:00
eddie
366f4d98ef
fix: remove unused feature flags (#7234)
* fix: remove unused feature flags

* fix: remove flag from tests

* fix: tests

* fix: remove useUniswapX param
2023-08-30 12:37:50 -07:00
Jack Short
4eda18a4d5
feat: currency selector (#7196)
* adding currency settings option

* moving menu item to shared component

* adding supported currencies

* currency menu items

* currency url params

* currency selector e2e tests

* fixing tests

* currency icons

* removing eslint

* removing another eslint disable

* renaming to local currency

* more name changes

* design updates

* renaming file

* fixing lint

* Update src/components/AccountDrawer/SettingsMenu.tsx

Co-authored-by: Charles Bachmeier <charles@bachmeier.io>

* alphabetical ordering currencies

* column padding

* padding only for mobile

* memoizing into switch

---------

Co-authored-by: Charles Bachmeier <charles@bachmeier.io>
2023-08-30 14:48:53 -04:00
eddie
ea66b8b959
fix: null check in lists code (#7248) 2023-08-30 11:41:40 -07:00
Charles Bachmeier
1eab4291f6
refactor: log NO_ROUTE found instead of paging (#7242)
* refactor: log no route found instead of paging

* typo

* log router preference

---------

Co-authored-by: Charles Bachmeier <charlie@genie.xyz>
2023-08-29 13:59:51 -07:00
eddie
bed144b994
fix: remove base goerli from chain selector (#7238)
* fix: remove base goerli from chain selector

* fix: remove all base goerli references

* fix: typecheck
2023-08-29 13:25:10 -07:00
Charles Bachmeier
dac334f975
feat: add info site migration feature flags (#7228)
* feat: add info site migration feature flags

* feat: feature flag modal improvements

* scrollbar padding

* button padding
2023-08-28 13:13:31 -07:00
Charles Bachmeier
5478cb0c7b
feat: useUSDPrice for nft eth usd price (#7232)
* feat: useStableCointValue for nft eth usd price

* add new file

* useUSDPrice

* rename
2023-08-28 09:09:30 -07:00
Nate Wienert
b47cebd40b
fix: Spore color fixes (#7233)
* fix: bridge chain popup line break

* fix: background initial gradient to match the default ETH bg for light and dark mode
2023-08-25 11:43:26 -10:00
Tina
bb51be545b
feat: Support UniswapX exact out trades (#7225)
* add feature flag for uniswapx exact out trades

* dont route PRICE lookups through uniswapx

* add e2e test
2023-08-25 15:00:22 -04:00
Charles Bachmeier
ce8105bf08
feat: track connected wallet provider calls to be replaced with BE/infura (#7197)
* feat: track connected wallet provider calls to be replaced with be/infura

* update analytics events

* wrap analytics events in useEffects

* Update src/hooks/useContract.ts

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

---------

Co-authored-by: Jordan Frankfurt <jordanwfrankfurt@gmail.com>
2023-08-25 09:51:56 -07:00
Nate Wienert
59db4c5b02
feat: Spore colors refresh (#7118)
* Add colors and type and fix everywhere

* fix text.tsx

* Color and text adjustments

* Further tweaks

* Removed promotional gradient

Changed to pink

* Add new icons and tweak broken colors

* Kill shadows

Removes shadows from NFT cards, Pools and Tokens tables

* Update icons

Update filled and info icons to filled versions

* Update bag icon

Changed to fill style

* Change share icon

Changed to the new filled arrow

* Fix merge errors

* update tests

* Complete find and replace old colors

* Fix colors on pool pages

* Update index.test.tsx.snap

* fix header hover states

* update test

* Update connect button hover state

* Update styles design bash

* Update tests

* Update fonts

* fix buy button font weight

* update tests

* fix jumping input boxes

* lint

* lints

* update tests

* redo auth header

* fix issues

* fix snapshots

* use individual weights instead of variable for nicer $ signn

* update tests

* make dark mode glow distinct

* remove commented out code

* icons in react

* update textSecondary

* fix feedback

* port over token test fix

* lint

* fix: make popups appear above drawer and near top conditionally only when drawer is open

* Revert "fix: make popups appear above drawer and near top conditionally only when drawer is open"

This reverts commit 994697144374ae3fc0cdf9275bce538fda5fc8de.

---------

Co-authored-by: Callil Capuozzo <callil.capuozzo@gmail.com>
Co-authored-by: pp-hh-ii-ll <111304124+pp-hh-ii-ll@users.noreply.github.com>
Co-authored-by: Callil Capuozzo <callil@uniswap.org>
2023-08-24 17:14:24 -10:00
Jack Short
1f6f1f1dbd
fix: smart contract wallets unsupported (#7226)
* fix: smart contract wallets unsupported

* logging to amp

* response was deleted
2023-08-24 16:56:07 -04:00
cartcrom
1c142bb71f
feat: workaround for FOT swaps (#7218)
* fix: workaround to include tax in slippage tolerance

* refactor: simplify tax line item components

* docs: update FOT comments

* fix: simplify tax calculation logic

* docs: update comment and add TODO

* fix: use postTaxAmountOut for price change calculation

* fix: use preTaxStablecoinPriceImpact for swab button warnings

* test: unit test for swap details/modal

* feat: add feature flag to gate FOT changes

* docs: add comment to postTaxOutputAmount getter

* fix: reword fee tooltip

* refactor: warning theme color variable usage

* fix: update snapshots

* fix: use preTaxStablecoinPriceImpact for price impact prompt logic

* lint: dependency array
2023-08-24 10:56:48 -04:00
eddie
3e67982bb4
fix: reset USDT logic (#7219) 2023-08-23 16:09:07 -07:00
Charles Bachmeier
bb79c73416
feat: add sentry monitoring for NO_ROUTE error (#7204)
feat: add sentry monitoring for no_route error
2023-08-23 14:59:26 -07:00
Jordan Frankfurt
b1da7d87f9
fix: proposal creation layout on safari (#7203)
* fix: proposal creation layout on safari

* add important to header margin
2023-08-23 16:06:24 -05:00
Jordan Frankfurt
a79324f23c
fix: repair broken link (#7198) 2023-08-23 16:06:09 -05:00
Jordan Frankfurt
9008db5166
fix: add v2 to lp importer link (#7199) 2023-08-23 15:58:09 -05:00
eddie
bcc57e4612
fix: null check on elapsedTime for some browsers (#7213) 2023-08-23 10:53:51 -07:00
eddie
8c7315760a
fix: make WrongChainError more specific (#7175)
* fix: setTraceError in swap callback

* fix: move error class to util file
2023-08-23 09:30:51 -07:00
Jordan Frankfurt
290083b414
fix: isolate assertions into single tests (#7209) 2023-08-22 16:34:29 -05:00
cartcrom
4bc778ff3e
feat: add client and router blocknumbers to analytics (#7170) 2023-08-22 16:03:23 -04:00
Jordan Frankfurt
49ae6ef6bd
fix: ensure lists are present before running update (#7206)
* fix: ensure lists are present before running update

* pr input from zzmp
2023-08-22 14:52:59 -05:00
Nate Wienert
3dab1da5ea
fix: cypress flaky token details test (#7193)
improve cypress test
2023-08-21 08:46:08 -10:00
Jack Short
6ec9bb7362
chore: moving conedison/provider to interface (#7119)
* chore: moving provider from coned to interface

* moving signing over to interface

* updating lockfile

* dedup

* use d3-array build for jest

* downgrading jest/types

* Revert "downgrading jest/types"

This reverts commit 88d3746c00dcd98275be18a4b8af0314ae4329ad.
2023-08-18 16:26:08 -04:00
Brendan Wong
31d0c3c9b3
fix: reorganize chain priority (#7189)
reorganize chain priority
2023-08-18 15:39:42 -04:00
Zach Pomerantz
88b7acf3ae
feat: use cache while debouncing quotes (#7188)
* feat: check cache before debouncing quote

* feat: use cached values if available

* fix: initial loading state

* fix: no transition to loading

* chore: return skipToken from args

* test: update snapshots

* fix: add back stale state
2023-08-18 12:36:24 -07:00
eddie
877e000da6
feat: swap quote event (#7174)
* wip: more metrics

* wip: SWAP_INPUT_FIRST_USED

* feat: track elapsed times

* feat: add e2e test

* fix: order of logging

* feat: swap quote request logging

* feat: e2e test

* feat: another property

* test: test events separately

* fix: dont log for price quotes
2023-08-18 11:47:45 -07:00
Jack Short
3f05a88409
chore: revert path based routing (#7192)
* Revert "feat: use router depending on the origin (#6982)"

This reverts commit c9b4016b78e597b824c98e4219867e0af301c755.

* updating tests

* fixing import from styled components

* fixing styled imports
2023-08-18 14:40:47 -04:00
Zach Pomerantz
03ab5c80a8
feat: prefetch eth price for swap currencies (#7187)
* feat: prefetch eth price for swap currencies

* chore: clarify namings
2023-08-18 10:47:14 -07:00
Jordan Frankfurt
4faaa60aea
chore: update web3-react (#7158)
* chore: update web3-react

yarn deduplicate

* catch .warn warnings
2023-08-18 11:31:50 -05:00
Zach Pomerantz
3a94a99293
fix: debouncing as a loading state (#7183)
fix: consider debouncing as loading state
2023-08-17 17:35:54 -07:00
Brendan Wong
e893bc2685
fix: make line height bigger for token preview (#7186)
* make line height bigger

* Update [[index]].tsx
2023-08-17 17:20:18 -04:00
Brendan Wong
cccf6ac680
fix: add assets to public folder (#7153)
* fix: add assets to public folder

* Update global-teardown.ts

* update assets

* resize logos
2023-08-17 16:15:17 -04:00
Jack Short
ea5af12b1d
chore: moving language selection to own settings panel (#7169)
* chore: moving language selection to own settings panel

* auto switch when close

* updating e2e

* clickable style

* moving behind feature flag

* fixing tests

* this looks nicer

* nowrap for overflow
2023-08-17 16:05:18 -04:00
eddie
bf1f613a4f
fix: network connector fix and lists fix (#7185) 2023-08-17 12:29:34 -07:00
Brendan Wong
49f1acb52a
fix: displays price when not updated on TDP (#7068)
* Update PriceChart.tsx

* simplify deltaarrow function

* update text coloring

* increase gap a bit more

* rename tags

* restyling of information

* fix import issue

* Update src/components/Tokens/TokenDetails/PriceChart.tsx

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

* unit testing!

---------

Co-authored-by: Jordan Frankfurt <jordanwfrankfurt@gmail.com>
2023-08-17 14:27:16 -04:00
Jordan Frankfurt
a97005e2e1
feat: dedupe on commit (#7171)
* feat: dedupe on commit

* run existing script
2023-08-17 12:58:35 -05:00
Brendan Wong
966b02b2de
fix: add distance check from white for token rich link previews (#7152)
* feat: lower white levels if too close

* testing and parameterization

* Update getColor.ts

* Update getColor.test.ts

* Update getColor.ts

* Update getColor.test.ts

* Update getColor.test.ts
2023-08-17 13:30:58 -04:00
eddie
024bbce9a4
feat: more swap metric logging (#7173)
* wip: more metrics

* wip: SWAP_INPUT_FIRST_USED

* feat: track elapsed times

* feat: add e2e test

* fix: order of logging

* fix: nits
2023-08-17 10:16:51 -07:00
Brendan Wong
c960c14170
fix: update default rich link preview image (#7176)
Update 1200x630_Rich_Link_Preview_Image.png
2023-08-17 12:05:52 -04:00
Zach Pomerantz
39295e9a33
feat: add real paths to app site association (#7179) 2023-08-17 09:05:10 -07:00
Brendan Wong
0feddebcc3
feat: add CodeCov to cloud tests (#7154)
* feat: add CodeCov to cloud tests

* Update codecov.yml

* Update codecov.yml

* get cov to 80%

* remove unneeded test
2023-08-17 11:30:56 -04:00
Thomas Thachil
5e4108fbdc
chore(): deeplink fingerprint update (#7181) 2023-08-17 10:30:25 -04:00
eddie
38cce46c7b
feat: redux migration (#6830)
* feat: start working on redux migrations

* feat: fix migations and add tests

* feat: fix persistence and improve tests

* fix: tests

* fix: rename test file so it doesnt run in jest

* fix: tests

* fix: lint

* feat: indexedDB

* fix: e2e tests

* fix: address some comments

* fix: update legacy migrations

* fix: fix rehydrations

* fix: remove PersistGate and fix e2e tests

* fix: add comment to helper function
2023-08-16 10:56:06 -07:00
Nate Wienert
69ae42f285
fix: broken spacing in tokens fixture (#7168) 2023-08-16 07:36:15 -10:00
cartcrom
ef9619b1bd
test: uniswapx e2e activity (#7137)
* test: e2e uniswapX toggle/opt-in tests

* fix: update visit to match new version of hardhat

* test: e2e gouda orders

* fix: remove swapping before allowance has loaded

* refactor: opt-in rather than toggle

* fix: test comment

* test: uniswapx activity

* fix: lint and small pending hook refactors

* test: e2e UniswapX orders (#7110)

* test: e2e gouda orders

* fix: remove swapping before allowance has loaded

* refactor: opt-in rather than toggle

* fix: test comment

* fix: PR nits
2023-08-15 15:02:24 -04:00
cartcrom
041f3d5ba2
test: e2e uniswapX toggle/opt-in and order tests (#7067)
* test: e2e uniswapX toggle/opt-in tests

* fix: update visit to match new version of hardhat

* test: e2e UniswapX orders (#7110)

* test: e2e gouda orders

* fix: remove swapping before allowance has loaded

* refactor: opt-in rather than toggle

* fix: test comment

* fix: PR nits
2023-08-15 14:50:08 -04:00
Charles Bachmeier
666bb79833
fix: test id based on address & chain instead of ticker (#7167)
* fix: test id based on address instead of ticker

* add chain to test id

* use token address

* lowercase
2023-08-15 11:22:20 -07:00
Charles Bachmeier
2736d94432
feat: Add base support to Explore & Search (#7165)
* filter search results

* feat: add full base TDP support

* add base to uni wallet supported chains
2023-08-15 10:12:33 -07:00
eddie
57b098f309
feat: swap quote latency logging (#7143)
* feat: swap quote latency

* feat: measure quote latency

* feat: swap quote latency

* fix: improve variable name
2023-08-14 14:20:03 -07:00
Tina
c802132bd5
feat: bump version of uniswapx-sdk for eth output trades (#7160)
bump ver
2023-08-14 17:08:31 -04:00
Nate Wienert
485764fe38
feat: improve logic around hidden section of mini-portfolio balances spam tokens (#6988) 2023-08-14 11:06:40 -10:00
Brendan Wong
51dc10b467
fix: remove flakey tests from cloud functions and overall deflake (#7156)
* fix: remove flakey tests

* increase setup time

* reduce max workers

* Update .github/workflows/test.yml

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Update functions/global-setup.ts

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Update global-teardown.ts

* add retry time

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-08-14 16:50:49 -04:00
Tina
7cf768b8dd
chore: feature flag cleanup for routing_api_price (#7159)
feature flag cleanup
2023-08-14 16:28:01 -04:00
eddie
59b5e81d16
feat: add chainId to SWAP_TRANSACTION_COMPLETED (#7094)
* feat: add chainId to swap_tx_completed

* feat: time_to_sign

* test: add tests for SignedTransactionTimestampRegistry

* fix: remove time_to_sign
2023-08-14 13:26:51 -07:00
Brendan Wong
8fc98abb1a
fix: margins for nav on mobile (#6908)
* fix margins for nav

* fix spacing on mobile

* Revert "fix spacing on mobile"

This reverts commit c87791669a826dd37f93ad219ad8e780e333b5b1.

* update css for minis
2023-08-14 15:27:39 -04:00
Tina
def4ab3bc0
feat: add time to sign analytics (#7140)
* add time to sign analytics

* move comment
2023-08-14 14:13:38 -04:00
Jack Short
bb6de9056b
fix: token margin in searchbar (#7155)
fix: token margin is searchbar
2023-08-14 13:59:45 -04:00
Tina
cc52da9fc4
fix: Remove double client side quoting (#7121)
* remove double client side quoting

* remove additional file

* remove file

* remove file

* MOVE YET ANOTHER FILE

* remove unused tokens

* fix export

* remove unused token constant and swap out for wbtc
2023-08-11 19:25:57 -04:00
Brendan Wong
b98e62cac8
fix: remove description from custom rich link previews (#7142)
* fix: remove description from custom rich link previews

* add static assets to prepare for prep

* remove added assets
2023-08-11 18:53:48 -04:00
Brendan Wong
6cd1f04584
fix: remove lowering opacity for token previews (#7145)
Update [[index]].tsx
2023-08-11 18:32:16 -04:00
cartcrom
8ffe4e991b
fix: properly display FOT swaps (#7146) 2023-08-11 18:19:28 -04:00
eddie
2b85852a48
fix: fail UR transaction if chain IDs don't match (#7150)
* fix: verify UR deployed

* fix: dont fallback to 1

* fix: dont instantiate contract

* fix: use chainId instead

* fix: compare chainIds
2023-08-11 18:15:35 -04:00
Nate Wienert
94015b279c
fix: fix jest breaking with new swc setting (#7149) 2023-08-11 13:53:48 -07:00
Jack Short
1291887049
chore: add to blocked nft infringing collections (#7125) 2023-08-11 14:53:10 -04:00
Nate Wienert
d4a26a5610
fix: make swc not break WalletConnect by targeting a newer version of es (#7139) 2023-08-11 07:57:55 -10:00
Jack Short
1249371397
feat: currency conversion feature flag (#7123)
* feat: currency conversion feature flag

* removing eslint
2023-08-11 13:13:17 -04:00
Brendan Wong
2ce7b08244
feat: custom colors for rich link previews (#7141)
* add custom color logic

* increase timeout
2023-08-11 12:27:46 -04:00
Tina
156254afa9
feat: Upgrade uniswapx-sdk for eth output (#7135)
upgrade sdk for eth output
2023-08-11 10:59:03 -04:00
Tina
e31f4e549b
feat: Fetch updated nonce before a UniswapX swap (#7120)
* add method to fetch updated gouda nonce

* remove console log
2023-08-11 10:33:07 -04:00
Brendan Wong
f47e1f16d7
fix: color extraction for rich link previews (#7138)
* feat: add token and nft injection

* feat: basic tests

* fix: get jest configured properly

* fix: change timeout

* fix: uninstall port ready

* fix: readd port ready

* fix: local tests work

* Update yarn.lock

* add lint disable for setup files

* fix: update dependencies

* fix: basic test suite for nfts/tokens

* feat: collection data

* fix: make tests more comprehensive

* fix: change matches to contains

* fix: tests for twitter alt image tag

* fix: image gen

* fix: add patch-package

* fix: update yarn install

* feat: basic image gen for nfts and collections

* fix: remove vibrant attempt

* use watermark asset

* dynamically grab color

* modularize code and prototype for token preview

* refactor code

* finalize css

* fix color grabber

* update tests

* fix up css

* refactor code a bit more

* remove console logs

* tests

* update tests

* update images based on design feedback

* network logos

* update lint

* slight refactoring

* more refactoring

* fix packages

* Update yarn.lock

* remove dynamically generated image stuff

* Revert "remove dynamically generated image stuff"

This reverts commit a80241edb3a970a724b9a07ce36e492ff8a1c2af.

* change image reference and revamp tests

* cleanup return values

* Create README.md

* Revert "Create README.md"

This reverts commit 7a91c98d384995fba914c9bf9a2fb3072793621f.

* First round of feedback

* comments

* feat: cache

* Update test.yml

* Update test.yml

* Update test.yml

* feedback round 2

* final feedback

* final final feedback

* add coverage and other options

* Update test.yml

* start typecheck

* update cache

* update snapshots?

* Update jest.config.json

* Update jest.config.json

* give timeout some buffer

* update import

* upgrade ts

* fix typing for apollo deps

* finalize typechecks

* downgrade typescript to original version

* add cache directory to jest

* remove coverage

* remove google analytics from tests

* merge main

* remove timeout

* update tests

* update graphql queries

* review changes

* try cache setup

* Update cache.test.ts

* make cache helper function

* cache test

* remove unneeded test causing issues

* feat: parallelize cache (#6930)

* feat: parallelize cache?

* remove graph query from concurrency await

* most of feedback

* move tests

* update token tests

* singleton cache

* restructuring res and cache promise

* abstract away repeated graph logic

* update tests and functions

* refactor

* update typing, parallelize, and start tests

* fix one tsc issue

* final feedback

* Update yarn.lock

* final final feedback

* add svgs

* try and setup svg

* stashing changes

* cleanup!

* prepare for start of feedback?

* LESS GOO

* modify versioning

* fix: update wrangler version

* Update yarn.lock

* downgrade wrangler

* Update yarn.lock

* Update yarn.lock

* fix type error

* update github test

* cleanup tests

* Delete custom.d.ts

* fix: cloudfunctions

* update tests

* final touchups

* lint

* change github action

* Update yarn.lock

* styling updates

* nate's feedback

* feedback p1

* typing feedback

* update yarn

* Create wrangler.toml

* move wrangler.toml location

* last try

* Delete wrangler.toml

* use 2.20?

* remove comment

* Update yarn.lock

* change compatibility date

* update wrangler and fix bugs

* Update colorthief+2.4.0.patch

* build: cleanup flags

* cleaner patches

* update compatibility date

* quick tweeks

* cleanup rendering and lint

* patch things up

* fix: color extraction

* DONE!

* tests and other qol updates

* lint

* add more tests

* feedback

* simplify getcolors

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-08-10 18:32:08 -04:00
Brendan Wong
9954f9502d
feat: dynamically generated images for rich link previews (#6902)
* feat: add token and nft injection

* feat: basic tests

* fix: get jest configured properly

* fix: change timeout

* fix: uninstall port ready

* fix: readd port ready

* fix: local tests work

* Update yarn.lock

* add lint disable for setup files

* fix: update dependencies

* fix: basic test suite for nfts/tokens

* feat: collection data

* fix: make tests more comprehensive

* fix: change matches to contains

* fix: tests for twitter alt image tag

* fix: image gen

* fix: add patch-package

* fix: update yarn install

* feat: basic image gen for nfts and collections

* fix: remove vibrant attempt

* use watermark asset

* dynamically grab color

* modularize code and prototype for token preview

* refactor code

* finalize css

* fix color grabber

* update tests

* fix up css

* refactor code a bit more

* remove console logs

* tests

* update tests

* update images based on design feedback

* network logos

* update lint

* slight refactoring

* more refactoring

* fix packages

* Update yarn.lock

* remove dynamically generated image stuff

* Revert "remove dynamically generated image stuff"

This reverts commit a80241edb3a970a724b9a07ce36e492ff8a1c2af.

* change image reference and revamp tests

* cleanup return values

* Create README.md

* Revert "Create README.md"

This reverts commit 7a91c98d384995fba914c9bf9a2fb3072793621f.

* First round of feedback

* comments

* feat: cache

* Update test.yml

* Update test.yml

* Update test.yml

* feedback round 2

* final feedback

* final final feedback

* add coverage and other options

* Update test.yml

* start typecheck

* update cache

* update snapshots?

* Update jest.config.json

* Update jest.config.json

* give timeout some buffer

* update import

* upgrade ts

* fix typing for apollo deps

* finalize typechecks

* downgrade typescript to original version

* add cache directory to jest

* remove coverage

* remove google analytics from tests

* merge main

* remove timeout

* update tests

* update graphql queries

* review changes

* try cache setup

* Update cache.test.ts

* make cache helper function

* cache test

* remove unneeded test causing issues

* feat: parallelize cache (#6930)

* feat: parallelize cache?

* remove graph query from concurrency await

* most of feedback

* move tests

* update token tests

* singleton cache

* restructuring res and cache promise

* abstract away repeated graph logic

* update tests and functions

* refactor

* update typing, parallelize, and start tests

* fix one tsc issue

* final feedback

* Update yarn.lock

* final final feedback

* add svgs

* try and setup svg

* stashing changes

* cleanup!

* prepare for start of feedback?

* LESS GOO

* modify versioning

* fix: update wrangler version

* Update yarn.lock

* downgrade wrangler

* Update yarn.lock

* Update yarn.lock

* fix type error

* update github test

* cleanup tests

* Delete custom.d.ts

* fix: cloudfunctions

* update tests

* final touchups

* lint

* change github action

* Update yarn.lock

* styling updates

* nate's feedback

* feedback p1

* typing feedback

* update yarn

* Create wrangler.toml

* move wrangler.toml location

* last try

* Delete wrangler.toml

* use 2.20?

* remove comment

* Update yarn.lock

* change compatibility date

* update wrangler and fix bugs

* Update colorthief+2.4.0.patch

* build: cleanup flags

* cleaner patches

* update compatibility date

* quick tweeks

* cleanup rendering and lint

* final color update

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-08-10 15:29:37 -04:00
eddie
9fbdc3cab1
feat: base flag cleanup (#7134)
feat: remove base feature flag
2023-08-10 11:05:48 -07:00
eddie
e04be0711f
fix: unknown token logo styling (#7132)
* fix: unknown token logo styling

* fix: tests
2023-08-10 11:05:32 -07:00
eddie
5c3caa7143
feat: query base backend (#7133) 2023-08-10 11:05:23 -07:00
Jack Short
1ea724609f
feat: bottom sheet for mobile swap settings (#7072)
* feat: bottom sheet for settings dialogue

* renaming to settings

* renmaing

* cypress tests

* fixing the cypress tests

* chore: e2e insufficient liquidity test

* Revert "chore: e2e insufficient liquidity test"

This reverts commit 8250730f35182246ec908b5878b91b55a51cb941.
2023-08-10 12:20:31 -04:00
Jordan Frankfurt
2b6948db94
fix: standardize styled component file names and ignore them in codecov (#7113)
* fix: standardize styled component file names and ignore them in codecov

* Update codecov.yml

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-08-10 11:15:33 -05:00
Jordan Frankfurt
0b8026e6fe
feat: add base promotional advert (#7124)
* feat: add base promotional advert

add mobile layout

tweak text container size

only show new banner on Base

fix import

update to new state structure

* Update src/components/Banner/BaseAnnouncementBanner/index.tsx

Co-authored-by: Charles Bachmeier <charles@bachmeier.io>

* pr feedback

---------

Co-authored-by: Charles Bachmeier <charles@bachmeier.io>
2023-08-10 11:03:21 -05:00
Brendan Wong
b14831be12
fix: downgrade wrangler (#7128)
* downgrade wrangler

* remove report

* comment and update test

* update comment
2023-08-09 20:20:02 -04:00
Charles Bachmeier
b12a61e2fb
feat: add multichain_ux flag (#7122)
* feat: add multichain_ux flag

* update flag text

* add new flag file
2023-08-09 16:47:38 -07:00
Jordan Frankfurt
6f6c9d7174
chore: remove e2e coverage from aggregate calculation in codecov (#7108)
* chore: remove e2e coverage from aggregate calculation in codecov

* pr feedback
2023-08-09 14:48:59 -05:00
Jordan Frankfurt
89c3ec7526
chore: reduce patch coverage requirement to 50% (#7109) 2023-08-09 14:40:48 -05:00
Charles Bachmeier
06c81d9304
feat: add amplitude logging for gas estimate failures (#7095)
* send gas estimate failure

* update event name

* update analytics events package

* add error and tx to analytics event
2023-08-09 12:28:52 -07:00
Thomas Thachil
15c59e8149
fix: fixing deeplinks json nesting (#7126) 2023-08-09 15:28:26 -04:00
Nate Wienert
f6b66c759a
fix: make loading indicator for pools nft card use a shine rather than spinner (#7071)
fix: make loading indicator for pools nft card use a shine rather than spinner and fill the full height
2023-08-09 08:14:08 -10:00
Jack Short
b1c99d4b37
chore: moving coned formatting to interface (#7114) 2023-08-09 14:01:37 -04:00
Thomas Thachil
add6df46e6
feat: adding more fingerprints for deeplink apps (#7107) 2023-08-09 11:49:10 -04:00
Zach Pomerantz
b2dfb29f51
build: simplify/fix test caching (#7084)
* build: rm unnecessary cache-on-main

* build: hardhat fan-in cache
2023-08-08 16:48:27 -07:00
Brendan Wong
097ef6a3df
feat: fallback metadata injection (#7070)
* feat: fallback metadata

* fix lint

* Update tsconfig.json

* feedback

* fix: cloudfunctions

* update test
2023-08-08 15:50:52 -04:00
Brendan Wong
984cf81911
fix: cleanup cloud function environment (#7085)
* cleanup!

* update comments

* fix: cloudfunctions
2023-08-08 15:21:30 -04:00
Zach Pomerantz
08501234a8
build: replace babel with swc (#7056)
* chore: refactor ms.macro to ms

* build: upgrade lingui@4

* chore: avoid styled-components/macro

* build: replace babel loader with swc

* build: upgrade vanilla-extract

* build: simplify e2e config

* build: migrate jest to swc

* build: dedup

* whoops

* fix: initial translations

* build: coverage

* build: ignore static extract warning

* build: rm old babel pkg

* test: rm e2e codecov

* build: fix swc cache

* cleanup

* fix visible t9ns

* cleanup

* cleanup setup

* crank it

* actual merge conflict resolution

* fix: restore locale initialization
2023-08-08 10:38:37 -07:00
Jordan Frankfurt
3afe7fe9f2
fix: add back correct fellback setter (#7102) 2023-08-08 12:37:57 -05:00
cartcrom
bd573724b9
fix: uniswapx review modal success display (#7097)
* fix: update swapConfirmed logic

* fix: success icon display
2023-08-08 10:15:32 -07:00
Zach Pomerantz
684258dc17
fix: keep a referentially stable connectors list (#7090) 2023-08-08 08:46:01 -07:00
Charles Bachmeier
a53e773e5d
refactor: shelve Details redesign for now (#7077)
* shelve Details redesign for now

* remove feature flag enum

* no longer used utils
2023-08-08 08:28:43 -07:00
cartcrom
5307d113a8
feat: eth output feature flag for uniswapx orders (#7078) 2023-08-08 11:23:46 -04:00
Nate Wienert
9e7d59f1fe
chore: fix typecheck error due to jest and cypress overlapping types (#7101) 2023-08-07 18:40:43 -07:00
Brendan Wong
2ccd228f23
fix: cloud tests broken by path based (#7100)
fix: cloudfunctions
2023-08-07 20:18:14 -04:00
Nate Wienert
a726f67453
fix: bring back flake retries for flaky test (only flakes ~33% of time) (#7063) 2023-08-07 14:14:41 -10:00
Mike Grabowski
c9b4016b78
feat: use router depending on the origin (#6982)
* feat: initial commit

* chore: whitelist vercel

* chore: fix e2e test

* chore: update all occurences of #

* chore: tweaks

* chore: remove todo

* chore: revert changes

* chore: bring back old tweet logic and fix nested URLs

* chore: fix merge

* improve check

* fix: cypress

* chore: fix tests

* chore: update snapshot

* chore: update readme

* address review

* satisfy eslint

* chore: fix ui issue

* fix: tests

* fix: e2e test
2023-08-07 15:01:45 -07:00
eddie
a7135c9ab1
fix: check chainId in findCancelTx (#7098)
* fix: check chainId in findCancelTx

* fix: add comment explaining fix

---------

Co-authored-by: cartcrom <cartergcromer@gmail.com>
2023-08-07 13:58:33 -07:00
Jordan Frankfurt
a1b3776686
feat: vertical LP (#7000)
* Re-organize add liquidity page

* fix title alignment

* Update styles

* Update logic for disable/enable input on creation

* lint and clean up a couple small things

* lint and clean up a couple small things

* Tweak UI

* clean up code

* add back range selector

* remove inline styles

---------

Co-authored-by: Callil Capuozzo <callil@uniswap.org>
2023-08-07 14:22:45 -05:00
Brendan Wong
dc2225a2bc
fix: update wrangler version (#7093)
* fix: update wrangler version

* yarn deduplicate

* Update .gitignore

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-08-07 12:56:59 -04:00
Nate Wienert
41571169c6
chore: align @reduxjs/toolkit dep versions with wallet (#7038) 2023-08-07 06:47:26 -10:00
Nate Wienert
7506dbb29c
chore: update typescript to 4.9.4 to align with wallet repo (#7036)
* chore: update typescript to 4.9.4 to align with wallet repo

* fix: update mainnet block (#7042)

* fix: update mainnet block

* fix: typecheck

* fix: use deeplink instead of universal link (#7017)

* fix: use deeplink instead of universal link

* docs: added comment

* test: mock quotes to avoid errors logged (#7031)

* fix: change style of mobile pool buttons and menu (#7020)

* fix: menu flyout alignment overridden on mobile

* fix: change button order, sizing

* Replace deprecated media queries and text components

* fix: remove flakey token test (#7029)

* fix: reverted swap state (#7044)

* fix: wait for transaction status in ConfirmSwapModal

* fix: use actual swap status in ConfirmSwapModal

* feat: add test

* fix: shared hook

* fix: fix test

* fix: dont create Activity instance

* fix: clearing input on connect wallet (#6928)

* fix: clearing input on connect wallet

* update e2e tests

* fix: text wrap and spacing on mobile TDP (#6909)

fix text wrap and spacing on mobile TDP

* fix: top token charts on mobile (#6967)

* fix: top token charts on mobile

* Update TokenRow.test.tsx.snap

* Update src/components/Tokens/TokenTable/TokenRow.tsx

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Update src/components/Tokens/TokenTable/__snapshots__/TokenRow.test.tsx.snap

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* update

* Update TokenRow.test.tsx.snap

* Update TokenRow.test.tsx.snap

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* test: deflake and clean universal search (#7034)

* fix: improve v2 network support (#7012)

* fix: improve v2 network support

* add an unsupported message to all v2 pages

* test: add v2 pool tests

* add guard on transaction callbacks

* fix: dep array

---------

Co-authored-by: eddie <66155195+just-toby@users.noreply.github.com>

* fix: failing nft buy test (#7049)

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
Co-authored-by: cartcrom <39385577+cartcrom@users.noreply.github.com>
Co-authored-by: gnewfield <18626088+gnewfield@users.noreply.github.com>
Co-authored-by: Brendan Wong <35351983+LunrEclipse@users.noreply.github.com>
Co-authored-by: eddie <66155195+just-toby@users.noreply.github.com>
Co-authored-by: Jordan Frankfurt <jordanwfrankfurt@gmail.com>
Co-authored-by: Jack Short <john.short.tj@gmail.com>
2023-08-04 10:52:49 -10:00
Nate Wienert
4f25c4a2bb
chore: align @graphql-codegen dep versions with wallet (#7041) 2023-08-04 10:52:17 -10:00
eddie
fa4e75b777
feat: base network (#6997)
* feat: initial support for base goerli

* wip: update dependencies

* chore: yarn deduplicate

* feat: mainnet wip support

* feat: mainnet wip support

* fix: radial gradient

* fix: logo update

* fix: ur address

* fix: add weth to common bases

* fix: updates

* fix: yarn dedup

* fix: correct rpc url

* fix: correct explorer url

* feat: add USDbC to common bases

* fix lint warnings

* bump SOR version

* fix: fallback URLs

* feat: statsig flag for base support (#7079)

* feat: put base support behind statsig flag

* fix: null checks

* fix: hide pool page

* fix: baseEnabledChains

* feat: update sor

---------

Co-authored-by: Jordan Frankfurt <jordan@uniswap.org>
2023-08-04 11:43:11 -07:00
Brendan Wong
f845695f6e
feat: caches GraphQL queries for Cloudflare workers (#6929)
* feat: add token and nft injection

* feat: basic tests

* fix: get jest configured properly

* fix: change timeout

* fix: uninstall port ready

* fix: readd port ready

* fix: local tests work

* Update yarn.lock

* add lint disable for setup files

* fix: update dependencies

* fix: basic test suite for nfts/tokens

* feat: collection data

* fix: make tests more comprehensive

* fix: change matches to contains

* fix: tests for twitter alt image tag

* fix: image gen

* fix: add patch-package

* fix: update yarn install

* feat: basic image gen for nfts and collections

* fix: remove vibrant attempt

* use watermark asset

* dynamically grab color

* modularize code and prototype for token preview

* refactor code

* finalize css

* fix color grabber

* update tests

* fix up css

* refactor code a bit more

* remove console logs

* tests

* update tests

* update images based on design feedback

* network logos

* update lint

* slight refactoring

* more refactoring

* fix packages

* Update yarn.lock

* remove dynamically generated image stuff

* cleanup return values

* Create README.md

* Revert "Create README.md"

This reverts commit 7a91c98d384995fba914c9bf9a2fb3072793621f.

* First round of feedback

* comments

* feat: cache

* Update test.yml

* Update test.yml

* Update test.yml

* feedback round 2

* final feedback

* final final feedback

* add coverage and other options

* Update test.yml

* start typecheck

* update cache

* update snapshots?

* Update jest.config.json

* Update jest.config.json

* give timeout some buffer

* update import

* upgrade ts

* fix typing for apollo deps

* finalize typechecks

* downgrade typescript to original version

* add cache directory to jest

* remove coverage

* remove google analytics from tests

* review changes

* try cache setup

* Update cache.test.ts

* make cache helper function

* cache test

* remove unneeded test causing issues

* feat: parallelize cache (#6930)

* feat: parallelize cache?

* remove graph query from concurrency await

* most of feedback

* move tests

* update token tests

* singleton cache

* restructuring res and cache promise

* abstract away repeated graph logic

* final feedback

* Update yarn.lock

* final final feedback

* final final final feedback!

* final final final final feedback?
2023-08-04 14:12:20 -04:00
eddie
dbb2f7f6a2
fix: re-enable UniswapX after disabling (#7080)
fix: allow gouda after user disables
2023-08-03 16:45:04 -07:00
eddie
264f145708
fix: Router label copy (#7060) 2023-08-03 15:08:59 -07:00
eddie
bb2677ab1b
fix: match PendingModalContent number formatting w/ SwapModalHeader (#7053)
* fix: match PendingModalContent number formatting w/ SwapModalHeader

* fix: typo

* fix: remove argument
2023-08-03 12:50:46 -07:00
eddie
29e46455c1
fix: use submitted icon on mainnet (#7055)
* fix: use submitted icon on mainnet

* fix: e2e test

* fix: some cleanup
2023-08-03 12:15:25 -07:00
Jack Short
cfc9748036
fix: adjusting slippage in a different language (#7073)
* fix: adjusting slippage in a different language

* making overflow hidden on close

* passing width instead of visibility

* min width
2023-08-03 15:05:47 -04:00
eddie
715555f340
feat: time-to-swap metric (#7051)
* test(cypress): disable infura from browser

* build: typecheck cypress

* build: es5

* build: rm cypress videos

* fix failing tests

* skip nft failure and rm infra-175

* feat: implement tts metric

* wip e2e test

* fix: improve v2 network support (#7012)

* fix: improve v2 network support

* add an unsupported message to all v2 pages

* test: add v2 pool tests

* add guard on transaction callbacks

* fix: dep array

---------

Co-authored-by: eddie <66155195+just-toby@users.noreply.github.com>

* test: adjust test options

* fix: move to helper method

* fix: merge and make code style change

* fix: use local variable to track first event

* fix: amplitude cypress command

* fix: use file-level var

* fix: clear input in test

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
Co-authored-by: Jordan Frankfurt <jordanwfrankfurt@gmail.com>
2023-08-03 11:33:16 -07:00
cartcrom
6a1f17ab5a
feat: update cancelled local tx's (#7008)
* feat: update cancelled local tx's

* fix: use updated queries

* test: add cancel reducer and hook tests

* fix: spelling in test descriptor

* feat: improved activity descriptors

* fix: check activity groups instead of activity

* fix: pending hooks cleanup

* fix: destruct object from pending hook

* refactor: update usage of pending util

* fix: removed unused util
2023-08-03 12:35:51 -04:00
Brendan Wong
cd43e0beaa
fix: failing token cloud function tests (#7074)
* fix: failing token cloud function tests

* utilize enum from chains
2023-08-03 12:30:50 -04:00
gnewfield
24d00f7c39
fix: init pool behavior (#7052)
* Disable increment/decrement  when range prices undefined

* Enable full-range price selection for new pools

* Add cypress tests

* Fix lint error
2023-08-03 10:52:18 -04:00
Brendan Wong
b8573930b9
fix: update v2 pool information link (#7058)
update link
2023-08-02 19:07:08 -04:00
Brendan Wong
2c1e608f84
fix: closes settings state when MP is closed (#7065)
* fix: close settings menu on drawer close

* migrate change to default menu

* remove indent

* add cleanup
2023-08-02 19:06:57 -04:00
Brendan Wong
f90066263e
fix: bring back safeNamehash (#7050)
* fix: bring back safeNamehash

* Update safeNamehash.test.ts
2023-08-02 15:15:10 -07:00
Nate Wienert
1daf15df9f
chore: align @uniswap/analytics dep versions with wallet (#7037)
* chore: align @uniswap/analytics dep versions with wallet

* fix: use deeplink instead of universal link (#7017)

* fix: use deeplink instead of universal link

* docs: added comment

* test: mock quotes to avoid errors logged (#7031)

* fix: change style of mobile pool buttons and menu (#7020)

* fix: menu flyout alignment overridden on mobile

* fix: change button order, sizing

* Replace deprecated media queries and text components

* fix: remove flakey token test (#7029)

* fix: reverted swap state (#7044)

* fix: wait for transaction status in ConfirmSwapModal

* fix: use actual swap status in ConfirmSwapModal

* feat: add test

* fix: shared hook

* fix: fix test

* fix: dont create Activity instance

* fix: clearing input on connect wallet (#6928)

* fix: clearing input on connect wallet

* update e2e tests

* fix: text wrap and spacing on mobile TDP (#6909)

fix text wrap and spacing on mobile TDP

* fix: top token charts on mobile (#6967)

* fix: top token charts on mobile

* Update TokenRow.test.tsx.snap

* Update src/components/Tokens/TokenTable/TokenRow.tsx

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Update src/components/Tokens/TokenTable/__snapshots__/TokenRow.test.tsx.snap

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* update

* Update TokenRow.test.tsx.snap

* Update TokenRow.test.tsx.snap

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* test: deflake and clean universal search (#7034)

* fix: improve v2 network support (#7012)

* fix: improve v2 network support

* add an unsupported message to all v2 pages

* test: add v2 pool tests

* add guard on transaction callbacks

* fix: dep array

---------

Co-authored-by: eddie <66155195+just-toby@users.noreply.github.com>

* fix: failing nft buy test (#7049)

---------

Co-authored-by: cartcrom <39385577+cartcrom@users.noreply.github.com>
Co-authored-by: gnewfield <18626088+gnewfield@users.noreply.github.com>
Co-authored-by: Brendan Wong <35351983+LunrEclipse@users.noreply.github.com>
Co-authored-by: eddie <66155195+just-toby@users.noreply.github.com>
Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
Co-authored-by: Jordan Frankfurt <jordanwfrankfurt@gmail.com>
Co-authored-by: Jack Short <john.short.tj@gmail.com>
2023-08-02 15:00:59 -07:00
Brendan Wong
708a813f2a
feat: MP closes on scroll down (#6682)
* feat: MP closes on scroll down

* fix: make dismissal smoother

* fix: implement react gestures and fix scroll

* fix: fix drag when not starting from top

* fix: double scroll on mobile

* fix: comments for clarity

* fix: mobile scrolling?

* remove console logs

* potential fix?

* remove change again

* maybe fix?

* cope

* even more cope

* even more more cope

* copiest

* make less buggy

* nope

* maybe?

* HOLD

* maybe

* try 2

* maybe

* hopefully

* test

* another try

* cope

* redo

* attempt 2

* hmm

* maybe

* I THINK
2023-08-02 17:15:23 -04:00
gnewfield
18b50283d3
fix: clip long token names (#7066)
* Clip token name with ellipsis style

* Use built-in ellipsis style
2023-08-02 17:02:40 -04:00
Brendan Wong
d9ff7b15a1
fix: swap flashing the wrong value after the input is cleared. (#6719)
* fix: set input panel to 0 when recalculating

* fix: only reset number when input cleared

* fix: remove useEffect and more graciously handle trade mutation
2023-08-02 16:04:50 -04:00
Ankit Boghra
cc5309b18f
fix: broken link for polygon mumbai bridge (#6986)
fix: broken link for polygon bridge

Co-authored-by: Charlie B <charles@bachmeier.io>
2023-08-02 12:20:21 -07:00
eddie
a060bf1079
fix: remove unused variable (#7061) 2023-08-02 12:06:04 -07:00
Jordan Frankfurt
1ffb9421b2
fix: style and copy updates to the swap box (#7006)
* add you pay/you receive label to swap inputs

* update styles

* update snapshots
2023-08-02 13:39:05 -05:00
Zach Pomerantz
7978ed97a9
test(cypress): clean up types/assumptions/infura (#7046) 2023-08-01 22:13:19 -07:00
Thomas Thachil
b4b6c347e3
feat: add mobile deeplinks json to public folder (#7059) 2023-08-01 14:43:48 -04:00
Jack Short
83cb750b2f
fix: failing nft buy test (#7049) 2023-07-31 14:06:45 -04:00
Jordan Frankfurt
fc0bf229a7
fix: improve v2 network support (#7012)
* fix: improve v2 network support

* add an unsupported message to all v2 pages

* test: add v2 pool tests

* add guard on transaction callbacks

* fix: dep array

---------

Co-authored-by: eddie <66155195+just-toby@users.noreply.github.com>
2023-07-31 10:04:22 -05:00
Zach Pomerantz
b55680dbce
test: deflake and clean universal search (#7034) 2023-07-28 16:36:13 -07:00
Brendan Wong
136e68201f
fix: top token charts on mobile (#6967)
* fix: top token charts on mobile

* Update TokenRow.test.tsx.snap

* Update src/components/Tokens/TokenTable/TokenRow.tsx

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Update src/components/Tokens/TokenTable/__snapshots__/TokenRow.test.tsx.snap

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* update

* Update TokenRow.test.tsx.snap

* Update TokenRow.test.tsx.snap

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-07-28 17:50:02 -04:00
Brendan Wong
b4bb3d72d5
fix: text wrap and spacing on mobile TDP (#6909)
fix text wrap and spacing on mobile TDP
2023-07-28 17:24:35 -04:00
Brendan Wong
3f812f4aee
fix: clearing input on connect wallet (#6928)
* fix: clearing input on connect wallet

* update e2e tests
2023-07-28 16:45:58 -04:00
eddie
02883aca13
fix: reverted swap state (#7044)
* fix: wait for transaction status in ConfirmSwapModal

* fix: use actual swap status in ConfirmSwapModal

* feat: add test

* fix: shared hook

* fix: fix test

* fix: dont create Activity instance
2023-07-28 12:48:12 -07:00
Brendan Wong
ace81ecc84
fix: remove flakey token test (#7029) 2023-07-28 13:31:19 -04:00
gnewfield
0aafcdf885
fix: change style of mobile pool buttons and menu (#7020)
* fix: menu flyout alignment overridden on mobile

* fix: change button order, sizing

* Replace deprecated media queries and text components
2023-07-28 13:22:48 -04:00
cartcrom
f55062f9a9
test: mock quotes to avoid errors logged (#7031) 2023-07-28 11:39:49 -04:00
cartcrom
1fde2504b4
fix: use deeplink instead of universal link (#7017)
* fix: use deeplink instead of universal link

* docs: added comment
2023-07-28 10:58:01 -04:00
Zach Pomerantz
6a3abbfb56
fix: update mainnet block (#7042)
* fix: update mainnet block

* fix: typecheck
2023-07-27 15:40:10 -07:00
gnewfield
9ced714718
fix: improve currency select styling (#7009)
* fix: remove currency select drop shadows and make deposit label non-interactive

* rename labelOnly prop to pointerEvents
2023-07-27 14:27:59 -04:00
Brendan Wong
8ed6481f16
fix: display ens name/avatar on other chains (#6981)
* maintain ens info on other chains

* update ens hook

* feedback!

* initial test

* test progress

* e2e test?

* final feedback

* fix(lint): rm unused test var

* fix final bugs

* last lint issue

* fix: update catches

* fix: define catch handlers

* fix: use error in catch

* empty commit

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-07-27 13:34:26 -04:00
cartcrom
d160d1a929
feat: don't fetch UniswapX quotes if user has disabled UniswapX (#7028) 2023-07-27 13:33:20 -04:00
Brendan Wong
1092bc2c58
fix: collision of network banner and swap settings (#6910)
* change z-index of network banner

* change to use pointer-events rather than deprecated value
2023-07-27 13:22:03 -04:00
Zach Pomerantz
a2e56aaabd
revert: "fix: update token tests for cloudflare functions" (#7027)
Revert "fix: update token tests for cloudflare functions (#7026)"

This reverts commit b58d4b72ab06673761e8a0406877f360ea015c4b.
2023-07-27 09:49:18 -07:00
Tina
7ec6a965d3
feat: bump uniswapx-sdk (#7023)
* bump uniswapx-sdk

* add feature flag

* use undefined if feature flag is off

* move to top level config

* remove unused variable
2023-07-27 12:16:17 -04:00
Brendan Wong
b58d4b72ab
fix: update token tests for cloudflare functions (#7026)
fix: update tests
2023-07-26 17:58:56 -04:00
Zach Pomerantz
a2d98607ea
fix: use redirect for landing (#6993)
* fix: use redirect for landing

* chore: rm console.log
2023-07-26 13:24:33 -07:00
eddie
27d9152949
fix: add amplitude event for uniswapX orders failing to post (#6977) 2023-07-26 12:10:22 -07:00
Zach Pomerantz
3cb069283c
build: fix promotion sha (#7022) 2023-07-26 11:51:49 -07:00
Brendan Wong
4d084d0055
fix: mock graphql pool queries in e2e tests (#7018)
mock graphql query
2023-07-26 13:34:17 -04:00
Jordan Frankfurt
4b39dfbd69
fix: update safety check cache time (#7005) 2023-07-26 10:14:54 -05:00
eddie
6c5c1c0032
fix: remove duplicate hook for permit2 approvals (#6999)
* fix: remove duplicate hook for permit2 approvals

* fix: address comments
2023-07-25 14:08:25 -07:00
Brendan Wong
22112c763c
feat: automated testing for cloud functions (#6931)
* feat: add token and nft injection

* feat: basic tests

* fix: get jest configured properly

* fix: change timeout

* fix: uninstall port ready

* fix: readd port ready

* fix: local tests work

* Update yarn.lock

* add lint disable for setup files

* fix: update dependencies

* fix: basic test suite for nfts/tokens

* feat: collection data

* fix: make tests more comprehensive

* fix: change matches to contains

* fix: tests for twitter alt image tag

* fix: image gen

* fix: add patch-package

* fix: update yarn install

* feat: basic image gen for nfts and collections

* fix: remove vibrant attempt

* use watermark asset

* dynamically grab color

* modularize code and prototype for token preview

* refactor code

* finalize css

* fix color grabber

* update tests

* fix up css

* refactor code a bit more

* remove console logs

* tests

* update tests

* update images based on design feedback

* network logos

* update lint

* slight refactoring

* more refactoring

* fix packages

* Update yarn.lock

* remove dynamically generated image stuff

* cleanup return values

* Create README.md

* Revert "Create README.md"

This reverts commit 7a91c98d384995fba914c9bf9a2fb3072793621f.

* First round of feedback

* comments

* Update test.yml

* Update test.yml

* Update test.yml

* feedback round 2

* final feedback

* final final feedback

* add coverage and other options

* Update test.yml

* start typecheck

* update cache

* update snapshots?

* Update jest.config.json

* Update jest.config.json

* give timeout some buffer

* update import

* upgrade ts

* fix typing for apollo deps

* finalize typechecks

* downgrade typescript to original version

* add cache directory to jest

* remove coverage

* remove google analytics from tests

* review changes
2023-07-25 15:12:13 -04:00
Brendan Wong
b230cb62f4
feat: readme for cloud functions (#6914)
* feat: add token and nft injection

* feat: basic tests

* fix: get jest configured properly

* fix: change timeout

* fix: uninstall port ready

* fix: readd port ready

* fix: local tests work

* Update yarn.lock

* add lint disable for setup files

* fix: update dependencies

* fix: basic test suite for nfts/tokens

* feat: collection data

* fix: make tests more comprehensive

* fix: change matches to contains

* fix: tests for twitter alt image tag

* fix: image gen

* fix: add patch-package

* fix: update yarn install

* feat: basic image gen for nfts and collections

* fix: remove vibrant attempt

* use watermark asset

* dynamically grab color

* modularize code and prototype for token preview

* refactor code

* finalize css

* fix color grabber

* update tests

* fix up css

* refactor code a bit more

* remove console logs

* tests

* update tests

* update images based on design feedback

* network logos

* update lint

* slight refactoring

* more refactoring

* fix packages

* Update yarn.lock

* remove dynamically generated image stuff

* cleanup return values

* Create README.md

* Revert "Create README.md"

This reverts commit 7a91c98d384995fba914c9bf9a2fb3072793621f.

* Revert "Revert "Create README.md""

This reverts commit d0a4f5b95115e8ad47b6b3fd01b47806d68ad3d7.

* add docs for html rewriter

* Update README.md

* remove previously removed files
2023-07-25 15:06:28 -04:00
Nate Wienert
9f71e384b2
fix: use deferred value to avoid suspense issues with inputting text (#6996)
fix: use deferred value to avoid suspense issues with inputting text during supsended render causing errors
2023-07-25 06:57:32 -10:00
Nate Wienert
8592a4a54d
fix: flaky test covering searchbar (#7002)
fix flaky test covering searchbar
2023-07-24 15:06:10 -10:00
Charles Bachmeier
ccc94fdfc2
feat: update infura fork block height for cypress tests to be dynamic (#6998)
* import creation block from ur sdk

* update ur sdk
2023-07-24 18:00:29 -07:00
Zach Pomerantz
4537a4dc94
fix: display already-loaded imgs with no transition (#6990) 2023-07-24 16:21:05 -07:00
Jack Short
db0cb41b61
fix: fixing price range filter passing as number (#6994) 2023-07-24 17:51:04 -04:00
eddie
4ced70f737
fix: use 100vh to position bottom sheet (#6989) 2023-07-24 10:02:48 -07:00
Jack Short
9262fec093
feat: add opt out analytics (#6983)
* making shared settings toggle component

* adding description to analytics toggle

* trace analytics wrapper

* changing sendAnalytics to optOut

* updating functions

* moving atom location

* adding back testid to testnet toggle

* sending data on page load

* defaulting to true

* refactoring toggles

* renaming and moving to new filepath

* exporting everything out of analytics

* updating eslint

* typo

* responding to requested changes

* fixing merge conflicts
2023-07-21 13:15:51 -04:00
Jack Short
ff3bcc4693
fix: purchase tweet url (#6987) 2023-07-21 10:24:55 -04:00
Charles Bachmeier
34a22ef9f0
fix: chain query parameter doesn't block you from switching chains (#6926)
* useSearchParams

* delete old param

* properly handle a connected wallet

* update chain query via network switcher

* updated tests

* working test

* comment typo

* don't overwrite current params

* change chain based on user wallet interaction

* one instance of set

* update chainIdRef on account load

* useeffect

* set chainIdRef when isActive

* remove logging

* update comment

* make condition else if
2023-07-20 17:05:12 -07:00
eddie
5e86cf7b29
fix: token img loading state (#6984)
* fix: token img loading state

* fix: nits

* fix: update snapshots

* fix: token logos in MP and tests

* fix: really weird visibility / tooltip bug

* fix: update snapshots
2023-07-20 13:51:29 -07:00
Nate Wienert
83172dc5ea
feat: add tracking params and go straight to app store for iOS for the landing page wallet CTA (#6732)
* feat: add tracking params and go straight to app store for iOS for the landing page wallet CTA
2023-07-20 10:28:08 -10:00
Nate Wienert
0ca68bb140
feat: disconnect button hides after hover out, click away, and improv… (#6968)
* feat: disconnect button hides after hover out, click away, and improved animations and colors
2023-07-20 09:00:56 -10:00
eddie
430356da9a
fix: update text in ConfirmSwapModal (#6971) 2023-07-20 10:12:31 -07:00
Nate Wienert
1c50460160
fix: using search hotkey enter navigates to the wrong result (#6735)
* fix: fix SearchBarDropdown selecting invalid result on enter after initial search when recent searches are filled

* add test

* Update cypress/e2e/universal-search.test.ts

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Update cypress/e2e/universal-search.test.ts

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Update cypress/e2e/universal-search.test.ts

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* use searhc hotkey

* Revert ""

This reverts commit 7b04d5d575e8f776e8127e9b43c3fff6f74d8919.

* chore: gitignore cypress/downloads.html

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-07-19 11:58:02 -10:00
Zach Pomerantz
2ef9e9b61c
fix: show logos on warned tokens (#6978)
* fix: show logos on warned tokens

* test: update snapshots

* fix: hide logos for unsupported tokens
2023-07-19 14:00:50 -07:00
Charles Bachmeier
b906cddc6a
fix: update depedencies to fix avax/bnb routing (#6974)
* fix: update depedencies to fix avax/bnb routing

* pull latest

* use rpc_url

* deduplicate
2023-07-19 09:58:08 -07:00
Ivan Sorokin
65fe8d4168
feat: add apple-app-site-association (#6957) 2023-07-18 23:59:58 +02:00
Charles Bachmeier
8956fba629
fix: Silence linter warnings for GA (#6962)
ga analytics
2023-07-18 09:59:19 -07:00
Charles Bachmeier
04884fe1b0
fix: Resolve Babel dependency warning (#6961) 2023-07-18 09:59:01 -07:00
Brendan Wong
ef28667d13
feat: cloudflare worker to inject meta tags (#6901)
* feat: add token and nft injection

* feat: basic tests

* fix: get jest configured properly

* fix: change timeout

* fix: uninstall port ready

* fix: readd port ready

* fix: local tests work

* Update yarn.lock

* add lint disable for setup files

* fix: update dependencies

* fix: basic test suite for nfts/tokens

* feat: collection data

* fix: make tests more comprehensive

* fix: change matches to contains

* fix: tests for twitter alt image tag

* fix: image gen

* fix: add patch-package

* fix: update yarn install

* feat: basic image gen for nfts and collections

* fix: remove vibrant attempt

* use watermark asset

* dynamically grab color

* modularize code and prototype for token preview

* refactor code

* finalize css

* fix color grabber

* update tests

* fix up css

* refactor code a bit more

* remove console logs

* tests

* update tests

* update images based on design feedback

* network logos

* update lint

* slight refactoring

* more refactoring

* fix packages

* Update yarn.lock

* remove dynamically generated image stuff

* cleanup return values

* Create README.md

* Revert "Create README.md"

This reverts commit 7a91c98d384995fba914c9bf9a2fb3072793621f.

* First round of feedback

* comments

* feedback round 2

* final feedback

* final final feedback

* nest twitter:image:alt in image check

* better title handling

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-07-18 12:35:29 -04:00
Zach Pomerantz
0ced5f2402
fix: duck type error checking (#6924)
* fix: duck type error checking

* fix: use duck-typing

* simplify

* fix typings

* fix comments
2023-07-18 09:21:00 -07:00
Zach Pomerantz
252bf32d2f
test(e2e): buy crypto modal flag (#6965) 2023-07-17 22:04:40 -07:00
eddie
01e87657c6
fix: format currency amounts as strings in logging (#6966)
* fix: format currency amounts as strings in logging

* fix: toExact
2023-07-17 17:27:17 -07:00
Brendan Wong
55bf30c0e0
fix: remove shadow and gap on mobile (#6906)
* remove shadow and gap on mobile

* remove empty brackets
2023-07-17 16:39:48 -04:00
Nate Wienert
95f61487e8
fix: uniswapx opt in double bounce animation (#6964) 2023-07-17 09:05:07 -10:00
eddie
3ed3ed4994
feat: sort tokens in selector by USD value (#6744)
* feat: sort tokens in selector by USD value

* fix: sync visible balances in list with the sorting values

* fix: tryParseCurrencyAmount

* fix: remove todo

* fix: make shared hook for cached query

* fix: replace true with modalOpen

* fix: default to zero balance

* fix: add test and comment

* feat: fallback to unfilterd tokens

* fix: unconnected balances

* fix: update tests

* fix: test selector
2023-07-17 11:28:28 -07:00
Zach Pomerantz
3a0c4ad4db
fix: do not cache gql across CI (#6963) 2023-07-17 10:33:50 -07:00
Charles Bachmeier
803eb46e5f
fix: Clear input and output when wrapping and unwrapping (#6913)
* add wrap handler

* onWrap passed back tx hash

* async await
2023-07-17 10:13:15 -07:00
Zach Pomerantz
a3f0c54f66
build: block promotion to prod on tests (#6904) 2023-07-17 10:12:59 -07:00
Charles Bachmeier
52796fcc55
feat: Sort chains based on user relevance (#6915)
* sort chains based on user relevance

* test.each

* remove unnecessary comment and add chainId to test name
2023-07-17 10:10:12 -07:00
eddie
ca02a6b56a
fix: log opt in impression (#6959)
* fix: log opt in impression

* fix: move trace up to parent level
2023-07-17 10:06:42 -07:00
Jack Short
b722a20d96
fix: swap divide by zero (#6922)
* fix: swap divide by zero

* putting evaluation in memo
2023-07-17 12:38:49 -04:00
Jack Short
9b5261aaeb
fix: v2 liquidity divide by zero (#6921) 2023-07-17 12:06:52 -04:00
Brendan Wong
0efb7f51a4
fix: remove new badge from Uniswap Wallet (#6911)
* remove new badge from Uniswap Wallet

* remove isNew field and badge

* clean lint
2023-07-17 11:55:28 -04:00
Zach Pomerantz
bbe42b81de
fix: display token images on first pageload (#6956)
* fix: always show img for common bases

* fix: include backup img in first render

* fix: initialize and update token safety lookup

* test: update snapshots to include initial logos

* refactor: better code colocation

* test: updating token safety lookup table

* refactor: tokenSafetyLookup

* refactor: tokenLogoLookup

* fix: pass lists state to token safety update

* test: mock initial update
2023-07-15 18:33:13 -07:00
cartcrom
e9f469d399
fix: hide pending orders from GQL (#6955)
* fix: hide pending orders from GQL

* fix: update comment and add TODO
2023-07-15 18:03:21 +01:00
Tina
4c58258f01
feat: additional routing option prototype (#6934)
* add npm secret and modify github actions

* inject npm secret for tests as well

* revert changes to staging and prod actions because we arent going to use themmm

* remove unused github actions

* minor copy change for convenience lol

* feat: add DutchOrderTrade type to Swap components (#8)

* feat: add flag for gouda (#5)

* feat: add new signature details type (#4)

* feat: local gouda activity (#9)

* feat: Unified Routing API classic and dutch limit quote requests (#10)

* chore: Rebase 5/26 (#13)

Co-authored-by: Mike Grabowski <grabbou@gmail.com>
Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
Co-authored-by: Jordan Frankfurt <jordanwfrankfurt@gmail.com>
Co-authored-by: Vignesh Mohankumar <me@vig.xyz>
Co-authored-by: cartcrom <39385577+cartcrom@users.noreply.github.com>
Co-authored-by: Jack Short <john.short.tj@gmail.com>
Co-authored-by: eddie <66155195+just-toby@users.noreply.github.com>
Co-authored-by: Jordan Frankfurt <jordan@CORN-Jordan-949.frankfurt>
Co-authored-by: Jordan Frankfurt <jordan@corn-jordan-949.lan>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: Nate Wienert <natewienert@gmail.com>
Co-authored-by: Charles Bachmeier <charles@bachmeier.io>
Co-authored-by: Charles Bachmeier <charlie@genie.xyz>

* feat: add UniswapX to Settings (#7)

* feat: merge upstream 5/31 (#16)

* feat: Upgrade unified-routing-api URL (#15)

* chore: merge upstream 6/2 (#19)

Co-authored-by: Mike Grabowski <grabbou@gmail.com>
Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
Co-authored-by: Tina <59578595+tinaszheng@users.noreply.github.com>
Co-authored-by: Jordan Frankfurt <jordanwfrankfurt@gmail.com>
Co-authored-by: Vignesh Mohankumar <me@vig.xyz>
Co-authored-by: cartcrom <39385577+cartcrom@users.noreply.github.com>
Co-authored-by: Jack Short <john.short.tj@gmail.com>
Co-authored-by: Jordan Frankfurt <jordan@CORN-Jordan-949.frankfurt>
Co-authored-by: Jordan Frankfurt <jordan@corn-jordan-949.lan>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: Nate Wienert <natewienert@gmail.com>
Co-authored-by: Charles Bachmeier <charles@bachmeier.io>
Co-authored-by: Charles Bachmeier <charlie@genie.xyz>

* feat: uniswapx gas tooltip (#12)

Co-authored-by: Mike Grabowski <grabbou@gmail.com>
Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
Co-authored-by: Tina <59578595+tinaszheng@users.noreply.github.com>
Co-authored-by: Jordan Frankfurt <jordanwfrankfurt@gmail.com>
Co-authored-by: Vignesh Mohankumar <me@vig.xyz>
Co-authored-by: cartcrom <39385577+cartcrom@users.noreply.github.com>
Co-authored-by: Jack Short <john.short.tj@gmail.com>
Co-authored-by: Jordan Frankfurt <jordan@CORN-Jordan-949.frankfurt>
Co-authored-by: Jordan Frankfurt <jordan@corn-jordan-949.lan>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: Nate Wienert <natewienert@gmail.com>
Co-authored-by: Charles Bachmeier <charles@bachmeier.io>
Co-authored-by: Charles Bachmeier <charlie@genie.xyz>

* feat: swap callback (#17)

* feat: gouda gating (#14)

Co-authored-by: Mike Grabowski <grabbou@gmail.com>
Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
Co-authored-by: Tina <59578595+tinaszheng@users.noreply.github.com>
Co-authored-by: Jordan Frankfurt <jordanwfrankfurt@gmail.com>
Co-authored-by: Vignesh Mohankumar <me@vig.xyz>
Co-authored-by: cartcrom <39385577+cartcrom@users.noreply.github.com>
Co-authored-by: Jack Short <john.short.tj@gmail.com>
Co-authored-by: Jordan Frankfurt <jordan@CORN-Jordan-949.frankfurt>
Co-authored-by: Jordan Frankfurt <jordan@corn-jordan-949.lan>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: Nate Wienert <natewienert@gmail.com>
Co-authored-by: Charles Bachmeier <charles@bachmeier.io>
Co-authored-by: Charles Bachmeier <charlie@genie.xyz>

* fix: settings e2e test (#22)

* feat: update swap callback to add orders to redux state (#18)

* chore: Fix types for useBestTrade return result (#21)

* feat: gql gouda orders (#20)

* feat: show $0 for gas fee for now (#25)

* chore: Rebase 06/08 (#26)

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
Co-authored-by: Tina <59578595+tinaszheng@users.noreply.github.com>
Co-authored-by: Jordan Frankfurt <jordanwfrankfurt@gmail.com>
Co-authored-by: Vignesh Mohankumar <me@vig.xyz>
Co-authored-by: cartcrom <39385577+cartcrom@users.noreply.github.com>
Co-authored-by: Jack Short <john.short.tj@gmail.com>
Co-authored-by: eddie <66155195+just-toby@users.noreply.github.com>
Co-authored-by: Jordan Frankfurt <jordan@CORN-Jordan-949.frankfurt>
Co-authored-by: Jordan Frankfurt <jordan@corn-jordan-949.lan>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: Nate Wienert <natewienert@gmail.com>
Co-authored-by: Charles Bachmeier <charles@bachmeier.io>
Co-authored-by: Charles Bachmeier <charlie@genie.xyz>
Co-authored-by: Brendan Wong <35351983+LunrEclipse@users.noreply.github.com>
Co-authored-by: cartcrom <cartergcromer@gmail.com>
Co-authored-by: clrdo <129212060+clrdo@users.noreply.github.com>
Co-authored-by: clrdo <clrdo@github.com>
Co-authored-by: Eddie Dugan <eddie.dugan@uniswap.org>

* feat: poll on order submit (#23)

* feat: update gouda-sdk to 1.0.0-alpha.3 (#31)

* feat: rename gasUseEstimateUSD for dutch orders (#30)

Co-authored-by: Tina Zheng <tina.s.zheng+github@gmail.com>

* chore: Fix response types (#36)

* feat: Gouda ETH input flow (#29)

Co-authored-by: Eddie Dugan <eddie.dugan@uniswap.org>

* fix: use trade to determine what router label to show (#41)

* feat: open uniswapx modal on click (#32)

* feat: gouda logging new params in swap quote received (#33)

* fix: wrap step ui fixes (#40)

* feat: use BE deadline padding (#46)

* chore: merge 6/23 (#50)

Co-authored-by: Mike Grabowski <grabbou@gmail.com>
Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
Co-authored-by: Jordan Frankfurt <jordanwfrankfurt@gmail.com>
Co-authored-by: Vignesh Mohankumar <me@vig.xyz>
Co-authored-by: cartcrom <39385577+cartcrom@users.noreply.github.com>
Co-authored-by: Jack Short <john.short.tj@gmail.com>
Co-authored-by: eddie <66155195+just-toby@users.noreply.github.com>
Co-authored-by: Jordan Frankfurt <jordan@CORN-Jordan-949.frankfurt>
Co-authored-by: Jordan Frankfurt <jordan@corn-jordan-949.lan>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: Nate Wienert <natewienert@gmail.com>
Co-authored-by: Charles Bachmeier <charles@bachmeier.io>
Co-authored-by: Charles Bachmeier <charlie@genie.xyz>
Co-authored-by: Brendan Wong <35351983+LunrEclipse@users.noreply.github.com>
Co-authored-by: cartcrom <cartergcromer@gmail.com>
Co-authored-by: clrdo <129212060+clrdo@users.noreply.github.com>
Co-authored-by: clrdo <clrdo@github.com>
Co-authored-by: Shubham Rasal <95695273+Shubham-Rasal@users.noreply.github.com>
Co-authored-by: Saro Vindigni <sarovindigni@bolket.com>
Co-authored-by: Jordan Frankfurt <<jordan@CORN-Jordan-949.frankfurt>
Co-authored-by: John Short <john.short@CORN-Jack-899.local>

* feat: Gouda opt-in flow request logic (#37)

Co-authored-by: eddie <66155195+just-toby@users.noreply.github.com>

* feat: hide slippage and deadline settings when the current trade is gouda (#44)

* feat: use settled order amounts (#45)

* feat: fetch receipt before dispatch (#49)

* fix: updated order popups to launch modal (#48)

* feat: Use slippage value from URA response for UniswapX trades (#51)

* fix: Bump gouda-sdk to match backend response for quotes (#58)

* feat: Change gouda order status URL param from offerer -> swapper (#59)

* feat: disable opt in flow (#57)

* feat: Dont show USD value change for uniswapx trades (#55)

* fix: Don't use WETH as input currency for Classic ETH-in trades (#54)

* feat: Reset to WETH after wrap is complete (#52)

* fix: correct descriptor in UniswapX activity row items (#61)

* fix: align review modal and gouda activity modal (#60)

Co-authored-by: Charles Bachmeier <charles@bachmeier.io>

* feat: Get wrap and approve gas info (#53)

Co-authored-by: eddie <66155195+just-toby@users.noreply.github.com>

* fix: restore summary view when wrap is rejected (#66)

* fix: serialize tx receipts before storing (#64)

* fix: Insufficient balance check should read from the right currency (#65)

* feat: update designs for gas tooltips (#67)

* fix: UniswapX gas descriptor boolean (#69)

* chore: Bump conedison for better gas price formatting (#70)

* chore: Switch from gouda-sdk to uniswapx-sdk (#71)

* chore: Rename all variables `gouda` to UniswapX (#72)

* chore: Merge 7/8/23 (#73)

Co-authored-by: Mike Grabowski <grabbou@gmail.com>
Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
Co-authored-by: Jordan Frankfurt <jordanwfrankfurt@gmail.com>
Co-authored-by: Vignesh Mohankumar <me@vig.xyz>
Co-authored-by: cartcrom <39385577+cartcrom@users.noreply.github.com>
Co-authored-by: Jack Short <john.short.tj@gmail.com>
Co-authored-by: eddie <66155195+just-toby@users.noreply.github.com>
Co-authored-by: Jordan Frankfurt <jordan@CORN-Jordan-949.frankfurt>
Co-authored-by: Jordan Frankfurt <jordan@corn-jordan-949.lan>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: Nate Wienert <natewienert@gmail.com>
Co-authored-by: Charles Bachmeier <charles@bachmeier.io>
Co-authored-by: Charles Bachmeier <charlie@genie.xyz>
Co-authored-by: Brendan Wong <35351983+LunrEclipse@users.noreply.github.com>
Co-authored-by: cartcrom <cartergcromer@gmail.com>
Co-authored-by: clrdo <129212060+clrdo@users.noreply.github.com>
Co-authored-by: clrdo <clrdo@github.com>
Co-authored-by: Shubham Rasal <95695273+Shubham-Rasal@users.noreply.github.com>
Co-authored-by: Saro Vindigni <sarovindigni@bolket.com>
Co-authored-by: Jordan Frankfurt <<jordan@CORN-Jordan-949.frankfurt>
Co-authored-by: John Short <john.short@CORN-Jack-899.local>
Co-authored-by: Charlie Bachmeier <charlie.bachmeier@Charlies-MacBook-Pro.local>
Co-authored-by: UL Service Account <hello-happy-puppy@users.noreply.github.com>

* chore(conedison): update package (#77)

* feat: add opt-in UI (#68)

* chore: address some todos (#79)

* chore: Rename feature flag from gouda_enabled to uniswapx_enabled (#81)

* feat: Copy changes (#82)

* fix: improve timings on animations for gouda opt-in (#80)

* chore: Use updated URLs (#84)

* chore: Merge 7/14 (#85)

Co-authored-by: Mike Grabowski <grabbou@gmail.com>
Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
Co-authored-by: Jordan Frankfurt <jordanwfrankfurt@gmail.com>
Co-authored-by: Vignesh Mohankumar <me@vig.xyz>
Co-authored-by: cartcrom <39385577+cartcrom@users.noreply.github.com>
Co-authored-by: Jack Short <john.short.tj@gmail.com>
Co-authored-by: eddie <66155195+just-toby@users.noreply.github.com>
Co-authored-by: Jordan Frankfurt <jordan@CORN-Jordan-949.frankfurt>
Co-authored-by: Jordan Frankfurt <jordan@corn-jordan-949.lan>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: Nate Wienert <natewienert@gmail.com>
Co-authored-by: Charles Bachmeier <charles@bachmeier.io>
Co-authored-by: Charles Bachmeier <charlie@genie.xyz>
Co-authored-by: Brendan Wong <35351983+LunrEclipse@users.noreply.github.com>
Co-authored-by: cartcrom <cartergcromer@gmail.com>
Co-authored-by: clrdo <129212060+clrdo@users.noreply.github.com>
Co-authored-by: clrdo <clrdo@github.com>
Co-authored-by: Shubham Rasal <95695273+Shubham-Rasal@users.noreply.github.com>
Co-authored-by: Saro Vindigni <sarovindigni@bolket.com>
Co-authored-by: Jordan Frankfurt <<jordan@CORN-Jordan-949.frankfurt>
Co-authored-by: John Short <john.short@CORN-Jack-899.local>
Co-authored-by: Charlie Bachmeier <charlie.bachmeier@Charlies-MacBook-Pro.local>
Co-authored-by: UL Service Account <hello-happy-puppy@users.noreply.github.com>

* remove changes to github actions files

* fix import

* actually revert changes to yml

* remove method export

* feat: Add feature flag for synthetic quotes (#6938)

* fix: use Lingui Trans macro (#6943)

* fix: use trans macro

* add comments

* fix: update updater.tsx (#6942)

* fix: reformat variable to use ms

* move interval definition above getOrderStatus

* lint :)

* revert

* chore: bunch of nits (#6944)

bunch of nits

* fix: translations etc (#6945)

* chore: Remove placeholder signature types (#6937)

remove placeholder

* chore: merge main into branch (#6948)

* fix: Handle Scientific Notation for NFT Collection Activity Prices (#6936)

wrap nft activity price in

* fix: e2e tests (#6941)

* fix: e2e test

* fix: set flag for buy-crypto-modal test

* fix: fund DAI

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

---------

Co-authored-by: Charles Bachmeier <charles@bachmeier.io>

* feat: make inputCurrency optional for swapheader (#6947)

* make inputCurrency optional for swapheader

* optional pass in

* fix: function defined twice (#6950)

fix lint

* test: add signatureToActivity undefined tests (#6949)

* fix: update token lists schema (#6951)

fix: update token list schema

* chore: some last nits (#6953)

* refactor: base type

* test: useUserDisabledUniswapX

* chore: simplify useAllSignatures usage

* chore: standard check order

* lint

---------

Co-authored-by: eddie <66155195+just-toby@users.noreply.github.com>
Co-authored-by: cartcrom <39385577+cartcrom@users.noreply.github.com>
Co-authored-by: Mike Grabowski <grabbou@gmail.com>
Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
Co-authored-by: Jordan Frankfurt <jordanwfrankfurt@gmail.com>
Co-authored-by: Vignesh Mohankumar <me@vig.xyz>
Co-authored-by: Jack Short <john.short.tj@gmail.com>
Co-authored-by: Jordan Frankfurt <jordan@CORN-Jordan-949.frankfurt>
Co-authored-by: Jordan Frankfurt <jordan@corn-jordan-949.lan>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: Nate Wienert <natewienert@gmail.com>
Co-authored-by: Charles Bachmeier <charles@bachmeier.io>
Co-authored-by: Charles Bachmeier <charlie@genie.xyz>
Co-authored-by: Brendan Wong <35351983+LunrEclipse@users.noreply.github.com>
Co-authored-by: cartcrom <cartergcromer@gmail.com>
Co-authored-by: clrdo <129212060+clrdo@users.noreply.github.com>
Co-authored-by: clrdo <clrdo@github.com>
Co-authored-by: Eddie Dugan <eddie.dugan@uniswap.org>
Co-authored-by: marktoda <toda.mark@gmail.com>
Co-authored-by: Shubham Rasal <95695273+Shubham-Rasal@users.noreply.github.com>
Co-authored-by: Saro Vindigni <sarovindigni@bolket.com>
Co-authored-by: Jordan Frankfurt <<jordan@CORN-Jordan-949.frankfurt>
Co-authored-by: John Short <john.short@CORN-Jack-899.local>
Co-authored-by: Charlie Bachmeier <charlie.bachmeier@Charlies-MacBook-Pro.local>
Co-authored-by: UL Service Account <hello-happy-puppy@users.noreply.github.com>
2023-07-14 14:46:59 -07:00
Jack Short
f6e6db6430
fix: pwat stack overflow (#6952) 2023-07-14 17:35:08 -04:00
Charles Bachmeier
dab445f237
fix: e2e tests (#6941)
* fix: e2e test

* fix: set flag for buy-crypto-modal test

* fix: fund DAI

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-07-14 11:54:25 -07:00
Charles Bachmeier
da90738ba1
fix: Handle Scientific Notation for NFT Collection Activity Prices (#6936)
wrap nft activity price in
2023-07-14 09:54:48 -07:00
Vignesh Mohankumar
e4dbef80eb
chore: remove Google Analytics from CSP (#6888)
* disable ga

* comment
2023-07-07 14:15:41 -04:00
Vignesh Mohankumar
e169c9d900
chore: delete WalletConnect v1 (#6857)
* chore: remove walletConnectFallback flag

* chore: remove walletConnectV2 flag

* chore: delete WalletConnect v1

* chore: remove walletConnectV2 flag (#6856)

* rm hidden

* toggle account drawer

* fix test

* Revert "rm hidden"

This reverts commit 9e8dd65b04b1072d3565cb70defb46d1524791f3.

* fix test

* -u

* optional?

* Revert "optional?"

This reverts commit 8456080b78cfae58737918daeb929bdaf0758cba.

* switch mock

* expect

* test

* fix test

* update connection tests
2023-07-07 14:06:07 -04:00
Zach Pomerantz
c8a17f5fe9
build: use context.sha (#6900) 2023-07-07 10:48:00 -07:00
Vignesh Mohankumar
552a38994b
chore: remove WalletConnect feature flags (#6855)
* chore: remove walletConnectFallback flag

* chore: remove walletConnectV2 flag (#6856)

* rm hidden

* toggle account drawer

* fix test

* Revert "rm hidden"

This reverts commit 9e8dd65b04b1072d3565cb70defb46d1524791f3.

* fix test

* -u

* optional?

* Revert "optional?"

This reverts commit 8456080b78cfae58737918daeb929bdaf0758cba.

* switch mock

* expect

* test
2023-07-07 13:15:13 -04:00
Zach Pomerantz
b313ac9843
build: upgrade cypress-hardhat (#6897) 2023-07-07 10:03:06 -07:00
Jack Short
88aec2c894
fix: 0 showing as collected fee amount (#6804)
* fix: 0 showing as collected fee amount

* initial test setup

* fire events

* checking for data in tests
2023-07-07 12:51:35 -04:00
Zach Pomerantz
86677ed193
test(staging): add staging-only t9n test (#6899)
* test(staging): add staging-only test

* test(staging): translations mount

* ci(t9n): download translations from crowdin

* test: proving that it works

* Revert "ci(t9n): download translations from crowdin"

This reverts commit b6e0f0c5c296c3ad4166419d72e9b2ebd053be87.

* Revert "test: proving that it works"

This reverts commit 1d3a1c2a2377e1a3b790f706c42b7169a47e59fd.

* fix: spec->test

---------

Co-authored-by: UL Service Account <hello-happy-puppy@users.noreply.github.com>
2023-07-07 09:41:20 -07:00
Zach Pomerantz
accf0905f8
build: block promotion on Test (#6898) 2023-07-07 08:47:32 -07:00
Brendan Wong
ef5065de48
feat: wrangler infra and test environment (#6797)
* feat: add token and nft injection

* feat: basic tests

* fix: get jest configured properly

* fix: change timeout

* fix: uninstall port ready

* fix: readd port ready

* fix: local tests work

* fix: remove other stuff to make this pr smaller

* fix: remove unneeded dependencies

* fix: remove port-ready

* Update yarn.lock

* fix: add lint disable due to module exports for jest

* fix: added waitPort

* fix: deduplicated things?

* Update package.json

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* update typing

* change tests to typescript instead of javascript

* changing typing of globalThis servers

* yarn deduplicate

* Update functions/global-teardown.ts

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Update functions/global.d.ts

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Update functions/tsconfig.json

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Update functions/tsconfig.json

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Update package.json

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* change dependencies to dev dependencies

* final touches

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-07-07 11:41:09 -04:00
Vignesh Mohankumar
bcb45cded6
feat: add user id to sentry (#6896)
* feat: add user id to sentry

* downgrade

* key

* Update src/tracing/index.ts

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Update src/tracing/index.ts

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* fixes

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-07-07 11:14:36 -04:00
cartcrom
dfe50b4bee
feat: remove old routing slice and flag (#6895)
feat: remove ura flag
2023-07-07 09:49:42 -04:00
Charles Bachmeier
90f72e05b9
feat: upgrade sdk-core to 3.2.6 and add AVAX (#6757)
* init refactor

* upgrade to 3.2.6 and refactor more uses of chainid

* cleaned up lock file

* remove console log and add placeholder

* use supported chains type for switch fn

* allow passing of all chainIds to switcher

* additional typecast

* better casting solution

* yarn.lock cleanup

* prettier

* better casting for rpc

* prettier

* deprecate no longer needed addresses

* better isSupported checking

* deprecate redundant fn

* cleanup toSupportedChainId

* address initial ocmments

* pretier

* includes testnet

* remove unused export

* merge conflicts

* spread for mutable copy

* explorer text

* check is supported before activating chain

* remove extra uses of mumbai

* remove cast to MockChainId

* retain var name supportedChainId

* updated prettier

* use t for explorer translation

* use mockchainid for test

* feat: Add Avalanche support (#6776)

* init avax

* add most avax props

* add logo

* correct subgraph

* update avax blocksPerFetch

* add square logo

* upgrade ur sdk

* version syntax

* correct tokens

* remove unused token

* remove unused token

* update token list and add coming soon to searchbar

* add coming soon to token explore page

* names to ids

* cleaned up routing

* usdc token

* upgrade default token list

* update SOR

* upgrade SOR

* merge conflicts

* snowtrace

* upgrade SOR

* handle be avax support

* temp hide avax

* show pool positions

* whole

* spotprice update

* not yet supported

* BACKEND_SUPPORTED_CHAINS

* add avax to BE not supported

* update multicall blocks to 5

* add todo

* updated prettier

---------

Co-authored-by: Charles Bachmeier <charlie@genie.xyz>

* be added avax token balances

* validateUrlChainParam should return eth for backend unsupported chain

* readonly

* respond to comments

---------

Co-authored-by: Charles Bachmeier <charlie@genie.xyz>
2023-07-06 21:44:06 -07:00
Vignesh Mohankumar
3a0f6920d0
build: use webpack-retry-chunk-load-plugin (#6885)
* build: use webpack retry chunk load plugin

* fix

* dedupe

* lint

* retry backoff

* reduce from 1000 to 500ms

* add cache bust query

* rm cache bust

* 3

* cache bust

* Update craco.config.cjs

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-07-06 17:54:49 -04:00
eddie
07eb9eb9a2
fix: combine userState with default injected wallet in cypress setup (#6849)
* fix: combine userState with default injected wallet in cypress setup

* fix: unconnected state in two tests

* fix: update name
2023-07-06 14:01:13 -07:00
Brendan Wong
a9e8e8b275
fix: web app without NFTs (#6712)
* fix: web app without NFTs

* fix: change card display to memoization

* fix: remove unneeded imports and variables

* fix: readd search bar modification

* fix: update dependencies

* fix: update atom value to use hook

* fix: change hook name

* fix: add tests

* Update src/pages/Landing/index.tsx

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

* Update src/components/NavBar/SearchBar.tsx

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

* Update src/components/NavBar/SearchBarDropdown.tsx

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Update src/components/NavBar/SearchBarDropdown.test.tsx

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Update SearchBar.tsx

* fix lint

---------

Co-authored-by: Jordan Frankfurt <jordanwfrankfurt@gmail.com>
Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-07-06 15:46:41 -04:00
Vignesh Mohankumar
4708d3d3d7
fix: update InterfaceGqlChain syntax (#6892)
lint: update InterfaceGqlChain syntax
2023-07-06 12:31:15 -04:00
Vignesh Mohankumar
27acddc0e7
chore: upgrade prettier (#6887)
* lint

* upgrade prettier

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-07-06 11:54:04 -04:00
Charles Bachmeier
102a935ff8
fix: Handle new and unsupported chains passed in from GQL BE (#6878)
* add subset chain type and checks

* add sentry logging for invalid chain errors

* add test cases

* dynamic token balances

* add test for BE adding a new chain

* rename and use slice

* address comments

* undo yarn.lock changes

* make copy in utils

* chore: Declare GQL variables as readonly (#6889)

* declare gql variables as readonly

* remove console log

* Merge branch 'cab/error_supported_chain' into tina/gql-readonly

---------

Co-authored-by: Charlie B <charles@bachmeier.io>

---------

Co-authored-by: Charlie Bachmeier <charlie.bachmeier@Charlies-MacBook-Pro.local>
Co-authored-by: Tina <59578595+tinaszheng@users.noreply.github.com>
2023-07-05 21:31:30 -07:00
Charles Bachmeier
614c15243e
fix: tokens with same name brake cypress test (#6890)
* fix: tokens with same name brake cypress test

* lowercase
2023-07-05 20:23:03 -07:00
Zach Pomerantz
082db21308
build: set test status per commit (#6824)
* build: annotate commit with test status

* build: Test / promotion

* fix: ellipsis

* build: also run on releases/staging

* errant comma

* script context

* runId

* build: post after pre
2023-07-05 14:42:43 -07:00
Jack Short
0f75c6a52b
chore: matching swap input number formatting to mobile (#6788)
* initial currency formatting

* updating price formatting on swap

* updating the test
2023-07-05 17:37:57 -04:00
Brendan Wong
1c2ed1d9e4
fix: add margins for empty pool icon (#6884)
* fix: increase height of svg

* update test
2023-07-05 16:36:18 -04:00
Vignesh Mohankumar
0e956fb7c4
chore: remove @walletconnect/modal dependency (#6877) 2023-07-05 13:34:24 -07:00
Zach Pomerantz
b49dd03e25
test(e2e): use electron (#6827)
* test(e2e): use electron

* build: use default container for cypress-test-matrix
2023-07-05 13:30:54 -07:00
Charles Bachmeier
82211a888c
fix: show bnb pool positions in mini port (#6880) 2023-07-05 11:16:11 -07:00
cartcrom
5dd8cbbdc9
chore: update tos & privacy policy last updated date (#6882) 2023-07-05 14:12:20 -04:00
eddie
5640c115de
fix: remove error popup when switching chains from URL param (#6866) 2023-07-03 17:13:12 -07:00
cartcrom
7b8114b401
fix: remove phantom from injection detection (#6875)
* fix: remove phantom from injection detection

* fix: remove logo image
2023-07-03 16:24:08 -04:00
Brendan Wong
8e36361866
fix: remove blue dot next to buy (#6808)
* remove button

* remove dependencies

* fix: remove useBuyFiatFlowCompleted

* fix: update lint and unit tests

* fix: update user state

* fix: remove migration

* Revert "fix: remove migration"

This reverts commit eef313f9ce2ea6b494ce2c9bc4a2fa6dbd1991ee.

* test

* fix: add ts ignore
2023-07-03 15:55:49 -04:00
Brendan Wong
0a04cff7eb
fix: icons no longer clip (#6812) 2023-06-30 17:41:53 -04:00
Jack Short
d3dd1d4ebd
fix: position list row highlight overflowing container (#6805) 2023-06-30 17:25:24 -04:00
Vignesh Mohankumar
50f2e2770a
chore: upgrade @web3-react/walletconnect-v2 (#6867)
chore: upgrade @web3-react/walletconnect-v2 (#6863)

* update

* types
2023-06-30 15:27:37 -05:00
Vignesh Mohankumar
830cd07f38
fix: upgrade @web3-react/gnosis-safe (#6868)
fix: upgrade @web3-react/gnosis-safe (#6864)

* fix: upgrade @web3-react/gnosis-safe

* Update yarn.lock
2023-06-30 15:27:20 -05:00
Vignesh Mohankumar
326ae58f04
chore: update @walletconnect/modal (#6851)
* chore: upgrade @walletconnect/modal

* fix
2023-06-30 14:05:10 -04:00
Vignesh Mohankumar
25f5a7178f
chore: upgrade @web3-react/walletconnect-v2 (#6847) 2023-06-30 13:34:03 -04:00
Zach Pomerantz
e5591e8f06
fix: allow wallets w/o mainnet to connect to WCv2 (#6854)
* fix: re-initialize wc connector with active chain

* test(e2e): fix universal-search flake
2023-06-30 13:28:48 -04:00
Jordan Frankfurt
1c4a383a49
feat: gate v1 retirement (#6845)
* Revert "feat(wallet-connect): retire v1 (#6820)"

This reverts commit d6759b86e3702a6da3df211752c06e4ee119d801.

* gate v1/v2 switch with v2 fallback on wc entry

* fix tests

* add a second flag--isolate ... menu and default values from each other

* Update src/components/WalletModal/Option.tsx

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Update src/featureFlags/flags/walletConnectPopover.ts

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* pr feedback

* pr feedback

* pr nit

---------

Co-authored-by: Jordan Frankfurt <jordan@CORN-Jordan-949.frankfurt>
Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-06-26 15:59:13 -04:00
Vignesh Mohankumar
469a006088
fix: filter more CSP errors (#6839)
* fix: filter more CSP errors

* fix regex

* fix
2023-06-26 14:04:54 -04:00
Vignesh Mohankumar
c673c9e458
fix: filter user reject errors temporarily (#6840) 2023-06-26 13:41:17 -04:00
Vignesh Mohankumar
dd957d07e4
chore: upgrade @web3-react/walletconnect-v2 (#6842)
* chore: upgrade @web3-react/walletconnect-v2

* fix typecheck
2023-06-26 13:15:16 -04:00
Vignesh Mohankumar
3837ce24ac
revert: "feat(wallet-connect): retire v1" (#6841)
Revert "feat(wallet-connect): retire v1 (#6820)"

This reverts commit d6759b86e3702a6da3df211752c06e4ee119d801.
2023-06-26 12:43:16 -04:00
Zach Pomerantz
4b87e3d9b8
test(e2e): skip failing slippage test (#6844) 2023-06-26 12:29:42 -04:00
Jordan Frankfurt
d6759b86e3
feat(wallet-connect): retire v1 (#6820)
* feat(wallet-connect): retire v1

* fix unit test

* Update src/state/user/reducer.ts

Co-authored-by: cartcrom <39385577+cartcrom@users.noreply.github.com>

* useToggleAccountDrawer

* fix test

---------

Co-authored-by: cartcrom <39385577+cartcrom@users.noreply.github.com>
2023-06-23 15:12:21 -05:00
Jordan Frankfurt
df55456409
fix: chrome tie sort resolution (#6833) 2023-06-23 15:05:47 -05:00
Jack Short
f290787b99
fix: divide by zero error on pool page (#6837)
* fix: divide by zero error on pool page

* removing changes here

* adding price in conditional

---------

Co-authored-by: John Short <john.short@CORN-Jack-899.local>
2023-06-23 15:56:41 -04:00
Zach Pomerantz
2f84507a23
chore: add CODEOWNERS to public (#6813) 2023-06-23 14:41:14 -04:00
Zach Pomerantz
96c58361a5
build: rm global yarn cache (#6822)
* build: omit caching global modules

* docs: build omitting cache
2023-06-23 14:41:06 -04:00
Zach Pomerantz
011136d0e9
build: improve workflow caching (#6825)
* build: only cache on main

* build: do not glob yarn.lock

* build: do not cache on yarn.lock
2023-06-23 14:40:58 -04:00
Vignesh Mohankumar
054d1de88a
chore: upgrade @web3-react/walletconnect-v2 (#6831) 2023-06-23 14:40:30 -04:00
Jack Short
ebab00d7bd
fix: adding wallet connect v2 behind feature flag (#6826)
* fix: adding wallet connect v2 behind feature flag

* passing unit tests
2023-06-22 16:16:41 -04:00
Brendan Wong
01dc10d4f3
fix: scroll behavior on MP on mobile (#6750)
* fix: update overflow

* fix: add margin for mobile

* fix: update css to use built in styling
2023-06-22 16:11:23 -04:00
Brendan Wong
fb3abf275e
fix: added op and arb as base tokens (#6810)
* fix: added op and arb as base tokens

* fix: unit testing
2023-06-22 16:10:49 -04:00
Zach Pomerantz
f6ad694200
build: fix slack markdown (#6811)
* build: fix slack markdown

* build: simpler slack messages

* build: simpler message
2023-06-22 14:52:26 -04:00
Zach Pomerantz
a3d72a4bbc
build: simplify workflows (#6814)
* build: simplify workflows

* docs: better name
2023-06-22 14:48:42 -04:00
Vignesh Mohankumar
1bb750f136
feat: track quote method in Quote Received event (#6807)
* WIP

* WIP

* more work

* comment

* fix

* v2slice

* add method to data

* add names

* fellback

* rm-log

* only success
2023-06-22 14:19:23 -04:00
Zach Pomerantz
5315272694
chore: rm committed t9n (#6792)
* chore: rm committed t9n

* chore: ignore t9n

* test(e2e): fix locale selection test
2023-06-22 09:30:06 -04:00
Jordan Frankfurt
43b9e398b5
fix: allow more session namespace keys (#6802)
* allow more session namespace keys

* pr feedback

* add test case
2023-06-21 17:02:13 -05:00
eddie
1247989cf4
fix: cut off wallet icon (#6815) 2023-06-21 14:35:08 -07:00
Jordan Frankfurt
45a5ca3b88
feat: sort supported chains to top of the chain selector list (#6800)
* feat: sort supported chains to top of the chain selector list

* pr feedback

---------

Co-authored-by: Jordan Frankfurt <jordan@CORN-Jordan-949.frankfurt>
2023-06-21 16:10:46 -05:00
eddie
54b4567a81
test: add e2e test for usdt special case (#6784)
* feat: revoke USDT approvals in ConfirmSwapModal

* chore: fix bad merge

* test: add e2e test for usdt special case

* fix: refactor test

* fix: make variable static

* fix: comments
2023-06-21 14:02:14 -07:00
Jordan Frankfurt
fc45a504fb
fix: log the error message instead of [object Object] (#6773)
* fix: log the error message instead of [object Object]

add tina's rec

pr review

zzmp input

* pr feedback
2023-06-21 15:35:23 -05:00
eddie
052cc69414
feat: log minimum_output_after_slippage to amplitude (#6769)
* feat: log minimum_output_after_slippage to amplitude

* fix: memoize logging props

* fix: dont memoize at all
2023-06-21 10:22:48 -07:00
Zach Pomerantz
5caaaf1b1f
test(e2e): switching network (#6662)
* test(e2e): switching network

Co-authored-by: Jordan Frankfurt <<jordan@CORN-Jordan-949.frankfurt>

* fix: reconnect after failed chain switch

* test(e2e): add forks to hardhat.config

* test(e2e): wait on wallet_switchEthereumChain

* build: upgrade cypress-hardhat

* fix: do not disconnect whilst switching

* fix: unit tests

* fix: better chain selector check

* test(e2e): better helper fn naming

* test(e2e): better stub naming

* fix: doc re-activation

* fix: add back click

* build: upgrade cypress-hardhat to include network caching

* unwrap web3status

---------

Co-authored-by: Jordan Frankfurt <<jordan@CORN-Jordan-949.frankfurt>
2023-06-21 13:15:03 -04:00
Zach Pomerantz
c0163767ed
build: rm crowdin-sync (#6793) 2023-06-21 10:45:21 -04:00
Zach Pomerantz
342b0c81f6
chore: rm pseudo locale (#6794)
chore: rm pseudo t9n
2023-06-21 10:45:03 -04:00
Jordan Frankfurt
cb21750b87
fix: remove unused types (#6791)
* fix: remove unused types

* update name
2023-06-16 14:38:03 -05:00
Jordan Frankfurt
2e8ef480f9
feat(testnets): add toggle for testnets (#6786)
* feat(testnets): add toggle for testnets

* e2e test

* update toggle syntax and fix a bug

* simplify list calculation per eddie's input

* add all testnets

* clean up the styles

* Update src/components/NavBar/ChainSelector.tsx

* fix lint
2023-06-16 14:09:05 -05:00
Nate Wienert
f27bba9ffa
fix: use shortenAddress for mini portfolio addresses (#6774)
* fix: use shortenAddress for mini portfolio addresses

* Update src/utils/addresses.ts

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

---------

Co-authored-by: Jordan Frankfurt <jordanwfrankfurt@gmail.com>
2023-06-16 08:51:03 -10:00
eddie
6528fd136e
feat: log swap failures to amplitude (#6789) 2023-06-16 11:20:09 -07:00
Zach Pomerantz
eb802266e1
build: rm ignored en-US (#6790) 2023-06-16 13:05:49 -05:00
Jordan Frankfurt
5bec0b78da
fix: update copy per Fred's input (#6787) 2023-06-16 12:46:59 -05:00
Zach Pomerantz
4894460821
build: download translations when pushing to staging (#6780)
* build: pin crowdin action

* build: download t9n to staging
2023-06-16 12:41:32 -05:00
Vignesh Mohankumar
f3889e326e
chore: migrate from JIRA to Linear (#6747)
* chore: migrate from JIRA to Linear

* INFRA -> WEB
2023-06-16 12:48:27 -04:00
Jordan Frankfurt
2d61c72588
feat(wallet-connect): make v2 the default walletconnect method (#6785)
* explicitly enumerate all supported wcv2 methods as optional ?

* use only sign methods in optionalMethods

* rename class

* feat(wallet-connect): make v2 the default

* fix loader and menu button occlusion

* fix test

* pr feedback from zzmp

* update connector name

* add slack convo link from x-walletconnect
2023-06-16 11:33:37 -05:00
Brendan Wong
1a634c350a
fix: success indication for copy (#6711)
* fix: success indication for copy

* fix: remove redundant styles
2023-06-15 20:51:11 -04:00
eddie
35b83ab842
feat: revoke USDT approvals in ConfirmSwapModal (#6730) 2023-06-15 17:12:10 -07:00
eddie
c0d42ade6f
fix: clear dependent variable when trade inputs become invalid (#6782)
* fix: handle polling interrupt separately from invalid trades

* fix: clear output when trade becomes invalid, dont use stale trade

* fix: tests

* fix: invert skip

* fix: remove debounce delay
2023-06-15 16:05:57 -07:00
eddie
0e2344ba85
feat: refactor ConfirmSwapModal for clarity (#6729)
* feat: refactor ConfirmSwapModal for clarity

* fix: remove reset effect for now

* fix: catchUserReject update

* fix: remove unnecessary awaits
2023-06-15 15:31:41 -07:00
Tina
309d03b5e7
feat: Bump default auto-slippage to 0.5% (#6778)
bump default to 0.5%
2023-06-15 18:10:28 -04:00
Vignesh Mohankumar
8d32e315ed
feat: filter moz-extension errors (#6781) 2023-06-15 18:05:39 -04:00
Jack Short
1c8b3f0339
fix: currency select modal when chain is not supported (#6759)
* fix: currency select modal when chain is not supported

* removing pay with if on unsupported network

* refactor
2023-06-15 12:39:35 -04:00
eddie
fc83659041
fix: bottom padding on error modal (#6758) 2023-06-15 09:16:32 -07:00
cartcrom
e8f5a0e8c8
feat: detect more injections (#6752)
* feat: detect more injectors

* feat: added comments

* refactor: move image folder

* test: add tests for new injectors

* feat: small test change

* fix: update comment about coinbase injection

* test: update snapshots

* fix: pr nits
2023-06-15 12:08:54 -04:00
Jordan Frankfurt
9e213fc396
fix: update web3-react (#6749)
* fix: update web3-react

* update flakey snapshot test and add required config var

* revert snapshot change

* allow ^

* update lockfile with permissive version

* add newly required explicit options for @web3modal
2023-06-15 10:55:19 -05:00
Saro Vindigni
f10ba73529
fix: <a> cannot appear as a descendant of <a> (#6737)
* fix: <a> cannot appear as a descendant of <a>

* refact: change render logic to SwitchLocaleLink
2023-06-15 10:02:18 -05:00
Jordan Frankfurt
c2a83cabaa
feat: add loading indicator to activity tab in mini portfolio (#6754)
* feat: add loading indicator to activity tab in mini portfolio

* should not render spinner when activity key is active

* add an unread notification dot that is dismissed when the user visits the activity tab

* pr feedback
2023-06-14 19:06:10 -05:00
Jordan Frankfurt
7a3c51bc90
fix: uniswap_wallet -> uniwallet (#6764)
* fix: uniswap_wallet -> uniwallet

update tests

Revert "fix: uniswap_wallet -> uniwallet"

This reverts commit 7bdf34b33025d0b564c5870b073eb20e3d1774e1.

Revert "update tests"

This reverts commit cc841cb5e01a1a239f79fa4d9d480e6479128f08.

add migration

* refactor: add deprecated value back to enum (#6768)

* add deprecated value back to enum

* Update src/connection/types.ts

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

---------

Co-authored-by: Charles Bachmeier <charlie@genie.xyz>
Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* add deprecated case to getConnection

---------

Co-authored-by: Charles Bachmeier <charles@bachmeier.io>
Co-authored-by: Charles Bachmeier <charlie@genie.xyz>
Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-06-14 18:16:12 -05:00
eddie
e69a7c2712
feat: log user router preference as a user property (#6761)
* feat: log router preference in user properties

* fix: update analytics events
2023-06-14 16:03:23 -07:00
Vignesh Mohankumar
d149512d93
fix: update arbitrum subgraph (#6679) 2023-06-14 17:14:05 -04:00
eddie
5826ed15c8
fix: remove sentry logging for swap failures (#6765) 2023-06-14 11:16:05 -07:00
eddie
3db9e1b9a4
feat: rename permit2 variables for clarity (#6728)
* feat: rename permit2 variables for clarity

* fix: types
2023-06-14 11:13:54 -07:00
eddie
79a72d6fe2
feat: update permit2 hook to allow revoking (#6727)
* feat: update permit2 hook to allow revoking

* fix: types

* fix: rename reset to revoke

* fix: re-use useUpdateTokenAllowance

* fix: add tests

* fix: improve code style

* fix: undefined nit
2023-06-14 10:26:12 -07:00
Brendan Wong
f3bfd4ad41
fix: prevent scrolling with settings modal open (#6739)
* fix: prevent scrolling with settings modal open

* fix: create hook

* fix: create tests

* fix: simplify useeffect and add JSDoc
2023-06-14 12:30:42 -04:00
Brendan Wong
45acf421b3
fix: tick labels respond to width of the graph (#6741)
* fix: tick labels respond to width of the graph

* fix: add description to new useeffect

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-06-14 12:30:22 -04:00
Saro Vindigni
2c5ea67ada
fix: remove gradientId from svg props (#6751) 2023-06-14 11:14:07 -05:00
eddie
2e141ac94c
fix: make text white in success state (#6755) 2023-06-13 14:20:26 -07:00
eddie
8b16f454ca
feat: add amount to local copy of Approval transactions (#6726)
* feat: add amount to local copy of Approval transactions

* fix: use alternate

* fix: type problem

* feat: add test
2023-06-13 13:55:45 -07:00
Tina
094664dc7a
chore: Feature flag cleanup for Arbitrum native USDC (#6743)
remove feature flag stuff
2023-06-12 15:20:24 -04:00
Charles Bachmeier
62a6ef00da
fix: [DetailsV2] flaky time relevant test (#6753)
fix flaky time relevant test

Co-authored-by: Charles Bachmeier <charlie@genie.xyz>
2023-06-12 10:51:11 -07:00
Tina
3a739476ca
fix: Catch routing-api v2 no liquidity error case (#6742)
catch URA no liquidity case
2023-06-12 12:25:24 -04:00
Tina
04e4335cc2
feat: Use routing-api or URA for price fetches behind feature flag (#6740)
use routing-api or URA for price fetches behind feature flag
2023-06-09 15:07:53 -04:00
Zach Pomerantz
4235b57cd8
build: make codecov reports consistent/not confusing (#6734)
* build: codecov config

* build: better codecov

* build: omit default

* build: sensical codecov

* build: upload-artifact

* build: customize codecov comment

* build: try again

* build: try again

* build: turn off status except flags

* build: flag comments

* build: changes on

* build: simplify

* build: after_n for comment
2023-06-09 11:00:27 -07:00
Charles Bachmeier
cb362f1b2c
fix: Handle scientific notation for NFT Details pricing (#6707)
* fix: Handle scientific notation for NFT Details pricing

* add test case

---------

Co-authored-by: Charles Bachmeier <charlie@genie.xyz>
2023-06-09 09:10:40 -07:00
Jack Short
a4d61d8eaa
fix: insufficient liquidity state flashes (#6733) 2023-06-09 12:10:13 -04:00
Jack Short
310623b948
fix: language updating in search bar (#6720) 2023-06-09 11:56:20 -04:00
Shubham Rasal
b7303fb9c0
style: navbar ui updated (#6627)
* ui: navbar ui updated

* added margin right

* moved style to higher component
2023-06-09 08:52:52 -07:00
Jack Short
4fbb8e9117
chore: removing error state for rejecting chain switch (#6713)
* chore: removing error state for rejecting chain switch

* removing connection error state
2023-06-09 11:45:35 -04:00
Zach Pomerantz
f0502bfc33
build: rm old release workflow (#6731) 2023-06-08 14:52:24 -07:00
eddie
98f4af55c9
fix: stop resetting modal when we interrupt quote polling (#6695)
* test(e2e): disable video compression

* refactor: improve popupList impl/test

* test(e2e): log JSON-RPC calls

* fix: retry backoff logic

* test(e2e): wait for hardhat/popup assertions

* fix: remove transactions after expired

* test(e2e): re-enable other swap tests

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

* chore: rm console.log

* fix: expire txs after 6h

* refactor: dry trade info

* test(e2e): use default deadline

* test(e2e): use aliases for permit2 test

* test(e2e): automine/off in beforeEach

* test(e2e): rm intermediate screen with no pause

* fix: stop resetting modal when we interrupt quote polling'

* feat: add e2e test for window losing focus

* fix: move test

* fix: combine tests

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
Co-authored-by: Jordan Frankfurt <jordanwfrankfurt@gmail.com>
2023-06-08 13:44:47 -07:00
Jordan Frankfurt
08b8bdd769
chore: update @web3-react/walletconnect-v2 (#6724) 2023-06-08 14:20:14 -05:00
Jordan Frankfurt
1283199d0d
fix: remove mainnet from optional chains list (#6725)
* fix: remove mainnet from optional chains list

* simplify imports
2023-06-08 14:09:41 -05:00
Jack Short
c1fff5ea49
fix: time interval axis overlap (#6717) 2023-06-08 13:26:25 -04:00
cartcrom
94adc449a1
refactor: convert getConnection to non-hook (#6714)
* refactor: convert getConnection to non-hook

* fix: remove getConnection from hook dependecies

* fix: unecessary optional
2023-06-08 13:06:46 -04:00
eddie
4b24e5f754
fix: remove step indicators in sucess state (#6716) 2023-06-08 09:14:39 -07:00
eddie
e0a531e538
fix: type error in cypress infra (#6700) 2023-06-07 18:16:57 -07:00
eddie
8cef1ca0f7
fix: bottom padding on swap modal (#6715)
<!-- Your PR title must follow conventional commits: https://github.com/Uniswap/interface#pr-title -->

## Description
<!-- Summary of change, including motivation and context. -->
<!-- Use verb-driven language: "Fixes XYZ" instead of "This change fixes XYZ" -->


<!-- Delete inapplicable lines: -->
_Linear ticket:_ https://linear.app/uniswap/issue/WEB-2151/permit2-fix-dialog-window-height


<!-- Delete this section if your change does not affect UI. -->
## Screen capture

### Before
|    Mobile    |   Desktop    |
| ------------ | ------------ |
| paste_before | <img width="516" alt="image" src="https://github.com/Uniswap/interface/assets/66155195/4b7320c3-9bd3-4c5c-8d28-341a5ae7fa4f"> |


### After
|    Mobile    |   Desktop   |
| ------------ | ----------- |
| paste_after  | ![image](https://github.com/Uniswap/interface/assets/66155195/8b112a05-39d5-4a01-b412-47a7d74d040f) |
2023-06-07 18:09:20 -07:00
Zach Pomerantz
088f1d9ae4
test(e2e): use aliases for permit2 test (#6656)
* test(e2e): disable video compression

* refactor: improve popupList impl/test

* test(e2e): log JSON-RPC calls

* fix: retry backoff logic

* test(e2e): wait for hardhat/popup assertions

* fix: remove transactions after expired

* test(e2e): re-enable other swap tests

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

* chore: rm console.log

* fix: expire txs after 6h

* refactor: dry trade info

* test(e2e): use default deadline

* test(e2e): use aliases for permit2 test

* test(e2e): automine/off in beforeEach

* test(e2e): rm intermediate screen with no pause

* fix merge

* fix only

---------

Co-authored-by: Jordan Frankfurt <jordanwfrankfurt@gmail.com>
2023-06-07 17:55:27 -07:00
Nate Wienert
89a7d98b41
ci: fix wallet disconnect test regression (#6723) 2023-06-07 13:17:58 -10:00
Zach Pomerantz
0076fdc65b
test(e2e): skip outdated disconnect-wallet test (#6722) 2023-06-07 16:57:37 -04:00
Nate Wienert
48b4a533c3
feat: disconnect button has confirmation step with animated width transition to show confirm text (#6668)
* feat: changes disconnect button to a two-step animated button with confirmation

* fix: use ConfirmSwapModal in expert mode (#6673)

Fixes the swap flow for users who are still in expert mode  and need permit2 approvals for a token

---------

Co-authored-by: eddie <66155195+just-toby@users.noreply.github.com>
2023-06-07 09:37:32 -10:00
Zach Pomerantz
0b66fde26c
fix: only remove expired transactions from updater (#6625)
* test(e2e): disable video compression

* refactor: improve popupList impl/test

* test(e2e): log JSON-RPC calls

* fix: retry backoff logic

* test(e2e): wait for hardhat/popup assertions

* fix: remove transactions after expired

* test(e2e): re-enable other swap tests

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

* chore: rm console.log

* fix: expire txs after 6h

* refactor: dry trade info

* test(e2e): use default deadline

---------

Co-authored-by: Jordan Frankfurt <jordanwfrankfurt@gmail.com>
2023-06-07 09:29:23 -07:00
Jordan Frankfurt
5788385951
feat(wallet-connect): add support for v2 (#6582)
* feat(wallet-connect): add support for v2

* use theme button to fix opacity issue

* fix lint

* add new web3-react v2 package

* add mainnet to chains list

* fix test

* yarn dedupe

* add new @walletconnect/ethereum-provider

* fix safari padding

* fix second-click flash on popover toggle

* add walletconnect theme

* add goerli to non-prod chain selector

* remove: debug

* remove vertical line

* WEB-2107 Fix modal close behavior

* remove logging

* clean up accountDrawerOpenAtom usage

* remove irrelevant comments

* remove unintentional whitespace diff

* yarn yarn-deduplicate --strategy=highest

* add conditional chain selector

* update wc package version

* goerli -> sepolia

* goerli -> sepolia

* yarn yarn-deduplicate --strategy=highest

* UNIWALLET -> UNISWAP_WALLET

* useWalletSupportsChain -> useWalletSupportedChains

* use TOGGLE_SIZE

* remove inline styles

* remove inline styles and use better alt text

* update Option.test

* use a named function for forwardRef arg

* fix types

---------

Co-authored-by: Jordan Frankfurt <jordan@CORN-Jordan-949.frankfurt>
2023-06-07 11:11:08 -05:00
Brendan Wong
0891e67528
fix: token bridge pointer bug (#6670)
* fix: token bridge pointer bug

* fix: use zIndex enum instead of hardcoded
2023-06-07 10:18:48 -04:00
Brendan Wong
b319acd9c4
fix: info labels for extended list tokens (#6678)
* fix: info labels for extended list tokens

* test: update warning tests for new changes

* fix: function for label and padding

* fix: use warning check function

* fix: update displayWarningLabel
2023-06-07 10:15:36 -04:00
Brendan Wong
05977f950b
fix: updated celo logo (#6676)
* fix: updated celo logo

* fix: use celo logo from local fs

* fix: removed outdated comments

* fix: combine if statements in celo check

* fix: fix lint
2023-06-07 10:15:06 -04:00
Nate Wienert
5ac36d4156
feat: add link to download the uniswap wallet to the homepage (#6690)
* feat: add link to download the uniswap wallet to the homepage
2023-06-06 14:17:42 -10:00
clrdo
fb998706c2
fix: swaps with native currency destination in BNB Chain (#6705)
fix: swaps with native currency destination in BNB Chain

Co-authored-by: clrdo <clrdo@github.com>
2023-06-06 16:48:36 -05:00
eddie
c45492c890
feat: log swap errors to sentry (#6698)
* feat: log swap errors to sentry

* fix: dont stringify
2023-06-06 13:31:46 -07:00
eddie
41219b435f
feat: update content in permit2 flow (#6699) 2023-06-06 13:30:06 -07:00
eddie
e1321843de
fix: disable settings button when contextual chainId !== connectedChainId (#6696)
* fix: disable settings button when contextual chainId !== connectedChainId

* fix: re-enable TDP tests (#6708)
2023-06-06 13:28:21 -07:00
Charles Bachmeier
0baa8a1fff
feat: upgrade to node 18 (#6606)
* feat: upgrade to node 18

* use 18.x

* try removing npx from fetch schema fn

* use yarn

* setup github build on 18

* no yarn

* use yarn and sanitize output

* yarn silent

* update workflows

* fully remove unused step

---------

Co-authored-by: Charles Bachmeier <charlie@genie.xyz>
2023-06-06 11:59:03 -07:00
Zach Pomerantz
f2a3b66357
test(e2e): simplify and re-enable token explore filter test (#6660) 2023-06-06 09:05:16 -07:00
Zach Pomerantz
f2af46037e
test(e2e): wallet connection (#6661) 2023-06-06 08:57:04 -07:00
Zach Pomerantz
20a06c9b5a
test: skip SwapDetailsDropdown tests (#6652)
* test: skip SwapDetailsDropdown tests

Tests depend on network requests, which may cause flakiness.
These tests should have the network requests mocked, then be re-enabled.

* add TODO

---------

Co-authored-by: cartcrom <cartergcromer@gmail.com>
2023-06-05 22:03:05 -07:00
Zach Pomerantz
8ef54d41b6
docs(e2e): cypress README (#6523)
* docs(e2e): best practices

* docs: rewording running

* wip: thenable

* docs(e2e): writing tests
2023-06-05 19:38:25 -07:00
Jordan Frankfurt
1cdddd1321
chore: add better documentation to a complicated hook (#6689)
* chore: add better documentation to a complicated hook

* input from eddie

* Update src/hooks/useUnmountingAnimation.ts

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* remove jsdoc types

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-06-05 20:34:34 -05:00
Brendan Wong
f834af69fe
fix: Trust wallet loading state (#6694) 2023-06-05 16:25:30 -04:00
Jordan Frankfurt
08cd4bec41
fix: add '-' instead of '$0.00' when the api does not return a price for a tokens page entry (#6691)
* fix: show '-' instead of .00 when we don't have price data on a token

* explicitly handle the 0 case

* add tests to token row component
2023-06-05 14:56:49 -05:00
cartcrom
63ac64f470
fix: use coned function for chart prices (#6693) 2023-06-05 15:40:03 -04:00
Nate Wienert
72686f1e32
ci: temporarily disable coverage tests as they are too flakey (#6684) 2023-06-05 06:42:59 -10:00
Jordan Frankfurt
c07359362f
feat: dismiss the landing page when the account drawer is opened (#6633)
* feat: dismiss the landing page when the account drawer is opened

* remove the gradient before the page transition

* pr feedback

* clean up darkmode handling

* pr feedback from design

* update link test

---------

Co-authored-by: Jordan Frankfurt <jordan@CORN-Jordan-949.frankfurt>
2023-06-05 11:37:18 -05:00
cartcrom
ed58c39bdc
feat: parse moonpay purchases (#6677)
* feat: parse moonpay purchases

* fix: update comment

* fix: use new coned function

* refactor: simplify nested if statements
2023-06-02 16:46:57 -04:00
Nate Wienert
5d2254be27
fix: searchbar showing incorrect spacing at medium size (#6637)
* fix: searchbar showing incorrect spacing at medium size

* refactor: remove media query navSearchInputVisible into hook only useNavSearchInputVisible

* fix: disable slight blur showing incorrectly when 1100px to lg breakpoint width

* build: use repository slack secret (#6639)

* feat: add animation to Settings menu (#6617)

* feat: add price impact back

* chore: update tes tname

* chore: update snapshot for price impact

* fix

* fix

* update snapshot after rebase

* update snapshot

* chore: finish

* chore: remove snapshot

* feat: add test matcher

* cleanup

* chore: add animation test

* add comment

* update comment

* fix: no-undefined-or in object field types (#6640)

* feat: show affordance in swap UI when we can't fetch usd quote (#6622)

* initial commit:

* add todo to linear

* fix: increase useBestTrade debounce time (#6631)

* fix: increase useBestTrade debounce time

* reduce

* increase

* 350

* fix

* build: caching i18n extractor (#6619)

* fix: do not attempt to cache i18n:extract

* fix: i18n extraction

* docs: improve comments

* fix: remove app advert on mobile safari (#6630)

Co-authored-by: Jordan Frankfurt <jordan@CORN-Jordan-949.frankfurt>

* fix: include sw metric with web vitals (#6646)

* build: add vscode settings for default formatter (#6644)

build: add vscode settings for default formatter to be dbaeumer.vscode-eslint

* test(e2e): improve hardhat configuration (#6650)

build: cache hardhat cache

* feat: permit2 flow updates (#6538)

* test: swap flow cypress tests

* fix: use default parameter

* feat: use Swap Component on TDP

* feat: auto nav for TDP tokens

* chore: merge

* chore: merge

* chore: merge

* chore: merge

* fix: remove extra inputCurrency URL parsing logic

* fix: undo last change

* fix: pass expected chain id to swap component

* fix: search for default tokens on unconnected networks if needed

* test: e2e test for l2 token

* fix: delete irrelevant tests

* fix: address comments

* fix: lint error

* test: update TDP e2e tests

* fix: use pageChainId for filter

* fix: rename chainId

* fix: typecheck

* fix: chainId bug

* fix: chainId required fixes

* fix: bad merge in e2e test

* fix: remove unused test util

* fix: remove unnecessary variable

* fix: token defaults

* fix: address comments

* fix: address comments and fix tests

* fix: e2e test formatting, remove Maybe<>

* fix: remove unused variable

* fix: use feature flag for swap component on TDP

* fix: back button

* feat: copy review screen UI from widgetg

* fix: modal padding

* feat: add final detail row

* fix: remove widget comment

* fix: update unit tests

* fix: code style consistency

* fix: remove padding from AutoColumn

* fix: update snapshots

* fix: use semantic gaps

* fix: more px and gaps

* fix: design feedbacks

* fix: button radius in summary modal

* fix: design nits

* feat: update design of summary modal

* fix: font weight and vertical spacing

* fix: update snapshots

* fix: css nits

* fix: modal flicker when refetching trade

* wip: move approval to summary modal

* wip: not working

* feat: working

* fix: fix flow

* feat: simplify states and build new modal UI

* feat: todos and differs fix

* feat: update tx status modal

* feat: split up approve and permit

* feat: error state

* feat: update success and error states

* feat: undo changes to TxConfirmationModal

* feat: remove step indicators when only one step

* feat: move content into PendingModalContent component

* fix: lint

* fix: correct modal state when moving between steps

* fix: comments

* fix: code style improvements

* feat: require trade to be defined

* fix: remove extra props from ThemedTexts

* fix: one more trans

* fix: remove unused export

* feat: remove undefined checks and other fixes

* fix: update test

* fix: add missing dollar sign

* fix: remove null check and update test

* fix: remove max width from detail row value

* fix: remove isOpen prop

* fix: isopen

* feat: refactor approval flow into a hook

* fix: tradeMeaningfullyDiffers improvement and prepareFlow fix

* fix: address  comments

* feat: add comments explaining async state

* fix: nits

* fix: address comments

* feat: permit2 e2e tests (#6541)

* wip: move approval to summary modal

* wip: not working

* feat: working

* fix: fix flow

* feat: simplify states and build new modal UI

* feat: todos and differs fix

* feat: update tx status modal

* feat: split up approve and permit

* feat: error state

* feat: update success and error states

* feat: undo changes to TxConfirmationModal

* feat: re-order functions

* wip: move approval to summary modal

* wip: not working

* feat: update permit2 e2e tests

* feat: tests passing

* fix: swap test

* fix: bad merge

* chore: merge

* fix: update tests for new modal

* fix: testid fix

* fix: test updates

* fix: reduce nesting

* test: remove line from test for debugging

* fix: update tests

* fix: more nesting in test

* fix: update test

* fix: reorganize test code

* test: permit2 flow component tests (#6551)

* test: swap flow cypress tests

* fix: use default parameter

* feat: use Swap Component on TDP

* feat: auto nav for TDP tokens

* chore: merge

* chore: merge

* chore: merge

* chore: merge

* fix: remove extra inputCurrency URL parsing logic

* fix: undo last change

* fix: pass expected chain id to swap component

* fix: search for default tokens on unconnected networks if needed

* test: e2e test for l2 token

* fix: delete irrelevant tests

* fix: address comments

* fix: lint error

* test: update TDP e2e tests

* fix: use pageChainId for filter

* fix: rename chainId

* fix: typecheck

* fix: chainId bug

* fix: chainId required fixes

* fix: bad merge in e2e test

* fix: remove unused test util

* fix: remove unnecessary variable

* fix: token defaults

* fix: address comments

* fix: address comments and fix tests

* fix: e2e test formatting, remove Maybe<>

* fix: remove unused variable

* fix: use feature flag for swap component on TDP

* fix: back button

* feat: copy review screen UI from widgetg

* fix: modal padding

* feat: add final detail row

* fix: remove widget comment

* fix: update unit tests

* fix: code style consistency

* fix: remove padding from AutoColumn

* fix: update snapshots

* fix: use semantic gaps

* fix: more px and gaps

* fix: design feedbacks

* fix: button radius in summary modal

* fix: design nits

* feat: update design of summary modal

* fix: font weight and vertical spacing

* fix: update snapshots

* fix: css nits

* wip: move approval to summary modal

* wip: not working

* feat: working

* fix: fix flow

* feat: simplify states and build new modal UI

* feat: todos and differs fix

* feat: update tx status modal

* feat: split up approve and permit

* feat: error state

* feat: update success and error states

* feat: undo changes to TxConfirmationModal

* feat: re-order functions

* wip: move approval to summary modal

* wip: not working

* feat: update permit2 e2e tests

* feat: tests passing

* fix: swap test

* fix: bad merge

* wip: move approval to summary modal

* wip: not working

* feat: PendingModalContent tests

* feat: useMaxAmountIn

* fix: bad merge

* fix: naming

* fix: modal flicker when refetching trade

* wip: move approval to summary modal

* wip: not working

* feat: working

* fix: fix flow

* feat: simplify states and build new modal UI

* feat: todos and differs fix

* feat: update tx status modal

* feat: split up approve and permit

* feat: error state

* feat: update success and error states

* feat: undo changes to TxConfirmationModal

* feat: remove step indicators when only one step

* feat: move content into PendingModalContent component

* fix: lint

* chore: merge

* fix: update tests for new modal

* fix: correct modal state when moving between steps

* fix: comments

* fix: code style improvements

* feat: require trade to be defined

* fix: remove extra props from ThemedTexts

* fix: one more trans

* fix: remove unused export

* feat: remove undefined checks and other fixes

* fix: update test

* fix: add missing dollar sign

* fix: remove null check and update test

* fix: remove max width from detail row value

* fix: remove isOpen prop

* fix: isopen

* feat: refactor approval flow into a hook

* fix: testid fix

* fix: tradeMeaningfullyDiffers improvement and prepareFlow fix

* fix: address  comments

* feat: add comments explaining async state

* fix: test updates

* fix: nits

* fix: reduce nesting

* fix: address comments

* test: remove line from test for debugging

* fix: update tests

* fix: update tests

* fix: more nesting in test

* fix: update test

* fix: reorganize test code

* feat: add l2 chain logo to modal (#6575)

* test: swap flow cypress tests

* fix: use default parameter

* feat: use Swap Component on TDP

* feat: auto nav for TDP tokens

* chore: merge

* chore: merge

* chore: merge

* chore: merge

* fix: remove extra inputCurrency URL parsing logic

* fix: undo last change

* fix: pass expected chain id to swap component

* fix: search for default tokens on unconnected networks if needed

* test: e2e test for l2 token

* fix: delete irrelevant tests

* fix: address comments

* fix: lint error

* test: update TDP e2e tests

* fix: use pageChainId for filter

* fix: rename chainId

* fix: typecheck

* fix: chainId bug

* fix: chainId required fixes

* fix: bad merge in e2e test

* fix: remove unused test util

* fix: remove unnecessary variable

* fix: token defaults

* fix: address comments

* fix: address comments and fix tests

* fix: e2e test formatting, remove Maybe<>

* fix: remove unused variable

* fix: use feature flag for swap component on TDP

* fix: back button

* feat: copy review screen UI from widgetg

* fix: modal padding

* feat: add final detail row

* fix: remove widget comment

* fix: update unit tests

* fix: code style consistency

* fix: remove padding from AutoColumn

* fix: update snapshots

* fix: use semantic gaps

* fix: more px and gaps

* fix: design feedbacks

* fix: button radius in summary modal

* fix: design nits

* feat: update design of summary modal

* fix: font weight and vertical spacing

* fix: update snapshots

* fix: css nits

* wip: move approval to summary modal

* wip: not working

* feat: working

* fix: fix flow

* feat: simplify states and build new modal UI

* feat: todos and differs fix

* feat: update tx status modal

* feat: split up approve and permit

* feat: error state

* feat: update success and error states

* feat: undo changes to TxConfirmationModal

* feat: re-order functions

* wip: move approval to summary modal

* wip: not working

* feat: update permit2 e2e tests

* feat: tests passing

* fix: swap test

* fix: bad merge

* wip: move approval to summary modal

* wip: not working

* feat: PendingModalContent tests

* feat: useMaxAmountIn

* fix: bad merge

* fix: naming

* fix: modal flicker when refetching trade

* wip: move approval to summary modal

* wip: not working

* feat: working

* fix: fix flow

* feat: simplify states and build new modal UI

* feat: todos and differs fix

* feat: update tx status modal

* feat: split up approve and permit

* feat: error state

* feat: update success and error states

* feat: undo changes to TxConfirmationModal

* feat: remove step indicators when only one step

* feat: move content into PendingModalContent component

* fix: lint

* chore: merge

* fix: update tests for new modal

* feat: add l2 chain logo to modal

* feat: add unit test

* fix: correct modal state when moving between steps

* fix: comments

* fix: code style improvements

* feat: require trade to be defined

* fix: remove extra props from ThemedTexts

* fix: one more trans

* fix: remove unused export

* feat: remove undefined checks and other fixes

* fix: update test

* fix: add missing dollar sign

* fix: remove null check and update test

* fix: remove max width from detail row value

* fix: remove isOpen prop

* fix: isopen

* feat: refactor approval flow into a hook

* fix: testid fix

* fix: tradeMeaningfullyDiffers improvement and prepareFlow fix

* fix: address  comments

* fix: headerContent prop

* feat: add comments explaining async state

* fix: test updates

* fix: nits

* fix: reduce nesting

* fix: address comments

* test: remove line from test for debugging

* fix: update tests

* fix: address  comments

* fix: update tests

* fix: more nesting in test

* fix: update test

* fix: reorganize test code

* feat: swap rejection error handling (#6576)

* test: swap flow cypress tests

* fix: use default parameter

* feat: use Swap Component on TDP

* feat: auto nav for TDP tokens

* chore: merge

* chore: merge

* chore: merge

* chore: merge

* fix: remove extra inputCurrency URL parsing logic

* fix: undo last change

* fix: pass expected chain id to swap component

* fix: search for default tokens on unconnected networks if needed

* test: e2e test for l2 token

* fix: delete irrelevant tests

* fix: address comments

* fix: lint error

* test: update TDP e2e tests

* fix: use pageChainId for filter

* fix: rename chainId

* fix: typecheck

* fix: chainId bug

* fix: chainId required fixes

* fix: bad merge in e2e test

* fix: remove unused test util

* fix: remove unnecessary variable

* fix: token defaults

* fix: address comments

* fix: address comments and fix tests

* fix: e2e test formatting, remove Maybe<>

* fix: remove unused variable

* fix: use feature flag for swap component on TDP

* fix: back button

* feat: copy review screen UI from widgetg

* fix: modal padding

* feat: add final detail row

* fix: remove widget comment

* fix: update unit tests

* fix: code style consistency

* fix: remove padding from AutoColumn

* fix: update snapshots

* fix: use semantic gaps

* fix: more px and gaps

* fix: design feedbacks

* fix: button radius in summary modal

* fix: design nits

* feat: update design of summary modal

* fix: font weight and vertical spacing

* fix: update snapshots

* fix: css nits

* wip: move approval to summary modal

* wip: not working

* feat: working

* fix: fix flow

* feat: simplify states and build new modal UI

* feat: todos and differs fix

* feat: update tx status modal

* feat: split up approve and permit

* feat: error state

* feat: update success and error states

* feat: undo changes to TxConfirmationModal

* feat: re-order functions

* wip: move approval to summary modal

* wip: not working

* feat: update permit2 e2e tests

* feat: tests passing

* fix: swap test

* fix: bad merge

* wip: move approval to summary modal

* wip: not working

* feat: PendingModalContent tests

* feat: useMaxAmountIn

* fix: bad merge

* fix: naming

* fix: modal flicker when refetching trade

* wip: move approval to summary modal

* wip: not working

* feat: working

* fix: fix flow

* feat: simplify states and build new modal UI

* feat: todos and differs fix

* feat: update tx status modal

* feat: split up approve and permit

* feat: error state

* feat: update success and error states

* feat: undo changes to TxConfirmationModal

* feat: remove step indicators when only one step

* feat: move content into PendingModalContent component

* fix: lint

* chore: merge

* fix: update tests for new modal

* feat: add l2 chain logo to modal

* feat: add unit test

* fix: correct modal state when moving between steps

* fix: correct modal state when moving between steps

* fix: proper error handling of user rejection of swap

* feat: update e2e test

* fix: typecheck

* fix: comments

* fix: code style improvements

* feat: require trade to be defined

* fix: remove extra props from ThemedTexts

* fix: one more trans

* fix: remove unused export

* feat: remove undefined checks and other fixes

* fix: update test

* fix: add missing dollar sign

* fix: remove null check and update test

* fix: remove max width from detail row value

* fix: remove isOpen prop

* fix: isopen

* feat: refactor approval flow into a hook

* fix: custom error type

* fix: testid fix

* fix: add comment

* fix: tradeMeaningfullyDiffers improvement and prepareFlow fix

* fix: address  comments

* fix: headerContent prop

* feat: add comments explaining async state

* fix: test updates

* fix: nits

* fix: reduce nesting

* fix: address comments

* test: remove line from test for debugging

* fix: update tests

* fix: address  comments

* fix: update tests

* fix: more nesting in test

* fix: update test

* fix: update e2e test

* fix: update error test

* fix: reorganize test code

* feat: update content in Swap Submission Modal (#6577)

* test: swap flow cypress tests

* fix: use default parameter

* feat: use Swap Component on TDP

* feat: auto nav for TDP tokens

* chore: merge

* chore: merge

* chore: merge

* chore: merge

* fix: remove extra inputCurrency URL parsing logic

* fix: undo last change

* fix: pass expected chain id to swap component

* fix: search for default tokens on unconnected networks if needed

* test: e2e test for l2 token

* fix: delete irrelevant tests

* fix: address comments

* fix: lint error

* test: update TDP e2e tests

* fix: use pageChainId for filter

* fix: rename chainId

* fix: typecheck

* fix: chainId bug

* fix: chainId required fixes

* fix: bad merge in e2e test

* fix: remove unused test util

* fix: remove unnecessary variable

* fix: token defaults

* fix: address comments

* fix: address comments and fix tests

* fix: e2e test formatting, remove Maybe<>

* fix: remove unused variable

* fix: use feature flag for swap component on TDP

* fix: back button

* feat: copy review screen UI from widgetg

* fix: modal padding

* feat: add final detail row

* fix: remove widget comment

* fix: update unit tests

* fix: code style consistency

* fix: remove padding from AutoColumn

* fix: update snapshots

* fix: use semantic gaps

* fix: more px and gaps

* fix: design feedbacks

* fix: button radius in summary modal

* fix: design nits

* feat: update design of summary modal

* fix: font weight and vertical spacing

* fix: update snapshots

* fix: css nits

* wip: move approval to summary modal

* wip: not working

* feat: working

* fix: fix flow

* feat: simplify states and build new modal UI

* feat: todos and differs fix

* feat: update tx status modal

* feat: split up approve and permit

* feat: error state

* feat: update success and error states

* feat: undo changes to TxConfirmationModal

* feat: re-order functions

* wip: move approval to summary modal

* wip: not working

* feat: update permit2 e2e tests

* feat: tests passing

* fix: swap test

* fix: bad merge

* wip: move approval to summary modal

* wip: not working

* feat: PendingModalContent tests

* feat: useMaxAmountIn

* fix: bad merge

* fix: naming

* fix: modal flicker when refetching trade

* wip: move approval to summary modal

* wip: not working

* feat: working

* fix: fix flow

* feat: simplify states and build new modal UI

* feat: todos and differs fix

* feat: update tx status modal

* feat: split up approve and permit

* feat: error state

* feat: update success and error states

* feat: undo changes to TxConfirmationModal

* feat: remove step indicators when only one step

* feat: move content into PendingModalContent component

* fix: lint

* chore: merge

* fix: update tests for new modal

* feat: add l2 chain logo to modal

* feat: add unit test

* fix: correct modal state when moving between steps

* fix: correct modal state when moving between steps

* fix: proper error handling of user rejection of swap

* feat: update e2e test

* fix: typecheck

* feat: design updates, state updates

* fix: comments

* fix: code style improvements

* feat: require trade to be defined

* fix: remove extra props from ThemedTexts

* fix: one more trans

* fix: remove unused export

* feat: remove undefined checks and other fixes

* fix: update test

* fix: add missing dollar sign

* fix: remove null check and update test

* fix: remove max width from detail row value

* fix: remove isOpen prop

* fix: isopen

* feat: refactor approval flow into a hook

* fix: custom error type

* fix: testid fix

* fix: text colors

* fix: add comment

* fix: tradeMeaningfullyDiffers improvement and prepareFlow fix

* fix: address  comments

* fix: headerContent prop

* fix: change tooltip to external link

* feat: add comments explaining async state

* fix: test updates

* fix: nits

* fix: reduce nesting

* fix: address comments

* test: remove line from test for debugging

* fix: update tests

* fix: address  comments

* fix: comments

* fix: update tests

* fix: update tests

* fix: more nesting in test

* fix: update test

* fix: update e2e test

* fix: update error test

* fix: update content in test

* fix: reorganize test code

* feat: permit2 animations WEB-2036 (#6590)

* test: swap flow cypress tests

* fix: use default parameter

* feat: use Swap Component on TDP

* feat: auto nav for TDP tokens

* chore: merge

* chore: merge

* chore: merge

* chore: merge

* fix: remove extra inputCurrency URL parsing logic

* fix: undo last change

* fix: pass expected chain id to swap component

* fix: search for default tokens on unconnected networks if needed

* test: e2e test for l2 token

* fix: delete irrelevant tests

* fix: address comments

* fix: lint error

* test: update TDP e2e tests

* fix: use pageChainId for filter

* fix: rename chainId

* fix: typecheck

* fix: chainId bug

* fix: chainId required fixes

* fix: bad merge in e2e test

* fix: remove unused test util

* fix: remove unnecessary variable

* fix: token defaults

* fix: address comments

* fix: address comments and fix tests

* fix: e2e test formatting, remove Maybe<>

* fix: remove unused variable

* fix: use feature flag for swap component on TDP

* fix: back button

* feat: copy review screen UI from widgetg

* fix: modal padding

* feat: add final detail row

* fix: remove widget comment

* fix: update unit tests

* fix: code style consistency

* fix: remove padding from AutoColumn

* fix: update snapshots

* fix: use semantic gaps

* fix: more px and gaps

* fix: design feedbacks

* fix: button radius in summary modal

* fix: design nits

* feat: update design of summary modal

* fix: font weight and vertical spacing

* fix: update snapshots

* fix: css nits

* wip: move approval to summary modal

* wip: not working

* feat: working

* fix: fix flow

* feat: simplify states and build new modal UI

* feat: todos and differs fix

* feat: update tx status modal

* feat: split up approve and permit

* feat: error state

* feat: update success and error states

* feat: undo changes to TxConfirmationModal

* feat: re-order functions

* wip: move approval to summary modal

* wip: not working

* feat: update permit2 e2e tests

* feat: tests passing

* fix: swap test

* fix: bad merge

* wip: move approval to summary modal

* wip: not working

* feat: PendingModalContent tests

* feat: useMaxAmountIn

* fix: bad merge

* fix: naming

* fix: modal flicker when refetching trade

* wip: move approval to summary modal

* wip: not working

* feat: working

* fix: fix flow

* feat: simplify states and build new modal UI

* feat: todos and differs fix

* feat: update tx status modal

* feat: split up approve and permit

* feat: error state

* feat: update success and error states

* feat: undo changes to TxConfirmationModal

* feat: remove step indicators when only one step

* feat: move content into PendingModalContent component

* fix: lint

* chore: merge

* fix: update tests for new modal

* feat: add l2 chain logo to modal

* feat: add unit test

* fix: correct modal state when moving between steps

* fix: correct modal state when moving between steps

* fix: proper error handling of user rejection of swap

* feat: update e2e test

* fix: typecheck

* feat: design updates, state updates

* fix: comments

* fix: code style improvements

* feat: require trade to be defined

* fix: remove extra props from ThemedTexts

* fix: one more trans

* fix: remove unused export

* feat: remove undefined checks and other fixes

* fix: update test

* fix: add missing dollar sign

* fix: remove null check and update test

* fix: remove max width from detail row value

* fix: remove isOpen prop

* fix: isopen

* feat: refactor approval flow into a hook

* fix: custom error type

* fix: testid fix

* fix: text colors

* fix: add comment

* wip: permit2 modal animations

* fix: entrance animations

* feat: step indicator transitions

* feat: icon aniamtions

* feat: fix spinner icon

* fix: re-organize new code

* fix: svg import

* fix: tradeMeaningfullyDiffers improvement and prepareFlow fix

* fix: address  comments

* fix: headerContent prop

* fix: change tooltip to external link

* feat: add comments explaining async state

* fix: test updates

* fix: nits

* fix: design nits

* fix: reduce nesting

* fix: address comments

* test: remove line from test for debugging

* fix: update tests

* fix: address  comments

* fix: comments

* fix: update tests

* fix: update tests

* fix: more nesting in test

* fix: update test

* fix: update e2e test

* fix: update error test

* fix: dont show loader unless onchain processing is happening

* fix: update designs and add comments

* fix: update content in test

* fix: update tests more

* fix: reorganize test code

* fix: mainnet loading indicator on last step

* fix: re-use opacity css code

* fix: testid issue with test

* fix: lint

* fix: modal height and css improvements

* fix: empty

* feat: fix help center link (#6621)

* test: swap flow cypress tests

* fix: use default parameter

* feat: use Swap Component on TDP

* feat: auto nav for TDP tokens

* chore: merge

* chore: merge

* chore: merge

* chore: merge

* fix: remove extra inputCurrency URL parsing logic

* fix: undo last change

* fix: pass expected chain id to swap component

* fix: search for default tokens on unconnected networks if needed

* test: e2e test for l2 token

* fix: delete irrelevant tests

* fix: address comments

* fix: lint error

* test: update TDP e2e tests

* fix: use pageChainId for filter

* fix: rename chainId

* fix: typecheck

* fix: chainId bug

* fix: chainId required fixes

* fix: bad merge in e2e test

* fix: remove unused test util

* fix: remove unnecessary variable

* fix: token defaults

* fix: address comments

* fix: address comments and fix tests

* fix: e2e test formatting, remove Maybe<>

* fix: remove unused variable

* fix: use feature flag for swap component on TDP

* fix: back button

* feat: copy review screen UI from widgetg

* fix: modal padding

* feat: add final detail row

* fix: remove widget comment

* fix: update unit tests

* fix: code style consistency

* fix: remove padding from AutoColumn

* fix: update snapshots

* fix: use semantic gaps

* fix: more px and gaps

* fix: design feedbacks

* fix: button radius in summary modal

* fix: design nits

* feat: update design of summary modal

* fix: font weight and vertical spacing

* fix: update snapshots

* fix: css nits

* wip: move approval to summary modal

* wip: not working

* feat: working

* fix: fix flow

* feat: simplify states and build new modal UI

* feat: todos and differs fix

* feat: update tx status modal

* feat: split up approve and permit

* feat: error state

* feat: update success and error states

* feat: undo changes to TxConfirmationModal

* feat: re-order functions

* wip: move approval to summary modal

* wip: not working

* feat: update permit2 e2e tests

* feat: tests passing

* fix: swap test

* fix: bad merge

* wip: move approval to summary modal

* wip: not working

* feat: PendingModalContent tests

* feat: useMaxAmountIn

* fix: bad merge

* fix: naming

* fix: modal flicker when refetching trade

* wip: move approval to summary modal

* wip: not working

* feat: working

* fix: fix flow

* feat: simplify states and build new modal UI

* feat: todos and differs fix

* feat: update tx status modal

* feat: split up approve and permit

* feat: error state

* feat: update success and error states

* feat: undo changes to TxConfirmationModal

* feat: remove step indicators when only one step

* feat: move content into PendingModalContent component

* fix: lint

* chore: merge

* fix: update tests for new modal

* feat: add l2 chain logo to modal

* feat: add unit test

* fix: correct modal state when moving between steps

* fix: correct modal state when moving between steps

* fix: proper error handling of user rejection of swap

* feat: update e2e test

* fix: typecheck

* feat: design updates, state updates

* fix: comments

* fix: code style improvements

* feat: require trade to be defined

* fix: remove extra props from ThemedTexts

* fix: one more trans

* fix: remove unused export

* feat: remove undefined checks and other fixes

* fix: update test

* fix: add missing dollar sign

* fix: remove null check and update test

* fix: remove max width from detail row value

* fix: remove isOpen prop

* fix: isopen

* feat: refactor approval flow into a hook

* fix: custom error type

* fix: testid fix

* fix: text colors

* fix: add comment

* wip: permit2 modal animations

* fix: entrance animations

* feat: step indicator transitions

* feat: icon aniamtions

* feat: fix spinner icon

* fix: re-organize new code

* fix: svg import

* fix: tradeMeaningfullyDiffers improvement and prepareFlow fix

* fix: address  comments

* fix: headerContent prop

* fix: change tooltip to external link

* feat: add comments explaining async state

* fix: test updates

* fix: nits

* fix: design nits

* fix: reduce nesting

* fix: address comments

* test: remove line from test for debugging

* fix: update tests

* fix: address  comments

* fix: comments

* fix: update tests

* fix: update tests

* fix: more nesting in test

* feat: correct help center article

* fix: update test

* fix: update e2e test

* fix: update error test

* fix: dont show loader unless onchain processing is happening

* fix: update designs and add comments

* fix: update content in test

* fix: update tests more

* fix: reorganize test code

* fix: mainnet loading indicator on last step

* fix: re-use opacity css code

* fix: testid issue with test

* fix: lint

* fix: modal height and css improvements

* fix: empty

* fix: design nits on summary view (#6623)

* fix: chainId required fixes

* fix: bad merge in e2e test

* fix: remove unused test util

* fix: remove unnecessary variable

* fix: token defaults

* fix: address comments

* fix: address comments and fix tests

* fix: e2e test formatting, remove Maybe<>

* fix: remove unused variable

* fix: use feature flag for swap component on TDP

* fix: back button

* feat: copy review screen UI from widgetg

* fix: modal padding

* feat: add final detail row

* fix: remove widget comment

* fix: update unit tests

* fix: code style consistency

* fix: remove padding from AutoColumn

* fix: update snapshots

* fix: use semantic gaps

* fix: more px and gaps

* fix: design feedbacks

* fix: button radius in summary modal

* fix: design nits

* feat: update design of summary modal

* fix: font weight and vertical spacing

* fix: update snapshots

* fix: css nits

* wip: move approval to summary modal

* wip: not working

* feat: working

* fix: fix flow

* feat: simplify states and build new modal UI

* feat: todos and differs fix

* feat: update tx status modal

* feat: split up approve and permit

* feat: error state

* feat: update success and error states

* feat: undo changes to TxConfirmationModal

* feat: re-order functions

* wip: move approval to summary modal

* wip: not working

* feat: update permit2 e2e tests

* feat: tests passing

* fix: swap test

* fix: bad merge

* wip: move approval to summary modal

* wip: not working

* feat: PendingModalContent tests

* feat: useMaxAmountIn

* fix: bad merge

* fix: naming

* fix: modal flicker when refetching trade

* wip: move approval to summary modal

* wip: not working

* feat: working

* fix: fix flow

* feat: simplify states and build new modal UI

* feat: todos and differs fix

* feat: update tx status modal

* feat: split up approve and permit

* feat: error state

* feat: update success and error states

* feat: undo changes to TxConfirmationModal

* feat: remove step indicators when only one step

* feat: move content into PendingModalContent component

* fix: lint

* chore: merge

* fix: update tests for new modal

* feat: add l2 chain logo to modal

* feat: add unit test

* fix: correct modal state when moving between steps

* fix: correct modal state when moving between steps

* fix: proper error handling of user rejection of swap

* feat: update e2e test

* fix: typecheck

* feat: design updates, state updates

* fix: comments

* fix: code style improvements

* feat: require trade to be defined

* fix: remove extra props from ThemedTexts

* fix: one more trans

* fix: remove unused export

* feat: remove undefined checks and other fixes

* fix: update test

* fix: add missing dollar sign

* fix: remove null check and update test

* fix: remove max width from detail row value

* fix: remove isOpen prop

* fix: isopen

* feat: refactor approval flow into a hook

* fix: custom error type

* fix: testid fix

* fix: text colors

* fix: add comment

* wip: permit2 modal animations

* fix: entrance animations

* feat: step indicator transitions

* feat: icon aniamtions

* feat: fix spinner icon

* fix: re-organize new code

* fix: svg import

* fix: tradeMeaningfullyDiffers improvement and prepareFlow fix

* fix: address  comments

* fix: headerContent prop

* fix: change tooltip to external link

* feat: add comments explaining async state

* fix: test updates

* fix: nits

* fix: design nits

* fix: reduce nesting

* fix: address comments

* test: remove line from test for debugging

* fix: update tests

* fix: address  comments

* fix: comments

* fix: update tests

* fix: update tests

* fix: more nesting in test

* feat: correct help center article

* fix: design nits on summary view

* fix: update test

* fix: update snapshots

* fix: update e2e test

* fix: etherscan link

* fix: update error test

* fix: dont show loader unless onchain processing is happening

* fix: update designs and add comments

* fix: update content in test

* fix: update tests more

* fix: test

* fix: reorganize test code

* fix: sentence case in one more test

* fix: mainnet loading indicator on last step

* fix: re-use opacity css code

* fix: testid issue with test

* fix: update copy

* fix: update strings in test

* fix: lint

* fix: modal height and css improvements

* fix: empty

* fix: padding on l2 badge

* fix: lint

* feat: log swap button click (#6654)

* build: disable scheduled releases (#6651)

* feat: [DetailsV2] Add Activity Chart Time Period Switcher (#6653)

* add endButton and new TimePeriodSwitcher component

* add snapshot testing

* add test file

* remove switcher from TabbedComponent

* update snapshots

* update describe

* update padding

* extra return

* as const notation

* update snapshots

* no more abs positioning

* cleanup tests and add dropdown test

* add divider line to tabbed component

* update design to match new specs

---------

Co-authored-by: Charles Bachmeier <charlie@genie.xyz>

* fix: reduce ETH amount on mainnet useUSDPrice request to 50 (#6642)

* feat: page wallet connect txn completed (#6655)

* feat: add page to wallet_connect_txn_completed event

* feat: unit test

* fix: test

* chore: cleaning up buy button states (#6618)

* fix: typecheck error in bagfooter (#6669)

* feat: increased debounce swap quote rate (#6666)

* feat: increased debounce swap quote time

* fix

* add basic test for initial useScreenSize

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
Co-authored-by: Mike Grabowski <grabbou@gmail.com>
Co-authored-by: eddie <66155195+just-toby@users.noreply.github.com>
Co-authored-by: Vignesh Mohankumar <me@vig.xyz>
Co-authored-by: Jordan Frankfurt <jordanwfrankfurt@gmail.com>
Co-authored-by: Jordan Frankfurt <jordan@CORN-Jordan-949.frankfurt>
Co-authored-by: Charles Bachmeier <charles@bachmeier.io>
Co-authored-by: Charles Bachmeier <charlie@genie.xyz>
Co-authored-by: Jack Short <john.short.tj@gmail.com>
2023-06-02 09:40:04 -10:00
Tina
83f4b53f55
feat: Add Circle native Arbitrum USDC to common base tokens in token selector (#6680)
* add feature flag for usdc arbitrum

* add to feature flag modal
2023-06-02 14:05:41 -04:00
Brendan Wong
4b5e2f7f16
fix: polygon bridge link leading to error page (#6664)
* fix: polygon bridge link leading to error page

* fix: fix polygon bridge to send directly to POS bridge
2023-06-02 10:03:50 -07:00
eddie
0c5d915638
feat: upgrade conedison (#6688)
<!-- Your PR title must follow conventional commits: https://github.com/Uniswap/interface#pr-title -->

## Description
<!-- Summary of change, including motivation and context. -->
<!-- Use verb-driven language: "Fixes XYZ" instead of "This change fixes XYZ" -->
upgrades the coned package to get this change: https://github.com/Uniswap/conedison/pull/19


## Test plan

<!-- Delete this section if your change is not a bug fix. -->
### Reproducing the error

<!-- Include steps to reproduce the bug. -->
1. Try to sign a permit2 signature with trustwallet ios on optimism or arbitrum - it will fail without this change.

### QA (ie manual testing)

<!-- Include steps to test the change, ensuring no regression. -->
- [x] manually moved this change into `interface` and tested it , it works as a fallback
2023-06-02 09:32:56 -07:00
Tina
a03231d356
fix: Bug with flipping ura feature flag on/off in dev mode (#6686)
fix bug
2023-06-02 12:12:06 -04:00
Jack Short
72936322b3
feat: adding price impact modal (#6681) 2023-06-02 11:01:28 -04:00
Charles Bachmeier
1bc6eb9a23
feat: Add support for Sepolia (#6610)
* initial sepolia const setup

* uni sepolia

* add more consts for sepolia

* better comment

* upgrade ur sdk

* need to request BE add Ethereum sepolia to supported chains

* update weth address

* remove sepolia from defaults

* add tick lens addr

* add multicall && quoter

* use weth9 checksum

* successful wrap

* use supportedChainId over magic num

* upgrade default-token-list && deduplicate

* cleanup

* use checksum for usdc

* upgrade SOR

* placeholder setProperty

* comment cleanup

* add to anonymizeLink

* bump core-sdk

* deduplicate

* update infura fork block

* add comment

---------

Co-authored-by: Charles Bachmeier <charlie@genie.xyz>
2023-06-01 17:57:03 -07:00
Tina
8954aa792a
feat: Use routing-api v2 behind feature flag (#6594)
* add unified-routing-api slice

* rename legacy -> legacyAPI

* deduplicate client params and ura params

* move shared functions into utils and rename comments for unified routing API

* use feature flag

* remove eslint ignore since the function is now being used

* add typing to args

* rename ura -> routing-api v2

* update trace name and comment

* rename variables

* lint
2023-06-01 16:52:03 -04:00
eddie
379437b720
fix: remove all references to expert mode (#6675) 2023-06-01 12:04:16 -07:00
Nate Wienert
02c0dee089
feat: hide logo on swap currency selector modal (and other areas that use CurrencyLogo) for unsupported currencies (#6659) 2023-06-01 08:00:02 -10:00
eddie
c55e1af101
fix: reset confirm trade modal state when chain switches (#6667)
<!-- Your PR title must follow conventional commits: https://github.com/Uniswap/interface#pr-title -->

## Description
<!-- Summary of change, including motivation and context. -->
<!-- Use verb-driven language: "Fixes XYZ" instead of "This change fixes XYZ" -->

Resets the swap component's local state when the chain changes, to fix Confirmation Modal behavior


<!-- Delete inapplicable lines: -->
_Linear ticket:_ https://linear.app/uniswap/issue/WEB-2161/wonky-swap-modal-behavior-after-switching-chains
_Slack thread:_ https://uniswapteam.slack.com/archives/C047U65H422/p1685467094162069?thread_ts=1685459249.400839&cid=C047U65H422


<!-- Delete this section if your change does not affect UI. -->
## Screen capture

### Before

https://github.com/Uniswap/interface/assets/66155195/115e243a-858b-490d-be9e-269174cc7561


### After

https://github.com/Uniswap/interface/assets/66155195/a47b3606-08ac-490f-abc8-01acf2423efb 



## Test plan

<!-- Delete this section if your change is not a bug fix. -->
### Reproducing the error

<!-- Include steps to reproduce the bug. -->
1. swap on a l2
2. via the metamask extension (or in whatever wallet), trigger a chain-change event (e.g. from optimism to mainnet)
    a. this does not repro if you change chains from within the app selector.
4. fill in the input details for a new trade (ideally with different tokens so you can notice the bug easily)
5. see that the Confirm Swap modal opens automatically when it shouldn't, and it has the wrong trade details

### QA (ie manual testing)

<!-- Include steps to test the change, ensuring no regression. -->
- [x] same steps as above, ensuring the modal behaves correctly 


#### Devices
<!-- If applicable, include different devices and screen sizes that may be affected, and how you've tested them. -->


### Automated testing

<!-- If N/A, check and note so it is obvious to your reviewers and does not show up as an incomplete task. -->
<!-- eg - [x] Unit test N/A -->
- [ ] Unit test
- [ ] Integration/E2E test
2023-06-01 10:02:37 -07:00
eddie
87cbd1ab38
fix: use ConfirmSwapModal in expert mode (#6673)
Fixes the swap flow for users who are still in expert mode  and need permit2 approvals for a token

### test plan

added e2e test for full permit2 flow with expert mode enabled. 

failing test without the change:
<img width="1394" alt="Screenshot 2023-05-31 at 2 24 12 PM" src="https://github.com/Uniswap/interface/assets/66155195/6a39e039-31b5-4bce-91d2-5e3ebc777378">


passing test with change in the CI of this PR
2023-05-31 14:52:04 -07:00
eddie
1090e97bb5
fix: update snapshots (#6672) 2023-05-31 16:37:45 -05:00
Nate Wienert
921c6b105f
fix: prevent searchbar from overflowing the bottom of the window viewport (WEB-2099) (#6645)
fix: prevent searchbar from overflowing the bottom of the window viewport, add scrolling support for inner contents
2023-05-31 10:03:02 -10:00
Vignesh Mohankumar
bc08e9263d
feat: increased debounce swap quote rate (#6666)
* feat: increased debounce swap quote time

* fix
2023-05-31 15:46:59 -04:00
Jack Short
8c8300a5de
fix: typecheck error in bagfooter (#6669) 2023-05-31 13:50:22 -04:00
Jack Short
3f169adcf2
chore: cleaning up buy button states (#6618) 2023-05-31 11:34:49 -04:00
eddie
774368f325
feat: page wallet connect txn completed (#6655)
* feat: add page to wallet_connect_txn_completed event

* feat: unit test

* fix: test
2023-05-30 11:10:16 -07:00
Vignesh Mohankumar
f83f15d37a
fix: reduce ETH amount on mainnet useUSDPrice request to 50 (#6642) 2023-05-30 12:30:16 -04:00
Charles Bachmeier
d9f1402576
feat: [DetailsV2] Add Activity Chart Time Period Switcher (#6653)
* add endButton and new TimePeriodSwitcher component

* add snapshot testing

* add test file

* remove switcher from TabbedComponent

* update snapshots

* update describe

* update padding

* extra return

* as const notation

* update snapshots

* no more abs positioning

* cleanup tests and add dropdown test

* add divider line to tabbed component

* update design to match new specs

---------

Co-authored-by: Charles Bachmeier <charlie@genie.xyz>
2023-05-26 16:06:36 -07:00
Zach Pomerantz
d81cb28010
build: disable scheduled releases (#6651) 2023-05-26 14:10:40 -07:00
eddie
b57a5d7ddb
feat: log swap button click (#6654) 2023-05-26 10:13:28 -07:00
eddie
e2dd78fd0e
fix: design nits on summary view (#6623)
* fix: chainId required fixes

* fix: bad merge in e2e test

* fix: remove unused test util

* fix: remove unnecessary variable

* fix: token defaults

* fix: address comments

* fix: address comments and fix tests

* fix: e2e test formatting, remove Maybe<>

* fix: remove unused variable

* fix: use feature flag for swap component on TDP

* fix: back button

* feat: copy review screen UI from widgetg

* fix: modal padding

* feat: add final detail row

* fix: remove widget comment

* fix: update unit tests

* fix: code style consistency

* fix: remove padding from AutoColumn

* fix: update snapshots

* fix: use semantic gaps

* fix: more px and gaps

* fix: design feedbacks

* fix: button radius in summary modal

* fix: design nits

* feat: update design of summary modal

* fix: font weight and vertical spacing

* fix: update snapshots

* fix: css nits

* wip: move approval to summary modal

* wip: not working

* feat: working

* fix: fix flow

* feat: simplify states and build new modal UI

* feat: todos and differs fix

* feat: update tx status modal

* feat: split up approve and permit

* feat: error state

* feat: update success and error states

* feat: undo changes to TxConfirmationModal

* feat: re-order functions

* wip: move approval to summary modal

* wip: not working

* feat: update permit2 e2e tests

* feat: tests passing

* fix: swap test

* fix: bad merge

* wip: move approval to summary modal

* wip: not working

* feat: PendingModalContent tests

* feat: useMaxAmountIn

* fix: bad merge

* fix: naming

* fix: modal flicker when refetching trade

* wip: move approval to summary modal

* wip: not working

* feat: working

* fix: fix flow

* feat: simplify states and build new modal UI

* feat: todos and differs fix

* feat: update tx status modal

* feat: split up approve and permit

* feat: error state

* feat: update success and error states

* feat: undo changes to TxConfirmationModal

* feat: remove step indicators when only one step

* feat: move content into PendingModalContent component

* fix: lint

* chore: merge

* fix: update tests for new modal

* feat: add l2 chain logo to modal

* feat: add unit test

* fix: correct modal state when moving between steps

* fix: correct modal state when moving between steps

* fix: proper error handling of user rejection of swap

* feat: update e2e test

* fix: typecheck

* feat: design updates, state updates

* fix: comments

* fix: code style improvements

* feat: require trade to be defined

* fix: remove extra props from ThemedTexts

* fix: one more trans

* fix: remove unused export

* feat: remove undefined checks and other fixes

* fix: update test

* fix: add missing dollar sign

* fix: remove null check and update test

* fix: remove max width from detail row value

* fix: remove isOpen prop

* fix: isopen

* feat: refactor approval flow into a hook

* fix: custom error type

* fix: testid fix

* fix: text colors

* fix: add comment

* wip: permit2 modal animations

* fix: entrance animations

* feat: step indicator transitions

* feat: icon aniamtions

* feat: fix spinner icon

* fix: re-organize new code

* fix: svg import

* fix: tradeMeaningfullyDiffers improvement and prepareFlow fix

* fix: address  comments

* fix: headerContent prop

* fix: change tooltip to external link

* feat: add comments explaining async state

* fix: test updates

* fix: nits

* fix: design nits

* fix: reduce nesting

* fix: address comments

* test: remove line from test for debugging

* fix: update tests

* fix: address  comments

* fix: comments

* fix: update tests

* fix: update tests

* fix: more nesting in test

* feat: correct help center article

* fix: design nits on summary view

* fix: update test

* fix: update snapshots

* fix: update e2e test

* fix: etherscan link

* fix: update error test

* fix: dont show loader unless onchain processing is happening

* fix: update designs and add comments

* fix: update content in test

* fix: update tests more

* fix: test

* fix: reorganize test code

* fix: sentence case in one more test

* fix: mainnet loading indicator on last step

* fix: re-use opacity css code

* fix: testid issue with test

* fix: update copy

* fix: update strings in test

* fix: lint

* fix: modal height and css improvements

* fix: empty

* fix: padding on l2 badge

* fix: lint
2023-05-25 15:57:13 -07:00
eddie
96d6e00ed6
feat: fix help center link (#6621)
* test: swap flow cypress tests

* fix: use default parameter

* feat: use Swap Component on TDP

* feat: auto nav for TDP tokens

* chore: merge

* chore: merge

* chore: merge

* chore: merge

* fix: remove extra inputCurrency URL parsing logic

* fix: undo last change

* fix: pass expected chain id to swap component

* fix: search for default tokens on unconnected networks if needed

* test: e2e test for l2 token

* fix: delete irrelevant tests

* fix: address comments

* fix: lint error

* test: update TDP e2e tests

* fix: use pageChainId for filter

* fix: rename chainId

* fix: typecheck

* fix: chainId bug

* fix: chainId required fixes

* fix: bad merge in e2e test

* fix: remove unused test util

* fix: remove unnecessary variable

* fix: token defaults

* fix: address comments

* fix: address comments and fix tests

* fix: e2e test formatting, remove Maybe<>

* fix: remove unused variable

* fix: use feature flag for swap component on TDP

* fix: back button

* feat: copy review screen UI from widgetg

* fix: modal padding

* feat: add final detail row

* fix: remove widget comment

* fix: update unit tests

* fix: code style consistency

* fix: remove padding from AutoColumn

* fix: update snapshots

* fix: use semantic gaps

* fix: more px and gaps

* fix: design feedbacks

* fix: button radius in summary modal

* fix: design nits

* feat: update design of summary modal

* fix: font weight and vertical spacing

* fix: update snapshots

* fix: css nits

* wip: move approval to summary modal

* wip: not working

* feat: working

* fix: fix flow

* feat: simplify states and build new modal UI

* feat: todos and differs fix

* feat: update tx status modal

* feat: split up approve and permit

* feat: error state

* feat: update success and error states

* feat: undo changes to TxConfirmationModal

* feat: re-order functions

* wip: move approval to summary modal

* wip: not working

* feat: update permit2 e2e tests

* feat: tests passing

* fix: swap test

* fix: bad merge

* wip: move approval to summary modal

* wip: not working

* feat: PendingModalContent tests

* feat: useMaxAmountIn

* fix: bad merge

* fix: naming

* fix: modal flicker when refetching trade

* wip: move approval to summary modal

* wip: not working

* feat: working

* fix: fix flow

* feat: simplify states and build new modal UI

* feat: todos and differs fix

* feat: update tx status modal

* feat: split up approve and permit

* feat: error state

* feat: update success and error states

* feat: undo changes to TxConfirmationModal

* feat: remove step indicators when only one step

* feat: move content into PendingModalContent component

* fix: lint

* chore: merge

* fix: update tests for new modal

* feat: add l2 chain logo to modal

* feat: add unit test

* fix: correct modal state when moving between steps

* fix: correct modal state when moving between steps

* fix: proper error handling of user rejection of swap

* feat: update e2e test

* fix: typecheck

* feat: design updates, state updates

* fix: comments

* fix: code style improvements

* feat: require trade to be defined

* fix: remove extra props from ThemedTexts

* fix: one more trans

* fix: remove unused export

* feat: remove undefined checks and other fixes

* fix: update test

* fix: add missing dollar sign

* fix: remove null check and update test

* fix: remove max width from detail row value

* fix: remove isOpen prop

* fix: isopen

* feat: refactor approval flow into a hook

* fix: custom error type

* fix: testid fix

* fix: text colors

* fix: add comment

* wip: permit2 modal animations

* fix: entrance animations

* feat: step indicator transitions

* feat: icon aniamtions

* feat: fix spinner icon

* fix: re-organize new code

* fix: svg import

* fix: tradeMeaningfullyDiffers improvement and prepareFlow fix

* fix: address  comments

* fix: headerContent prop

* fix: change tooltip to external link

* feat: add comments explaining async state

* fix: test updates

* fix: nits

* fix: design nits

* fix: reduce nesting

* fix: address comments

* test: remove line from test for debugging

* fix: update tests

* fix: address  comments

* fix: comments

* fix: update tests

* fix: update tests

* fix: more nesting in test

* feat: correct help center article

* fix: update test

* fix: update e2e test

* fix: update error test

* fix: dont show loader unless onchain processing is happening

* fix: update designs and add comments

* fix: update content in test

* fix: update tests more

* fix: reorganize test code

* fix: mainnet loading indicator on last step

* fix: re-use opacity css code

* fix: testid issue with test

* fix: lint

* fix: modal height and css improvements

* fix: empty
2023-05-25 15:40:42 -07:00
eddie
dd29c59238
feat: permit2 animations WEB-2036 (#6590)
* test: swap flow cypress tests

* fix: use default parameter

* feat: use Swap Component on TDP

* feat: auto nav for TDP tokens

* chore: merge

* chore: merge

* chore: merge

* chore: merge

* fix: remove extra inputCurrency URL parsing logic

* fix: undo last change

* fix: pass expected chain id to swap component

* fix: search for default tokens on unconnected networks if needed

* test: e2e test for l2 token

* fix: delete irrelevant tests

* fix: address comments

* fix: lint error

* test: update TDP e2e tests

* fix: use pageChainId for filter

* fix: rename chainId

* fix: typecheck

* fix: chainId bug

* fix: chainId required fixes

* fix: bad merge in e2e test

* fix: remove unused test util

* fix: remove unnecessary variable

* fix: token defaults

* fix: address comments

* fix: address comments and fix tests

* fix: e2e test formatting, remove Maybe<>

* fix: remove unused variable

* fix: use feature flag for swap component on TDP

* fix: back button

* feat: copy review screen UI from widgetg

* fix: modal padding

* feat: add final detail row

* fix: remove widget comment

* fix: update unit tests

* fix: code style consistency

* fix: remove padding from AutoColumn

* fix: update snapshots

* fix: use semantic gaps

* fix: more px and gaps

* fix: design feedbacks

* fix: button radius in summary modal

* fix: design nits

* feat: update design of summary modal

* fix: font weight and vertical spacing

* fix: update snapshots

* fix: css nits

* wip: move approval to summary modal

* wip: not working

* feat: working

* fix: fix flow

* feat: simplify states and build new modal UI

* feat: todos and differs fix

* feat: update tx status modal

* feat: split up approve and permit

* feat: error state

* feat: update success and error states

* feat: undo changes to TxConfirmationModal

* feat: re-order functions

* wip: move approval to summary modal

* wip: not working

* feat: update permit2 e2e tests

* feat: tests passing

* fix: swap test

* fix: bad merge

* wip: move approval to summary modal

* wip: not working

* feat: PendingModalContent tests

* feat: useMaxAmountIn

* fix: bad merge

* fix: naming

* fix: modal flicker when refetching trade

* wip: move approval to summary modal

* wip: not working

* feat: working

* fix: fix flow

* feat: simplify states and build new modal UI

* feat: todos and differs fix

* feat: update tx status modal

* feat: split up approve and permit

* feat: error state

* feat: update success and error states

* feat: undo changes to TxConfirmationModal

* feat: remove step indicators when only one step

* feat: move content into PendingModalContent component

* fix: lint

* chore: merge

* fix: update tests for new modal

* feat: add l2 chain logo to modal

* feat: add unit test

* fix: correct modal state when moving between steps

* fix: correct modal state when moving between steps

* fix: proper error handling of user rejection of swap

* feat: update e2e test

* fix: typecheck

* feat: design updates, state updates

* fix: comments

* fix: code style improvements

* feat: require trade to be defined

* fix: remove extra props from ThemedTexts

* fix: one more trans

* fix: remove unused export

* feat: remove undefined checks and other fixes

* fix: update test

* fix: add missing dollar sign

* fix: remove null check and update test

* fix: remove max width from detail row value

* fix: remove isOpen prop

* fix: isopen

* feat: refactor approval flow into a hook

* fix: custom error type

* fix: testid fix

* fix: text colors

* fix: add comment

* wip: permit2 modal animations

* fix: entrance animations

* feat: step indicator transitions

* feat: icon aniamtions

* feat: fix spinner icon

* fix: re-organize new code

* fix: svg import

* fix: tradeMeaningfullyDiffers improvement and prepareFlow fix

* fix: address  comments

* fix: headerContent prop

* fix: change tooltip to external link

* feat: add comments explaining async state

* fix: test updates

* fix: nits

* fix: design nits

* fix: reduce nesting

* fix: address comments

* test: remove line from test for debugging

* fix: update tests

* fix: address  comments

* fix: comments

* fix: update tests

* fix: update tests

* fix: more nesting in test

* fix: update test

* fix: update e2e test

* fix: update error test

* fix: dont show loader unless onchain processing is happening

* fix: update designs and add comments

* fix: update content in test

* fix: update tests more

* fix: reorganize test code

* fix: mainnet loading indicator on last step

* fix: re-use opacity css code

* fix: testid issue with test

* fix: lint

* fix: modal height and css improvements

* fix: empty
2023-05-25 15:25:07 -07:00
eddie
8c2a0f1905
feat: update content in Swap Submission Modal (#6577)
* test: swap flow cypress tests

* fix: use default parameter

* feat: use Swap Component on TDP

* feat: auto nav for TDP tokens

* chore: merge

* chore: merge

* chore: merge

* chore: merge

* fix: remove extra inputCurrency URL parsing logic

* fix: undo last change

* fix: pass expected chain id to swap component

* fix: search for default tokens on unconnected networks if needed

* test: e2e test for l2 token

* fix: delete irrelevant tests

* fix: address comments

* fix: lint error

* test: update TDP e2e tests

* fix: use pageChainId for filter

* fix: rename chainId

* fix: typecheck

* fix: chainId bug

* fix: chainId required fixes

* fix: bad merge in e2e test

* fix: remove unused test util

* fix: remove unnecessary variable

* fix: token defaults

* fix: address comments

* fix: address comments and fix tests

* fix: e2e test formatting, remove Maybe<>

* fix: remove unused variable

* fix: use feature flag for swap component on TDP

* fix: back button

* feat: copy review screen UI from widgetg

* fix: modal padding

* feat: add final detail row

* fix: remove widget comment

* fix: update unit tests

* fix: code style consistency

* fix: remove padding from AutoColumn

* fix: update snapshots

* fix: use semantic gaps

* fix: more px and gaps

* fix: design feedbacks

* fix: button radius in summary modal

* fix: design nits

* feat: update design of summary modal

* fix: font weight and vertical spacing

* fix: update snapshots

* fix: css nits

* wip: move approval to summary modal

* wip: not working

* feat: working

* fix: fix flow

* feat: simplify states and build new modal UI

* feat: todos and differs fix

* feat: update tx status modal

* feat: split up approve and permit

* feat: error state

* feat: update success and error states

* feat: undo changes to TxConfirmationModal

* feat: re-order functions

* wip: move approval to summary modal

* wip: not working

* feat: update permit2 e2e tests

* feat: tests passing

* fix: swap test

* fix: bad merge

* wip: move approval to summary modal

* wip: not working

* feat: PendingModalContent tests

* feat: useMaxAmountIn

* fix: bad merge

* fix: naming

* fix: modal flicker when refetching trade

* wip: move approval to summary modal

* wip: not working

* feat: working

* fix: fix flow

* feat: simplify states and build new modal UI

* feat: todos and differs fix

* feat: update tx status modal

* feat: split up approve and permit

* feat: error state

* feat: update success and error states

* feat: undo changes to TxConfirmationModal

* feat: remove step indicators when only one step

* feat: move content into PendingModalContent component

* fix: lint

* chore: merge

* fix: update tests for new modal

* feat: add l2 chain logo to modal

* feat: add unit test

* fix: correct modal state when moving between steps

* fix: correct modal state when moving between steps

* fix: proper error handling of user rejection of swap

* feat: update e2e test

* fix: typecheck

* feat: design updates, state updates

* fix: comments

* fix: code style improvements

* feat: require trade to be defined

* fix: remove extra props from ThemedTexts

* fix: one more trans

* fix: remove unused export

* feat: remove undefined checks and other fixes

* fix: update test

* fix: add missing dollar sign

* fix: remove null check and update test

* fix: remove max width from detail row value

* fix: remove isOpen prop

* fix: isopen

* feat: refactor approval flow into a hook

* fix: custom error type

* fix: testid fix

* fix: text colors

* fix: add comment

* fix: tradeMeaningfullyDiffers improvement and prepareFlow fix

* fix: address  comments

* fix: headerContent prop

* fix: change tooltip to external link

* feat: add comments explaining async state

* fix: test updates

* fix: nits

* fix: reduce nesting

* fix: address comments

* test: remove line from test for debugging

* fix: update tests

* fix: address  comments

* fix: comments

* fix: update tests

* fix: update tests

* fix: more nesting in test

* fix: update test

* fix: update e2e test

* fix: update error test

* fix: update content in test

* fix: reorganize test code
2023-05-25 14:57:04 -07:00
eddie
682fba219d
feat: swap rejection error handling (#6576)
* test: swap flow cypress tests

* fix: use default parameter

* feat: use Swap Component on TDP

* feat: auto nav for TDP tokens

* chore: merge

* chore: merge

* chore: merge

* chore: merge

* fix: remove extra inputCurrency URL parsing logic

* fix: undo last change

* fix: pass expected chain id to swap component

* fix: search for default tokens on unconnected networks if needed

* test: e2e test for l2 token

* fix: delete irrelevant tests

* fix: address comments

* fix: lint error

* test: update TDP e2e tests

* fix: use pageChainId for filter

* fix: rename chainId

* fix: typecheck

* fix: chainId bug

* fix: chainId required fixes

* fix: bad merge in e2e test

* fix: remove unused test util

* fix: remove unnecessary variable

* fix: token defaults

* fix: address comments

* fix: address comments and fix tests

* fix: e2e test formatting, remove Maybe<>

* fix: remove unused variable

* fix: use feature flag for swap component on TDP

* fix: back button

* feat: copy review screen UI from widgetg

* fix: modal padding

* feat: add final detail row

* fix: remove widget comment

* fix: update unit tests

* fix: code style consistency

* fix: remove padding from AutoColumn

* fix: update snapshots

* fix: use semantic gaps

* fix: more px and gaps

* fix: design feedbacks

* fix: button radius in summary modal

* fix: design nits

* feat: update design of summary modal

* fix: font weight and vertical spacing

* fix: update snapshots

* fix: css nits

* wip: move approval to summary modal

* wip: not working

* feat: working

* fix: fix flow

* feat: simplify states and build new modal UI

* feat: todos and differs fix

* feat: update tx status modal

* feat: split up approve and permit

* feat: error state

* feat: update success and error states

* feat: undo changes to TxConfirmationModal

* feat: re-order functions

* wip: move approval to summary modal

* wip: not working

* feat: update permit2 e2e tests

* feat: tests passing

* fix: swap test

* fix: bad merge

* wip: move approval to summary modal

* wip: not working

* feat: PendingModalContent tests

* feat: useMaxAmountIn

* fix: bad merge

* fix: naming

* fix: modal flicker when refetching trade

* wip: move approval to summary modal

* wip: not working

* feat: working

* fix: fix flow

* feat: simplify states and build new modal UI

* feat: todos and differs fix

* feat: update tx status modal

* feat: split up approve and permit

* feat: error state

* feat: update success and error states

* feat: undo changes to TxConfirmationModal

* feat: remove step indicators when only one step

* feat: move content into PendingModalContent component

* fix: lint

* chore: merge

* fix: update tests for new modal

* feat: add l2 chain logo to modal

* feat: add unit test

* fix: correct modal state when moving between steps

* fix: correct modal state when moving between steps

* fix: proper error handling of user rejection of swap

* feat: update e2e test

* fix: typecheck

* fix: comments

* fix: code style improvements

* feat: require trade to be defined

* fix: remove extra props from ThemedTexts

* fix: one more trans

* fix: remove unused export

* feat: remove undefined checks and other fixes

* fix: update test

* fix: add missing dollar sign

* fix: remove null check and update test

* fix: remove max width from detail row value

* fix: remove isOpen prop

* fix: isopen

* feat: refactor approval flow into a hook

* fix: custom error type

* fix: testid fix

* fix: add comment

* fix: tradeMeaningfullyDiffers improvement and prepareFlow fix

* fix: address  comments

* fix: headerContent prop

* feat: add comments explaining async state

* fix: test updates

* fix: nits

* fix: reduce nesting

* fix: address comments

* test: remove line from test for debugging

* fix: update tests

* fix: address  comments

* fix: update tests

* fix: more nesting in test

* fix: update test

* fix: update e2e test

* fix: update error test

* fix: reorganize test code
2023-05-25 14:56:37 -07:00
eddie
0f5e871054
feat: add l2 chain logo to modal (#6575)
* test: swap flow cypress tests

* fix: use default parameter

* feat: use Swap Component on TDP

* feat: auto nav for TDP tokens

* chore: merge

* chore: merge

* chore: merge

* chore: merge

* fix: remove extra inputCurrency URL parsing logic

* fix: undo last change

* fix: pass expected chain id to swap component

* fix: search for default tokens on unconnected networks if needed

* test: e2e test for l2 token

* fix: delete irrelevant tests

* fix: address comments

* fix: lint error

* test: update TDP e2e tests

* fix: use pageChainId for filter

* fix: rename chainId

* fix: typecheck

* fix: chainId bug

* fix: chainId required fixes

* fix: bad merge in e2e test

* fix: remove unused test util

* fix: remove unnecessary variable

* fix: token defaults

* fix: address comments

* fix: address comments and fix tests

* fix: e2e test formatting, remove Maybe<>

* fix: remove unused variable

* fix: use feature flag for swap component on TDP

* fix: back button

* feat: copy review screen UI from widgetg

* fix: modal padding

* feat: add final detail row

* fix: remove widget comment

* fix: update unit tests

* fix: code style consistency

* fix: remove padding from AutoColumn

* fix: update snapshots

* fix: use semantic gaps

* fix: more px and gaps

* fix: design feedbacks

* fix: button radius in summary modal

* fix: design nits

* feat: update design of summary modal

* fix: font weight and vertical spacing

* fix: update snapshots

* fix: css nits

* wip: move approval to summary modal

* wip: not working

* feat: working

* fix: fix flow

* feat: simplify states and build new modal UI

* feat: todos and differs fix

* feat: update tx status modal

* feat: split up approve and permit

* feat: error state

* feat: update success and error states

* feat: undo changes to TxConfirmationModal

* feat: re-order functions

* wip: move approval to summary modal

* wip: not working

* feat: update permit2 e2e tests

* feat: tests passing

* fix: swap test

* fix: bad merge

* wip: move approval to summary modal

* wip: not working

* feat: PendingModalContent tests

* feat: useMaxAmountIn

* fix: bad merge

* fix: naming

* fix: modal flicker when refetching trade

* wip: move approval to summary modal

* wip: not working

* feat: working

* fix: fix flow

* feat: simplify states and build new modal UI

* feat: todos and differs fix

* feat: update tx status modal

* feat: split up approve and permit

* feat: error state

* feat: update success and error states

* feat: undo changes to TxConfirmationModal

* feat: remove step indicators when only one step

* feat: move content into PendingModalContent component

* fix: lint

* chore: merge

* fix: update tests for new modal

* feat: add l2 chain logo to modal

* feat: add unit test

* fix: correct modal state when moving between steps

* fix: comments

* fix: code style improvements

* feat: require trade to be defined

* fix: remove extra props from ThemedTexts

* fix: one more trans

* fix: remove unused export

* feat: remove undefined checks and other fixes

* fix: update test

* fix: add missing dollar sign

* fix: remove null check and update test

* fix: remove max width from detail row value

* fix: remove isOpen prop

* fix: isopen

* feat: refactor approval flow into a hook

* fix: testid fix

* fix: tradeMeaningfullyDiffers improvement and prepareFlow fix

* fix: address  comments

* fix: headerContent prop

* feat: add comments explaining async state

* fix: test updates

* fix: nits

* fix: reduce nesting

* fix: address comments

* test: remove line from test for debugging

* fix: update tests

* fix: address  comments

* fix: update tests

* fix: more nesting in test

* fix: update test

* fix: reorganize test code
2023-05-25 14:14:35 -07:00
eddie
07527bab26
test: permit2 flow component tests (#6551)
* test: swap flow cypress tests

* fix: use default parameter

* feat: use Swap Component on TDP

* feat: auto nav for TDP tokens

* chore: merge

* chore: merge

* chore: merge

* chore: merge

* fix: remove extra inputCurrency URL parsing logic

* fix: undo last change

* fix: pass expected chain id to swap component

* fix: search for default tokens on unconnected networks if needed

* test: e2e test for l2 token

* fix: delete irrelevant tests

* fix: address comments

* fix: lint error

* test: update TDP e2e tests

* fix: use pageChainId for filter

* fix: rename chainId

* fix: typecheck

* fix: chainId bug

* fix: chainId required fixes

* fix: bad merge in e2e test

* fix: remove unused test util

* fix: remove unnecessary variable

* fix: token defaults

* fix: address comments

* fix: address comments and fix tests

* fix: e2e test formatting, remove Maybe<>

* fix: remove unused variable

* fix: use feature flag for swap component on TDP

* fix: back button

* feat: copy review screen UI from widgetg

* fix: modal padding

* feat: add final detail row

* fix: remove widget comment

* fix: update unit tests

* fix: code style consistency

* fix: remove padding from AutoColumn

* fix: update snapshots

* fix: use semantic gaps

* fix: more px and gaps

* fix: design feedbacks

* fix: button radius in summary modal

* fix: design nits

* feat: update design of summary modal

* fix: font weight and vertical spacing

* fix: update snapshots

* fix: css nits

* wip: move approval to summary modal

* wip: not working

* feat: working

* fix: fix flow

* feat: simplify states and build new modal UI

* feat: todos and differs fix

* feat: update tx status modal

* feat: split up approve and permit

* feat: error state

* feat: update success and error states

* feat: undo changes to TxConfirmationModal

* feat: re-order functions

* wip: move approval to summary modal

* wip: not working

* feat: update permit2 e2e tests

* feat: tests passing

* fix: swap test

* fix: bad merge

* wip: move approval to summary modal

* wip: not working

* feat: PendingModalContent tests

* feat: useMaxAmountIn

* fix: bad merge

* fix: naming

* fix: modal flicker when refetching trade

* wip: move approval to summary modal

* wip: not working

* feat: working

* fix: fix flow

* feat: simplify states and build new modal UI

* feat: todos and differs fix

* feat: update tx status modal

* feat: split up approve and permit

* feat: error state

* feat: update success and error states

* feat: undo changes to TxConfirmationModal

* feat: remove step indicators when only one step

* feat: move content into PendingModalContent component

* fix: lint

* chore: merge

* fix: update tests for new modal

* fix: correct modal state when moving between steps

* fix: comments

* fix: code style improvements

* feat: require trade to be defined

* fix: remove extra props from ThemedTexts

* fix: one more trans

* fix: remove unused export

* feat: remove undefined checks and other fixes

* fix: update test

* fix: add missing dollar sign

* fix: remove null check and update test

* fix: remove max width from detail row value

* fix: remove isOpen prop

* fix: isopen

* feat: refactor approval flow into a hook

* fix: testid fix

* fix: tradeMeaningfullyDiffers improvement and prepareFlow fix

* fix: address  comments

* feat: add comments explaining async state

* fix: test updates

* fix: nits

* fix: reduce nesting

* fix: address comments

* test: remove line from test for debugging

* fix: update tests

* fix: update tests

* fix: more nesting in test

* fix: update test

* fix: reorganize test code
2023-05-25 14:13:55 -07:00
eddie
7934777fa2
feat: permit2 flow updates (#6538)
* test: swap flow cypress tests

* fix: use default parameter

* feat: use Swap Component on TDP

* feat: auto nav for TDP tokens

* chore: merge

* chore: merge

* chore: merge

* chore: merge

* fix: remove extra inputCurrency URL parsing logic

* fix: undo last change

* fix: pass expected chain id to swap component

* fix: search for default tokens on unconnected networks if needed

* test: e2e test for l2 token

* fix: delete irrelevant tests

* fix: address comments

* fix: lint error

* test: update TDP e2e tests

* fix: use pageChainId for filter

* fix: rename chainId

* fix: typecheck

* fix: chainId bug

* fix: chainId required fixes

* fix: bad merge in e2e test

* fix: remove unused test util

* fix: remove unnecessary variable

* fix: token defaults

* fix: address comments

* fix: address comments and fix tests

* fix: e2e test formatting, remove Maybe<>

* fix: remove unused variable

* fix: use feature flag for swap component on TDP

* fix: back button

* feat: copy review screen UI from widgetg

* fix: modal padding

* feat: add final detail row

* fix: remove widget comment

* fix: update unit tests

* fix: code style consistency

* fix: remove padding from AutoColumn

* fix: update snapshots

* fix: use semantic gaps

* fix: more px and gaps

* fix: design feedbacks

* fix: button radius in summary modal

* fix: design nits

* feat: update design of summary modal

* fix: font weight and vertical spacing

* fix: update snapshots

* fix: css nits

* fix: modal flicker when refetching trade

* wip: move approval to summary modal

* wip: not working

* feat: working

* fix: fix flow

* feat: simplify states and build new modal UI

* feat: todos and differs fix

* feat: update tx status modal

* feat: split up approve and permit

* feat: error state

* feat: update success and error states

* feat: undo changes to TxConfirmationModal

* feat: remove step indicators when only one step

* feat: move content into PendingModalContent component

* fix: lint

* fix: correct modal state when moving between steps

* fix: comments

* fix: code style improvements

* feat: require trade to be defined

* fix: remove extra props from ThemedTexts

* fix: one more trans

* fix: remove unused export

* feat: remove undefined checks and other fixes

* fix: update test

* fix: add missing dollar sign

* fix: remove null check and update test

* fix: remove max width from detail row value

* fix: remove isOpen prop

* fix: isopen

* feat: refactor approval flow into a hook

* fix: tradeMeaningfullyDiffers improvement and prepareFlow fix

* fix: address  comments

* feat: add comments explaining async state

* fix: nits

* fix: address comments

* feat: permit2 e2e tests (#6541)

* wip: move approval to summary modal

* wip: not working

* feat: working

* fix: fix flow

* feat: simplify states and build new modal UI

* feat: todos and differs fix

* feat: update tx status modal

* feat: split up approve and permit

* feat: error state

* feat: update success and error states

* feat: undo changes to TxConfirmationModal

* feat: re-order functions

* wip: move approval to summary modal

* wip: not working

* feat: update permit2 e2e tests

* feat: tests passing

* fix: swap test

* fix: bad merge

* chore: merge

* fix: update tests for new modal

* fix: testid fix

* fix: test updates

* fix: reduce nesting

* test: remove line from test for debugging

* fix: update tests

* fix: more nesting in test

* fix: update test

* fix: reorganize test code
2023-05-25 13:49:27 -07:00
Zach Pomerantz
2415a1e3cd
test(e2e): improve hardhat configuration (#6650)
build: cache hardhat cache
2023-05-25 11:53:39 -07:00
Nate Wienert
1ba796a895
build: add vscode settings for default formatter (#6644)
build: add vscode settings for default formatter to be dbaeumer.vscode-eslint
2023-05-25 08:22:51 -10:00
Zach Pomerantz
4446eb9b84
fix: include sw metric with web vitals (#6646) 2023-05-25 10:12:20 -07:00
Jordan Frankfurt
d23b6e5da6
fix: remove app advert on mobile safari (#6630)
Co-authored-by: Jordan Frankfurt <jordan@CORN-Jordan-949.frankfurt>
2023-05-25 10:36:57 -05:00
Zach Pomerantz
44c355c7f0
build: caching i18n extractor (#6619)
* fix: do not attempt to cache i18n:extract

* fix: i18n extraction

* docs: improve comments
2023-05-24 14:23:40 -07:00
Vignesh Mohankumar
e4a9764a12
fix: increase useBestTrade debounce time (#6631)
* fix: increase useBestTrade debounce time

* reduce

* increase

* 350

* fix
2023-05-24 14:44:18 -04:00
Mike Grabowski
303fa15240
feat: show affordance in swap UI when we can't fetch usd quote (#6622)
* initial commit:

* add todo to linear
2023-05-24 22:32:53 +04:00
eddie
d180aef306
fix: no-undefined-or in object field types (#6640) 2023-05-24 11:31:40 -07:00
Mike Grabowski
c07c401189
feat: add animation to Settings menu (#6617)
* feat: add price impact back

* chore: update tes tname

* chore: update snapshot for price impact

* fix

* fix

* update snapshot after rebase

* update snapshot

* chore: finish

* chore: remove snapshot

* feat: add test matcher

* cleanup

* chore: add animation test

* add comment

* update comment
2023-05-24 22:02:59 +04:00
Zach Pomerantz
65d91eb363
build: use repository slack secret (#6639) 2023-05-24 13:15:28 -04:00
Jordan Frankfurt
bd4042aa16
chore: update pr template (#6634)
Co-authored-by: Jordan Frankfurt <jordan@CORN-Jordan-949.frankfurt>
2023-05-23 14:53:07 -07:00
github-actions[bot]
1dcafd2f2d
chore(i18n): new Crowdin translations (#6215)
* chore(i18n): synchronize translations from crowdin [skip ci]

* chore: trigger actions

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-05-23 14:39:58 -07:00
Jordan Frankfurt
66fcdb4465
feat: improve yarn prepare scripts (#6609)
* feat: improve yarn prepare scripts

* reset yarn.lock to main

* pr feedback

* Update scripts/prepare.js

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Update scripts/prepare.js

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Update scripts/prepare.js

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Update scripts/prepare.js

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Update scripts/prepare.js

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Update scripts/prepare.js

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Update scripts/prepare.js

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* pr feedback

* switch to using concurrently

* yarn dedupe

---------

Co-authored-by: Jordan Frankfurt <jordan@CORN-Jordan-949.frankfurt>
Co-authored-by: Jordan Frankfurt <jordan@corn-jordan-949.lan>
Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-05-23 16:07:05 -05:00
Jack Short
e398e8b950
fix: allow unsupported chain in pwat (#6629)
chore: allow unsupported chain in pwat
2023-05-23 13:36:28 -04:00
Tina
6424fdfbcd
fix: Simplify event logging for SWAP_QUOTE_RECEIVED (#6628)
* simplify event logging

* remove unused function parameter
2023-05-23 11:06:18 -04:00
eddie
95814e3271
fix: prevent race condition for swap state (#6624) 2023-05-22 15:57:17 -07:00
Jack Short
caa2524e27
feat: [DetailsV2] instant buy (#6599)
* initial impl

* removing isopen change

* stopping refetching

* shared button

* pending animiation

* updating shared

* updating snapshots

* adding disabled state

* isLoading in hook

* pulling out ternary

* removing fragment

* separate file for offer button

* fixing price diff check

* remove unnecessary export

* changing name to useBuyAssetCallback
2023-05-22 18:28:48 -04:00
Zach Pomerantz
d28a4b34cd
fix: do not attempt to cache i18n:extract (#6616) 2023-05-22 14:03:11 -07:00
cartcrom
f3a80c6272
feat: special case arb search (#6584)
* feat: special case arb search

* fix: check both current and existing token
2023-05-22 12:40:46 -04:00
Zach Pomerantz
b89ee36448
test(e2e): attempt to de-flake (#6611)
* test(e2e): improve memory mgmt

* test(e2e): record flakes

* test(e2e): simplify tests in attempt to de-flake

* test(e2e): more simplification

* test(e2e): disable transaction popup checks

* test(e2e): better wrap assertions

* test(e2e): always assert both inputs
2023-05-22 09:02:54 -07:00
Vignesh Mohankumar
fbc55db937
chore: remove chunkResponseStatus tag (#6586)
* chore: remove chunkResponseStatus tag

* lint
2023-05-21 17:25:58 -04:00
Jordan Frankfurt
835c62acfa
fix: use ephemeral props for styled component (#6607)
* fix: use ephemeral props for styled component

* add
2023-05-20 16:55:37 -05:00
Zach Pomerantz
8fe7c7a0a7
build: notify from notify/test (#6597)
* build: notify from notify/test

* debug

* debug2

* revert debugs
2023-05-19 12:24:11 -07:00
Tina
41113e6e41
fix: Use client side router only for price fetching (#6604)
use client side router only for price fetching
2023-05-19 13:35:29 -04:00
Mike Grabowski
58b25d29a9
feat: expand settings by default when custom values are set (#6603)
feat: expand by default
2023-05-19 21:35:02 +04:00
Zach Pomerantz
a2db3e2719
test(e2e): configure Cypress to post PR status comments (#6591) 2023-05-19 06:32:42 -07:00
Mike Grabowski
b62f9066a7
fix: add price impact back (#6581)
* feat: add price impact back

* chore: update tes tname

* chore: update snapshot for price impact

* fix

* fix

* update snapshot after rebase

* update snapshot
2023-05-19 09:24:06 +04:00
Zach Pomerantz
258f22e037
build: continue-on-error for slack notifications (#6600) 2023-05-18 15:30:43 -07:00
Zach Pomerantz
38b306a80f
build: pin github-tag-action (#6598) 2023-05-18 15:30:24 -07:00
Zach Pomerantz
9050f09bfe
build: notify from notify/releases (#6596) 2023-05-18 15:30:03 -07:00
Zach Pomerantz
77d46c361a
test(e2e): de-flake wrap (#6589)
* test(e2e): mv swap to dir

* test(e2e): split swap/wrap/errors

* test(e2e): de-flake wrap
2023-05-18 13:47:15 -07:00
Charles Bachmeier
4fb48bdd1f
fix: only request 1 listing on NFTDetails page (#6602)
only request 1 listing

Co-authored-by: Charles Bachmeier <charlie@genie.xyz>
2023-05-18 13:35:01 -07:00
cartcrom
cf2b6bf568
fix: portfolio balances after switching accounts (#6527)
* fix: handle portfolio staleness upon account change

* fix: only consider current account for tx updates

* test: add e2e test for account switching

* fix: remove unnused data-testid

* fix: added todo comment

* refactor: move test into existing folder

* fix: add account to dependency array

* todo: tx reducer

* test: update cypress config to pass in env variables

* fix: undo unintended change

* fix: use process.env

* fix: use regex instead of env
2023-05-18 16:32:35 -04:00
eddie
03095f4e48
feat: add feature flag for URA (#6593) 2023-05-18 10:14:18 -07:00
lavalamp
b2966f8d29
ci: Fix YAML spacing (#6592)
Fix YAML spacing
2023-05-18 09:43:02 -07:00
Charles Bachmeier
ef6d1f20ed
feat: [DetailsV2] Show data page header when nft scrolled out of view (#6585)
* show data page header when nft scrolled out of view

* add new snapshot test

* useRef for observer

* add comment

---------

Co-authored-by: Charles Bachmeier <charlie@genie.xyz>
2023-05-18 09:41:04 -07:00
lavalamp
10b156ff2b
ci: Final CI fixes pass (#6556)
* Final CI fixes pass

* Change cut to awk

* Remove workflow_dispatch

* Start, success, failure messges

* Deploy from main and add comment

* Update .github/workflows/2-deploy-to-staging.yml

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Update jobs to have correct comments, simplification in prod

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-05-17 14:29:06 -06:00
Zach Pomerantz
146c5f29cf
feat: only pre-cache the document (#6580)
* test(e2e): de-flake service-worker

* feat: rm stale cache storage

* fix: put not del

* fix: staging and test

* test: include staging

* fix: log

* test: rm console.log

* fix: unregister before

* test: deflake by restoring state afterwards
2023-05-17 12:10:28 -07:00
Zach Pomerantz
66a3475bf6
test(e2e): split swap tests (#6587)
* test(e2e): mv swap to dir

* test(e2e): split swap/wrap/errors
2023-05-17 09:43:52 -07:00
Zach Pomerantz
f6c393b016
test(e2e): de-flake activity-history (#6583) 2023-05-17 09:43:26 -07:00
cartcrom
15f8d34320
fix: update nonce deduplication logic (#6588)
* fix: update nonce-deduplication logic
* lint
2023-05-16 21:28:19 -04:00
eddie
504e09d3dc
feat: new review design (#6451)
* test: swap flow cypress tests

* fix: use default parameter

* feat: use Swap Component on TDP

* feat: auto nav for TDP tokens

* chore: merge

* chore: merge

* chore: merge

* chore: merge

* fix: remove extra inputCurrency URL parsing logic

* fix: undo last change

* fix: pass expected chain id to swap component

* fix: search for default tokens on unconnected networks if needed

* test: e2e test for l2 token

* fix: delete irrelevant tests

* fix: address comments

* fix: lint error

* test: update TDP e2e tests

* fix: use pageChainId for filter

* fix: rename chainId

* fix: typecheck

* fix: chainId bug

* fix: chainId required fixes

* fix: bad merge in e2e test

* fix: remove unused test util

* fix: remove unnecessary variable

* fix: token defaults

* fix: address comments

* fix: address comments and fix tests

* fix: e2e test formatting, remove Maybe<>

* fix: remove unused variable

* fix: use feature flag for swap component on TDP

* fix: back button

* feat: copy review screen UI from widgetg

* fix: modal padding

* feat: add final detail row

* fix: remove widget comment

* fix: update unit tests

* fix: code style consistency

* fix: remove padding from AutoColumn

* fix: update snapshots

* fix: use semantic gaps

* fix: more px and gaps

* fix: design feedbacks

* fix: button radius in summary modal

* fix: design nits

* feat: update design of summary modal

* fix: font weight and vertical spacing

* fix: update snapshots

* fix: css nits

* fix: modal flicker when refetching trade

* fix: comments

* fix: code style improvements

* feat: require trade to be defined

* fix: remove extra props from ThemedTexts

* fix: one more trans

* fix: remove unused export

* feat: remove undefined checks and other fixes

* fix: update test

* fix: add missing dollar sign

* fix: remove null check and update test

* fix: remove max width from detail row value

* fix: remove isOpen prop

* fix: isopen
2023-05-16 15:15:30 -07:00
Vignesh Mohankumar
1f755e8b0d
feat: add retry logic for dynamic imports (#6512)
* feat: add retry logic for lazy import

* try again

* add tests

* refactor: moves retry helper to subfolder

* missing-files

* fix

* doc comment

* tsdoc

* fake timers

* fix

* add eslint rule

* try again?

* try again?

* only dynamic

* try again

* try again

* IT WORKS

* add retry

* fix

* add test

* warn -> error

* lint

* lint

* lint

* add back cache

* rm test

* try again

* real timers but really short intervals

* try returning the promise?

* try returning the promise?

* try this package

* retry

* Update src/utils/retry.ts

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Update rules/enforce-retry-on-import.js

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Update rules/enforce-retry-on-import.js

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* eslint_rules

* test fixes

* name

* fix

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-05-16 16:53:22 -04:00
Vignesh Mohankumar
f45a7f921b
fix: handle switchChain failure in swap (#6507)
* fix: handle switchChain failure in swap

* comment

* fix
2023-05-16 16:47:13 -04:00
Vignesh Mohankumar
29db61ff90
fix: filter error caused by missing meta tags (#6546)
* fix: filter error caused by missing meta tags

* fix
2023-05-16 16:40:25 -04:00
Tina
8431ad9161
chore: Refactor swap request flow (#6499)
* Refactor swap quote flow with widget logic

* remove console logging

* add ignore path for serialization check and pass in native currencies for client side routing

* apply stashed changes

* revert node version change

* remove TODO comment because maybe no longer relevant

* update unit tests

* wip: add snapshot test

* add snapshot test for gas estimate badge

* address PR comments: rename variables, fix client side router initialization

* update Trade type

* add TODO comment about isExactInput util

* change | undefined convention to ?

* PR comments

* update type

* remove client side initialization logic and replace with TODO

* use routing-api for price fetching trades too

* remove QuoteType.Initialized
2023-05-16 16:33:46 -04:00
Vignesh Mohankumar
fd1aded517
fix: remove trailing slash from request url (#6542)
* fix: remove trailing slash from request url

* moves cast

* {}
2023-05-16 12:36:24 -04:00
Vignesh Mohankumar
27ad7cbd41
test: move all tests to beforeSend (#6513)
* beforeSend tests

* fix

* refactor: filterKnownErrors -> shouldRejectError (#6547)

* refactor: filterKnownErrors -> shouldRejectError

* no unknown

* comments
2023-05-16 12:36:17 -04:00
Joshua DeCristi
01e5de436a
fix: "Minimum output" should be "Maximum output" when trade is Exact Output (#6565)
* fix: minimum output should be showing maximum input when trade type is exact output

* fix: test for minimum output should be showing maximum input when trade type is exact output

---------

Co-authored-by: Josh DeCristi <joshdecristi@Joshs-MacBook-Pro.local>
2023-05-16 12:07:39 -04:00
Charles Bachmeier
fd5aa1b51e
fix: use padding component (#6579)
* fix: rm unused const

* use component

* update snapshot

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
Co-authored-by: Charles Bachmeier <charlie@genie.xyz>
2023-05-16 08:56:51 -07:00
Mike Grabowski
a6e1a7e6d9
feat: add slippage warning to MenuButton (#6548)
* feat: initial commit

* chore: add unit tests

* chore: move menubutton to sep. component

* chore: simplify styles and add real focused state

* chore: fix tests + some other tweaks

* chore: rename

* test: add snapshot tests

* tweaks
2023-05-16 11:41:14 +04:00
Jack Short
629fe2c144
feat: [DetailsV2] trait bubbles (#6552) 2023-05-15 19:17:45 -04:00
Vignesh Mohankumar
d73763ce75
refactor: imports shared polyfills in setupTests (#6571) 2023-05-15 17:11:28 -04:00
Zach Pomerantz
fe6df38997
build: upgrade to webpack5 with polyfilled Buffer (#6568)
* fix: Revert "fix: Revert "build: upgrade to webpack 5 (#6459)" (#6566)"

This reverts commit 5e591455b38c9618c750a23bc2a63cdcc30dba57.

* build: polyfill Buffer

* docs: fix comment negation
2023-05-15 14:07:05 -07:00
eddie
719ee0f5b5
fix: loosen permit2 expiration tolerance in e2e tests (#6573) 2023-05-15 10:58:05 -07:00
Charles Bachmeier
75bdf9a8d4
feat: [DetailsV2] Add left padding to trait rows and headers (#6534)
* feat: [DetailsV2] Add left padding to trait rows

* update snapshot

---------

Co-authored-by: Charles Bachmeier <charlie@genie.xyz>
2023-05-15 10:40:38 -07:00
Tina
efbe3994bb
fix: catch RouterPreference.AUTO case for routing-api usage (#6572)
catch AUTO case for routing-api
2023-05-15 13:38:59 -04:00
Vignesh Mohankumar
93fe8e4349
fix: polyfill ResizeObserver (#6553)
* polyfill

* lint

* polyfill test

* dedupe
2023-05-15 12:39:31 -04:00
Vignesh Mohankumar
6062f615a0
build: change automated release to 16:00 UTC (#6567) 2023-05-15 12:25:49 -04:00
Charles Bachmeier
42e3af7b5c
feat: [DetailsV2] Offer and Listing Tables (#6515)
* added home icon, basic content container with scroll behaviour

* add more struct

* add timeUntil util, add main structure of generic component, basic mock data

* propagate asset

* actual fake data

* working scroll

* proper alignment

* 1155 quantity

* small window sizes

* more action buttons

* cleanup

* update snapshot

* add tests

* add new test files

* add outline and hide usd price for certain screen sizes

* use sell order data

* update tests

* fetch multiple listings

* better price width on select screens

* mobile icon for approve

* bottom padding on mobile

* update snapshot

* use test objs in tests

* update query

* add border between rows

* update page padding

* breakpoint overlap

* simplified sellOrder check

* external link

* upstream button and better mobile padding

* add file and update tests

---------

Co-authored-by: Charles Bachmeier <charlie@genie.xyz>
2023-05-15 09:14:09 -07:00
Vignesh Mohankumar
57274a800d
fix: don't console.error for WalletConnect modal close (#6559) 2023-05-15 12:13:34 -04:00
Tina
5e591455b3
fix: Revert "build: upgrade to webpack 5 (#6459)" (#6566)
Revert "build: upgrade to webpack 5 (#6459)"

This reverts commit ec547ab100f793d127246186d5fd60786758a862.
2023-05-15 09:48:27 -04:00
Zach Pomerantz
ec547ab100
build: upgrade to webpack 5 (#6459)
* fix: import default from json

* fix: fallback to path-browserify

* build: upgrade to webpack5

* test: update size-tests to reflect single entry

* test: increase service-worker timeout

* docs: improve comments

* build: rm MiniCssExtract workaround

* docs: even better comments

* test: back out longer test

* build: vendor chunk

* test: increase sw timeout

* fix: justified splitChunks config

* better explanation

* fix: longer timeout

* fix: caching

* merge and rm duplication

* build
2023-05-12 12:55:01 -07:00
Charles Bachmeier
9de76c69ae
feat: [DetailsV2] Data Page Header (#6549)
* hide header on mobile

* add buy and offer buttons, thumbnail, text

* handle no sell orders and add tests

* rehide on mobile

* breakpoint optimizations

* design feedback

---------

Co-authored-by: Charles Bachmeier <charlie@genie.xyz>
2023-05-12 14:48:26 -04:00
Charles Bachmeier
85d1b90197
feat: [DetailsV2] Mobile support for traits (#6535)
Co-authored-by: Charles Bachmeier <charlie@genie.xyz>
2023-05-12 13:39:31 -04:00
lavalamp
38af86e1bb
ci: More CI pipeline fixes (#6550)
Move git config
2023-05-12 10:03:45 -07:00
Zach Pomerantz
11a8df2a3e
build: report test failures via Slack (#6539)
* build: report test failures
2023-05-12 09:19:20 -07:00
Vignesh Mohankumar
3726b6bb47
fix: remove top-level Fragment (#6540) 2023-05-12 11:19:52 -04:00
Vignesh Mohankumar
bfde34c774
refactor: moves retry helper to subfolder (#6531) 2023-05-12 11:08:14 -04:00
Tina
bd8113d018
chore: Goodbye widget :( (#6543)
* goodbye widget :(

* remove unused function

* modify trace tests

* fix lint

* is github down?
2023-05-12 11:05:22 -04:00
lavalamp
14e3ef044e
ci: CI pipeline fixes for merge issues (#6529)
* CI fixes

* update text content

* Change PR to force push

* releases environment for prod deploy

* add runs-on

* Rename third step

* Update .github/workflows/1-main-to-staging.yml

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Update .github/workflows/1-main-to-staging.yml

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* nits

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-05-12 08:30:30 -04:00
Vignesh Mohankumar
4fc4bdcd55
fix: propagates user rejection errors (#6533) 2023-05-11 19:40:02 -04:00
Zach Pomerantz
3733570a89
build: update workflow owners (#6537) 2023-05-11 14:24:52 -07:00
Tina
7a042a5199
chore: Replace widget skeleton with internal swap skeleton (#6524)
* replace widget skeleton with internal version

* remove unuecessary div wrappers

* add snapshot test

* forgot to commit this file earlier

* remove exports

* revert(e2e): waitForAnimations

* convert values to px, refactor a bit to use flex gap instead of padding

* remove unnecessary props

* update snapshot test

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-05-11 16:58:35 -04:00
Jordan Frankfurt
6d5e17a6e7
fix: deduplicate remote and local tx lists (#6438)
* fix: deduplicate remote and local tx lists

* add nonce to local transactions

* removes local transactions that have nonces that are duplicates of remote transactions

* add e2e test

* lint fix

* fix types in test

* use supported chain id for reducer tests

* use getReceipt to remove outdated transactions via existing polling setup

* pr nits from cmcewen

* fix lint

* fix test
2023-05-11 13:16:18 -05:00
Jack Short
8301c5892c
chore: removing token type check from routing (#6536) 2023-05-11 13:37:28 -04:00
Vignesh Mohankumar
59b757dda0
fix: disables CMC list temporarily (#6532)
* fix: disables CMC list temporarily

* -
2023-05-10 20:32:43 -04:00
Jack Short
92a6ec67b3
feat: [DetailsV2] different media types on landing page (#6492)
* initial layout assuming media type exists

* fixing embeds

* media type function

* updated snapshot test

* initial shadow impl

* better shadows

* audio player controls

* updating tests

* content not available handlers

* errors on all media types

* removing fullscreen from iframe

* adding snapshot tests

* responding to comments

* text align center

* updating tests
2023-05-10 13:10:25 -04:00
lavalamp
1d6a1e90d7
ci: GH action for deploying to production (#6482)
* GH action for deploying to production

* Remove dependency on tests

* Update .github/workflows/4-deploy-to-prod.yml

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Update .github/workflows/4-deploy-to-prod.yml

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Add tag as action step rather than separate target

* Comments

* Update .github/workflows/4-deploy-to-prod.yml

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Specify branches

* Update run name

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-05-10 12:59:59 -04:00
Jack Short
01aa3291b3
chore: bubbling up pwat spender from route query (#6481)
* chore: bubbling up pwat spender from route query

* refactoring

* adding loading state

* moving to loading allowance

* responding to comments

* linting
2023-05-10 12:45:58 -04:00
Zach Pomerantz
5539ebedf7
build: update stage 2 name (#6526) 2023-05-10 09:38:31 -07:00
Vignesh Mohankumar
e6adddbf55
refactor: return onDemandEntries instead of mediaURLs (#6514)
* refactor: return onDemandEntries instead of mediaURLs

* lint

* fix test
2023-05-10 11:46:28 -04:00
Mike Grabowski
0050b1e165
feat: new routing diagram (#6510)
* chore: initial commit

* chore: add todo to refactor and simplify if conditional in the future

* chore: update layout

* chore: ui tweaks

* chore: add todo

* chore: change todo

* chore: update UI

* chore: tmp

* feat: rename router preference

* chore: update type

* fix error

* fix one more issue

* finish UI work

* chore: remove unecessary components

* chore: update non-snapshot unit tests

* chore: fix lint

* chore: fix ts

* chore: one more time

* fix

* chore: update snapshots

* chore: add jira tickets

* chore: fix mobile popovers

* chore: add analytics event

* chore: fix padding and send event

* chore: fix loading state

* oops

* chore: address review

* chore: comment

* chore
2023-05-10 19:06:12 +04:00
Vignesh Mohankumar
5bf33ab004
revert(e2e): waitForAnimations (#6525)
Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-05-10 10:53:53 -04:00
lavalamp
a4cfeecd8c
ci: Workflow for pushing to releases/staging (#6319)
* Initial draft of releases/staging force push

* Rename

* Update PAT, test on PR target

* Remove pull request target, add environment

* Update .github/workflows/push-staging.yml

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Update .github/workflows/push-staging.yml

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Update .github/workflows/push-staging.yml

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* comments

* Update step name

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-05-10 08:29:31 -04:00
lavalamp
76cbfdd0b9
ci: GH action for promoting staging -> prod (#6366)
* Add action for promoting to prod

* Update .github/workflows/pr-staging-to-prod.yml

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Update .github/workflows/pr-staging-to-prod.yml

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Update .github/workflows/pr-staging-to-prod.yml

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Update .github/workflows/pr-staging-to-prod.yml

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Update .github/workflows/pr-staging-to-prod.yml

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Comments

* Comments

* Remove commit message

* Fix service account reference, add CODEOWNERS

* Update .github/workflows/pr-staging-to-prod.yml

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Nits

* Fix newline

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-05-10 08:29:20 -04:00
lavalamp
0db9e51e41
ci: Staging deploy GH action definition (#6455)
* Staging deploy GH action definition

* Remove workflow_dispatch

* Update src/utils/env.ts

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Restrict sentry reporting to staging environment

* Rename and change environment

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-05-10 08:28:59 -04:00
Vignesh Mohankumar
82e7925a17
fix: properly filter AbortErrors (#6519)
* fix: properly filter AbortErrors

* lol
2023-05-09 19:04:41 -04:00
Zach Pomerantz
2150347ba2
build: cache generated files across builds (#6495)
* build: cache generated files across builds

* docs: lingui pkg-up comment

* docs: explain clean extraction
2023-05-09 15:49:53 -07:00
Vignesh Mohankumar
2f80646ddd
fix: add chunkResponseStatus tag (#6509)
* fix: add chunkResponseStatus tag

* add-tests

* fix tests

* tests

* description

* comments

* comment

* move

* comment

* lint
2023-05-09 17:44:58 -04:00
matteen
55eea6a724
chore(deps): bump @uniswap/token-lists (#6520)
* chore(deps): bump @uniswap/token-lists

* run yarn deduplicate
2023-05-09 17:34:05 -04:00
matteen
709a70652f
feat: add tokenlist validation (#6504)
* feat: add tokenlist validation

* use alternative for spread operator

* maintain tokenlists version and use original ajv version

* bump ajv

* Revert "bump ajv"

This reverts commit b9d2dd61c61f4aeedc00faf034c5a6e89b0d28fc.

* rename vars in validator

* update gitignore

* nit fixes

* test

* add ^ back

* remove ^

* removed and readded ajv

* try require.resolve

* Revert "try require.resolve"

This reverts commit 62f58bcb7f02f1ead430a4c94ca3428a60d4d4c5.

* bump eslint-config

* yarn lock merge conflict

* bring back spread operator

* remove redundant lint ignore
2023-05-09 16:34:15 -04:00
Jack Short
5a7a041f12
feat: [DetailsV2] background for nft details (#6496)
* feat: background for nft details

* fixing top spacing

* adding new states for zindex
2023-05-09 16:08:28 -04:00
cartcrom
b60d98fc17
fix: loading spinner console bug (#6518)
fix: update svg path
2023-05-09 14:59:26 -04:00
Zach Pomerantz
38d9ab67eb
test(e2e): token details and test cleanup (#6516)
* test(e2e): split e2e commands/setup

* test(e2e): consolidate tests

* test(e2e): simplify

* test(e2e): mv token details tests to appropriate spec

* test(e2e): rm obsolete constant

* test(e2e): comments

* test(e2e): do not wait for animations
2023-05-09 10:33:55 -07:00
Jordan Frankfurt
5e6ef1575b
test: skip flakey e2e test (#6517) 2023-05-09 11:07:13 -05:00
Vignesh Mohankumar
4a015e9d0d
fix: ensure event.request is defined in trace (#6498)
* fix: ensure event.request is defined in trace

* add check for empty event
2023-05-09 11:44:07 -04:00
Mike Grabowski
c383a0a0a2
feat: new Settings menu for Swap (#6480)
* feat: initial commit

* remove extra check

* chore: divider fix

* feat: switch from boolean to routerPreference enum

* chore: align name

* chore: fix two errors

* chore: clean up

* chore: entire radio button clickable

* chore: remove unused toggle component

* Revert "chore: remove unused toggle component"

This reverts commit 42858a02b5bcd572682db38025b69f8b1426a8c1.

* feat: rewrite slippage

* feat: Slippage

* chore: tbd tomorrow

* Update src/state/user/reducer.ts

Co-authored-by: Tina <59578595+tinaszheng@users.noreply.github.com>

* feat: replace auto with Slippage enum

* chore: add todo for deadline

* chore: cleanup

* feat: improve autoslippage

* chore: replace price with auto

* chore: fix lint

* test: add coverage for Expand

* chore: fix tests

* chore: review feedback part 1

* chore: rework warning

* chore: add jira tickets

* feat: add tests for useUserSlippageTolerance

* chore: add some more

* chore: one more

* add tests for slippage

* chore: add unit tests for transactionsettings

* remove

* revet changes to improve coverage

* chore: update to figma caption

* chore

* chore

* chore: update wording

* Update src/components/Expand/index.tsx

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* fix: issue with new value, update confusing migration comment

* chore: remove opacity animation temporarily

* chore: update snapshot test

* chore: fix e2e + update comment

* chore: fix tests

* chore: fix tests

---------

Co-authored-by: Tina <59578595+tinaszheng@users.noreply.github.com>
Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-05-09 10:33:25 -04:00
Vignesh Mohankumar
d6e92804ad
fix: filter AbortError from Sentry (#6497) 2023-05-08 18:25:00 -04:00
Zach Pomerantz
f0d8f8b23b
test(e2e): mock uniswap token lists from ipfs (#6511)
* test(e2e): mock uniswap token lists from ipfs

* test(e2e): correctly intercept
2023-05-08 15:04:02 -07:00
Charles Bachmeier
ff080aa957
fix: update OS listing fee (#6505)
* update OS listing fee

* remove redundancy

---------

Co-authored-by: Charles Bachmeier <charlie@genie.xyz>
2023-05-08 10:28:01 -07:00
cartcrom
04d9ff7d71
feat: update useAllTokensMultichain usage (#6493)
* feat: updates useAllTokensMultichain to return userAddedTokens

* fix: use correct types in tests

* chore: add documentation for future removal of TokenAddressMap

* fix: use doc comments

* test: add unit test for useAllTokensMultichain

* fix: check userAddedTokens for undefined
2023-05-05 18:15:27 -04:00
cartcrom
406893d99a
test(e2e): permit2 approval (#6488)
* build: upgrade cypress-hardhat

* test: reset hardhat between tests

* test: enable auto-mining

* build: upgrade cypress-hardhat again

* test: permit2 e2e tests

* test: user approval rejection

* refactor: reuse common permit util vars to reduce # of lines

* fix: var casing

* refactor: polish

* refactor: clean up comments and function names

* refactor: remove approval util and update scoping

* fix: further nits
2023-05-05 17:52:22 -04:00
Vignesh Mohankumar
4630720956
fix: handle addEventListener being unsupported on Safari <14 (#6426)
* fix: handle addEventListener being unsupported on Safari

* conditionally call

* Revert "conditionally call"

This reverts commit b6b7d2f0170caeca3aa8bf82ea97fd16a73cba44.

* comment

* fix

* callback

* add tests

* lint

* casting

* good pr comments

* fix
2023-05-05 13:36:20 -04:00
Jordan Frankfurt
e73e1540ad
fix: errors are responsible for their own grammar (#6490) 2023-05-05 11:38:00 -05:00
Vignesh Mohankumar
3a82642fe6
fix: update service worker to precache css/js files (#6486)
* fix: update service worker to precache css/js files

* add test

* move to utils

* working tests

* fixes

* lint

* change names

* lint

* change return type

* fix

* fix

* changes

* lint

* rename cache

* lint

* fix comments and remove string[] case

* string |

* Update src/serviceWorker/utils.ts

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

---------
2023-05-04 14:29:13 -04:00
Zach Pomerantz
2a50d6a17e
test(e2e): reset hardhat between tests (#6487) 2023-05-04 08:31:53 -07:00
eddie
c8a8149127
fix: add amplitude page context to swap flow events (#6489) 2023-05-04 11:20:12 -04:00
Vignesh Mohankumar
38cde648cf
fix: add a catch on collect static call (#6491)
* fix: add a catch on collect static call

* comment
2023-05-04 11:07:01 -04:00
Charles Bachmeier
33c099119d
chore: refactor Bag to use scroll hook (#6483)
* chore: refactor Bag to use scroll hook

* remove outdated comment

---------

Co-authored-by: Charles Bachmeier <charlie@genie.xyz>
2023-05-03 14:19:27 -07:00
Jordan Frankfurt
40247ff7e0
test(e2e): slippage failure (#6464)
* initial draft

* remove logs

* assertions improvement

* add more comments

* add explicit call to disable automine

* test out a very long timeout

* Revert "test out a very long timeout"

This reverts commit 0fc2666d6f4cb02739d14cf2aa07f041e6046669.

* improve test reliability

* remove mock list response

* remove hardhat reset and clean up tests

* simplify assertion

* add zzmp's nits
2023-05-03 16:03:43 -05:00
eddie
30d1de8e84
fix: moonpay modal height (#6439) 2023-05-03 14:05:50 -04:00
Jack Short
0e5328bee9
feat: [DetailsV2] initial details landing page view (#6453)
* feat: initial view of details landing page

* gap

* dynamic font sizes

* added test

* responding to comments

* updating snapshot

* linting
2023-05-03 11:08:48 -04:00
Jordan Frankfurt
d1995bc5a6
test(e2e): deadline passed swap error state (#6444)
* chore: ignore hardhat cache files

* test: add forking hardhat config

* test: install cypress-hardhat

* build: add cypress-hardhat

* fix: lint

* build: add hardhat

* build: add @sentry/types

* fix: better origin

* test: update cypress VisitOptions to include hardhat

* fix: default to connected wallet user state

* test: add a hardhat provider

* build: update imports

* chore: comments

* fix: massage eth_sendTransaction

* feat: example swap test (#6415)

* initial commit

* add intercept for amplitude

* fix: destructure result

* click swap submission

* fix: eth_sendTransaction via bridge

* test works

* finish chain interaction test

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* swap should render an error when a transaction fails due to a passed deadline

* use mining utils to manage transaction confirmation

* update to use new hardhat syntax and make comments more clear

* test a very long timeout in CI

* Revert "test a very long timeout in CI"

This reverts commit 141c28e15c511f2338c2b5b2b60521a7cb4c1bda.

* fiddle with automine settings

* pr feedback

* cleanup

* bump cypress-hardhat

* use setAutomine

* use setAutomine

* remove .reset

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-05-02 23:52:07 -05:00
Jordan Frankfurt
4959836c2a
test(e2e): (un/)wrap transactions (#6474)
* chore: e2e test (un/)wrap transactions

* wrap button should not be disabled (wait for enabled state)

* use automine

* pr feedback

* configure automine

* make tests stop relying on reset
2023-05-02 23:51:17 -05:00
Charles Bachmeier
ef4a80852d
chore: update to listing with seaport 1.5 (#6485)
update to listing with seaport 1.5

Co-authored-by: Charles Bachmeier <charlie@genie.xyz>
2023-05-02 18:46:12 -07:00
Vignesh Mohankumar
c2a972eb75
fix: filter chrome-extension errors (#6475)
* fix: filter chrome-extension errors in Sentry

* check stack
2023-05-02 15:43:37 -04:00
eddie
47a2768d89
chore: remove unused feature flags (#6484) 2023-05-02 15:28:12 -04:00
eddie
ca60caf6b0
feat: use Swap Component on TDP (#6332)
* test: swap flow cypress tests

* fix: use default parameter

* feat: use Swap Component on TDP

* feat: auto nav for TDP tokens

* chore: merge

* chore: merge

* chore: merge

* chore: merge

* fix: remove extra inputCurrency URL parsing logic

* fix: undo last change

* fix: pass expected chain id to swap component

* fix: search for default tokens on unconnected networks if needed

* test: e2e test for l2 token

* fix: delete irrelevant tests

* fix: address comments

* fix: lint error

* test: update TDP e2e tests

* fix: use pageChainId for filter

* fix: rename chainId

* fix: typecheck

* fix: chainId bug

* fix: chainId required fixes

* fix: bad merge in e2e test

* fix: remove unused test util

* fix: remove unnecessary variable

* fix: token defaults

* fix: address comments

* fix: address comments and fix tests

* fix: e2e test formatting, remove Maybe<>

* fix: remove unused variable

* fix: use feature flag for swap component on TDP

* fix: back button
2023-05-02 14:39:44 -04:00
Zach Pomerantz
252acef199
build: cap chunk size to 5MB (#6479)
* build: cap chunk size to 5MB

* test: rm size-tests
2023-05-02 08:46:32 -07:00
Zach Pomerantz
00ecb933ac
test(lint): separate multiline comments (#6476) 2023-05-02 08:26:07 -07:00
Vignesh Mohankumar
607d0d443e
fix: filter errors with OneKey in stack (#6477)
* fix: filter errors with OneKey in stack

* check stack
2023-05-01 15:32:05 -04:00
Charles Bachmeier
ff0209a78f
feat: [DetailsV2] add link and hover state to trait component (#6472)
* hide trait container when asset has no traits

* add traits header row

* trait value rows and scroll behaviour

* row with placeholder values

* add random filler values and proper scrollbar styles

* working rarity graph

* bar border radius

* move rarity graph to its own file

* always show scrim

* working scrim and move traitrow to its own file

* cleanup

* remove padding

* move scrollbar right

* add snapshot tests

* add comment about randomly generated rarities

* cleanup

* only pass traits

* justify

* not important

* cleanup scrim styles

* remove comment

* add scroll state hook

* lint

* update test

* object over map

* remove spaces

* justify content

* add ticket

* add comments

* update snapshot

* add link and hover state to trait component

* correct padding

* respond to comments

* add component and use css for vis

---------

Co-authored-by: Charles Bachmeier <charlie@genie.xyz>
2023-05-01 11:52:49 -07:00
Zach Pomerantz
924e83139b
test: keep test output clean (#6469) 2023-05-01 10:58:32 -07:00
Jack Short
4d5cc8267e
chore: removing pwat feature flag (#6467)
* chore: removing pwat flag

* removing it from enum

* updating test

* trade is not the same as usingPwat
2023-05-01 11:57:56 -04:00
Charles Bachmeier
6bc7cfc996
feat: [DetailsV2] Add Trait component content (#6460)
* hide trait container when asset has no traits

* add traits header row

* trait value rows and scroll behaviour

* row with placeholder values

* add random filler values and proper scrollbar styles

* working rarity graph

* bar border radius

* move rarity graph to its own file

* always show scrim

* working scrim and move traitrow to its own file

* cleanup

* remove padding

* move scrollbar right

* add snapshot tests

* add comment about randomly generated rarities

* cleanup

* only pass traits

* justify

* not important

* cleanup scrim styles

* remove comment

* add scroll state hook

* lint

* update test

* object over map

* remove spaces

* justify content

* add ticket

* add comments

* update snapshot

* correct padding

---------

Co-authored-by: Charles Bachmeier <charlie@genie.xyz>
2023-05-01 11:43:55 -04:00
Vignesh Mohankumar
97312bb174
fix: match OneKey more generically (#6461)
* fix: match OneKey more generically

* flip

* Update src/tracing/errors.test.ts

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Update src/tracing/errors.test.ts

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Update src/tracing/errors.test.ts

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* backslashes

* fix

---------
2023-05-01 11:02:26 -04:00
cartcrom
d0a10fcf8d
refactor: activation hook w/ global state (#6413)
* feat: moved tryActivation to global hook/state

* test: activation hook

* fix: merge conflicts

* fix: update file path for render utils in activate.test.ts

* fix: add await for connector deactivation

* fix: pr comment fixes

* fix: update tests

* refactor: use stronger activation state type

* refactor: use global state instead of props in ConnectionErrorView

* fix: re-add uri availability check

* fix: lint

* fix: nits

* fix: css regression

* fix: update test enum usage

* fix: use native disabled attribute

* test: add snapshot tests for different Option states

* fix: zach's PR comments

* test: update snapshots/unit tests

* style: pending boolean names

* fix: updated test import

* docs: added comment explaining analytics difference in wallet connection

* test: assert console.debug calls and fix act() issues

* test: drawer close

* test: import specific drawer fn instead of whole module
2023-04-28 19:14:30 -04:00
Jordan Frankfurt
7a1a476e45
fix: spoof origin and referer (#6468)
* fix: spoof origin and referer

* comments, chaining, and an accurate replication of amplitude response bodies
2023-04-28 17:29:16 -05:00
Vignesh Mohankumar
b3bfc1003a
build: upgrade sentry-release action (#6463) 2023-04-28 11:55:28 -04:00
Zach Pomerantz
3b1ef8033b
test: upgrade cypress-hardhat (#6462) 2023-04-28 08:46:42 -07:00
Zach Pomerantz
803485b96a
build: update default test settings (#6441)
build: coverage on CI by default
2023-04-27 14:34:37 -07:00
Jack Short
6df5d3a701
chore: moving nft test fixtures to their own file (#6456)
* chore: moving nft test fixtures to their own file

* refactoring structure

* renaming file
2023-04-27 17:10:06 -04:00
lynn
2d4eafc6b3
test: unsupported currency footer unit test (#6360)
* tests are complete

* update comment

* remove console log, and test close icon

* init

* lets try something else to avoid timeout

* try splitting up last test for timeout

* undo, it wasnt working

* revert order test

* add comment for sanity check

* test another way

* try userEvent

* increase timeout

* move timeout

* init

* use test constants

* use constants

* change address

* more comprehensive tests

* merge constants and use mocked

* remove comments

* remove dual import

* Update src/components/swap/UnsupportedCurrencyFooter.test.tsx

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* respond comments

* update tests

* remove console log

* fixes

* add act

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-04-27 16:54:05 -04:00
lynn
9b52fea58a
test: swap details dropdown unit test (#6349)
* init for swap details dropdown test

* more tests

* complete tests, ready for review

* add to dev deps

* init

* merge main

* init

* use test constants

* use constants

* change address

* more comprehensive tests

* merge with constants

* move noop

* add eslint rule

* return null in noop

* merge

* update snapshot

* constant name

* snapshot change

* lint

* undo eslint change

* Update src/components/swap/SwapDetailsDropdown.test.tsx

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Update src/components/swap/SwapDetailsDropdown.test.tsx

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Update src/components/swap/SwapDetailsDropdown.test.tsx

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* respond comments

* update snapshot

* merge main

* user event instead

* add act

* import fix

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-04-27 16:53:45 -04:00
Jack Short
b92b286626
chore: updating listing marketplace icons (#6458)
* chore: updating listing marketplace icons

* removing svgs from public

* responding to comments
2023-04-27 16:51:53 -04:00
lynn
a8268728d3
test: advanced swap details component unit test (#6363)
* init

* init

* init

* use test constants

* use constants

* change address

* more comprehensive tests

* move noop

* add eslint rule

* return null in noop

* merge

* checkpoint

* fixes

* add tooltip test

* remove unused file

* merge swap modal header

* add third test

* add test for syncing and loading case

* respond to comments

* more descriptive comments

* update snapshot

* update

* change to act
2023-04-27 16:36:36 -04:00
lynn
ab6debbf46
test: swap modal footer unit test (#6353)
* swap footer modal test

* remove empty test

* init

* merge main and jordan comment

* init

* use test constants

* use constants

* change address

* more comprehensive tests

* merge constants

* fix errors

* remove dual import noop

* update snapshot

* Update src/components/swap/SwapModalFooter.test.tsx

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* update snapshot

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-04-27 15:07:49 -04:00
matteen
4c664645c6
feat: add L2 CG tokenlists (#6292)
* feat: add L2 CG tokenlists

* remove extra line
2023-04-27 12:50:05 -04:00
Jordan Frankfurt
4416a84fd7
fix: disable bnb network option on uniwallet (#6452)
* fix: disable bnb network option on uniwallet

* use supported chain set
2023-04-27 09:16:28 -05:00
lavalamp
eaaff81a67
ci: Emit to slack on merge to releases/* branch (#6318)
* Initial draft of Slack notification on releases/* merges

Test

* Add back proper Slack message content

* Feedback revisions

* Update .github/workflows/notify-slack-on-release-merge.yml

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Update .github/workflows/notify-slack-on-release-merge.yml

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Update .github/workflows/notify-slack-on-release-merge.yml

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* Comments

* revert to github env

* Add PR target back

* Revert multi-line

* write to context, add multi-line back

* Try other reference to context

* one other way of settings output...

* Pull from output

* Remove env

* Remove PR target

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-04-26 20:32:42 -06:00
Zach Pomerantz
f7b8f945f2
build: allow parallel cypress re-run (#6449)
* build: allow parallel cypress re-run

* build: add a step
2023-04-26 17:02:53 -07:00
Jordan Frankfurt
115c65500b
feat: mining mode switch to disable auto-mine (#6450)
* feat: mining mode switch to update so we can make assertions about pending transaction state

* update test to use explicit mining

* Update hardhat.config.js

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-04-26 15:16:51 -05:00
Jordan Frankfurt
3d8d29fd18
feat: e2e testing - Handle wallet rejection (#6442)
* chore: ignore hardhat cache files

* test: add forking hardhat config

* test: install cypress-hardhat

* build: add cypress-hardhat

* fix: lint

* build: add hardhat

* build: add @sentry/types

* fix: better origin

* test: update cypress VisitOptions to include hardhat

* fix: default to connected wallet user state

* test: add a hardhat provider

* build: update imports

* chore: comments

* fix: massage eth_sendTransaction

* feat: example swap test (#6415)

* initial commit

* add intercept for amplitude

* fix: destructure result

* click swap submission

* fix: eth_sendTransaction via bridge

* test works

* finish chain interaction test

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* stub sending a transaction to simulate wallet rejection of a transaction

finish test

s

* Update cypress/e2e/swap.test.ts

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

* lint

* fix network connection bug

---------

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2023-04-26 13:02:51 -05:00
Charles Bachmeier
c178da626f
chore: add more ip infringing collections to the blocklist (#6446)
* updated blocked collections and don't allow for address search of blocked collections

* revert to array
2023-04-26 10:31:49 -07:00
Zach Pomerantz
e3c589ae41
fix: wallet connection analytics (#6296)
* test: web3

* fix: wallet connection analytics

* test: wallet connection analytics

* build: upgrade web3-react@^8.2

* test: web3

* chore: better merge

* fix: unmock

* fix: use usePrevious

* fix: naming

* fix: deps
2023-04-26 10:27:04 -07:00
Vignesh Mohankumar
6d60aca437
fix: filter OneKey related errors (#6396)
* fix: filter OneKey related errors

* fix

* .app
2023-04-26 11:57:13 -04:00
Charles Bachmeier
c77885c4c0
fix: remove patches (#6448)
remove patches
2023-04-25 16:20:46 -07:00
Zach Pomerantz
01684977b3
test: add a 'hardhat' mock window.ethereum (#6395) 2023-04-25 14:24:57 -07:00
Vignesh Mohankumar
025a84de93
build: analyzes only mapped (#6437)
build: analyze only mapped
2023-04-25 16:59:10 -04:00
Jack Short
0025997175
chore: updating purchasable markets from activity (#6443)
* updating purchasable markets from activity

* renaming

* adding trans + refactor

* snapshot test

* removing snapshot test and only matchin test

* deleting snap
2023-04-25 16:17:36 -04:00
Vignesh Mohankumar
acf97e042c
fix: filter WebAssembly compile errors (#6445)
* test

* fix: filter WebAssembly compilition errors

* Update src/tracing/errors.ts

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>

---------
2023-04-25 15:35:14 -04:00
Jack Short
771618b1c9
chore: updating marketplace icons (#6424)
* chore: updating marketplace icons

* removing console

* eslint

* uni logo

* nft20

* weird svg id bug

* adding gradient id to other marketplaces

* purchasable markets

* test size inc

* removing the nxyz endpoint

* adding back nxyz endpoint for testing

* graphql enum is purchasable markets

* removing nxyz

* self nit

* changing width and height to size - removing gradientId from props - updating gradient id

* removing purchasable markets

* linting

* adding tests to ensure marketplace

* better description

* needs to check for null and not undefined
2023-04-25 15:20:30 -04:00
Zach Pomerantz
87144de9c8
test: transform vanilla-extract for jest (#6425)
* fix: transform vanilla extract for jest

* lint: vanilla transform

* build: deduplicate

* test: improve transformIgnorePatterns

* fix: broken snapshot

* nits

* Update craco.config.cjs

* build: lockfile

* build: lockfile

* Update vanilla.transform.cjs
2023-04-25 12:06:58 -07:00
Charles Bachmeier
63d0290a50
feat: [DetailsV2] more shared component content (#6420)
* add page break and placeholder files

* container layout

* description tabs

* add table tabs

* mobile wrap

* remove todo

* adaptive padding

* add extensible tabbed component

* add new file

* add snapshot test for empty data page

* update snapshot

* add new snapshot

* undo unrelated snapshot change

* draft: details v2 containers

* Revert "draft: details v2 containers"

This reverts commit 7c6580c974a7c749490c909778757a51a13b8e07.

* uniform padding and single tab styling

* update snapshot

* update default tab behaviour

* add trait bubble

* working chevrons

* shared bubble tab title

* add placeholder nums for offers and listings

* remove styles and update snapshot

* remove chevron and update snapshot

* use test asset for snapshot

* max width

* convert to map with keys

* remove bubbletext helper

* remove extra brace

* use styled components and memo

* update trait component height

* update snapshot

* Add count field to Tab

* add comment

* update snapshot

* move styled component to shared folder

* update snapshot

---------

Co-authored-by: Charles Bachmeier <charlie@genie.xyz>
Co-authored-by: Jack Short <john.short.tj@gmail.com>
2023-04-25 09:40:43 -07:00
1202 changed files with 86929 additions and 122116 deletions

11
.env
View File

@ -1,13 +1,16 @@
# These API keys are intentionally public. Please do not report them - thank you for your concern.
ESLINT_NO_DEV_ERRORS=true
REACT_APP_AMPLITUDE_PROXY_URL="https://api.uniswap.org/v1/amplitude-proxy"
REACT_APP_AMPLITUDE_PROXY_URL="https://null.null"
REACT_APP_AWS_API_REGION="us-east-2"
REACT_APP_AWS_API_ENDPOINT="https://beta.api.uniswap.org/v1/graphql"
REACT_APP_AWS_API_ENDPOINT="https://null.null"
REACT_APP_BNB_RPC_URL="https://rough-sleek-hill.bsc.quiknode.pro/413cc98cbc776cda8fdf1d0f47003583ff73d9bf"
REACT_APP_INFURA_KEY="4bf032f2d38a4ed6bb975b80d6340847"
REACT_APP_QUICKNODE_MAINNET_RPC_URL="https://magical-alien-tab.quiknode.pro/669e87e569a8277d3fbd9e202f9df93189f19f4c"
REACT_APP_MOONPAY_API="https://api.moonpay.com"
REACT_APP_MOONPAY_LINK="https://us-central1-uniswap-mobile.cloudfunctions.net/signMoonpayLinkV2?platform=web&env=staging"
REACT_APP_MOONPAY_PUBLISHABLE_KEY="pk_test_DycfESRid31UaSxhI5yWKe1r5E5kKSz"
REACT_APP_SENTRY_DSN="https://a3c62e400b8748b5a8d007150e2f38b7@o1037921.ingest.sentry.io/4504255148851200"
REACT_APP_STATSIG_PROXY_URL="https://api.uniswap.org/v1/statsig-proxy"
REACT_APP_TEMP_API_URL="https://temp.api.uniswap.org/v1"
REACT_APP_STATSIG_PROXY_URL="https://null.null"
REACT_APP_TEMP_API_URL="https://null.null"
REACT_APP_UNISWAP_API_URL="https://null.null"
REACT_APP_WALLET_CONNECT_PROJECT_ID="c6c9bacd35afa3eb9e6cccf6d8464395"

View File

@ -1,15 +1,16 @@
# 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_ENDPOINT="https://api.uniswap.org/v1/graphql"
REACT_APP_AMPLITUDE_PROXY_URL="https://null.null"
REACT_APP_AWS_API_ENDPOINT="https://null.null"
REACT_APP_BNB_RPC_URL="https://old-wispy-arrow.bsc.quiknode.pro/f5c060177236065c1058531a0615ab4f7a34a2fd"
REACT_APP_FIREBASE_KEY="AIzaSyBcZWwTcTJHj_R6ipZcrJkXdq05PuX0Rs0"
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/signMoonpayLinkV2?platform=web&env=production"
REACT_APP_MOONPAY_LINK="https://null.null"
REACT_APP_MOONPAY_PUBLISHABLE_KEY="pk_live_uQG4BJC4w3cxnqpcSqAfohdBFDTsY6E"
REACT_APP_SENTRY_ENABLED=true
REACT_APP_SENTRY_TRACES_SAMPLE_RATE=0.00003
REACT_APP_STATSIG_PROXY_URL="https://api.uniswap.org/v1/statsig-proxy"
THE_GRAPH_SCHEMA_ENDPOINT="https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v3"
REACT_APP_STATSIG_PROXY_URL="https://null.null"
REACT_APP_QUICKNODE_MAINNET_RPC_URL="https://ultra-blue-flower.quiknode.pro/770b22d5f362c537bc8fe19b034c45b22958f880"
THE_GRAPH_SCHEMA_ENDPOINT="https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v3?source=uniswap"

View File

@ -1,10 +1,22 @@
/* eslint-env node */
const { node: restrictedImports } = require('@uniswap/eslint-config/restrictedImports')
require('@uniswap/eslint-config/load')
const rulesDirPlugin = require('eslint-plugin-rulesdir')
rulesDirPlugin.RULES_DIR = 'eslint_rules'
module.exports = {
extends: '@uniswap/eslint-config/react',
extends: ['@uniswap/eslint-config/react'],
plugins: ['rulesdir'],
overrides: [
{
files: ['**/*'],
rules: {
'multiline-comment-style': ['error', 'separate-lines'],
'rulesdir/no-undefined-or': 'error',
},
},
{
// Configuration/typings typically export objects/definitions that are used outside of the transpiled package
// (eg not captured by the tsconfig). Because it's typical and not exceptional, this is turned off entirely.
@ -16,6 +28,20 @@ module.exports = {
{
files: ['**/*.ts', '**/*.tsx'],
rules: {
'@typescript-eslint/no-restricted-imports': [
'error',
{
...restrictedImports,
paths: [
...restrictedImports.paths,
{
name: '@uniswap/smart-order-router',
message: 'Only import types, unless you are in the client-side SOR, to preserve lazy-loading.',
allowTypeImports: true,
},
],
},
],
'import/no-restricted-paths': [
'error',
{
@ -44,6 +70,30 @@ module.exports = {
],
},
],
'no-restricted-syntax': [
'error',
{
selector: ':matches(ExportAllDeclaration)',
message: 'Barrel exports bloat the bundle size by preventing tree-shaking.',
},
],
},
},
{
files: ['**/*.ts', '**/*.tsx'],
excludedFiles: ['src/analytics/*'],
rules: {
'no-restricted-imports': [
'error',
{
paths: [
{
name: '@uniswap/analytics',
message: `Do not import from '@uniswap/analytics' directly. Use 'analytics' instead.`,
},
],
},
],
},
},
],

1
.github/CODEOWNERS vendored
View File

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

View File

@ -1,22 +0,0 @@
---
name: Bug Report
about: Describe an issue in the Uniswap Interface
title: ''
labels: bug
assignees: ''
---
**Bug Description**
A clear and concise description of the bug.
**Steps to Reproduce**
1. Go to ...
2. Click on ...
...
**Expected Behavior**
A clear and concise description of what you expected to happen.
**Additional Context**
Add any other context about the problem here (screenshots, whether the bug only occurs only in certain mobile/desktop/browser environments, etc.)

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,19 +0,0 @@
---
name: Feature Request
about: Suggest an idea for improving the UX of the Uniswap Interface
title: ''
labels: 'improvement'
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@ -1,24 +0,0 @@
name: Setup
description: checkout repo, setup node, and install node_modules
runs:
using: composite
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 14
registry-url: https://registry.npmjs.org
# node_modules/.cache is intentionally omitted, as this is used for build tool caches.
- uses: actions/cache@v3
id: install-cache
with:
path: |
node_modules
!node_modules/.cache
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,13 +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'
reviewers:
- 'Uniswap/dependabot-reviewers'

View File

@ -1,45 +0,0 @@
<!-- Your PR title must follow conventional commits: https://github.com/Uniswap/interface#pr-title -->
## Description
<!-- Summary of change, including motivation and context. -->
<!-- Use verb-driven language: "Fixes XYZ" instead of "This change fixes XYZ" -->
<!-- Delete inapplicable lines: -->
_JIRA ticket:_
_Slack thread:_
_Relevant docs:_
<!-- Delete this section if your change does not affect UI. -->
## Screen capture
| Before | After (Desktop) | After (Mobile) |
| ------------ |---------------- | -------------- |
| paste_before | past_after | paste_after |
## Test plan
<!-- Delete this section if your change is not a bug fix. -->
### Reproducing the error
<!-- Include steps to reproduce the bug. -->
1.
### QA (ie manual testing)
<!-- Include steps to test the change, ensuring no regression. -->
- [ ] N/A
#### Devices
<!-- If applicable, include different devices and screen sizes that may be affected, and how you've tested them. -->
### Automated testing
<!-- If N/A, check and note so it is obvious to your reviewers and does not show up as an incomplete task. -->
<!-- eg - [x] Unit test N/A -->
- [ ] Unit test
- [ ] Integration/E2E test

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,126 +0,0 @@
name: Release
on:
schedule:
- cron: '0 12 * * 1-4' # every day 12:00 UTC Monday-Thursday
# manual trigger
workflow_dispatch:
jobs:
wait-on-tests:
runs-on: ubuntu-latest
steps:
- id: unit-tests
uses: fountainhead/action-wait-for-check@v1.0.0
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
environment:
name: release
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/setup
- run: yarn prepare
- 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.pinata.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:
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.pinata.outputs.hash }}/](ipfs://${{ steps.pinata.outputs.hash }}/)
${{ needs.tag.outputs.changelog }}
- 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 }}
- name: Upload source maps to Sentry
uses: getsentry/action-release@bd5f874fcda966ba48139b0140fb3ec0cb3aabdd
continue-on-error: true
env:
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
with:
environment: production
sourcemaps: './build/static/js'
url_prefix: '~/static/js'

View File

@ -1,174 +0,0 @@
name: Test
# Many build steps have their own caches, so each job has its own cache to improve subsequent build times.
# Build tools are configured to cache cache to node_modules/.cache, so this is cached independently of node_modules.
# See https://jongleberry.medium.com/speed-up-your-ci-and-dx-with-node-modules-cache-ac8df82b7bb0.
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
- uses: actions/cache@v3
id: eslint-cache
with:
path: node_modules/.cache
key: ${{ runner.os }}-eslint-${{ hashFiles('**/yarn.lock') }}-${{ github.run_id }}
restore-keys: ${{ runner.os }}-eslint-${{ hashFiles('**/yarn.lock') }}-
- run: yarn lint
typecheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/setup
- uses: actions/cache@v3
id: tsc-cache
with:
path: node_modules/.cache
key: ${{ runner.os }}-tsc-${{ hashFiles('**/yarn.lock') }}-${{ github.run_id }}
restore-keys: ${{ runner.os }}-tsc-${{ hashFiles('**/yarn.lock') }}-
- run: yarn prepare
- run: yarn typecheck
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
- uses: actions/cache@v3
id: jest-cache
with:
path: node_modules/.cache
key: ${{ runner.os }}-jest-${{ hashFiles('**/yarn.lock') }}-${{ github.run_id }}
restore-keys: ${{ runner.os }}-jest-${{ hashFiles('**/yarn.lock') }}-
- run: yarn prepare
- run: yarn test --silent --maxWorkers=100%
- uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: false
verbose: true
flags: unit-tests
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/setup
- uses: actions/cache@v3
id: build-cache
with:
path: node_modules/.cache
key: ${{ runner.os }}-build-${{ hashFiles('**/yarn.lock') }}-${{ github.run_id }}
restore-keys: ${{ runner.os }}-build-${{ hashFiles('**/yarn.lock') }}-
- run: yarn prepare
- run: yarn build
- uses: actions/upload-artifact@v3
with:
name: build
path: build
if-no-files-found: error
build-e2e:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/setup
- uses: actions/cache@v3
id: build-e2e-cache
with:
path: node_modules/.cache
key: ${{ runner.os }}-build-e2e-${{ hashFiles('**/yarn.lock') }}-${{ github.run_id }}
restore-keys: ${{ runner.os }}-build-e2e-${{ hashFiles('**/yarn.lock') }}-
- run: yarn prepare
- run: yarn build:e2e
env:
NODE_OPTIONS: "--max_old_space_size=4096"
- uses: actions/upload-artifact@v2
with:
name: build-e2e
path: build
if-no-files-found: error
size-tests:
needs: [build]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/setup
- uses: actions/download-artifact@v3
with:
name: build
path: build
- run: yarn test:size
cypress-test-matrix:
needs: [build-e2e]
runs-on: ubuntu-latest
container: cypress/browsers:node-18.14.1-chrome-111.0.5563.64-1-ff-111.0-edge-111.0.1661.43-1
strategy:
fail-fast: false
matrix:
containers: [1, 2, 3, 4]
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/setup
- uses: actions/cache@v3
id: cypress-cache
with:
path: /root/.cache/Cypress
key: ${{ runner.os }}-cypress
- run: |
yarn cypress install
yarn cypress info
- uses: actions/download-artifact@v3
with:
name: build-e2e
path: build
- 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 }}
- uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: false
verbose: true
flags: e2e-tests
# Included as a single job to check for cypress-test-matrix success, as a matrix cannot be checked.
cypress-tests:
if: ${{ always() }}
needs: [cypress-test-matrix]
runs-on: ubuntu-latest
steps:
- if: needs.cypress-test-matrix.result != 'success'
run: exit 1

14
.gitignore vendored
View File

@ -5,11 +5,12 @@
/src/types/v3
/src/abis/types
/src/locales/**/*.js
/src/locales/**/en-US.po
/src/locales/**/pseudo.po
/src/locales/**/*.po
# generated graphql types
/src/graphql/**/__generated__
# generated files
/src/**/__generated__
# schema
schema.graphql
# dependencies
@ -18,6 +19,8 @@ schema.graphql
# testing
/coverage
/cache
/functions/coverage
/.swc
# builds
/build
@ -45,7 +48,10 @@ notes.txt
package-lock.json
cypress/downloads
cypress/videos
cypress/screenshots
.vercel
.wrangler

4
.husky/pre-commit Normal file
View File

@ -0,0 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx lint-staged

2
.nvmrc
View File

@ -1 +1 @@
14.20.0
v18.16.0

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: {}

36
.swcrc Normal file
View File

@ -0,0 +1,36 @@
{
"$schema": "https://json.schemastore.org/swcrc",
// has to duplicate from package.json, see swc issue: https://swc.rs/docs/configuration/compilation#env
// this breaks jest because jest is setting target for some reason
// "env": {
// "targets": "> 0.5%, not dead"
// },
"jsc": {
// without this swc breaks WalletConnect class super() call
"target": "es2020",
"keepClassNames": true,
"experimental": {
"plugins": [
[
"@lingui/swc-plugin",
{}
],
[
"@swc/plugin-styled-components",
{
"displayName": true
}
]
]
},
"parser": {
"syntax": "typescript",
"tsx": true
},
"transform": {
"react": {
"runtime": "automatic"
}
}
}
}

11
.vscode/settings.json vendored
View File

@ -12,5 +12,14 @@
},
"files.eol": "\n",
"eslint.enable": true,
"eslint.debug": true
"eslint.debug": true,
"[javascript]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
},
"[typescript]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
},
"[typescriptreact]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
},
}

View File

@ -69,10 +69,10 @@ Other things to note:
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/#/pools/v2>
- Add V2 liquidity: <https://app.uniswap.org/#/add/v2>
- Migrate V2 liquidity to V3: <https://app.uniswap.org/#/migrate/v2>
- Swap on Uniswap V2: <https://app.uniswap.org/swap?use=v2>
- View V2 liquidity: <https://app.uniswap.org/pools/v2>
- Add V2 liquidity: <https://app.uniswap.org/add/v2>
- Migrate V2 liquidity to V3: <https://app.uniswap.org/migrate/v2>
## Accessing Uniswap V1

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

@ -6,8 +6,15 @@ ignore:
- "**/instrumented/**/*"
- "**/styles/**/*"
- "styles/**/*"
- "**/styled.tsx"
- "**/constants/**/*"
- "constants/**/*"
- "src/dev/*"
coverage:
status:
project: off
patch: off
flag_management:
default_rules:
@ -15,11 +22,22 @@ flag_management:
- type: project
target: auto
threshold: 1%
# Adjust the base when removing code to avoid penalizing tech debt payback / dead code removal.
removed_code_behavior: adjust_base
if_ci_failed: error
- type: patch
target: 80%
target: 50%
individual_flags:
- name: e2e-tests
- name: unit-tests
- name: cloud-tests
statuses:
- type: patch
target: 0%
- type: project
target: 80%
comment:
layout: flags
hide_comment_details: false
github_checks:
# Turn off GitHub Check annotations, as they make it more difficult to review code.
annotations: false

View File

@ -1,5 +1,5 @@
overrideExisting: true
schema: 'https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v3'
schema: 'https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v3?source=uniswap'
generates:
./src/graphql/thegraph/schema/schema.graphql:
plugins:

View File

@ -1,51 +1,40 @@
/* eslint-env node */
const { VanillaExtractPlugin } = require('@vanilla-extract/webpack-plugin')
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin')
const { execSync } = require('child_process')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin')
const { DefinePlugin, IgnorePlugin } = require('webpack')
const path = require('path')
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin')
const { IgnorePlugin, ProvidePlugin } = require('webpack')
const { RetryChunkLoadPlugin } = require('webpack-retry-chunk-load-plugin')
const commitHash = execSync('git rev-parse HEAD').toString().trim()
const isProduction = process.env.NODE_ENV === 'production'
process.env.REACT_APP_GIT_COMMIT_HASH = commitHash
// Linting and type checking are only necessary as part of development and testing.
// Omit them from production builds, as they slow down the feedback loop.
const shouldLintOrTypeCheck = !isProduction
function getCacheDirectory(cacheName) {
// Include the trailing slash to denote that this is a directory.
return `${path.join(__dirname, 'node_modules/.cache/', cacheName)}/`
}
module.exports = {
babel: {
plugins: [
'@vanilla-extract/babel-plugin',
...(process.env.REACT_APP_ADD_COVERAGE_INSTRUMENTATION
? [
[
'istanbul',
{
all: true,
include: ['src/**/*.tsx', 'src/**/*.ts'],
exclude: [
'src/**/*.css',
'src/**/*.css.ts',
'src/**/*.test.ts',
'src/**/*.test.tsx',
'src/**/*.spec.ts',
'src/**/*.spec.tsx',
'src/**/graphql/**/*',
'src/**/*.d.ts',
],
},
],
]
: []),
],
},
eslint: {
enable: shouldLintOrTypeCheck,
pluginOptions(eslintConfig) {
return Object.assign(eslintConfig, {
cache: true,
cacheLocation: 'node_modules/.cache/eslint/',
cacheLocation: getCacheDirectory('eslint'),
ignorePath: '.gitignore',
// Use our own eslint/plugins/config, as overrides interfere with caching.
// This ensures that `yarn start` and `yarn lint` share one cache.
eslintPath: require.resolve('eslint'),
resolvePluginsRelativeTo: null,
baseConfig: null,
})
},
},
@ -55,38 +44,64 @@ module.exports = {
jest: {
configure(jestConfig) {
return Object.assign(jestConfig, {
cacheDirectory: 'node_modules/.cache/jest',
transformIgnorePatterns: ['@uniswap/conedison/format', '@uniswap/conedison/provider'],
cacheDirectory: getCacheDirectory('jest'),
transform: {
...Object.entries(jestConfig.transform).reduce((transform, [key, value]) => {
if (value.match(/babel/)) return transform
return { ...transform, [key]: value }
}, {}),
// Transform vanilla-extract using its own transformer.
// See https://sandroroth.com/blog/vanilla-extract-cra#jest-transform.
'\\.css\\.ts$': '@vanilla-extract/jest-transform',
'\\.(t|j)sx?$': '@swc/jest',
},
// Use d3-arrays's build directly, as jest does not support its exports.
transformIgnorePatterns: ['d3-array'],
moduleNameMapper: {
'@uniswap/conedison/format': '@uniswap/conedison/dist/format',
'@uniswap/conedison/provider': '@uniswap/conedison/dist/provider',
'd3-array': 'd3-array/dist/d3-array.min.js',
},
})
},
},
webpack: {
plugins: [new VanillaExtractPlugin({ identifiers: 'short' })],
plugins: [
// Webpack 5 does not polyfill node globals, so we do so for those necessary:
new ProvidePlugin({
// - react-markdown requires process.cwd
process: 'process/browser.js',
}),
new VanillaExtractPlugin(),
new RetryChunkLoadPlugin({
cacheBust: `function() {
return 'cache-bust=' + Date.now();
}`,
// Retries with exponential backoff (500ms, 1000ms, 2000ms).
retryDelay: `function(retryAttempt) {
return 2 ** (retryAttempt - 1) * 500;
}`,
maxRetries: 3,
}),
],
configure: (webpackConfig) => {
// Configure webpack plugins:
webpackConfig.plugins = webpackConfig.plugins
.map((plugin) => {
// Extend process.env with dynamic values (eg commit hash).
// This will make dynamic values available to JavaScript only, not to interpolated HTML (ie index.html).
if (plugin instanceof DefinePlugin) {
Object.assign(plugin.definitions['process.env'], {
REACT_APP_GIT_COMMIT_HASH: JSON.stringify(commitHash),
})
}
// CSS ordering is mitigated through scoping / naming conventions, so we can ignore order warnings.
// See https://webpack.js.org/plugins/mini-css-extract-plugin/#remove-order-warnings.
if (plugin instanceof MiniCssExtractPlugin) {
plugin.options.ignoreOrder = true
}
// Disable TypeScript's config overwrite, as it interferes with incremental build caching.
// This ensures that `yarn start` and `yarn typecheck` share one cache.
if (plugin.constructor.name == 'ForkTsCheckerWebpackPlugin') {
delete plugin.options.typescript.configOverwrite
}
return plugin
})
.filter((plugin) => {
// Case sensitive paths are enforced by TypeScript.
// Case sensitive paths are already enforced by TypeScript.
// See https://www.typescriptlang.org/tsconfig#forceConsistentCasingInFileNames.
if (plugin instanceof CaseSensitivePathsPlugin) return false
@ -96,10 +111,71 @@ module.exports = {
return true
})
// We're currently on Webpack 4.x which doesn't support the `exports` field in package.json.
// Instead, we need to manually map the import path to the correct exports path (eg dist or build folder).
// See https://github.com/webpack/webpack/issues/9509.
webpackConfig.resolve.alias['@uniswap/conedison'] = '@uniswap/conedison/dist'
// Configure webpack resolution:
webpackConfig.resolve = Object.assign(webpackConfig.resolve, {
plugins: webpackConfig.resolve.plugins.map((plugin) => {
// Allow vanilla-extract in production builds.
// This is necessary because create-react-app guards against external imports.
// See https://sandroroth.com/blog/vanilla-extract-cra#production-build.
if (plugin instanceof ModuleScopePlugin) {
plugin.allowedPaths.push(path.join(__dirname, 'node_modules/@vanilla-extract/webpack-plugin'))
}
return plugin
}),
// Webpack 5 does not resolve node modules, so we do so for those necessary:
fallback: {
// - react-markdown requires path
path: require.resolve('path-browserify'),
},
})
// Retain source maps for node_modules packages:
webpackConfig.module.rules[0] = {
...webpackConfig.module.rules[0],
exclude: /node_modules/,
}
// Configure webpack transpilation (create-react-app specifies transpilation rules in a oneOf):
webpackConfig.module.rules[1].oneOf = webpackConfig.module.rules[1].oneOf.map((rule) => {
if (rule.loader && rule.loader.match(/babel-loader/)) {
rule.loader = 'swc-loader'
delete rule.options
}
return rule
})
// Run terser compression on node_modules before tree-shaking, so that tree-shaking is more effective.
// This works by eliminating dead code, so that webpack can identify unused imports and tree-shake them;
// it is only necessary for node_modules - it is done through linting for our own source code -
// see https://medium.com/engineering-housing/dead-code-elimination-and-tree-shaking-at-housing-part-1-307a94b30f23#7e03:
webpackConfig.module.rules.push({
enforce: 'post',
test: /node_modules.*\.(js)$/,
loader: path.join(__dirname, 'scripts/terser-loader.js'),
options: { compress: true, mangle: false },
})
// Configure webpack optimization:
webpackConfig.optimization = Object.assign(
webpackConfig.optimization,
isProduction
? {
splitChunks: {
// Cap the chunk size to 5MB.
// react-scripts suggests a chunk size under 1MB after gzip, but we can only measure maxSize before gzip.
// react-scripts also caps cacheable chunks at 5MB, which gzips to below 1MB, so we cap chunk size there.
// See https://github.com/facebook/create-react-app/blob/d960b9e/packages/react-scripts/config/webpack.config.js#L713-L716.
maxSize: 5 * 1024 * 1024,
// Optimize over all chunks, instead of async chunks (the default), so that initial chunks are also optimized.
chunks: 'all',
},
}
: {}
)
// Configure webpack resolution. webpackConfig.cache is unused with swc-loader, but the resolver can still cache:
webpackConfig.resolve = Object.assign(webpackConfig.resolve, { unsafeCache: true })
return webpackConfig
},

View File

@ -1,25 +1,19 @@
import codeCoverageTask from '@cypress/code-coverage/task'
import { defineConfig } from 'cypress'
import { setupHardhatEvents } from 'cypress-hardhat'
export default defineConfig({
projectId: 'yp82ef',
videoUploadOnPasses: false,
defaultCommandTimeout: 24000, // 2x average block time
chromeWebSecurity: false,
retries: { runMode: 2 },
experimentalMemoryManagement: true, // better memory management, see https://github.com/cypress-io/cypress/pull/25462
retries: { runMode: process.env.CYPRESS_RETRIES ? +process.env.CYPRESS_RETRIES : 1 },
video: false, // GH provides 2 CPUs, and cypress video eats one up, see https://github.com/cypress-io/cypress/issues/20468#issuecomment-1307608025
e2e: {
async setupNodeEvents(on, config) {
await setupHardhatEvents(on, config)
codeCoverageTask(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'),
}
return config
},
baseUrl: 'http://localhost:3000',
specPattern: 'cypress/e2e/**/*.{js,jsx,ts,tsx}',
specPattern: 'cypress/{e2e,staging}/**/*.test.ts',
},
})

201
cypress/README.md Normal file
View File

@ -0,0 +1,201 @@
# e2e testing with Cypress
End-to-end tests are run through [Cypress](https://docs.cypress.io/api/table-of-contents/), which runs tests in a real browser. Cypress is a little different than other testing frameworks, and e2e tests are a little different than unit tests, so this directory has its own set of patterns, idioms, and best practices. Not only that, but we're testing against a forked blockchain, not just against typical Web APIs, so we have unique flows that you may not have seen elsewhere.
## Running your first e2e tests
Cypress tests run against a local server, so you'll need to run the application locally at the same time. The fastest way to run e2e tests is to use your dev server: `yarn start`.
Open cypress at the same time with `yarn cypress:open`. You should do this from another window or tab, so that you can continue to see any typechecking/linting warnings from `yarn start`.
Cypress opens its own instance of Chrome, with a list of "E2E specs" for you to select. When you're developing locally, you usually only want to run one spec file at a time. Select your spec by clicking on the filename and it will run.
## Glossary
#### spec
Cypress considers each file a separate spec, or collection of tests.
Specs are always run as a whole through `yarn cypress:open` or on the same machine through CI.
#### Thenable
Cypress queues commands to run in the browser using [Thenables](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise#thenables), not Promises.
For this reason, you should not use `async/await` syntax in Cypress unless it is wholly-contained in a `cy.then` function argument.
## Writing your first e2e test
_For an excellent treatment on tests, check out the [Cypress Fundamentals](https://learn.cypress.io/cypress-fundamentals/how-to-write-a-test) course._
_While some of that will be paraphrased here, this should be sufficient to get you started:_
### What is a test?
Cypress tests are just like any other test: you should set up an initial state, execute an action, and verify the action's consequence. This is codified in the AAA (Arrange-Act-Assert) pattern, and you'll see this in most of our tests. In _our_ case, it plays out as:
1. Arrange: Visit a page, eg `cy.visit('/swap')`, and set up the state, on the blockchain and the page.
2. Act: Initiate your action under test, eg `initiateSwap()`
3. Assert: Verify that the action has occured, eg `// Verify swap has occured`
You'll usually see the setup, followed by a newline, followed by assertions with comments stating what they are asserting.
Because Cypress tests are translated into user actions, it may be hard to follow the action being described. You should use comments liberally to describe what you are doing and what you intend to test, to make tests easier to read and maintain in the future.
### Thinking about tests: queuing up a sequence of commands
Cypress uses `Thenable`s to achieve "command chaining". A test is described as a series of commands, which are only executed once the previous command in the chain has executed.
```
cy.visit('/swap')
cy.contains('Select token').click()
cy.contains('DAI').click()
```
In this example, `cy.contains('Select token').click()` is queued up right away (all the code is synchronous), but it will not execute until `/swap` has loaded (all the commands are chained); and `click()` will not execute until `Select token` has been found.
This becomes more relevant as you work with data on the blockchain, as you'll need to load it at the correct time, _after_ it's been modified by the application:
```
cy.hardhat().then(async (hardhat) => {
cy.visit(`/swap?inputCurrency=ETH&outputCurrency=${USDC_MAINNET.address}`)
cy.get('#swap-currency-output .token-amount-input').type('1').should('have.value', '1')
cy.get('#swap-button').click()
cy.contains('Confirm swap').click()
// wait for the transaction to be executed
cy.get(getTestSelector('web3-status-connected')).should('contain', '1 Pending')
cy.get(getTestSelector('web3-status-connected')).should('not.contain', 'Pending')
// BAD: This will get the balance _before_ the other queued actions have executed.
const balance = await hardhat.getBalance(hardhat.wallet, USDC_MAINNET)
cy.wrap(balance).should('deep.equal', expectedBalance)
})
```
```
cy.visit(`/swap?inputCurrency=ETH&outputCurrency=${USDC_MAINNET.address}`)
cy.get('#swap-currency-output .token-amount-input').type('1').should('have.value', '1')
cy.get('#swap-button').click()
cy.contains('Confirm swap').click()
// wait for the transaction to be executed
cy.get(getTestSelector('web3-status-connected')).should('contain', '1 Pending')
cy.get(getTestSelector('web3-status-connected')).should('not.contain', 'Pending')
// GOOD: cy.then chains the command so that it runs _after_ executing the swap
cy.hardhat()
.then((hardhat) => hardhat.getBalance(hardhat.wallet, USDC_MAINNET))
.should('deep.equal', expectedBalance)
})
```
### Working with the blockchain (ie hardhat)
Our tests use a local hardhat node to simulate blockchain transactions. This can be accessed with `cy.hardhat().then((hardhat) => ...)`.
By default, automining is turned on, so that any transaction that you send to the blockchain is mined immediately. If you want to assert on intermediate states (between sending a transaction and mining it), you can turn off automining: `cy.hardhat({ automine: false })`.
The hardhat integration has built-in utilities to let you modify and assert on balances, approvals, and permits, and should be fully typed. Check it out at [Uniswap/cypress-hardhat](https://github.com/Uniswap/cypress-hardhat).
### Asserting on wallet methods
Wallet methods to hardhat are all aliased. If you'd like to assert that a method was sent to the wallet, you can do so using the method name, prefixed with `@`:
```
// Asserts that `eth_sendRawTransaction` was sent to the wallet.
cy.wait('@eth_sendRawTransaction')
```
Sometimes, you may want a method to _fail_. In this case, you can stub it, but you should disable logging to avoid spamming the test:
```
// Stub calls to eth_signTypedData_v4 and fail them
cy.hardhat().then((hardhat) => {
// Note the closure to keep signTypedDataStub in scope. Using closures instead of variables (eg let) helps prevent misuse of chaining.
const signTypedDataStub = cy.stub(hardhat.provider, 'send').log(false)
signTypedDataStub.withArgs('eth_signTypedData_v4).rejects(USER_REJECTION)
signTypedDataStub.callThrough() // allws other methods to call through to hardhat
cy.contains('Confirm swap').click()
// Verify the call occured
// Note the call to cy.wrap to correctly queue the chained command. Without this, the test would occur before the stub is called.
cy.wrap(permitApprovalStub).should('be.calledWith', 'eth_signTypedData_v4')
// Restore the stub
// note the call to cy.then to correctly queue the chained command. Without this, the stub would be restored immediately.
cy.then(() => permitApprovalStub.restore())
})
```
## Best practices
<!-- Best practices should all be labeled using H3, with the rationale italicized at the end of the section. -->
<!-- Best practice 🤣 is to also include an example before your rationale. -->
### Spec / test grouping
Each spec should be specific to one route, _not_ one functional behavior.
For example, `token-details.test.ts` is separated from `swap.test.ts`.
If a route has different functional behaviors, that route should become a directory name, and its spec should be split.
For example, `swap.test.ts` may be split into `swap/swap.test.ts`, `swap/wrap.test.ts`, `swap/permit2.test.ts`.
_This prevents specs from growing too large, which is important because they are always run as a whole locally and on the same machine through CI. If a spec grows too large, it will have a longer local feedback loop, and it will become the bottleneck for CI test runtime._
_Similarly, avoid actions outside the scope of your spec, as it will cause total testing time to increase._
### Use closures instead of variables
Avoid usage of `let`, instead assigning a constant. In practice, this means using closures for your variables:
```javascript
let badVariable
cy.hardhat({ automine: false })
.then((hardhat) => cy.then(() => hardhat.provider.getBalance(hardhat.wallet.address)))
.then((initialBalance) => {
// Do not assign to a variable outside of your closure!
badVariable = initialBalance // <-- bad!
// Use initial balance here, within the closure.
})
cy.get('.class-name').then((el) => {
// Do not use badVariable here! It may have changed value due to the queued async nature of Cypress.
expect(el).should('contain', badVariable) // <-- bad!
})
```
_This prevents misuse of a not-yet-initialized variable, or a variable that has changed as the test progresses._
### Prefer selecting elements using on-screen text over data-testid attributes
When selecting components (eg with `cy.get`), prefer defining your selector with visible UI. Sometimes this is not possible (eg if the text is duplicated on-screen), and you'll need to add a `data-testid` property.
_Defining tests using visual fields helps ensure that we don't break them. `data-testid` may select an element that is only selectable programmatically, and should be used only when necessary, as its use may cover up UI breakages._
_You'll still want to use `data-testid` in cases where the text is rendered in multiple containers and you need to select the correct one, or where the component doesn't render predictable text output._
### Avoid branching logic
Do not write tests that rely on if-statements or conditionals. Do not create helper methods which do more than one thing, and rely on branching logic to apply to different but similar situations.
_Tests should be readable and simple. Branching logic makes it harder to reason about tests, and may hide otherwise flaky or ill-defined behaviors._
_Similarly, you should avoid complicated for-loops. Sometimes, for simple repetition, for-loops are ok._
### Avoid spamming the console
It is ok to include logging while you are developing a test, but that logging should be removed if it is not needed to debug (potential) errors.
For example, stubbing a wallet method will result in dumping a hex string (the calldata) to the log. Instead, suppress logging from methods which you know will flood the log.
```javascript
cy.stub(hardhat.wallet, 'sendTransaction')
.log(false) // <-- suppresses logs from this stub
.rejects(new Error('user cancelled'))
```
_Unnecessary logs it makes it harder to reason about a test overall._
### Name helper methods using transitive verbs
Name helper methods using "action verbs": `expectsThisToHappen`, not `expectThisToHappen`; `selectsToken(token: string)`, not `selectAToken(token: string)`.
_This makes your tests read more naturally, and makes it easier to follow given existing `should` syntax._

View File

@ -4,41 +4,47 @@ import { aliasQuery, hasQuery } from '../utils/graphql-test-utils'
describe('Add Liquidity', () => {
beforeEach(() => {
cy.intercept('POST', '/subgraphs/name/uniswap/uniswap-v3', (req) => {
cy.intercept('POST', '/subgraphs/name/uniswap/uniswap-v3?source=uniswap', (req) => {
aliasQuery(req, 'feeTierDistribution')
})
})
it('loads the two correct tokens', () => {
cy.visit('/add/0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984/0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6/500')
it('loads the token pair', () => {
cy.visit('/add/0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984/ETH/500')
cy.get('#add-liquidity-input-tokena .token-symbol-container').should('contain.text', 'UNI')
cy.get('#add-liquidity-input-tokenb .token-symbol-container').should('contain.text', 'ETH')
cy.contains('0.05% fee tier')
})
it('does not crash if ETH is duplicated', () => {
cy.visit('/add/0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6/0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6')
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('clears the token selection when chain changes', () => {
cy.visit('/add/0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984/ETH/500')
cy.get('#add-liquidity-input-tokena .token-symbol-container').should('contain.text', 'UNI')
cy.get('#add-liquidity-input-tokenb .token-symbol-container').should('contain.text', 'ETH')
cy.get('[data-testid="chain-selector"]').last().click()
cy.contains('Polygon').click()
cy.get('#add-liquidity-input-tokenb .token-symbol-container').should('contain.text', 'ETH')
cy.get('#add-liquidity-input-tokena .token-symbol-container').should('not.contain.text', 'UNI')
})
it.skip('token not in storage is loaded', () => {
cy.visit('/add/0x07865c6e87b9f70255377e024ace6630c1eaa37f/0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984')
cy.get('#add-liquidity-input-tokena .token-symbol-container').should('contain.text', 'USDC')
cy.get('#add-liquidity-input-tokenb .token-symbol-container').should('contain.text', 'UNI')
it('does not crash if token is duplicated', () => {
cy.visit('/add/0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984/0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984')
cy.get('#add-liquidity-input-tokena .token-symbol-container').should('contain.text', 'UNI')
cy.get('#add-liquidity-input-tokenb .token-symbol-container').should('not.contain.text', 'UNI')
})
it.skip('single token can be selected', () => {
cy.visit('/add/0x07865c6e87b9f70255377e024ace6630c1eaa37f')
cy.get('#add-liquidity-input-tokena .token-symbol-container').should('contain.text', 'USDC')
it('single token can be selected', () => {
cy.visit('/add/0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984')
cy.get('#add-liquidity-input-tokena .token-symbol-container').should('contain.text', 'UNI')
})
it.skip('loads fee tier distribution', () => {
it('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'
cy.intercept(
'POST',
'/subgraphs/name/uniswap/uniswap-v3?source=uniswap',
(req: CyHttpMessages.IncomingHttpRequest) => {
if (hasQuery(req, 'FeeTierDistribution')) {
req.alias = 'FeeTierDistribution'
req.reply({
body: {
@ -51,14 +57,60 @@ describe('Add Liquidity', () => {
},
})
}
}
)
cy.visit('/add/0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984/ETH')
cy.wait('@FeeTierDistribution')
cy.get('#add-liquidity-selected-fee .selected-fee-label').should('contain.text', '0.30% fee tier')
cy.get('#add-liquidity-selected-fee .selected-fee-percentage').should('contain.text', '40% select')
})
})
cy.visit('/add/0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984/0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6')
it('disables increment and decrement until initial prices are inputted', () => {
// ETH / BITCOIN pool (0.05% tier not created)
cy.visit('/add/ETH/0x72e4f9F808C49A2a61dE9C5896298920Dc4EEEa9/500')
// Set starting price in order to enable price range step counters
cy.get('.start-price-input').type('1000')
cy.wait('@FeeTierDistributionQuery')
// Min Price increment / decrement buttons should be disabled
cy.get('[data-testid="increment-price-range"]').eq(0).should('be.disabled')
cy.get('[data-testid="decrement-price-range"]').eq(0).should('be.disabled')
// Enter min price, which should enable the buttons
cy.get('.rate-input-0').eq(0).type('900').blur()
cy.get('[data-testid="increment-price-range"]').eq(0).should('not.be.disabled')
cy.get('[data-testid="decrement-price-range"]').eq(0).should('not.be.disabled')
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%')
// Repeat for Max Price step counter
cy.get('[data-testid="increment-price-range"]').eq(1).should('be.disabled')
cy.get('[data-testid="decrement-price-range"]').eq(1).should('be.disabled')
// Enter max price, which should enable the buttons
cy.get('.rate-input-0').eq(1).type('1100').blur()
cy.get('[data-testid="increment-price-range"]').eq(1).should('not.be.disabled')
cy.get('[data-testid="decrement-price-range"]').eq(1).should('not.be.disabled')
})
it('allows full range selection on new pool creation', () => {
// ETH / BITCOIN pool (0.05% tier not created)
cy.visit('/add/ETH/0x72e4f9F808C49A2a61dE9C5896298920Dc4EEEa9/500')
// Set starting price in order to enable price range step counters
cy.get('.start-price-input').type('1000')
cy.get('[data-testid="set-full-range"]').click()
// Check that the min price is 0 and the max price is infinity
cy.get('.rate-input-0').eq(0).should('have.value', '0')
cy.get('.rate-input-0').eq(1).should('have.value', '∞')
// Increment and decrement buttons are disabled when full range is selected
cy.get('[data-testid="increment-price-range"]').eq(0).should('be.disabled')
cy.get('[data-testid="decrement-price-range"]').eq(0).should('be.disabled')
cy.get('[data-testid="increment-price-range"]').eq(1).should('be.disabled')
cy.get('[data-testid="decrement-price-range"]').eq(1).should('be.disabled')
// Check that url params were added
cy.url().then((url) => {
const params = new URLSearchParams(url)
const minPrice = params.get('minPrice')
const maxPrice = params.get('maxPrice')
// Note: although 0 and ∞ displayed, actual values in query are ticks at limit
return minPrice && maxPrice && parseFloat(minPrice) < parseFloat(maxPrice)
})
})
})

View File

@ -0,0 +1,28 @@
import { getTestSelector } from '../utils'
describe('Buy Crypto Modal', () => {
it('should open and close', () => {
cy.visit('/')
// Open the fiat onramp modal
cy.get(getTestSelector('buy-fiat-button')).click()
cy.get(getTestSelector('fiat-onramp-modal')).should('be.visible')
// Click on a location that should be outside the modal, which should close it
cy.get('body').click(0, 100)
cy.get(getTestSelector('fiat-onramp-modal')).should('not.exist')
})
it('should open and close, mobile viewport', () => {
cy.viewport('iphone-6')
cy.visit('/')
// Open the fiat onramp modal
cy.get(getTestSelector('buy-fiat-button')).click()
cy.get(getTestSelector('fiat-onramp-modal')).should('be.visible')
// Click on a location that should be outside the modal, which should close it
cy.get('body').click(10, 10)
cy.get(getTestSelector('fiat-onramp-modal')).should('not.exist')
})
})

View File

@ -1,25 +1,27 @@
import { getTestSelector } from '../utils'
import { CONNECTED_WALLET_USER_STATE, DISCONNECTED_WALLET_USER_STATE } from '../utils/user-state'
describe('Landing Page', () => {
it('shows landing page when no selectedWallet', () => {
cy.visit('/', { noWallet: true })
it('shows landing page when no user state exists', () => {
cy.visit('/', { userState: DISCONNECTED_WALLET_USER_STATE })
cy.get(getTestSelector('landing-page'))
cy.screenshot()
})
it('redirects to swap page when selectedWallet is INJECTED', () => {
cy.visit('/', { selectedWallet: 'INJECTED' })
it('redirects to swap page when a user has already connected a wallet', () => {
cy.visit('/', { userState: CONNECTED_WALLET_USER_STATE })
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' })
it('shows landing page when a user has already connected a wallet but ?intro=true is in query', () => {
cy.visit('/?intro=true', { userState: CONNECTED_WALLET_USER_STATE })
cy.get(getTestSelector('landing-page'))
})
it('shows landing page when the unicorn icon in nav is selected', () => {
cy.visit('/swap')
cy.get(getTestSelector('uniswap-logo')).click()
cy.get(getTestSelector('landing-page'))
})
@ -37,4 +39,50 @@ describe('Landing Page', () => {
cy.get(getTestSelector('pool-nav-link')).last().click()
cy.url().should('include', '/pools')
})
it('does not render landing page when / path is blocked', () => {
cy.intercept('/', (req) => {
req.reply((res) => {
const parser = new DOMParser()
const doc = parser.parseFromString(res.body, 'text/html')
const meta = document.createElement('meta')
meta.setAttribute('property', 'x:blocked-paths')
meta.setAttribute('content', '/,/buy')
doc.head.appendChild(meta)
res.body = doc.documentElement.outerHTML
})
})
cy.visit('/', { userState: DISCONNECTED_WALLET_USER_STATE })
cy.get(getTestSelector('landing-page')).should('not.exist')
cy.get(getTestSelector('buy-fiat-button')).should('not.exist')
cy.url().should('include', '/swap')
})
it('does not render uk compliance banner in US', () => {
cy.visit('/swap')
cy.contains('UK disclaimer').should('not.exist')
})
it('renders uk compliance banner in uk', () => {
cy.intercept('https://api.uniswap.org/v1/amplitude-proxy', (req) => {
const requestBody = JSON.stringify(req.body)
const byteSize = new Blob([requestBody]).size
req.alias = 'amplitude'
req.reply(
JSON.stringify({
code: 200,
server_upload_time: Date.now(),
payload_size_bytes: byteSize,
events_ingested: req.body.events.length,
}),
{
'origin-country': 'GB',
}
)
})
cy.visit('/swap')
cy.contains('UK disclaimer')
})
})

View File

@ -2,7 +2,7 @@
describe('Link', () => {
it('should update route', () => {
cy.viewport(2000, 1600)
cy.visit('/')
cy.visit('/swap')
cy.contains('Pool').click()
cy.get('[data-cy="join-pool-button"]').should('exist')
})

View File

@ -0,0 +1,131 @@
import { getTestSelector } from '../../utils'
describe('Mini Portfolio account drawer', () => {
beforeEach(() => {
const portfolioSpy = cy.spy().as('portfolioSpy')
cy.intercept(/api.uniswap.org\/v1\/graphql/, (req) => {
if (req.body.operationName === 'PortfolioBalances') {
portfolioSpy(req)
}
})
cy.visit('/swap')
})
it('fetches balances when account button is first hovered', () => {
// The balances should not be fetched before the account button is hovered
cy.get('@portfolioSpy').should('not.have.been.called')
// Balances should have been fetched once after hover
cy.get(getTestSelector('web3-status-connected')).trigger('mouseover')
cy.get('@portfolioSpy').should('have.been.calledOnce')
})
it('should not re-fetch balances on second hover', () => {
// The balances should not be fetched before the account button is hovered
cy.get('@portfolioSpy').should('not.have.been.called')
// Balances should have been fetched once after hover
cy.get(getTestSelector('web3-status-connected')).trigger('mouseover')
cy.get('@portfolioSpy').should('have.been.calledOnce')
// Balances should not be refetched upon second hover
cy.get(getTestSelector('web3-status-connected')).trigger('mouseover')
cy.get('@portfolioSpy').should('have.been.calledOnce')
})
it('should not re-fetch balances when the account drawer is opened', () => {
// The balances should not be fetched before the account button is hovered
cy.get('@portfolioSpy').should('not.have.been.called')
// Balances should have been fetched once after hover
cy.get(getTestSelector('web3-status-connected')).trigger('mouseover')
cy.get('@portfolioSpy').should('have.been.calledOnce')
// Balances should not be refetched upon opening drawer
cy.get(getTestSelector('web3-status-connected')).click()
cy.get('@portfolioSpy').should('have.been.calledOnce')
})
it('fetches account information', () => {
// Open the mini portfolio
cy.intercept(/graphql/, { fixture: 'mini-portfolio/tokens.json' })
cy.get(getTestSelector('web3-status-connected')).click()
// Verify that wallet state loads correctly
cy.get(getTestSelector('mini-portfolio-navbar')).contains('Tokens')
cy.get(getTestSelector('mini-portfolio-page')).contains('Hidden (197)')
cy.intercept(/graphql/, { fixture: 'mini-portfolio/nfts.json' })
cy.get(getTestSelector('mini-portfolio-navbar')).contains('NFTs').click()
cy.get(getTestSelector('mini-portfolio-page')).contains('I Got Plenty')
// Skip this for now, someone sent test account an NFT on block 17445713 that causes this test to fail
// cy.intercept(/graphql/, { fixture: 'mini-portfolio/pools.json' })
// cy.get(getTestSelector('mini-portfolio-navbar')).contains('Pools').click()
// cy.get(getTestSelector('mini-portfolio-page')).contains('No pools yet')
cy.intercept(/graphql/, { fixture: 'mini-portfolio/full_activity.json' })
cy.get(getTestSelector('mini-portfolio-navbar')).contains('Activity').click()
cy.get(getTestSelector('mini-portfolio-page')).contains('Contract Interaction')
})
it('refetches balances when account changes', () => {
cy.hardhat().then((hardhat) => {
const accountA = hardhat.wallets[0].address
const accountB = hardhat.wallets[1].address
// Opens the account drawer
cy.get(getTestSelector('web3-status-connected')).click()
// A shortened version of the first account's address should be shown
cy.contains(accountA.slice(0, 6)).should('exist')
// Stores the current portfolio balance to later compare to next account's balance
cy.get(getTestSelector('portfolio-total-balance'))
.invoke('text')
.then((originalBalance) => {
// TODO(INFRA-3) Replace window.ethereum access below with cypress-hardhat utility
// Simulates the wallet changing accounts via eip-1193 event
cy.window().then((win) => win.ethereum.emit('accountsChanged', [accountB]))
// The second account's address should now be shown
cy.contains(accountB.slice(0, 6)).should('exist')
// The second account's portfolio balance should differ from the original balance
cy.get(getTestSelector('portfolio-total-balance')).should('not.have.text', originalBalance)
})
})
})
it('fetches ENS name', () => {
cy.hardhat().then(() => {
const haydenAccount = '0x50EC05ADe8280758E2077fcBC08D878D4aef79C3'
const haydenENS = 'hayden.eth'
// Opens the account drawer
cy.get(getTestSelector('web3-status-connected')).click()
// Simulate wallet changing to Hayden's account
cy.window().then((win) => win.ethereum.emit('accountsChanged', [haydenAccount]))
// Hayden's ENS name should be shown
cy.contains(haydenENS).should('exist')
// Close account drawer
cy.get(getTestSelector('close-account-drawer')).click()
// Switch chain to Polygon
cy.get(getTestSelector('chain-selector')).eq(1).click()
cy.contains('Polygon').click()
//Reopen account drawer
cy.get(getTestSelector('web3-status-connected')).click()
// Simulate wallet changing to Hayden's account
cy.window().then((win) => win.ethereum.emit('accountsChanged', [haydenAccount]))
// Hayden's ENS name should be shown
cy.contains(haydenENS).should('exist')
})
})
})

View File

@ -0,0 +1,114 @@
import { USDC_MAINNET } from '../../../src/constants/tokens'
import { getTestSelector } from '../../utils'
describe('mini-portfolio activity history', () => {
beforeEach(() => {
cy.hardhat()
.then((hardhat) => hardhat.wallet.getTransactionCount())
.then((nonce) => {
// Mock graphql response to include specific nonces.
cy.intercept(
{
method: 'POST',
url: 'https://beta.api.uniswap.org/v1/graphql',
},
{
body: {
data: {
portfolios: [
{
id: 'UG9ydGZvbGlvOjB4NUNlYUI3NGU0NDZkQmQzYkY2OUUyNzcyMDBGMTI5ZDJiQzdBMzdhMQ==',
assetActivities: [
{
id: 'QXNzZXRBY3Rpdml0eTpWSEpoYm5OaFkzUnBiMjQ2TUhnME5tUm1PVGs0T0RrNVl6UmtNR1kzWTJNNE9HRTVNVFEzTURBME9EWmtOVGhrTURnNFpqbG1NelkxTnpRM1l6WXdZek15WVRFNE4yWXlaRFEwWVdVNFh6QjRZV1EyWXpCa05XTmlOVEZsWWpjMU5qUTFaRGszT1RneE4yRTJZVEkxTmpreU1UbG1ZbVE1Wmw4d2VEQXpOR0UwTURjMk5EUTROV1kzWlRBNFkyRXhOak0yTm1VMU1ETTBPVEZoTm1GbU56ZzFNR1E9',
timestamp: 1681150079,
type: 'UNKNOWN',
chain: 'ETHEREUM',
transaction: {
id: 'VHJhbnNhY3Rpb246MHg0NmRmOTk4ODk5YzRkMGY3Y2M4OGE5MTQ3MDA0ODZkNThkMDg4ZjlmMzY1NzQ3YzYwYzMyYTE4N2YyZDQ0YWU4XzB4YWQ2YzBkNWNiNTFlYjc1NjQ1ZDk3OTgxN2E2YTI1NjkyMTlmYmQ5Zl8weDAzNGE0MDc2NDQ4NWY3ZTA4Y2ExNjM2NmU1MDM0OTFhNmFmNzg1MGQ=',
blockNumber: 17019453,
hash: '0x46df998899c4d0f7cc88a914700486d58d088f9f365747c60c32a187f2d44ae8',
status: 'CONFIRMED',
to: '0x034a40764485f7e08ca16366e503491a6af7850d',
from: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',
nonce,
__typename: 'Transaction',
},
assetChanges: [],
__typename: 'AssetActivity',
},
{
id: 'QXNzZXRBY3Rpdml0eTpWSEpoYm5OaFkzUnBiMjQ2TUhneE16UXpaR1ppTlROaE9XRmpNR00yWW1aaVpqUTNNRFEyWWpObFkyRXhORGN3TUdZd00yWXhOMkV3WWpnM1pqWXpPRFpsWVRnNU16QTRNVFZtWmpoaFh6QjRZMkUzTXpOalkySm1OelZoTXpnME1ERXhPR1ZpT1RjNU9EVTJOemRpTkdRMk56TTBZemMwWmw4d2VERmlOVEUxTkdGaE5HSTRaakF5TjJJNVptUXhPVE0wTVRFek1tWmpPV1JoWlRFd1pqY3pOVGs9',
timestamp: 1681149995,
type: 'SEND',
chain: 'ETHEREUM',
transaction: {
id: 'VHJhbnNhY3Rpb246MHgxMzQzZGZiNTNhOWFjMGM2YmZiZjQ3MDQ2YjNlY2ExNDcwMGYwM2YxN2EwYjg3ZjYzODZlYTg5MzA4MTVmZjhhXzB4Y2E3MzNjY2JmNzVhMzg0MDExOGViOTc5ODU2NzdiNGQ2NzM0Yzc0Zl8weDFiNTE1NGFhNGI4ZjAyN2I5ZmQxOTM0MTEzMmZjOWRhZTEwZjczNTk=',
blockNumber: 17019446,
hash: '0x1343dfb53a9ac0c6bfbf47046b3eca14700f03f17a0b87f6386ea8930815ff8a',
status: 'CONFIRMED',
to: '0x1b5154aa4b8f027b9fd19341132fc9dae10f7359',
from: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',
nonce: nonce + 1,
__typename: 'Transaction',
},
assetChanges: [
{
__typename: 'TokenTransfer',
id: 'VG9rZW5UcmFuc2ZlcjoweDVjZWFiNzRlNDQ2ZGJkM2JmNjllMjc3MjAwZjEyOWQyYmM3YTM3YTFfMHhiMWRjNDlmMDY1N2FkNTA1YjUzNzUyN2RkOWE1MDk0YTM2NTkzMWMxXzB4MTM0M2RmYjUzYTlhYzBjNmJmYmY0NzA0NmIzZWNhMTQ3MDBmMDNmMTdhMGI4N2Y2Mzg2ZWE4OTMwODE1ZmY4YQ==',
asset: {
id: 'VG9rZW46RVRIRVJFVU1fMHgxY2MyYjA3MGNhZjAxNmE3ZGRjMzA0N2Y5MzI3MmU4Yzc3YzlkZGU5',
name: 'USD Coin (USDC)',
symbol: 'USDC',
address: '0x1cc2b070caf016a7ddc3047f93272e8c77c9dde9',
decimals: 6,
chain: 'ETHEREUM',
standard: null,
project: {
id: 'VG9rZW5Qcm9qZWN0OkVUSEVSRVVNXzB4MWNjMmIwNzBjYWYwMTZhN2RkYzMwNDdmOTMyNzJlOGM3N2M5ZGRlOQ==',
isSpam: true,
logo: null,
__typename: 'TokenProject',
},
__typename: 'Token',
},
tokenStandard: 'ERC20',
quantity: '18011.212084',
sender: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',
recipient: '0xb1dc49f0657ad505b537527dd9a5094a365931c1',
direction: 'OUT',
transactedValue: null,
},
],
__typename: 'AssetActivity',
},
],
__typename: 'Portfolio',
},
],
},
},
}
).as('graphql')
})
})
it('should deduplicate activity history by nonce', () => {
cy.visit(`/swap?inputCurrency=ETH&outputCurrency=${USDC_MAINNET.address}`).hardhat({ automine: false })
// Input swap info.
cy.get('#swap-currency-input .token-amount-input').clear().type('1').should('have.value', '1')
cy.get('#swap-currency-output .token-amount-input').should('not.have.value', '')
cy.get('#swap-button').click()
cy.get('#confirm-swap-or-send').click()
cy.get(getTestSelector('confirmation-close-icon')).click()
// Check activity history tab.
cy.get(getTestSelector('web3-status-connected')).click()
cy.get(getTestSelector('mini-portfolio-navbar')).contains('Activity').click()
// Assert that the local pending transaction is replaced by a remote transaction with the same nonce.
cy.contains('Swapping').should('not.exist')
})
})

View File

@ -1,14 +1,10 @@
import { getTestSelector } from '../utils'
const PUDGY_COLLECTION_ADDRESS = '0xbd3531da5cf5857e7cfaa92426877b022e612cf8'
const BONSAI_COLLECTION_ADDRESS = '0xec9c519d49856fd2f8133a0741b4dbe002ce211b'
describe('Testing nfts', () => {
beforeEach(() => {
cy.visit('/')
})
it('should load nft leaderboard', () => {
cy.visit('/')
cy.get(getTestSelector('nft-nav')).first().click()
cy.get(getTestSelector('nft-nav')).first().should('exist')
cy.get(getTestSelector('nft-nav')).first().click()
@ -16,7 +12,7 @@ describe('Testing nfts', () => {
})
it('should load pudgy penguin collection page', () => {
cy.visit(`/#/nfts/collection/${PUDGY_COLLECTION_ADDRESS}`)
cy.visit(`/nfts/collection/${PUDGY_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()
@ -24,13 +20,13 @@ describe('Testing nfts', () => {
})
it('should be able to navigate to activity', () => {
cy.visit(`/#/nfts/collection/${PUDGY_COLLECTION_ADDRESS}`)
cy.visit(`/nfts/collection/${PUDGY_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/${PUDGY_COLLECTION_ADDRESS}`)
cy.visit(`/nfts/collection/${PUDGY_COLLECTION_ADDRESS}`)
cy.get(getTestSelector('nft-filter')).first().click()
cy.get(getTestSelector('nft-collection-filter-buy-now')).click()
cy.get(getTestSelector('nft-collection-asset')).first().click()
@ -41,7 +37,10 @@ describe('Testing nfts', () => {
})
it('should toggle buy now on details page', () => {
cy.visit(`#/nfts/asset/${BONSAI_COLLECTION_ADDRESS}/7580`)
cy.visit(`/nfts/collection/${PUDGY_COLLECTION_ADDRESS}`)
cy.get(getTestSelector('nft-filter')).first().click()
cy.get(getTestSelector('nft-collection-filter-buy-now')).click()
cy.get(getTestSelector('nft-collection-asset')).first().click()
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')
@ -49,15 +48,11 @@ describe('Testing nfts', () => {
cy.get(getTestSelector('nft-bag')).should('exist')
})
it('should navigate to the owned nfts page', () => {
it('should navigate to and from the owned nfts page', () => {
cy.visit('/')
cy.get(getTestSelector('web3-status-connected')).click()
cy.get(getTestSelector('nft-view-self-nfts')).click()
})
it('should close the sidebar when navigating to NFT details', () => {
cy.get(getTestSelector('web3-status-connected')).click()
cy.get(getTestSelector('mini-portfolio-nav-nfts')).click()
cy.get(getTestSelector('mini-portfolio-navbar')).contains('NFTs').click()
cy.get(getTestSelector('mini-portfolio-nft')).first().click()
cy.contains('Buy crypto').should('not.be.visible')
cy.get(getTestSelector('mini-portfolio-navbar')).should('not.be.visible')
})
})

277
cypress/e2e/permit2.test.ts Normal file
View File

@ -0,0 +1,277 @@
import { BigNumber } from '@ethersproject/bignumber'
import { MaxUint160, MaxUint256 } from '@uniswap/permit2-sdk'
import { CurrencyAmount, Token } from '@uniswap/sdk-core'
import { DAI, USDC_MAINNET, USDT } from '../../src/constants/tokens'
import { getTestSelector } from '../utils'
/** Initiates a swap. */
function initiateSwap() {
// The swap button is re-rendered once enabled, so we must wait until the original button is not disabled to re-select the appropriate button.
cy.get('#swap-button').should('not.be.disabled')
// Completes the swap.
cy.get('#swap-button').click()
cy.contains('Confirm swap').click()
}
describe('Permit2', () => {
function setupInputs(inputToken: Token, outputToken: Token) {
// Sets up a swap between inputToken and outputToken.
cy.visit(`/swap/?inputCurrency=${inputToken.address}&outputCurrency=${outputToken.address}`)
cy.get('#swap-currency-input .token-amount-input').type('0.01')
}
/** Asserts permit2 has a max approval for spend of the input token on-chain. */
function expectTokenAllowanceForPermit2ToBeMax(inputToken: Token) {
// check token approval
cy.hardhat()
.then(({ approval, wallet }) => approval.getTokenAllowanceForPermit2({ owner: wallet, token: inputToken }))
.then((allowance) => {
Cypress.log({ name: `Token allowance: ${allowance.toString()}` })
cy.wrap(allowance).should('deep.equal', MaxUint256)
})
}
/** Asserts the universal router has a max permit2 approval for spend of the input token on-chain. */
function expectPermit2AllowanceForUniversalRouterToBeMax(inputToken: Token) {
cy.hardhat()
.then(({ approval, wallet }) => approval.getPermit2Allowance({ owner: wallet, token: inputToken }))
.then((allowance) => {
Cypress.log({ name: `Permit2 allowance: ${allowance.amount.toString()}` })
cy.wrap(allowance.amount).should('deep.equal', MaxUint160)
// Asserts that the on-chain expiration is in 30 days, within a tolerance of 40 seconds.
const THIRTY_DAYS_SECONDS = 2_592_000
const expected = Math.floor(Date.now() / 1000 + THIRTY_DAYS_SECONDS)
cy.wrap(allowance.expiration).should('be.closeTo', expected, 40)
})
}
beforeEach(() =>
cy.hardhat().then(async (hardhat) => {
await hardhat.fund(hardhat.wallet, CurrencyAmount.fromRawAmount(DAI, 1e18))
await hardhat.mine()
})
)
describe('approval process (with intermediate screens)', () => {
// Turn off automine so that intermediate screens are available to assert on.
beforeEach(() => cy.hardhat({ automine: false }))
it('swaps after completing full permit2 approval process', () => {
setupInputs(DAI, USDC_MAINNET)
initiateSwap()
// verify that the modal retains its state when the window loses focus
cy.window().trigger('blur')
// Verify token approval
cy.contains('Enable spending DAI on Uniswap')
cy.wait('@eth_sendRawTransaction')
cy.hardhat().then((hardhat) => hardhat.mine())
cy.get(getTestSelector('popups')).contains('Approved')
expectTokenAllowanceForPermit2ToBeMax(DAI)
// Verify permit2 approval
cy.contains('Allow DAI to be used for swapping')
cy.wait('@eth_signTypedData_v4')
cy.wait('@eth_sendRawTransaction')
cy.contains('Swap submitted')
cy.hardhat().then((hardhat) => hardhat.mine())
cy.contains('Swap success!')
cy.get(getTestSelector('popups')).contains('Swapped')
expectPermit2AllowanceForUniversalRouterToBeMax(DAI)
})
it('swaps with existing permit approval and missing token approval', () => {
setupInputs(DAI, USDC_MAINNET)
cy.hardhat().then(async (hardhat) => {
await hardhat.approval.setPermit2Allowance({ owner: hardhat.wallet, token: DAI })
await hardhat.mine()
})
initiateSwap()
// Verify token approval
cy.contains('Enable spending DAI on Uniswap')
cy.wait('@eth_sendRawTransaction')
cy.hardhat().then((hardhat) => hardhat.mine())
cy.get(getTestSelector('popups')).contains('Approved')
expectTokenAllowanceForPermit2ToBeMax(DAI)
// Verify transaction
cy.wait('@eth_sendRawTransaction')
cy.hardhat().then((hardhat) => hardhat.mine())
cy.contains('Swap success!')
cy.get(getTestSelector('popups')).contains('Swapped')
})
/**
* On mainnet, you have to revoke USDT approval before increasing it.
* From the token contract:
* To change the approve amount you first have to reduce the addresses`
* allowance to zero by calling `approve(_spender, 0)` if it is not
* already 0 to mitigate the race condition described here:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*/
it('swaps USDT with existing permit, and existing but insufficient token approval', () => {
cy.hardhat().then(async (hardhat) => {
await hardhat.fund(hardhat.wallet, CurrencyAmount.fromRawAmount(USDT, 2e6))
await hardhat.mine()
await hardhat.approval.setTokenAllowanceForPermit2({ owner: hardhat.wallet, token: USDT }, 1e6)
await hardhat.mine()
await hardhat.approval.setPermit2Allowance({ owner: hardhat.wallet, token: USDT })
await hardhat.mine()
})
setupInputs(USDT, USDC_MAINNET)
cy.get('#swap-currency-input .token-amount-input').clear().type('2')
initiateSwap()
// Verify allowance revocation
cy.contains('Reset USDT')
cy.wait('@eth_sendRawTransaction')
cy.hardhat().then((hardhat) => hardhat.mine())
cy.hardhat()
.then(({ approval, wallet }) => approval.getTokenAllowanceForPermit2({ owner: wallet, token: USDT }))
.should('deep.equal', BigNumber.from(0))
// Verify token approval
cy.contains('Enable spending USDT on Uniswap')
cy.wait('@eth_sendRawTransaction')
cy.hardhat().then((hardhat) => hardhat.mine())
cy.get(getTestSelector('popups')).contains('Approved')
expectTokenAllowanceForPermit2ToBeMax(USDT)
// Verify transaction
cy.wait('@eth_sendRawTransaction')
cy.hardhat().then((hardhat) => hardhat.mine())
cy.contains('Swap success!')
cy.get(getTestSelector('popups')).contains('Swapped')
})
it('swaps USDT with existing permit, and existing and sufficient token approval', () => {
cy.hardhat().then(async (hardhat) => {
await hardhat.fund(hardhat.wallet, CurrencyAmount.fromRawAmount(USDT, 2e6))
await hardhat.mine()
await hardhat.approval.setTokenAllowanceForPermit2({ owner: hardhat.wallet, token: USDT }, 1e6)
await hardhat.mine()
await hardhat.approval.setPermit2Allowance({ owner: hardhat.wallet, token: USDT })
await hardhat.mine()
})
setupInputs(USDT, USDC_MAINNET)
cy.get('#swap-currency-input .token-amount-input').clear().type('1')
initiateSwap()
// Verify transaction
cy.wait('@eth_sendRawTransaction')
cy.hardhat().then((hardhat) => hardhat.mine())
cy.contains('Swap success!')
cy.get(getTestSelector('popups')).contains('Swapped')
})
})
it('swaps when user has already approved token and permit2', () => {
cy.hardhat().then(({ approval, wallet }) =>
Promise.all([
approval.setTokenAllowanceForPermit2({ owner: wallet, token: DAI }),
approval.setPermit2Allowance({ owner: wallet, token: DAI }),
])
)
setupInputs(DAI, USDC_MAINNET)
initiateSwap()
// Verify transaction
cy.contains('Swap success!')
cy.get(getTestSelector('popups')).contains('Swapped')
})
it('swaps after handling user rejection of both approval and signature', () => {
setupInputs(DAI, USDC_MAINNET)
const USER_REJECTION = { code: 4001 }
cy.hardhat().then((hardhat) => {
// Reject token approval
const tokenApprovalStub = cy.stub(hardhat.wallet, 'sendTransaction').log(false)
tokenApprovalStub.rejects(USER_REJECTION) // rejects token approval
initiateSwap()
// Verify token approval rejection
cy.wrap(tokenApprovalStub).should('be.calledOnce')
cy.contains('Review swap')
// Allow token approval
cy.then(() => tokenApprovalStub.restore())
// Reject permit2 approval
const permitApprovalStub = cy.stub(hardhat.provider, 'send').log(false)
permitApprovalStub.withArgs('eth_signTypedData_v4').rejects(USER_REJECTION) // rejects permit approval
permitApprovalStub.callThrough() // allows non-eth_signTypedData_v4 send calls to return non-stubbed values
cy.contains('Confirm swap').click()
// Verify token approval
cy.get(getTestSelector('popups')).contains('Approved')
expectTokenAllowanceForPermit2ToBeMax(DAI)
// Verify permit2 approval rejection
cy.wrap(permitApprovalStub).should('be.calledWith', 'eth_signTypedData_v4')
cy.contains('Review swap')
// Allow permit2 approval
cy.then(() => permitApprovalStub.restore())
cy.contains('Confirm swap').click()
// Verify permit2 approval
cy.contains('Swap success!')
cy.get(getTestSelector('popups')).contains('Swapped')
expectPermit2AllowanceForUniversalRouterToBeMax(DAI)
})
})
it('prompts token approval when existing approval amount is too low', () => {
setupInputs(DAI, USDC_MAINNET)
cy.hardhat().then(({ approval, wallet }) =>
Promise.all([
approval.setPermit2Allowance({ owner: wallet, token: DAI }),
approval.setTokenAllowanceForPermit2({ owner: wallet, token: DAI }, 1),
])
)
initiateSwap()
// Verify token approval
cy.get(getTestSelector('popups')).contains('Approved')
expectPermit2AllowanceForUniversalRouterToBeMax(DAI)
})
it('prompts signature when existing permit approval is expired', () => {
setupInputs(DAI, USDC_MAINNET)
const expiredAllowance = { expiration: Math.floor((Date.now() - 1) / 1000) }
cy.hardhat().then(({ approval, wallet }) =>
Promise.all([
approval.setTokenAllowanceForPermit2({ owner: wallet, token: DAI }),
approval.setPermit2Allowance({ owner: wallet, token: DAI }, expiredAllowance),
])
)
initiateSwap()
// Verify permit2 approval
cy.wait('@eth_signTypedData_v4')
cy.contains('Swap success!')
cy.get(getTestSelector('popups')).contains('Swapped')
expectPermit2AllowanceForUniversalRouterToBeMax(DAI)
})
it('prompts signature when existing permit approval amount is too low', () => {
setupInputs(DAI, USDC_MAINNET)
const smallAllowance = { amount: 1 }
cy.hardhat().then(({ approval, wallet }) =>
Promise.all([
approval.setTokenAllowanceForPermit2({ owner: wallet, token: DAI }),
approval.setPermit2Allowance({ owner: wallet, token: DAI }, smallAllowance),
])
)
initiateSwap()
// Verify permit2 approval
cy.wait('@eth_signTypedData_v4')
cy.contains('Swap success!')
cy.get(getTestSelector('popups')).contains('Swapped')
expectPermit2AllowanceForUniversalRouterToBeMax(DAI)
})
})

View File

@ -1,25 +1,33 @@
import { ChainId, MaxUint256, UNI_ADDRESSES } from '@uniswap/sdk-core'
const UNI_MAINNET = UNI_ADDRESSES[ChainId.MAINNET]
describe('Remove Liquidity', () => {
it('eth remove', () => {
cy.visit('/remove/v2/ETH/0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984')
it('loads the token pair in v2', () => {
cy.visit(`/remove/v2/ETH/${UNI_MAINNET}`)
cy.get('#remove-liquidity-tokena-symbol').should('contain.text', 'ETH')
cy.get('#remove-liquidity-tokenb-symbol').should('contain.text', 'UNI')
})
it('eth remove swap order', () => {
cy.visit('/remove/v2/0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984/ETH')
cy.get('#remove-liquidity-tokena-symbol').should('contain.text', 'UNI')
cy.get('#remove-liquidity-tokenb-symbol').should('contain.text', 'ETH')
it('loads the token pair in v3', () => {
cy.visit(`/remove/1`)
cy.get('#remove-liquidity-tokens').should('contain.text', 'UNI/ETH')
cy.get('#remove-pooled-tokena-symbol').should('contain.text', 'Pooled UNI')
cy.get('#remove-pooled-tokenb-symbol').should('contain.text', 'Pooled ETH')
})
it('loads the two correct tokens', () => {
cy.visit('/remove/v2/0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6/0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984')
cy.get('#remove-liquidity-tokena-symbol').should('contain.text', 'WETH')
cy.get('#remove-liquidity-tokenb-symbol').should('contain.text', 'UNI')
})
it('should redirect to error pages if pool does not exist', () => {
// Duplicate-token v2 pools redirect to position unavailable
cy.visit(`/remove/v2/ETH/ETH`)
cy.contains('Position unavailable')
it('does not crash if ETH is duplicated', () => {
cy.visit('/remove/v2/0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6/0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6')
cy.get('#remove-liquidity-tokena-symbol').should('contain.text', 'WETH')
cy.get('#remove-liquidity-tokenb-symbol').should('contain.text', 'WETH')
// Single-token pools don't exist
cy.visit('/remove/v2/ETH')
cy.url().should('match', /\/not-found/)
// Nonexistent v3 pool
cy.visit(`/remove/${MaxUint256}`)
cy.contains('Position unavailable')
})
})

View File

@ -9,7 +9,7 @@ describe('Service Worker', () => {
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`'
'To test, build with `yarn build` and serve with `yarn serve`'
)
}
})
@ -20,65 +20,78 @@ describe('Service Worker', () => {
}
})
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)
}
function unregisterServiceWorker() {
return cy.log('unregisters service worker').then(async () => {
const sw = await window.navigator.serviceWorker.getRegistration(Cypress.config().baseUrl ?? undefined)
await sw?.unregister()
})
}
before(unregister)
after(unregister)
before(unregisterServiceWorker)
after(unregisterServiceWorker)
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'
}
cy.intercept('https://api.uniswap.org/v1/amplitude-proxy', (req) => {
const body = JSON.stringify(req.body)
const serviceWorkerStatus = body.match(/"service_worker":"(\w+)"/)?.[1]
if (serviceWorkerStatus) {
req.alias = `ServiceWorker:${serviceWorkerStatus}`
}
})
})
it('installs a ServiceWorker', () => {
it('installs a ServiceWorker and reports the uninstalled status to analytics', () => {
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')
cy.wait('@ServiceWorker:uninstalled')
cy.window().should(
'have.nested.property',
// The parent is checked instead of the AUT because it is on the same origin,
// and the AUT will not be considered "activated" until the parent is idle.
'parent.navigator.serviceWorker.controller.state',
'activated'
)
})
describe('cache hit', () => {
it('reports the hit to analytics', () => {
cy.visit('/', { serviceWorker: true })
cy.wait('@ServiceWorker:hit')
})
})
it('records a cache hit', () => {
cy.visit('/', { serviceWorker: true }).get('#swap-page').wait('@CacheHit', { timeout: 20000 })
})
it('records a cache miss', () => {
cy.then(async () => {
describe('cache miss', () => {
let cache: Cache | undefined
let request: Request | undefined
let response: Response | undefined
before(() => {
// Mocks the index.html in the cache to force a cache miss.
cy.visit('/', { serviceWorker: true }).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)
cache = await window.caches.open(cacheKey)
const keys = await cache.keys()
const key = keys.find((key) => key.url.match(/index/))
assert(key)
request = keys.find((key) => key.url.match(/index/))
assert(request)
await cache.put(key, new Response())
response = await cache.match(request)
assert(response)
await cache.put(request, new Response())
})
})
after(() => {
// Restores the index.html in the cache so that re-runs behave as expected.
// This is necessary because the Service Worker will not re-populate the cache.
cy.then(async () => {
if (cache && request && response) {
await cache.put(request, response)
}
})
})
it('reports the miss to analytics', () => {
cy.visit('/', { serviceWorker: true })
cy.wait('@ServiceWorker:miss')
})
.visit('/', { serviceWorker: true })
.get('#swap-page')
.wait('@CacheMiss', { timeout: 20000 })
})
})

View File

@ -1,108 +0,0 @@
import { FeatureFlag } from '../../src/featureFlags/flags/featureFlags'
import { getClassContainsSelector, getTestSelector } from '../utils'
const UNI_GOERLI = '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984'
const WETH_GOERLI = '0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6'
describe('swap widget integration tests', () => {
const verifyInputToken = (inputText: string) => {
cy.get(getClassContainsSelector('TokenButtonRow')).first().contains(inputText)
}
const verifyOutputToken = (outputText: string) => {
cy.get(getClassContainsSelector('TokenButtonRow')).last().contains(outputText)
}
const selectOutputAndSwitch = (outputText: string) => {
// open token selector...
cy.contains('Select token').click()
// select token...
cy.contains(outputText).click({ force: true })
cy.get('body')
.then(($body) => {
if ($body.find(getTestSelector('TokenSafetyWrapper')).length) {
return 'I understand'
}
return 'You pay' // Just click on a random element as a no-op
})
.then((selector) => {
cy.contains(selector).click()
})
// token selector should close...
cy.contains('Search name or paste address').should('not.exist')
cy.get(getClassContainsSelector('ReverseButton')).first().click()
}
describe('widget on swap page', () => {
beforeEach(() => {
cy.viewport(1200, 800)
})
it('should have the correct default input/output and token selection should work', () => {
cy.visit('/swap', { featureFlags: [FeatureFlag.swapWidget] }).then(() => {
cy.wait('@eth_blockNumber')
verifyInputToken('ETH')
verifyOutputToken('Select token')
selectOutputAndSwitch('WETH')
verifyInputToken('WETH')
verifyOutputToken('ETH')
})
})
it('should have the correct default input from URL params ', () => {
cy.visit(`/swap?inputCurrency=${WETH_GOERLI}`, {
featureFlags: [FeatureFlag.swapWidget],
}).then(() => {
cy.wait('@eth_blockNumber')
})
verifyInputToken('WETH')
verifyOutputToken('Select token')
selectOutputAndSwitch('Ether')
verifyInputToken('ETH')
verifyOutputToken('WETH')
})
it('should have the correct default output from URL params ', () => {
cy.visit(`/swap?outputCurrency=${WETH_GOERLI}`, {
featureFlags: [FeatureFlag.swapWidget],
}).then(() => {
cy.wait('@eth_blockNumber')
})
verifyInputToken('Select token')
verifyOutputToken('WETH')
cy.get(getClassContainsSelector('ReverseButton')).first().click()
verifyInputToken('WETH')
verifyOutputToken('Select token')
selectOutputAndSwitch('Ether')
verifyInputToken('ETH')
verifyOutputToken('WETH')
})
})
describe('widget on Token Detail Page', () => {
beforeEach(() => {
cy.viewport(1200, 800)
cy.visit(`/tokens/ethereum/${UNI_GOERLI}`, { featureFlags: [FeatureFlag.swapWidget] }).then(() => {
cy.wait('@eth_blockNumber')
})
})
it('should have the expected output for a tokens detail page', () => {
verifyOutputToken('UNI')
cy.contains('Connect to Ethereum').should('exist')
})
})
})

View File

@ -1,145 +0,0 @@
import { WETH_GOERLI } from '../fixtures/constants'
import { getTestSelector } from '../utils'
describe('Swap', () => {
const verifyAmount = (field: 'input' | 'output', amountText: string | null) => {
if (amountText === null) {
cy.get(`#swap-currency-${field} .token-amount-input`).should('not.have.value')
} else {
cy.get(`#swap-currency-${field} .token-amount-input`).should('have.value', amountText)
}
}
const verifyToken = (field: 'input' | 'output', tokenSymbol: string | null) => {
if (tokenSymbol === null) {
cy.get(`#swap-currency-${field} .token-symbol-container`).should('contain.text', 'Select token')
} else {
cy.get(`#swap-currency-${field} .token-symbol-container`).should('contain.text', tokenSymbol)
}
}
const selectOutput = (tokenSymbol: string) => {
// open token selector...
cy.contains('Select token').click()
// select token...
cy.contains(tokenSymbol).click()
cy.get('body')
.then(($body) => {
if ($body.find(getTestSelector('TokenSafetyWrapper')).length) {
return 'I understand'
}
return 'no-op' // Don't click on anything, a no-op
})
.then((content) => {
if (content !== 'no-op') {
cy.contains(content).click()
}
})
// token selector should close...
cy.contains('Search name or paste address').should('not.exist')
}
before(() => {
cy.visit('/swap')
})
it('starts with ETH selected by default', () => {
verifyAmount('input', '')
verifyToken('input', 'ETH')
verifyAmount('output', null)
verifyToken('output', null)
})
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('should have the correct default input/output and token selection should work', () => {
cy.visit('/swap')
verifyToken('input', 'ETH')
verifyToken('output', null)
selectOutput('WETH')
cy.get(getTestSelector('swap-currency-button')).first().click()
verifyToken('input', 'WETH')
verifyToken('output', 'ETH')
})
it('should have the correct default input from URL params ', () => {
cy.visit(`/swap?inputCurrency=${WETH_GOERLI}`)
verifyToken('input', 'WETH')
verifyToken('output', null)
selectOutput('Ether')
cy.get(getTestSelector('swap-currency-button')).first().click()
verifyToken('input', 'ETH')
verifyToken('output', 'WETH')
})
it('should have the correct default output from URL params ', () => {
cy.visit(`/swap?outputCurrency=${WETH_GOERLI}`)
verifyToken('input', null)
verifyToken('output', 'WETH')
cy.get(getTestSelector('swap-currency-button')).first().click()
verifyToken('input', 'WETH')
verifyToken('output', null)
selectOutput('Ether')
cy.get(getTestSelector('swap-currency-button')).first().click()
verifyToken('input', 'ETH')
verifyToken('output', 'WETH')
})
it('ETH to wETH is same value (wrapped swaps have no price impact)', () => {
cy.visit('/swap')
selectOutput('WETH')
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')
})
it('Opens and closes the settings menu', () => {
cy.visit('/swap')
cy.contains('Settings').should('not.exist')
cy.get(getTestSelector('swap-settings-button')).click()
cy.contains('Slippage tolerance').should('exist')
cy.contains('Transaction deadline').should('exist')
cy.contains('Auto Router API').should('exist')
cy.contains('Expert Mode').should('exist')
cy.get(getTestSelector('swap-settings-button')).click()
cy.contains('Settings').should('not.exist')
})
it('inputs reset when navigating between pages', () => {
cy.get('#swap-currency-input .token-amount-input').clear().type('0.01')
cy.get('#swap-currency-output .token-amount-input').should('not.equal', '')
cy.visit('/pool')
cy.visit('/swap')
cy.get('#swap-currency-input .token-amount-input').should('have.value', '')
cy.get('#swap-currency-output .token-amount-input').should('not.equal', '')
})
})

View File

@ -0,0 +1,135 @@
import { BigNumber } from '@ethersproject/bignumber'
import { InterfaceSectionName } from '@uniswap/analytics-events'
import { CurrencyAmount } from '@uniswap/sdk-core'
import { DEFAULT_DEADLINE_FROM_NOW } from '../../../src/constants/misc'
import { DAI, USDC_MAINNET } from '../../../src/constants/tokens'
import { getBalance, getTestSelector } from '../../utils'
describe('Swap errors', () => {
it('wallet rejection', () => {
cy.visit(`/swap?inputCurrency=ETH&outputCurrency=${USDC_MAINNET.address}`)
cy.hardhat().then((hardhat) => {
// Stub the wallet to reject any transaction.
cy.stub(hardhat.wallet, 'sendTransaction').log(false).rejects(new Error('user cancelled'))
// Enter amount to swap
cy.get('#swap-currency-output .token-amount-input').type('1').should('have.value', '1')
cy.get('#swap-currency-input .token-amount-input').should('not.have.value', '')
// Submit transaction
cy.get('#swap-button').click()
cy.contains('Confirm swap').click()
cy.wait('@eth_estimateGas')
// Verify rejection
cy.contains('Review swap')
cy.contains('Confirm swap')
})
})
it('transaction past deadline', () => {
cy.visit(`/swap?inputCurrency=ETH&outputCurrency=${USDC_MAINNET.address}`)
cy.hardhat({ automine: false })
getBalance(USDC_MAINNET).then((initialBalance) => {
// Enter amount to swap
cy.get('#swap-currency-output .token-amount-input').type('1').should('have.value', '1')
cy.get('#swap-currency-input .token-amount-input').should('not.have.value', '')
// Submit transaction
cy.get('#swap-button').click()
cy.contains('Confirm swap').click()
cy.wait('@eth_estimateGas').wait('@eth_sendRawTransaction').wait('@eth_getTransactionReceipt')
cy.contains('Swap submitted')
cy.get(getTestSelector('confirmation-close-icon')).click()
cy.get(getTestSelector('web3-status-connected')).should('contain', '1 Pending')
// Mine transaction
cy.hardhat().then(async (hardhat) => {
// Remove the transaction from the mempool, so that it doesn't fail but it is past the deadline.
// This should result in it being removed from pending transactions, without a failure notificiation.
const transactions = await hardhat.send('eth_pendingTransactions', [])
await hardhat.send('hardhat_dropTransaction', [transactions[0].hash])
// Mine past the deadline
await hardhat.mine(1, DEFAULT_DEADLINE_FROM_NOW + 1)
})
cy.wait('@eth_getTransactionReceipt')
// Verify transaction did not occur
cy.get(getTestSelector('web3-status-connected')).should('not.contain', 'Pending')
cy.get(getTestSelector('popups')).should('not.contain', 'Swap failed')
cy.get('#swap-currency-output').contains(`Balance: ${initialBalance}`)
getBalance(USDC_MAINNET).should('eq', initialBalance)
})
})
it('slippage failure', () => {
cy.visit(`/swap?inputCurrency=${USDC_MAINNET.address}&outputCurrency=${DAI.address}`)
cy.hardhat({ automine: false }).then(async (hardhat) => {
await hardhat.fund(hardhat.wallet, CurrencyAmount.fromRawAmount(USDC_MAINNET, 500e6))
await hardhat.mine()
await Promise.all([
hardhat.approval.setTokenAllowanceForPermit2({ owner: hardhat.wallet, token: USDC_MAINNET }),
hardhat.approval.setPermit2Allowance({ owner: hardhat.wallet, token: USDC_MAINNET }),
])
await hardhat.mine()
})
getBalance(DAI).then((initialBalance) => {
// Gas estimation fails for this transaction (that would normally fail), so we stub it.
cy.hardhat().then((hardhat) => {
const send = cy.stub(hardhat.provider, 'send').log(false)
send.withArgs('eth_estimateGas').resolves(BigNumber.from(2_000_000))
send.callThrough()
})
// Set slippage to a very low value.
cy.get(getTestSelector('open-settings-dialog-button')).click()
cy.get(getTestSelector('max-slippage-settings')).click()
cy.get(getTestSelector('slippage-input')).clear().type('0.01')
cy.get(getTestSelector('toggle-uniswap-x-button')).click() // turn off uniswapx
cy.get('body').click('topRight') // close modal
cy.get(getTestSelector('slippage-input')).should('not.exist')
// Submit 2 transactions
for (let i = 0; i < 2; i++) {
cy.get('#swap-currency-input .token-amount-input').type('200').should('have.value', '200')
cy.get('#swap-currency-output .token-amount-input').should('not.have.value', '')
cy.get('#swap-button').click()
cy.contains('Confirm swap').click()
cy.wait('@eth_sendRawTransaction').wait('@eth_getTransactionReceipt')
cy.contains('Swap submitted')
if (i === 0) {
cy.get(getTestSelector('confirmation-close-icon')).click()
}
}
cy.get(getTestSelector('web3-status-connected')).should('contain', '2 Pending')
// Mine transactions
cy.hardhat().then((hardhat) => hardhat.mine())
cy.wait('@eth_getTransactionReceipt')
cy.contains('Swap failed')
// Verify only 1 transaction occurred
cy.get(getTestSelector('web3-status-connected')).should('not.contain', 'Pending')
cy.get(getTestSelector('popups')).contains('Swapped')
cy.get(getTestSelector('popups')).contains('Swap failed')
getBalance(DAI).should('be.closeTo', initialBalance + 200, 1)
})
})
it('insufficient liquidity', () => {
// The API response is too variable so stubbing a 404.
cy.intercept('POST', 'https://api.uniswap.org/v2/quote', {
statusCode: 404,
fixture: 'insufficientLiquidity.json',
})
cy.visit(`/swap?inputCurrency=${USDC_MAINNET.address}&outputCurrency=${DAI.address}`)
cy.get('#swap-currency-output .token-amount-input').type('100000000000000').should('have.value', '100000000000000') // 100 trillion
cy.contains('Insufficient liquidity for this trade.')
cy.get('#swap-button').should('not.exist')
cy.get(getTestSelector(`fiat-value-${InterfaceSectionName.CURRENCY_OUTPUT_PANEL}`)).contains('-')
})
})

View File

@ -0,0 +1,146 @@
import { CurrencyAmount } from '@uniswap/sdk-core'
import { FeatureFlag } from 'featureFlags'
import { USDC_MAINNET } from '../../../src/constants/tokens'
import { getBalance, getTestSelector } from '../../utils'
describe.skip('Swap with fees', () => {
describe('Classic swaps', () => {
beforeEach(() => {
cy.visit('/swap', { featureFlags: [{ name: FeatureFlag.feesEnabled, value: true }] })
// Store trade quote into alias
cy.intercept({ url: 'https://api.uniswap.org/v2/quote' }, (req) => {
// Avoid tracking stablecoin pricing fetches
if (JSON.parse(req.body).intent !== 'pricing') req.alias = 'quoteFetch'
})
})
it('displays $0 fee on swaps without fees', () => {
// Set up a stablecoin <> stablecoin swap (no fees)
cy.get('#swap-currency-input .open-currency-select-button').click()
cy.contains('DAI').click()
cy.get('#swap-currency-output .open-currency-select-button').click()
cy.contains('USDC').click()
cy.get('#swap-currency-output .token-amount-input').type('1')
// Verify 0 fee UI is displayed
cy.get(getTestSelector('swap-details-header-row')).click()
cy.contains('Fee')
cy.contains('$0')
})
it('swaps ETH for USDC exact-out with swap fee', () => {
cy.hardhat().then((hardhat) => {
getBalance(USDC_MAINNET).then((initialBalance) => {
// Set up swap
cy.get('#swap-currency-output .open-currency-select-button').click()
cy.contains('USDC').click()
cy.get('#swap-currency-output .token-amount-input').type('1')
cy.wait('@quoteFetch')
.its('response.body')
.then(({ quote: { portionBips, portionRecipient, portionAmount } }) => {
// Fees are generally expected to always be enabled for ETH -> USDC swaps
// If the routing api does not include a fee, end the test early rather than manually update routes and hardcode fee vars
if (portionRecipient) return
cy.then(() => hardhat.getBalance(portionRecipient, USDC_MAINNET)).then((initialRecipientBalance) => {
const feeCurrencyAmount = CurrencyAmount.fromRawAmount(USDC_MAINNET, portionAmount)
// Initiate transaction
cy.get('#swap-button').click()
cy.contains('Review swap')
// Verify fee percentage and amount is displayed
cy.contains(`Fee (${portionBips / 100}%)`)
// Confirm transaction
cy.contains('Confirm swap').click()
// Verify transaction
cy.get(getTestSelector('web3-status-connected')).should('not.contain', 'Pending')
cy.get(getTestSelector('popups')).contains('Swapped')
// Verify the post-fee output is the expected exact-out amount
const finalBalance = initialBalance + 1
cy.get('#swap-currency-output').contains(`Balance: ${finalBalance}`)
getBalance(USDC_MAINNET).should('eq', finalBalance)
// Verify fee recipient received fee
cy.then(() => hardhat.getBalance(portionRecipient, USDC_MAINNET)).then((finalRecipientBalance) => {
const expectedFinalRecipientBalance = initialRecipientBalance.add(feeCurrencyAmount)
cy.then(() => finalRecipientBalance.equalTo(expectedFinalRecipientBalance)).should('be.true')
})
})
})
})
})
})
it('swaps ETH for USDC exact-in with swap fee', () => {
cy.hardhat().then((hardhat) => {
// Set up swap
cy.get('#swap-currency-output .open-currency-select-button').click()
cy.contains('USDC').click()
cy.get('#swap-currency-input .token-amount-input').type('.01')
cy.wait('@quoteFetch')
.its('response.body')
.then(({ quote: { portionBips, portionRecipient } }) => {
// Fees are generally expected to always be enabled for ETH -> USDC swaps
// If the routing api does not include a fee, end the test early rather than manually update routes and hardcode fee vars
if (portionRecipient) return
cy.then(() => hardhat.getBalance(portionRecipient, USDC_MAINNET)).then((initialRecipientBalance) => {
// Initiate transaction
cy.get('#swap-button').click()
cy.contains('Review swap')
// Verify fee percentage and amount is displayed
cy.contains(`Fee (${portionBips / 100}%)`)
// Confirm transaction
cy.contains('Confirm swap').click()
// Verify transaction
cy.get(getTestSelector('web3-status-connected')).should('not.contain', 'Pending')
cy.get(getTestSelector('popups')).contains('Swapped')
// Verify fee recipient received fee
cy.then(() => hardhat.getBalance(portionRecipient, USDC_MAINNET)).then((finalRecipientBalance) => {
cy.then(() => finalRecipientBalance.greaterThan(initialRecipientBalance)).should('be.true')
})
})
})
})
})
})
describe('UniswapX swaps', () => {
it('displays UniswapX fee in UI', () => {
cy.visit('/swap', {
featureFlags: [{ name: FeatureFlag.feesEnabled, value: true }],
})
// Intercept the trade quote
cy.intercept({ url: 'https://api.uniswap.org/v2/quote' }, (req) => {
// Avoid intercepting stablecoin pricing fetches
if (JSON.parse(req.body).intent !== 'pricing') {
req.reply({ fixture: 'uniswapx/feeQuote.json' })
}
})
// Setup swap
cy.get('#swap-currency-input .open-currency-select-button').click()
cy.contains('USDC').click()
cy.get('#swap-currency-output .open-currency-select-button').click()
cy.contains('ETH').click()
cy.get('#swap-currency-input .token-amount-input').type('200')
// Verify fee UI is displayed
cy.get(getTestSelector('swap-details-header-row')).click()
cy.contains('Fee (0.15%)')
})
})
})

View File

@ -0,0 +1,76 @@
import { SwapEventName } from '@uniswap/analytics-events'
import { USDC_MAINNET } from '../../../src/constants/tokens'
import { getTestSelector } from '../../utils'
describe('swap flow logging', () => {
it('completes two swaps and verifies the TTS logging for the first, plus all intermediate steps along the way', () => {
cy.visit(`/swap?inputCurrency=ETH&outputCurrency=${USDC_MAINNET.address}`)
cy.hardhat()
// First swap in the session:
// Enter amount to swap
cy.get('#swap-currency-output .token-amount-input').type('1').should('have.value', '1')
cy.get('#swap-currency-input .token-amount-input').should('not.have.value', '')
// Verify first swap action
cy.waitForAmplitudeEvent(SwapEventName.SWAP_FIRST_ACTION).then((event: any) => {
cy.wrap(event.event_properties).should('have.property', 'time_to_first_swap_action')
cy.wrap(event.event_properties.time_to_first_swap_action).should('be.a', 'number')
cy.wrap(event.event_properties.time_to_first_swap_action).should('be.gte', 0)
})
// Verify Swap Quote
cy.waitForAmplitudeEvent(SwapEventName.SWAP_QUOTE_FETCH).then((event: any) => {
// Price quotes don't include these values, so we only verify the types if they exist
if (event.event_properties.time_to_first_quote_request) {
cy.wrap(event.event_properties.time_to_first_quote_request).should('be.a', 'number')
cy.wrap(event.event_properties.time_to_first_quote_request).should('be.gte', 0)
cy.wrap(event.event_properties.time_to_first_quote_request_since_first_input).should('be.a', 'number')
cy.wrap(event.event_properties.time_to_first_quote_request_since_first_input).should('be.gte', 0)
}
})
// Submit transaction
cy.get('#swap-button').click()
cy.contains('Confirm swap').click()
cy.get(getTestSelector('confirmation-close-icon')).click()
cy.get(getTestSelector('popups')).contains('Swapped')
// Verify logging
cy.waitForAmplitudeEvent(SwapEventName.SWAP_TRANSACTION_COMPLETED).then((event: any) => {
cy.wrap(event.event_properties).should('have.property', 'time_to_swap')
cy.wrap(event.event_properties.time_to_swap).should('be.a', 'number')
cy.wrap(event.event_properties.time_to_swap).should('be.gte', 0)
cy.wrap(event.event_properties).should('have.property', 'time_to_swap_since_first_input')
cy.wrap(event.event_properties.time_to_swap_since_first_input).should('be.a', 'number')
cy.wrap(event.event_properties.time_to_swap_since_first_input).should('be.gte', 0)
})
// Second swap in the session:
// Enter amount to swap (different from first trade, to trigger a new quote request)
cy.get('#swap-currency-output .token-amount-input').clear().type('10').should('have.value', '10')
cy.get('#swap-currency-input .token-amount-input').should('not.have.value', '')
// Verify second Swap Quote
cy.waitForAmplitudeEvent(SwapEventName.SWAP_QUOTE_FETCH).then((event: any) => {
// Price quotes don't include these values, so we only verify the types if they exist
if (event.event_properties.time_to_first_quote_request) {
cy.wrap(event.event_properties.time_to_first_quote_request).should('be.undefined')
cy.wrap(event.event_properties.time_to_first_quote_request_since_first_input).should('be.undefined')
}
})
// Submit transaction
cy.get('#swap-button').click()
cy.contains('Confirm swap').click()
cy.get(getTestSelector('confirmation-close-icon')).click()
cy.get(getTestSelector('popups')).contains('Swapped')
cy.waitForAmplitudeEvent(SwapEventName.SWAP_TRANSACTION_COMPLETED).then((event: any) => {
cy.wrap(event.event_properties).should('not.have.property', 'time_to_swap')
cy.wrap(event.event_properties).should('not.have.property', 'time_to_swap_since_first_input')
})
})
})

View File

@ -0,0 +1,34 @@
import { getTestSelector } from '../../utils'
describe('Swap settings', () => {
it('Opens and closes the settings menu', () => {
cy.visit('/swap')
cy.contains('Settings').should('not.exist')
cy.get(getTestSelector('open-settings-dialog-button')).click()
cy.get(getTestSelector('mobile-settings-menu')).should('not.exist')
cy.contains('Max. slippage').should('exist')
cy.contains('Transaction deadline').should('exist')
cy.contains('UniswapX').should('exist')
cy.get(getTestSelector('open-settings-dialog-button')).click()
cy.contains('Settings').should('not.exist')
})
it('should open the mobile settings menu', () => {
// Set viewport to iPhone 6
cy.viewport('iphone-6')
cy.visit('/swap')
// Click the button to open the settings dialog
cy.get(getTestSelector('open-settings-dialog-button')).click({ waitForAnimations: true })
// Verify the mobile settings menu and its contents
cy.get(getTestSelector('mobile-settings-menu'))
.should('exist')
.within(() => {
cy.contains('Max. slippage').should('exist')
cy.contains('UniswapX').should('exist')
cy.contains('Transaction deadline').should('exist')
cy.get(getTestSelector('mobile-settings-close')).click()
})
})
})

View File

@ -0,0 +1,98 @@
import { SwapEventName } from '@uniswap/analytics-events'
import { ChainId } from '@uniswap/sdk-core'
import { UNI, USDC_MAINNET } from '../../../src/constants/tokens'
import { getBalance, getTestSelector } from '../../utils'
const UNI_MAINNET = UNI[ChainId.MAINNET]
describe('Swap', () => {
describe('Swap on main page', () => {
it('starts with ETH selected by default', () => {
cy.visit('/swap')
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('should default inputs from URL params ', () => {
cy.visit(`/swap?inputCurrency=${UNI_MAINNET.address}`)
cy.get(`#swap-currency-input .token-symbol-container`).should('contain.text', 'UNI')
cy.get(`#swap-currency-output .token-symbol-container`).should('contain.text', 'Select token')
cy.visit(`/swap?outputCurrency=${UNI_MAINNET.address}`)
cy.get(`#swap-currency-input .token-symbol-container`).should('contain.text', 'Select token')
cy.get(`#swap-currency-output .token-symbol-container`).should('contain.text', 'UNI')
cy.visit(`/swap?inputCurrency=ETH&outputCurrency=${UNI_MAINNET.address}`)
cy.get(`#swap-currency-input .token-symbol-container`).should('contain.text', 'ETH')
cy.get(`#swap-currency-output .token-symbol-container`).should('contain.text', 'UNI')
})
it('inputs reset when navigating between pages', () => {
cy.visit('/swap')
cy.get('#swap-currency-input .token-amount-input').should('have.value', '')
cy.get('#swap-currency-input .token-amount-input').type('0.01').should('have.value', '0.01')
cy.visit('/pool').visit('/swap')
cy.get('#swap-currency-input .token-amount-input').should('have.value', '')
})
it('resets the dependent input when the independent input is cleared', () => {
cy.visit(`/swap?inputCurrency=ETH&outputCurrency=${UNI_MAINNET.address}`)
cy.get('#swap-currency-input .token-amount-input').should('have.value', '')
cy.get(`#swap-currency-output .token-amount-input`).should('have.value', '')
cy.get('#swap-currency-input .token-amount-input').type('0.01').should('have.value', '0.01')
cy.get(`#swap-currency-output .token-amount-input`).should('not.have.value', '')
cy.get('#swap-currency-input .token-amount-input').clear()
cy.get(`#swap-currency-output .token-amount-input`).should('not.have.value')
cy.window().trigger('blur')
cy.get(`#swap-currency-output .token-amount-input`).should('not.have.value')
})
it('swaps ETH for USDC', () => {
cy.visit('/swap')
cy.hardhat({ automine: false })
getBalance(USDC_MAINNET).then((initialBalance) => {
// Select USDC
cy.get('#swap-currency-output .open-currency-select-button').click()
cy.get(getTestSelector('token-search-input')).type(USDC_MAINNET.address)
cy.get(getTestSelector('common-base-USDC')).click()
// Enter amount to swap
cy.get('#swap-currency-output .token-amount-input').type('1').should('have.value', '1')
cy.get('#swap-currency-input .token-amount-input').should('not.have.value', '')
// Verify logging
cy.waitForAmplitudeEvent(SwapEventName.SWAP_QUOTE_RECEIVED).then((event: any) => {
cy.wrap(event.event_properties).should('have.property', 'quote_latency_milliseconds')
cy.wrap(event.event_properties.quote_latency_milliseconds).should('be.a', 'number')
cy.wrap(event.event_properties.quote_latency_milliseconds).should('be.gte', 0)
})
// Submit transaction
cy.get('#swap-button').click()
cy.contains('Review swap')
cy.contains('Confirm swap').click()
cy.wait('@eth_estimateGas').wait('@eth_sendRawTransaction').wait('@eth_getTransactionReceipt')
cy.contains('Swap submitted')
cy.get(getTestSelector('confirmation-close-icon')).click()
cy.contains('Swap submitted').should('not.exist')
cy.get(getTestSelector('web3-status-connected')).should('contain', '1 Pending')
// Mine transaction
cy.hardhat().then((hardhat) => hardhat.mine())
cy.wait('@eth_getTransactionReceipt')
// Verify transaction
cy.get(getTestSelector('web3-status-connected')).should('not.contain', 'Pending')
cy.get(getTestSelector('popups')).contains('Swapped')
const finalBalance = initialBalance + 1
cy.get('#swap-currency-output').contains(`Balance: ${finalBalance}`)
getBalance(USDC_MAINNET).should('eq', finalBalance)
})
})
})
})

View File

@ -0,0 +1,376 @@
import { ChainId, CurrencyAmount } from '@uniswap/sdk-core'
import { CyHttpMessages } from 'cypress/types/net-stubbing'
import { DAI, nativeOnChain, USDC_MAINNET } from '../../../src/constants/tokens'
import { getTestSelector } from '../../utils'
const QuoteWhereUniswapXIsBetter = 'uniswapx/quote1.json'
const QuoteWithEthInput = 'uniswapx/quote2.json'
const QuoteEndpoint = 'https://api.uniswap.org/v2/quote'
const OrderSubmissionEndpoint = 'https://api.uniswap.org/v2/order'
const OrderStatusEndpoint =
'https://api.uniswap.org/v2/orders?swapper=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266&orderHashes=0xa9dd6f05ad6d6c79bee654c31ede4d0d2392862711be0f3bc4a9124af24a6a19'
/**
* Stubs quote to return a quote for non-price requests
* Price quotes are blocked with 409, as the backend would not accept them regardless
*/
function stubNonPriceQuoteWith(fixture: string) {
cy.intercept(QuoteEndpoint, (req: CyHttpMessages.IncomingHttpRequest) => {
let body = req.body
if (typeof body === 'string') {
body = JSON.parse(body)
}
if (body.intent === 'pricing') {
req.reply({ statusCode: 409 })
} else {
req.reply({ fixture })
}
}).as('quote')
}
/** Stubs the provider to return a tx receipt corresponding to the mock filled uniswapx order's txHash */
function stubSwapTxReceipt() {
cy.hardhat().then((hardhat) => {
cy.fixture('uniswapx/fillTransactionReceipt.json').then((mockTxReceipt) => {
const getTransactionReceiptStub = cy.stub(hardhat.provider, 'getTransactionReceipt').log(false)
getTransactionReceiptStub.withArgs(mockTxReceipt.transactionHash).resolves(mockTxReceipt)
getTransactionReceiptStub.callThrough()
})
})
}
// TODO: FIX THESE TESTS where we should NOT stub for pricing requests
describe.skip('UniswapX Toggle', () => {
beforeEach(() => {
stubNonPriceQuoteWith(QuoteWhereUniswapXIsBetter)
cy.visit(`/swap/?inputCurrency=${USDC_MAINNET.address}&outputCurrency=${DAI.address}`)
})
it('displays uniswapx ui when setting is on', () => {
// Setup a swap
cy.get('#swap-currency-input .token-amount-input').type('300')
cy.wait('@quote')
// UniswapX UI should be visible
cy.get(getTestSelector('gas-estimate-uniswapx-icon')).should('exist')
})
})
describe.skip('UniswapX Orders', () => {
beforeEach(() => {
stubNonPriceQuoteWith(QuoteWhereUniswapXIsBetter)
cy.intercept(OrderSubmissionEndpoint, { fixture: 'uniswapx/orderResponse.json' })
cy.intercept(OrderStatusEndpoint, { fixture: 'uniswapx/openStatusResponse.json' })
stubSwapTxReceipt()
cy.hardhat().then((hardhat) => hardhat.fund(hardhat.wallet, CurrencyAmount.fromRawAmount(USDC_MAINNET, 3e8)))
cy.visit(`/swap/?inputCurrency=${USDC_MAINNET.address}&outputCurrency=${DAI.address}`)
})
it('can swap exact-in trades using uniswapX', () => {
// Setup a swap
cy.get('#swap-currency-input .token-amount-input').type('300')
cy.wait('@quote')
// Submit uniswapx order signature
cy.get('#swap-button').click()
cy.contains('Confirm swap').click()
cy.wait('@eth_signTypedData_v4')
cy.contains('Swap submitted')
cy.contains('Learn more about swapping with UniswapX')
// Return filled order status from uniswapx api
cy.intercept(OrderStatusEndpoint, { fixture: 'uniswapx/filledStatusResponse.json' })
// Verify swap success
cy.contains('Swapped')
})
it('can swap exact-out trades using uniswapX', () => {
// Setup a swap
cy.get('#swap-currency-output .token-amount-input').type('300')
cy.wait('@quote')
// Submit uniswapx order signature
cy.get('#swap-button').click()
cy.contains('Confirm swap').click()
cy.wait('@eth_signTypedData_v4')
cy.contains('Swap submitted')
cy.contains('Learn more about swapping with UniswapX')
// Return filled order status from uniswapx api
cy.intercept(OrderStatusEndpoint, { fixture: 'uniswapx/filledStatusResponse.json' })
// Verify swap success
cy.contains('Swapped')
})
it('renders proper view if uniswapx order expires', () => {
// Setup a swap
cy.get('#swap-currency-input .token-amount-input').type('300')
cy.wait('@quote')
// Submit uniswapx order signature
cy.get('#swap-button').click()
cy.contains('Confirm swap').click()
// Return expired order status from uniswapx api
cy.intercept(OrderStatusEndpoint, { fixture: 'uniswapx/expiredStatusResponse.json' })
// Verify swap failure message
cy.contains('Swap expired')
})
it('renders proper view if uniswapx order has insufficient funds', () => {
// Setup a swap
cy.get('#swap-currency-input .token-amount-input').type('300')
cy.wait('@quote')
// Submit uniswapx order signature
cy.get('#swap-button').click()
cy.contains('Confirm swap').click()
// Return insufficient_funds order status from uniswapx api
cy.intercept(OrderStatusEndpoint, { fixture: 'uniswapx/insufficientFundsStatusResponse.json' })
// Verify swap failure message
cy.contains('Insufficient funds')
})
})
describe.skip('UniswapX Eth Input', () => {
beforeEach(() => {
stubNonPriceQuoteWith(QuoteWithEthInput)
cy.intercept(OrderSubmissionEndpoint, { fixture: 'uniswapx/orderResponse.json' })
cy.intercept(OrderStatusEndpoint, { fixture: 'uniswapx/openStatusResponse.json' })
// Turn off automine so that intermediate screens are available to assert on.
cy.hardhat({ automine: false }).then(async (hardhat) => {
await hardhat.fund(hardhat.wallet, CurrencyAmount.fromRawAmount(nativeOnChain(ChainId.MAINNET), 2e18))
await hardhat.mine()
})
stubSwapTxReceipt()
cy.visit(`/swap/?inputCurrency=ETH&outputCurrency=${DAI.address}`)
})
it('can swap using uniswapX with ETH as input', () => {
// Setup a swap
cy.get('#swap-currency-input .token-amount-input').type('1')
cy.wait('@quote')
// Prompt ETH wrap to use for order
cy.get('#swap-button').click()
cy.contains('Confirm swap').click()
cy.contains('Wrap ETH')
// Wrap ETH
cy.wait('@eth_sendRawTransaction')
cy.contains('Pending...')
cy.hardhat().then((hardhat) => hardhat.mine())
cy.contains('Wrapped')
// Approve WETH spend
cy.wait('@eth_sendRawTransaction')
cy.hardhat().then((hardhat) => hardhat.mine())
// Verify signed order submission
cy.wait('@eth_signTypedData_v4')
cy.contains('Swap submitted')
cy.contains('Learn more about swapping with UniswapX')
// Return filled order status from uniswapx api
cy.intercept(OrderStatusEndpoint, { fixture: 'uniswapx/filledStatusResponse.json' })
// Verify swap success
cy.contains('Swapped')
})
it('keeps ETH as the input currency before wrap completes', () => {
// Setup a swap
cy.get('#swap-currency-input .token-amount-input').type('1')
cy.wait('@quote')
// Prompt ETH wrap and confirm
cy.get('#swap-button').click()
cy.contains('Confirm swap').click()
cy.wait('@eth_sendRawTransaction')
// Close review modal before wrap is confirmed on chain
cy.get(getTestSelector('confirmation-close-icon')).click()
// Confirm ETH is still the input token before wrap succeeds
cy.contains('ETH')
})
it('switches swap input to WETH after wrap', () => {
// Setup a swap
cy.get('#swap-currency-input .token-amount-input').type('1')
cy.wait('@quote')
// Prompt ETH wrap and confirm
cy.get('#swap-button').click()
cy.contains('Confirm swap').click()
cy.wait('@eth_sendRawTransaction')
cy.hardhat().then((hardhat) => hardhat.mine())
// Confirm wrap is successful and WETH is now input token
cy.contains('Wrapped')
cy.contains('WETH')
// Approve WETH spend
cy.wait('@eth_sendRawTransaction')
cy.hardhat().then((hardhat) => hardhat.mine())
// Submit uniswapx order signature
cy.wait('@eth_signTypedData_v4')
cy.contains('Swap submitted')
cy.contains('Learn more about swapping with UniswapX')
// Return filled order status from uniswapx api
cy.intercept(OrderStatusEndpoint, { fixture: 'uniswapx/filledStatusResponse.json' })
// Verify swap success
cy.contains('Swapped')
// Close modal
cy.get(getTestSelector('confirmation-close-icon')).click()
// The input currency should now be WETH
cy.contains('WETH')
})
})
describe.skip('UniswapX activity history', () => {
beforeEach(() => {
cy.intercept(QuoteEndpoint, { fixture: QuoteWhereUniswapXIsBetter })
cy.intercept(OrderSubmissionEndpoint, { fixture: 'uniswapx/orderResponse.json' })
cy.intercept(OrderStatusEndpoint, { fixture: 'uniswapx/openStatusResponse.json' })
stubSwapTxReceipt()
cy.hardhat().then(async (hardhat) => {
await hardhat.fund(hardhat.wallet, CurrencyAmount.fromRawAmount(USDC_MAINNET, 3e8))
})
cy.visit(`/swap/?inputCurrency=${USDC_MAINNET.address}&outputCurrency=${DAI.address}`)
})
it('can view UniswapX order status progress in activity', () => {
// Setup a swap
cy.get('#swap-currency-input .token-amount-input').type('300')
// Submit uniswapx order signature
cy.get('#swap-button').click()
cy.contains('Confirm swap').click()
cy.wait('@eth_signTypedData_v4')
cy.get(getTestSelector('confirmation-close-icon')).click()
// Open mini portfolio and navigate to activity history
cy.get(getTestSelector('web3-status-connected')).click()
cy.intercept(/graphql/, { fixture: 'mini-portfolio/empty_activity.json' })
cy.get(getTestSelector('mini-portfolio-navbar')).contains('Activity').click()
// Open pending order modal
cy.contains('Swapping').click()
cy.get(getTestSelector('offchain-activity-modal')).contains('Swapping')
cy.get(getTestSelector('offchain-activity-modal')).contains('Learn more about swapping with UniswapX')
// Return filled order status from uniswapx api
cy.intercept(OrderStatusEndpoint, { fixture: 'uniswapx/filledStatusResponse.json' })
cy.get(getTestSelector('offchain-activity-modal')).contains('Swapped')
cy.get(getTestSelector('offchain-activity-modal')).contains('View on Explorer')
})
it('can view UniswapX order status progress in activity upon expiry', () => {
// Setup a swap
cy.get('#swap-currency-input .token-amount-input').type('300')
// Submit uniswapx order signature
cy.get('#swap-button').click()
cy.contains('Confirm swap').click()
cy.wait('@eth_signTypedData_v4')
cy.get(getTestSelector('confirmation-close-icon')).click()
// Open mini portfolio and navigate to activity history
cy.get(getTestSelector('web3-status-connected')).click()
cy.intercept(/graphql/, { fixture: 'mini-portfolio/empty_activity.json' })
cy.get(getTestSelector('mini-portfolio-navbar')).contains('Activity').click()
// Open pending order modal
cy.contains('Swapping').click()
cy.get(getTestSelector('offchain-activity-modal')).contains('Swapping')
// Return filled order status from uniswapx api
cy.intercept(OrderStatusEndpoint, { fixture: 'uniswapx/expiredStatusResponse.json' })
cy.get(getTestSelector('offchain-activity-modal')).contains('Swap expired')
cy.get(getTestSelector('offchain-activity-modal')).contains('learn more')
})
it('deduplicates remote vs local uniswapx orders', () => {
// Setup a swap
cy.get('#swap-currency-input .token-amount-input').type('300')
// Submit uniswapx order signature
cy.get('#swap-button').click()
cy.contains('Confirm swap').click()
cy.wait('@eth_signTypedData_v4')
cy.get(getTestSelector('confirmation-close-icon')).click()
// Return filled order status from uniswapx api
cy.intercept(OrderStatusEndpoint, { fixture: 'uniswapx/filledStatusResponse.json' })
cy.contains('Swapped')
// Open mini portfolio
cy.get(getTestSelector('web3-status-connected')).click()
cy.fixture('mini-portfolio/uniswapx_activity.json').then((uniswapXActivity) => {
// Replace fixture's timestamp with current time
uniswapXActivity.data.portfolios[0].assetActivities[0].timestamp = Date.now() / 1000
cy.intercept(/graphql/, uniswapXActivity)
})
// Open activity history
cy.get(getTestSelector('mini-portfolio-navbar')).contains('Activity').click()
// Ensure gql and local order have been deduped, such that there is one swap activity listed
cy.get(getTestSelector('activity-content')).contains('Swapped').should('have.length', 1)
})
it('balances should refetch after uniswapx swap', () => {
// Setup a swap
cy.get('#swap-currency-input .token-amount-input').type('300')
const gqlSpy = cy.spy().as('gqlSpy')
cy.intercept(/graphql/, (req) => {
// Spy on request frequency
req.on('response', gqlSpy)
// Reply with a fixture to speed up test
req.reply({
fixture: 'mini-portfolio/tokens.json',
})
})
// Expect balances to fetch upon opening mini portfolio
cy.get(getTestSelector('web3-status-connected')).click()
cy.get('@gqlSpy').should('have.been.calledOnce')
// Submit uniswapx order signature
cy.get('#swap-button').click()
cy.contains('Confirm swap').click()
// Expect balances to refetch after approval
cy.get('@gqlSpy').should('have.been.calledTwice')
// Return filled order status from uniswapx api
cy.intercept(OrderStatusEndpoint, { fixture: 'uniswapx/filledStatusResponse.json' })
// Expect balances to refetch after swap
cy.get('@gqlSpy').should('have.been.calledThrice')
})
})

View File

@ -0,0 +1,78 @@
import { ChainId, CurrencyAmount, WETH9 } from '@uniswap/sdk-core'
import { getBalance, getTestSelector } from '../../utils'
const WETH = WETH9[ChainId.MAINNET]
describe('Swap wrap', () => {
beforeEach(() => {
cy.visit(`/swap?inputCurrency=ETH&outputCurrency=${WETH.address}`).hardhat({ automine: false })
})
it('ETH to wETH is same value (wrapped swaps have no price impact)', () => {
cy.get('#swap-currency-input .token-amount-input').type('0.01').should('have.value', '0.01')
cy.get('#swap-currency-output .token-amount-input').should('have.value', '0.01')
cy.get('#swap-currency-output .token-amount-input').clear().type('0.02').should('have.value', '0.02')
cy.get('#swap-currency-input .token-amount-input').should('have.value', '0.02')
})
it('should be able to wrap ETH', () => {
getBalance(WETH).then((initialBalance) => {
cy.contains('Enter ETH amount')
// Enter amount to wrap
cy.get('#swap-currency-output .token-amount-input').type('1').should('have.value', 1)
cy.get('#swap-currency-input .token-amount-input').should('have.value', 1)
// Submit transaction
cy.contains('Wrap').click()
cy.wait('@eth_estimateGas').wait('@eth_sendRawTransaction').wait('@eth_getTransactionReceipt')
cy.get(getTestSelector('web3-status-connected')).should('contain', '1 Pending')
// Mine transaction
cy.hardhat().then((hardhat) => hardhat.mine())
cy.wait('@eth_getTransactionReceipt')
// Verify transaction
cy.get(getTestSelector('web3-status-connected')).should('not.contain', 'Pending')
cy.get(getTestSelector('popups')).contains('Wrapped')
const finalBalance = initialBalance + 1
cy.get('#swap-currency-output').contains(`Balance: ${finalBalance}`)
getBalance(WETH).should('equal', finalBalance)
})
})
it('should be able to unwrap WETH', () => {
cy.hardhat().then(async (hardhat) => {
await hardhat.fund(hardhat.wallet, CurrencyAmount.fromRawAmount(WETH, 1e18))
await hardhat.mine()
})
getBalance(WETH).then((initialBalance) => {
// Swap input/output to unwrap WETH
cy.get(getTestSelector('swap-currency-button')).click()
cy.contains('Enter WETH amount')
// Enter the amount to unwrap
cy.get('#swap-currency-output .token-amount-input').type('1').should('have.value', 1)
cy.get('#swap-currency-input .token-amount-input').should('have.value', 1)
// Submit transaction
cy.contains('Unwrap').click()
cy.wait('@eth_estimateGas').wait('@eth_sendRawTransaction').wait('@eth_getTransactionReceipt')
cy.get(getTestSelector('web3-status-connected')).should('contain', '1 Pending')
// Mine transaction
cy.hardhat().then((hardhat) => hardhat.mine())
cy.wait('@eth_getTransactionReceipt')
// Verify transaction
cy.get(getTestSelector('web3-status-connected')).should('not.contain', 'Pending')
cy.get(getTestSelector('popups')).contains('Unwrapped')
const finalBalance = initialBalance - 1
cy.get('#swap-currency-input').contains(`Balance: ${finalBalance}`)
getBalance(WETH).should('equal', finalBalance)
})
})
})

View File

@ -1,16 +1,23 @@
import { getClassContainsSelector, getTestSelector } from '../utils'
import { ChainId, WETH9 } from '@uniswap/sdk-core'
import { FeatureFlag } from 'featureFlags'
import { ARB, UNI } from '../../src/constants/tokens'
import { getTestSelector } from '../utils'
const UNI_MAINNET = UNI[ChainId.MAINNET]
const UNI_ADDRESS = '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984'
describe('Token details', () => {
before(() => {
cy.visit('/')
beforeEach(() => {
cy.viewport(1440, 900)
})
it('Uniswap token should have all information populated', () => {
// Uniswap token
cy.visit(`/tokens/ethereum/${UNI_ADDRESS}`)
cy.visit(`/tokens/ethereum/${UNI_ADDRESS}`, {
featureFlags: [{ name: FeatureFlag.infoTDP, value: false }],
})
// Price chart should be filled in
cy.get('[data-cy="chart-header"]').should('include.text', '$')
cy.get('[data-cy="price-chart"]').should('exist')
@ -40,49 +47,52 @@ describe('Token details', () => {
// Contract address should be displayed
cy.contains(UNI_ADDRESS).should('exist')
})
// Swap widget should have this token pre-selected as the “destination” token
cy.get(getTestSelector('token-select')).should('include.text', 'UNI')
it('Uniswap token should have correct stats boxes if infoTDP flag on', () => {
// Uniswap token
cy.visit(`/tokens/ethereum/${UNI_ADDRESS}`, {
featureFlags: [{ name: FeatureFlag.infoTDP, value: true }],
})
// Stats should have: TVL, FDV, market cap, 24H volume
cy.get(getTestSelector('token-details-stats')).should('exist')
cy.get(getTestSelector('token-details-stats')).within(() => {
cy.get('[data-cy="tvl"]').should('include.text', '$')
cy.get('[data-cy="fdv"]').should('include.text', '$')
cy.get('[data-cy="market-cap"]').should('include.text', '$')
cy.get('[data-cy="volume-24h"]').should('include.text', '$')
})
})
it('token with warning and low trading volume should have all information populated', () => {
// Shiba predator token, low trading volume and also has warning modal
cy.visit('/tokens/ethereum/0xa71d0588EAf47f12B13cF8eC750430d21DF04974')
// Null token created for this test, 0 trading volume and has warning modal
cy.visit('/tokens/ethereum/0x1eFBB78C8b917f67986BcE54cE575069c0143681')
// Should have missing price chart when price unavailable (expected for this token)
if (cy.get('[data-cy="chart-header"]').contains('Price Unavailable')) {
if (cy.get('[data-cy="chart-header"]').contains('Price unavailable')) {
cy.get('[data-cy="missing-chart"]').should('exist')
}
// Stats should have: TVL, 24H Volume, 52W low, 52W high
cy.get(getTestSelector('token-details-stats')).should('exist')
cy.get(getTestSelector('token-details-stats')).within(() => {
cy.get('[data-cy="tvl"]').should('exist')
cy.get('[data-cy="volume-24h"]').should('exist')
cy.get('[data-cy="52w-low"]').should('exist')
cy.get('[data-cy="52w-high"]').should('exist')
})
// Stats should not exist
cy.get(getTestSelector('token-details-stats')).should('not.exist')
// About section should have description of token
cy.get(getTestSelector('token-details-about-section')).should('exist')
cy.contains('QOM is the Shiba Predator').should('exist')
cy.contains('No token information available').should('exist')
// Links section should link out to Etherscan, More analytics, Website, Twitter
// Links section should link out to Etherscan, More analytics
cy.get('[data-cy="resources-container"]').within(() => {
cy.contains('Etherscan')
.should('have.attr', 'href')
.and('include', 'etherscan.io/address/0xa71d0588EAf47f12B13cF8eC750430d21DF04974')
.and('include', 'etherscan.io/address/0x1eFBB78C8b917f67986BcE54cE575069c0143681')
cy.contains('More analytics')
.should('have.attr', 'href')
.and('include', 'info.uniswap.org/#/tokens/0xa71d0588EAf47f12B13cF8eC750430d21DF04974')
cy.contains('Website').should('have.attr', 'href').and('include', 'qom')
cy.contains('Twitter').should('have.attr', 'href').and('include', 'twitter.com/ShibaPredator1')
.and('include', 'info.uniswap.org/#/tokens/0x1eFBB78C8b917f67986BcE54cE575069c0143681')
})
// Contract address should be displayed
cy.contains('0xa71d0588EAf47f12B13cF8eC750430d21DF04974').should('exist')
// Swap widget should have this token pre-selected as the “destination” token
cy.get(getTestSelector('token-select')).should('include.text', 'QOM')
cy.contains('0x1eFBB78C8b917f67986BcE54cE575069c0143681').should('exist')
// Warning label should show if relevant ([spec](https://www.notion.so/3f7fce6f93694be08a94a6984d50298e))
cy.get('[data-cy="token-safety-message"]')
@ -90,27 +100,68 @@ describe('Token details', () => {
.and('include.text', "This token isn't traded on leading U.S. centralized exchanges")
})
describe('Swap on Token Detail Page', () => {
const verifyOutputToken = (outputText: string) => {
cy.get(getClassContainsSelector('TokenButtonRow')).last().contains(outputText)
}
describe('swapping', () => {
beforeEach(() => {
// On mobile widths, we just link back to /swap instead of rendering the swap component.
cy.viewport(1200, 800)
cy.visit(`/tokens/goerli/${UNI_ADDRESS}`).then(() => {
cy.visit(`/tokens/ethereum/${UNI_MAINNET.address}`).then(() => {
cy.wait('@eth_blockNumber')
cy.scrollTo('top')
})
})
it('should have the expected output for a tokens detail page', () => {
verifyOutputToken('UNI')
cy.get(`#swap-currency-input .token-amount-input`).should('have.value', '')
cy.get(`#swap-currency-input .token-symbol-container`).should('contain.text', 'Select token')
cy.get(`#swap-currency-output .token-amount-input`).should('not.have.value')
cy.get(`#swap-currency-output .token-symbol-container`).should('contain.text', 'UNI')
})
it('should automatically navigate to the new TDP', () => {
cy.get(`#swap-currency-output .open-currency-select-button`).click()
cy.get('[data-reach-dialog-content]').contains('WETH').click()
cy.url().should('include', `${WETH9[1].address}`)
cy.url().should('not.include', `${UNI_MAINNET.address}`)
})
it('should not share swap state with the main swap page', () => {
verifyOutputToken('UNI')
cy.get(`#swap-currency-output .token-symbol-container`).should('contain.text', 'UNI')
cy.get(`#swap-currency-input .open-currency-select-button`).click()
cy.contains('WETH').click()
cy.visit('/swap')
cy.contains('UNI').should('not.exist')
cy.contains('WETH').should('not.exist')
})
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('should show a L2 token even if the user is connected to a different network', () => {
cy.visit('/tokens')
cy.get(getTestSelector('tokens-network-filter-selected')).click()
cy.get(getTestSelector('tokens-network-filter-option-arbitrum')).click()
cy.get(getTestSelector('tokens-network-filter-selected')).should('contain', 'Arbitrum')
cy.get(getTestSelector(`token-table-row-${ARB.address.toLowerCase()}`)).click()
cy.get(`#swap-currency-output .token-symbol-container`).should('contain.text', 'ARB')
cy.get(getTestSelector('open-settings-dialog-button')).should('be.disabled')
cy.contains('Connect to Arbitrum').should('exist')
})
})
})

View File

@ -1,82 +1,29 @@
describe.skip('Token explore filter', () => {
before(() => {
cy.visit('/')
})
it('should filter correctly by uni search term', () => {
describe('Token explore filter', () => {
beforeEach(() => {
cy.visit('/tokens')
cy.get('[data-cy="token-name"]').then(($els) => {
const tokenNames = Array.from($els, (el) => el.innerText)
const filteredByUni = tokenNames.filter((tokenName) => tokenName.toLowerCase().includes('uni'))
cy.wrap(filteredByUni).as('filteredByUni')
})
cy.get('[data-cy="explore-tokens-search-input"]')
.clear()
.type('uni')
.type('{enter}')
.then(() => {
cy.get('[data-cy="token-name"]').its('length').should('be.lt', 100)
cy.get('@filteredByUni').then((filteredByUni) => {
cy.get('[data-cy="token-name"]').then(($els) => {
const tokenNames = Array.from($els, (el) => el.innerText)
expect(tokenNames.length).to.equal(filteredByUni.length)
tokenNames.forEach((tokenName) => {
expect(filteredByUni).to.include(tokenName)
})
})
})
function aliasFilteredTokens(filter: string) {
cy.get('[data-cy="token-name"]').then((tokens) => {
cy.wrap(Array.from(tokens).filter((token) => token.innerText.toLowerCase().includes(filter))).as('filteredTokens')
})
}
function searchFor(filter: string) {
cy.get('[data-cy="explore-tokens-search-input"]').clear().type(filter).type('{enter}')
// wait for it to finish the filtered render
cy.get('[data-cy="token-name"]').first().contains(filter, {
matchCase: false,
})
}
it('should filter correctly by dao search term', () => {
cy.visit('/tokens')
cy.get('[data-cy="token-name"]').then(($els) => {
const tokenNames = Array.from($els, (el) => el.innerText)
const filteredByDao = tokenNames.filter((tokenName) => tokenName.toLowerCase().includes('dao'))
cy.wrap(filteredByDao).as('filteredByDao')
})
aliasFilteredTokens('dao')
searchFor('dao')
cy.get('[data-cy="explore-tokens-search-input"]')
.clear()
.type('dao')
.type('{enter}')
.then(() => {
cy.get('[data-cy="token-name"]').its('length').should('be.lt', 100)
cy.get('@filteredByDao').then((filteredByDao) => {
cy.get('[data-cy="token-name"]').then(($els) => {
const tokenNames = Array.from($els, (el) => el.innerText)
expect(tokenNames.length).to.equal(filteredByDao.length)
tokenNames.forEach((tokenName) => {
expect(filteredByDao).to.include(tokenName)
})
})
})
})
})
it('should filter correctly by ax search term', () => {
cy.visit('/tokens')
cy.get('[data-cy="token-name"]').then(($els) => {
const tokenNames = Array.from($els, (el) => el.innerText)
const filteredByAx = tokenNames.filter((tokenName) => tokenName.toLowerCase().includes('ax'))
cy.wrap(filteredByAx).as('filteredByAx')
})
cy.get('[data-cy="explore-tokens-search-input"]')
.clear()
.type('ax')
.type('{enter}')
.then(() => {
cy.get('[data-cy="token-name"]').its('length').should('be.lt', 100)
cy.get('@filteredByAx').then((filteredByAx) => {
cy.get('[data-cy="token-name"]').then(($els) => {
const tokenNames = Array.from($els, (el) => el.innerText)
expect(tokenNames.length).to.equal(filteredByAx.length)
tokenNames.forEach((tokenName) => {
expect(filteredByAx).to.include(tokenName)
})
})
cy.get('@filteredTokens').then((filteredTokens) => {
cy.get('[data-cy="token-name"]').then((tokens) => {
cy.wrap(Array.from(tokens)).should('deep.equal', Array.from(filteredTokens))
})
})
})

View File

@ -10,11 +10,11 @@ describe('Token explore', () => {
cy.get(getTestSelectorStartsWith('token-table')).its('length').should('be.greaterThan', 0)
// 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'))
cy.get(getTestSelector('token-table-row-NATIVE')).find(getTestSelector('name-cell')).should('include.text', 'Ether')
cy.get(getTestSelector('token-table-row-NATIVE')).find(getTestSelector('volume-cell')).should('include.text', '$')
cy.get(getTestSelector('token-table-row-NATIVE')).find(getTestSelector('price-cell')).should('include.text', '$')
cy.get(getTestSelector('token-table-row-NATIVE')).find(getTestSelector('tvl-cell')).should('include.text', '$')
cy.get(getTestSelector('token-table-row-NATIVE'))
.find(getTestSelector('percent-change-cell'))
.should('include.text', '%')
cy.get(getTestSelector('header-row')).find(getTestSelector('price-cell')).click()
@ -24,24 +24,24 @@ describe('Token explore', () => {
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'))
cy.get(getTestSelector('token-table-row-NATIVE'))
.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'))
cy.get(getTestSelector('token-table-row-NATIVE'))
.find(getTestSelector('volume-cell'))
.then(function ($elem) {
cy.wrap($elem.text()).as('yearlyEthVol')
})
expect(cy.get('@dailyEthVol')).to.not.equal(cy.get('@yearlyEthVol'))
cy.get('@dailyEthVol').should('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-table-row-NATIVE')).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')
@ -53,13 +53,13 @@ describe('Token explore', () => {
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')
cy.get(getTestSelector('token-table-row-NATIVE')).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')
cy.get(getTestSelector('token-table-row-NATIVE')).find(getTestSelector('name-cell')).should('include.text', 'Matic')
})
it('should update when token explore table network changed', () => {
@ -67,8 +67,6 @@ describe('Token explore', () => {
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-logo')).invoke('attr', 'alt').should('eq', 'Ethereum')
cy.get(getTestSelector('chain-selector-logo')).find('title').should('include.text', 'Ethereum logo')
})
})

View File

@ -1,64 +1,72 @@
import { ChainId } from '@uniswap/sdk-core'
import { UNI } from 'constants/tokens'
import { getTestSelector } from '../utils'
const UNI_ADDRESS = UNI[ChainId.MAINNET].address.toLowerCase()
describe('Universal search bar', () => {
before(() => {
function openSearch() {
// can't just type "/" because on mobile it doesn't respond to that
cy.get('[data-cy="magnifying-icon"]').parent().eq(1).click()
}
beforeEach(() => {
cy.visit('/')
cy.get('[data-cy="magnifying-icon"]')
.parent()
.then(($navIcon) => {
$navIcon.click()
})
})
it('should yield clickable result for regular token or nft collection search term', () => {
// Search for uni token by name.
cy.get('[data-cy="search-bar-input"]').last().clear().type('uni')
cy.get('[data-cy="searchbar-token-row-UNI"]')
function getSearchBar() {
return cy.get('[data-cy="search-bar-input"]').last()
}
it('should yield clickable result that is then added to recent searches', () => {
// Search for UNI token by name.
openSearch()
getSearchBar().clear().type('uni')
cy.get(getTestSelector(`searchbar-token-row-ETHEREUM-${UNI_ADDRESS}`))
.should('contain.text', 'Uniswap')
.and('contain.text', 'UNI')
.and('contain.text', '$')
.and('contain.text', '%')
cy.get('[data-cy="searchbar-token-row-UNI"]').click()
.click()
cy.location('pathname').should('equal', '/tokens/ethereum/0x1f9840a85d5af5bf1d1762f925bdaddc4201f984')
cy.get('div').contains('Uniswap').should('exist')
// Stats should have: TVL, 24H Volume, 52W low, 52W high.
cy.get(getTestSelector('token-details-stats')).should('exist')
cy.get(getTestSelector('token-details-stats')).within(() => {
cy.get('[data-cy="tvl"]').should('include.text', '$')
cy.get('[data-cy="volume-24h"]').should('include.text', '$')
cy.get('[data-cy="52w-low"]').should('include.text', '$')
cy.get('[data-cy="52w-high"]').should('include.text', '$')
})
// About section should have description of token.
cy.get(getTestSelector('token-details-about-section')).should('exist')
cy.contains('UNI is the governance token for Uniswap').should('exist')
})
it.skip('should show recent tokens and popular tokens with empty search term', () => {
cy.get('[data-cy="magnifying-icon"]')
.parent()
.then(($navIcon) => {
$navIcon.click()
})
// Recently searched UNI token should exist.
cy.get('[data-cy="search-bar-input"]').last().clear()
cy.get('[data-cy="searchbar-dropdown"]')
.contains('[data-cy="searchbar-dropdown"]', 'Recent searches')
.find('[data-cy="searchbar-token-row-UNI"]')
openSearch()
cy.get(getTestSelector('searchbar-dropdown'))
.contains(getTestSelector('searchbar-dropdown'), 'Recent searches')
.find(getTestSelector(`searchbar-token-row-ETHEREUM-${UNI_ADDRESS}`))
.should('exist')
// Most popular 3 tokens should be shown.
cy.get('[data-cy="searchbar-dropdown"]')
.contains('[data-cy="searchbar-dropdown"]', 'Popular tokens')
.find('[data-cy^="searchbar-token-row"]')
.its('length')
.should('be.eq', 3)
})
it.skip('should show blocked badge when blocked token is searched for', () => {
// Search for mTSLA, which is a blocked token.
cy.get('[data-cy="search-bar-input"]').last().clear().type('mtsla')
cy.get('[data-cy="searchbar-token-row-mTSLA"]').find('[data-cy="blocked-icon"]').should('exist')
})
it(
'should go to the selected result when recent results are shown',
// this test is experiencing flake despite being correct, i can see the right value in DOM
// but for some reason cypress doesn't find it, so adding retries for now :/
{
// @ts-ignore see https://uniswapteam.slack.com/archives/C047U65H422/p1691455547556309
// basically cypress has bad types due to overlap with jest and you just have to deal with it
// i tried removing jest types but still happens
retries: {
runMode: 3,
openMode: 3,
},
},
() => {
// Seed recent results with UNI.
openSearch()
getSearchBar().type('uni')
cy.get(getTestSelector(`searchbar-token-row-ETHEREUM-${UNI_ADDRESS}`))
getSearchBar().clear().type('{esc}')
// Search a different token by name.
openSearch()
getSearchBar().type('eth')
cy.get(getTestSelector('searchbar-token-row-ETHEREUM-NATIVE'))
// Validate that we go to the searched/selected result.
cy.get(getTestSelector('searchbar-token-row-ETHEREUM-NATIVE')).click()
cy.url().should('contain', 'tokens/ethereum/NATIVE')
}
)
})

View File

@ -0,0 +1,41 @@
import { getTestSelector } from '../../utils'
import { DISCONNECTED_WALLET_USER_STATE } from '../../utils/user-state'
describe('disconnect wallet', () => {
it('should clear state', () => {
cy.visit('/swap')
cy.get('#swap-currency-input .token-amount-input').clear().type('1')
// Verify wallet is connected
cy.hardhat().then((hardhat) => cy.contains(hardhat.wallet.address.substring(0, 6)))
cy.contains('Balance:')
// Disconnect the wallet
cy.hardhat().then((hardhat) => cy.contains(hardhat.wallet.address.substring(0, 6)).click())
cy.get(getTestSelector('wallet-disconnect')).click()
cy.get(getTestSelector('wallet-disconnect')).contains('Disconnect')
cy.get(getTestSelector('wallet-disconnect')).click()
// Verify wallet has disconnected
cy.contains('Connect a wallet').should('exist')
cy.get(getTestSelector('navbar-connect-wallet')).contains('Connect')
cy.contains('Connect wallet')
// Verify swap input is cleared
cy.get('#swap-currency-input .token-amount-input').should('have.value', '1')
})
})
describe('connect wallet', () => {
it('should load state', () => {
cy.visit('/swap', { userState: DISCONNECTED_WALLET_USER_STATE })
// Connect the wallet
cy.get(getTestSelector('navbar-connect-wallet')).contains('Connect').click()
cy.contains('MetaMask').click()
// Verify wallet is connected
cy.hardhat().then((hardhat) => cy.contains(hardhat.wallet.address.substring(0, 6)))
cy.contains('Balance:')
})
})

View File

@ -0,0 +1,144 @@
import { createDeferredPromise } from '../../../src/test-utils/promise'
import { getTestSelector } from '../../utils'
function waitsForActiveChain(chain: string) {
cy.get(getTestSelector('chain-selector-logo')).find('title').should('include.text', `${chain} logo`)
}
function switchChain(chain: string) {
cy.get(getTestSelector('chain-selector')).eq(1).click()
cy.contains(chain).click()
}
describe('network switching', () => {
beforeEach(() => {
cy.visit('/swap')
cy.get(getTestSelector('web3-status-connected'))
})
function rejectsNetworkSwitchWith(rejection: unknown) {
cy.hardhat().then((hardhat) => {
// Reject network switch
const sendStub = cy.stub(hardhat.provider, 'send').log(false).as('switch')
sendStub.withArgs('wallet_switchEthereumChain').rejects(rejection)
sendStub.callThrough() // allows other calls to return non-stubbed values
})
switchChain('Polygon')
// Verify rejected network switch
cy.get('@switch').should('have.been.calledWith', 'wallet_switchEthereumChain')
waitsForActiveChain('Ethereum')
cy.get(getTestSelector('web3-status-connected'))
}
it('should not display message on user rejection', () => {
const USER_REJECTION = { code: 4001 }
rejectsNetworkSwitchWith(USER_REJECTION)
cy.get(getTestSelector('popups')).should('not.contain', 'Failed to switch networks')
})
it('should display message on unknown error', () => {
rejectsNetworkSwitchWith(new Error('Unknown error'))
cy.get(getTestSelector('popups')).contains('Failed to switch networks')
})
it('should add missing chain', () => {
cy.hardhat().then((hardhat) => {
// https://docs.metamask.io/guide/rpc-api.html#unrestricted-methods
const CHAIN_NOT_ADDED = { code: 4902 } // missing message in useSelectChain
// Reject network switch with CHAIN_NOT_ADDED
const sendStub = cy.stub(hardhat.provider, 'send').log(false).as('switch')
let added = false
sendStub
.withArgs('wallet_switchEthereumChain')
.callsFake(() => (added ? Promise.resolve(null) : Promise.reject(CHAIN_NOT_ADDED)))
sendStub.withArgs('wallet_addEthereumChain').callsFake(() => {
added = true
return Promise.resolve(null)
})
sendStub.callThrough() // allows other calls to return non-stubbed values
})
switchChain('Polygon')
// Verify the network was added
cy.get('@switch').should('have.been.calledWith', 'wallet_switchEthereumChain')
cy.get('@switch').should('have.been.calledWith', 'wallet_addEthereumChain', [
{
blockExplorerUrls: ['https://polygonscan.com/'],
chainId: '0x89',
chainName: 'Polygon',
nativeCurrency: { name: 'Polygon Matic', symbol: 'MATIC', decimals: 18 },
rpcUrls: ['https://polygon-rpc.com/'],
},
])
})
it('should not disconnect while switching', () => {
const promise = createDeferredPromise()
cy.hardhat().then((hardhat) => {
// Reject network switch with CHAIN_NOT_ADDED
const sendStub = cy.stub(hardhat.provider, 'send').log(false).as('switch')
sendStub.withArgs('wallet_switchEthereumChain').returns(promise)
sendStub.callThrough() // allows other calls to return non-stubbed values
})
switchChain('Polygon')
// Verify there is no disconnection
cy.get('@switch').should('have.been.calledWith', 'wallet_switchEthereumChain')
cy.contains('Connecting to Polygon')
cy.get(getTestSelector('web3-status-connected')).should('be.disabled')
promise.resolve()
})
it('should switch networks', () => {
// Select an output currency
cy.get('#swap-currency-output .open-currency-select-button').click()
cy.contains('USDC').click()
// Populate input/output fields
cy.get('#swap-currency-input .token-amount-input').clear().type('1')
cy.get('#swap-currency-output .token-amount-input').should('not.equal', '')
// Switch network
switchChain('Polygon')
// Verify network switch
cy.wait('@wallet_switchEthereumChain')
waitsForActiveChain('Polygon')
cy.get(getTestSelector('web3-status-connected'))
cy.url().should('contain', 'chain=polygon')
// Verify that the input/output fields were reset
cy.get('#swap-currency-input .token-amount-input').should('have.value', '')
cy.get(`#swap-currency-input .token-symbol-container`).should('contain.text', 'MATIC')
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')
})
})
describe('network switching from URL param', () => {
it('should switch network from URL param', () => {
cy.visit('/swap?chain=polygon')
cy.get(getTestSelector('web3-status-connected'))
cy.wait('@wallet_switchEthereumChain')
waitsForActiveChain('Polygon')
})
it('should be able to switch network after loading from URL param', () => {
cy.visit('/swap?chain=polygon')
cy.get(getTestSelector('web3-status-connected'))
cy.wait('@wallet_switchEthereumChain')
waitsForActiveChain('Polygon')
// switching to another chain clears query param
switchChain('Ethereum')
cy.wait('@wallet_switchEthereumChain')
waitsForActiveChain('Ethereum')
cy.url().should('not.contain', 'chain=polygon')
})
})

View File

@ -1,28 +1,10 @@
import { FeatureFlag } from 'featureFlags'
import { getTestSelector } from '../utils'
function visit(darkMode: boolean) {
cy.visit('/swap', {
onBeforeLoad(win) {
cy.stub(win, 'matchMedia')
.withArgs('(prefers-color-scheme: dark)')
.returns({
matches: darkMode,
addEventListener() {
// do nothing
},
})
},
})
}
describe('Wallet Dropdown', () => {
before(() => {
cy.visit('/pools')
})
it('should change the theme', () => {
cy.get(getTestSelector('web3-status-connected')).click()
cy.get(getTestSelector('wallet-settings')).click()
function itChangesTheme() {
it('should change theme', () => {
cy.get(getTestSelector('theme-lightmode')).click()
cy.get(getTestSelector('theme-lightmode')).should('not.have.css', 'background-color', 'rgba(0, 0, 0, 0)')
@ -39,58 +21,185 @@ describe('Wallet Dropdown', () => {
cy.get(getTestSelector('theme-darkmode')).should('have.css', 'background-color', 'rgba(0, 0, 0, 0)')
cy.get(getTestSelector('theme-auto')).should('not.have.css', 'background-color', 'rgba(0, 0, 0, 0)')
})
}
function itChangesLocale({ featureFlag = false }: { featureFlag?: boolean } = {}) {
it('should change locale', () => {
cy.contains('Uniswap available in: English').should('not.exist')
if (featureFlag) {
cy.get(getTestSelector('language-settings-button')).click()
}
cy.get(getTestSelector('wallet-language-item')).contains('Afrikaans').click({ force: true })
cy.location('search').should('match', /\?lng=af-ZA$/)
cy.contains('Uniswap available in: English')
it('should select a language', () => {
cy.get(getTestSelector('wallet-language-item')).contains('Deutsch').click({ force: true })
cy.get(getTestSelector('wallet-header')).should('contain', 'Sprache')
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()
cy.location('search').should('match', /\?lng=en-US$/)
cy.contains('Uniswap available in: English').should('not.exist')
})
}
describe('connected', () => {
beforeEach(() => {
cy.visit('/')
cy.get(getTestSelector('web3-status-connected')).click()
cy.get(getTestSelector('wallet-settings')).click()
})
itChangesTheme()
itChangesLocale()
it('should not show buy crypto button in uk', () => {
cy.document().then((doc) => {
const meta = document.createElement('meta')
meta.setAttribute('property', 'x:blocked-paths')
meta.setAttribute('content', '/,/nfts,/buy')
doc.head.appendChild(meta)
})
cy.get(getTestSelector('wallet-buy-crypto')).should('not.exist')
})
})
it('should change the theme when not connected', () => {
describe('do not render buy button when /buy is blocked', () => {
beforeEach(() => {
cy.document().then((doc) => {
const meta = document.createElement('meta')
meta.setAttribute('property', 'x:blocked-paths')
meta.setAttribute('content', '/buy')
doc.head.appendChild(meta)
})
cy.visit('/')
cy.get(getTestSelector('web3-status-connected')).click()
cy.get(getTestSelector('wallet-settings')).click()
})
it('should not render buy button', () => {
cy.get(getTestSelector('wallet-buy-crypto')).should('not.exist')
})
})
describe('should change locale with feature flag', () => {
beforeEach(() => {
cy.visit('/', { featureFlags: [{ name: FeatureFlag.currencyConversion, value: true }] })
cy.get(getTestSelector('web3-status-connected')).click()
cy.get(getTestSelector('wallet-settings')).click()
})
itChangesLocale({ featureFlag: true })
})
describe('testnet toggle', () => {
beforeEach(() => {
cy.visit('/swap')
})
it('should toggle testnet visibility', () => {
cy.get(getTestSelector('chain-selector')).last().click()
cy.get(getTestSelector('chain-selector-options')).should('not.contain.text', 'Sepolia')
cy.get(getTestSelector('web3-status-connected')).click()
cy.get(getTestSelector('wallet-settings')).click()
cy.get('#testnets-toggle').click()
cy.get(getTestSelector('close-account-drawer')).click()
cy.get(getTestSelector('chain-selector')).last().click()
cy.get(getTestSelector('chain-selector-options')).should('contain.text', 'Sepolia')
})
})
describe('disconnected', () => {
beforeEach(() => {
cy.visit('/')
cy.get(getTestSelector('web3-status-connected')).click()
// click twice, first time to show confirmation, second to confirm
cy.get(getTestSelector('wallet-disconnect')).click()
cy.get(getTestSelector('wallet-disconnect')).should('contain', 'Disconnect')
cy.get(getTestSelector('wallet-disconnect')).click()
cy.get(getTestSelector('wallet-settings')).click()
cy.get(getTestSelector('theme-lightmode')).should('exist')
})
itChangesTheme()
itChangesLocale()
})
it('should select a language when not connected', () => {
cy.get(getTestSelector('wallet-language-item')).contains('Deutsch').click({ force: true })
cy.get(getTestSelector('wallet-header')).should('contain', 'Sprache')
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()
describe('with color theme', () => {
function visitSwapWithColorTheme({ dark }: { dark: boolean }) {
cy.visit('/swap', {
onBeforeLoad(win) {
cy.stub(win, 'matchMedia')
.withArgs('(prefers-color-scheme: dark)')
.returns({
matches: dark,
addEventListener() {
/* noop */
},
removeEventListener() {
/* noop */
},
})
},
})
}
it('should properly use dark system theme when auto theme setting is selected', () => {
visit(true)
visitSwapWithColorTheme({ dark: true })
cy.get(getTestSelector('web3-status-connected')).click()
cy.get(getTestSelector('wallet-settings')).click()
cy.get(getTestSelector('theme-auto')).click()
cy.get(getTestSelector('wallet-header')).should('have.css', 'color', 'rgb(152, 161, 192)')
cy.get(getTestSelector('wallet-header')).should('have.css', 'color', 'rgb(155, 155, 155)')
})
it('should properly use light system theme when auto theme setting is selected', () => {
visit(false)
visitSwapWithColorTheme({ dark: false })
cy.get(getTestSelector('web3-status-connected')).click()
cy.get(getTestSelector('wallet-settings')).click()
cy.get(getTestSelector('theme-auto')).click()
cy.get(getTestSelector('wallet-header')).should('have.css', 'color', 'rgb(119, 128, 160)')
cy.get(getTestSelector('wallet-header')).should('have.css', 'color', 'rgb(125, 125, 125)')
})
})
describe('mobile', () => {
beforeEach(() => {
cy.viewport('iphone-6').visit('/')
})
it('should dismiss the wallet bottom sheet when clicking buy crypto', () => {
visit(false)
cy.viewport('iphone-6')
cy.get(getTestSelector('web3-status-connected')).click()
cy.get(getTestSelector('wallet-buy-crypto')).click()
cy.contains('Buy crypto').should('not.be.visible')
})
it('should use a bottom sheet and dismiss when on a mobile screen size', () => {
visit(true)
cy.viewport('iphone-6')
cy.get(getTestSelector('web3-status-connected')).click()
cy.root().click(15, 40)
cy.get(getTestSelector('wallet-settings')).should('not.be.visible')
})
})
describe('local currency', () => {
it('loads local currency from the query param', () => {
cy.visit('/', { featureFlags: [{ name: FeatureFlag.currencyConversion, value: true }] })
cy.get(getTestSelector('web3-status-connected')).click()
cy.get(getTestSelector('wallet-settings')).click()
cy.contains('USD')
cy.visit('/?cur=AUD', { featureFlags: [{ name: FeatureFlag.currencyConversion, value: true }] })
cy.get(getTestSelector('web3-status-connected')).click()
cy.get(getTestSelector('wallet-settings')).click()
cy.contains('AUD')
})
it('loads local currency from menu', () => {
cy.visit('/', { featureFlags: [{ name: FeatureFlag.currencyConversion, value: true }] })
cy.get(getTestSelector('web3-status-connected')).click()
cy.get(getTestSelector('wallet-settings')).click()
cy.contains('USD')
cy.get(getTestSelector('local-currency-settings-button')).click()
cy.get(getTestSelector('wallet-local-currency-item')).contains('AUD').click({ force: true })
cy.location('search').should('match', /\?cur=AUD$/)
cy.contains('AUD')
cy.get(getTestSelector('wallet-local-currency-item')).contains('USD').click({ force: true })
cy.location('search').should('match', /\?cur=USD$/)
cy.contains('USD')
})
})
})

View File

@ -1 +0,0 @@
export const WETH_GOERLI = '0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6'

View File

@ -0,0 +1,5 @@
{
"errorCode": "QUOTE_ERROR",
"detail": "No quotes available",
"id": "63363cc1-d474-4584-b386-7c356814b79f"
}

View File

@ -0,0 +1,12 @@
{
"data": {
"portfolios": [
{
"id": "UG9ydGZvbGlvOjB4ZjM5RmQ2ZTUxYWFkODhGNkY0Y2U2YUI4ODI3Mjc5Y2ZmRmI5MjI2Ng==",
"assetActivities": [],
"__typename": "Portfolio"
}
]
},
"errors": []
}

View File

@ -0,0 +1,580 @@
{
"data": {
"portfolios": [
{
"id": "UG9ydGZvbGlvOjB4ZjM5RmQ2ZTUxYWFkODhGNkY0Y2U2YUI4ODI3Mjc5Y2ZmRmI5MjI2Ng==",
"assetActivities": [
{
"id": "QXNzZXRBY3Rpdml0eTpWSEpoYm5OaFkzUnBiMjQ2TUhnM09EQm1NamcwTURSak1qRXpPRGd6TVRVM00yRXdOakJtTVRaaE1UQTNaV0ZtTW1Jd01qazFZbUZqTmpjNU5tUm1ZamN5TW1WbVl6VmpPVE5tTmpRM1h6QjRaak01Wm1RMlpUVXhZV0ZrT0RobU5tWTBZMlUyWVdJNE9ESTNNamM1WTJabVptSTVNakkyTmw4d2VEQXdNREF3TURBek1HWTBPV0ptTW1Vd01ESmxOakJqTm1Wa01UWTJNV1ppTWpNME5tUTRPREk9",
"timestamp": 1684364195,
"chain": "ETHEREUM",
"details": {
"__typename": "TransactionDetails",
"id": "VHJhbnNhY3Rpb246MHg3ODBmMjg0MDRjMjEzODgzMTU3M2EwNjBmMTZhMTA3ZWFmMmIwMjk1YmFjNjc5NmRmYjcyMmVmYzVjOTNmNjQ3XzB4ZjM5ZmQ2ZTUxYWFkODhmNmY0Y2U2YWI4ODI3Mjc5Y2ZmZmI5MjI2Nl8weDAwMDAwMDAzMGY0OWJmMmUwMDJlNjBjNmVkMTY2MWZiMjM0NmQ4ODI=",
"type": "UNKNOWN",
"blockNumber": 17282434,
"hash": "0x780f28404c2138831573a060f16a107eaf2b0295bac6796dfb722efc5c93f647",
"status": "CONFIRMED",
"to": "0x000000030f49bf2e002e60c6ed1661fb2346d882",
"from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266",
"nonce": 465,
"assetChanges": []
},
"__typename": "AssetActivity"
},
{
"id": "QXNzZXRBY3Rpdml0eTpWSEpoYm5OaFkzUnBiMjQ2TUhobFl6QTROMkpoTjJJMk4yUTFPVEEwTVdNMU5XTXdObU16TkdNNVlXVmhPVEUxTkRreVpUYzRNRFl4WldRd016TTBNMlprWmprMU1qa3dPR1U0WTJSa1h6QjRaR0psWmpNM05HWmtaamhrTnpNMVpUYzFPRGxoT1dFNVpUSmpOV0V3T1RGbFlqSmtZbVUxTjE4d2VHWXpPV1prTm1VMU1XRmhaRGc0WmpabU5HTmxObUZpT0RneU56STNPV05tWm1aaU9USXlOalk9",
"timestamp": 1684364135,
"chain": "ETHEREUM",
"details": {
"__typename": "TransactionDetails",
"id": "VHJhbnNhY3Rpb246MHhlYzA4N2JhN2I2N2Q1OTA0MWM1NWMwNmMzNGM5YWVhOTE1NDkyZTc4MDYxZWQwMzM0M2ZkZjk1MjkwOGU4Y2RkXzB4ZGJlZjM3NGZkZjhkNzM1ZTc1ODlhOWE5ZTJjNWEwOTFlYjJkYmU1N18weGYzOWZkNmU1MWFhZDg4ZjZmNGNlNmFiODgyNzI3OWNmZmZiOTIyNjY=",
"type": "RECEIVE",
"blockNumber": 17282429,
"hash": "0xec087ba7b67d59041c55c06c34c9aea915492e78061ed03343fdf952908e8cdd",
"status": "CONFIRMED",
"to": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266",
"from": "0xdbef374fdf8d735e7589a9a9e2c5a091eb2dbe57",
"nonce": 66,
"assetChanges": [
{
"__typename": "TokenTransfer",
"id": "VG9rZW5UcmFuc2ZlcjoweGRiZWYzNzRmZGY4ZDczNWU3NTg5YTlhOWUyYzVhMDkxZWIyZGJlNTdfMHhmMzlmZDZlNTFhYWQ4OGY2ZjRjZTZhYjg4MjcyNzljZmZmYjkyMjY2XzB4ZWMwODdiYTdiNjdkNTkwNDFjNTVjMDZjMzRjOWFlYTkxNTQ5MmU3ODA2MWVkMDMzNDNmZGY5NTI5MDhlOGNkZA==",
"asset": {
"id": "VG9rZW46RVRIRVJFVU1fbnVsbA==",
"name": "Ether",
"symbol": "ETH",
"address": null,
"decimals": 18,
"chain": "ETHEREUM",
"standard": null,
"project": {
"id": "VG9rZW5Qcm9qZWN0OkVUSEVSRVVNX251bGw=",
"isSpam": false,
"logo": {
"id": "SW1hZ2U6aHR0cHM6Ly90b2tlbi1pY29ucy5zMy5hbWF6b25hd3MuY29tL2V0aC5wbmc=",
"url": "https://token-icons.s3.amazonaws.com/eth.png",
"__typename": "Image"
},
"__typename": "TokenProject"
},
"__typename": "Token"
},
"tokenStandard": "NATIVE",
"quantity": "0.001",
"sender": "0xdbef374fdf8d735e7589a9a9e2c5a091eb2dbe57",
"recipient": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266",
"direction": "IN",
"transactedValue": {
"id": "QW1vdW50OjEuODI5NjcwMDAwMDAwMDAwMV9VU0Q=",
"currency": "USD",
"value": 1.8296700000000001,
"__typename": "Amount"
}
}
]
},
"__typename": "AssetActivity"
},
{
"id": "QXNzZXRBY3Rpdml0eTpWSEpoYm5OaFkzUnBiMjQ2TUhoaE9URXdPVFEwT1Rka01UVmpNelpsWWprd1pXUXpZVEkwWW1Wa09ESTBOalpqWmpKaU9URXpNV1l4WkRVMk1EUmlNelppWW1aallqRTBOMkUzTURnNFh6QjRaV1JoTldVeE9ERXhORFppTVdZNVlUZG1OREJtT0RWak1HUmhNek0wT1RNNE5ESXdaRFV4TkY4d2VHWXpPV1prTm1VMU1XRmhaRGc0WmpabU5HTmxObUZpT0RneU56STNPV05tWm1aaU9USXlOalk9",
"timestamp": 1684319903,
"chain": "ETHEREUM",
"details": {
"id": "VHJhbnNhY3Rpb246MHhhOTEwOTQ0OTdkMTVjMzZlYjkwZWQzYTI0YmVkODI0NjZjZjJiOTEzMWYxZDU2MDRiMzZiYmZjYjE0N2E3MDg4XzB4ZWRhNWUxODExNDZiMWY5YTdmNDBmODVjMGRhMzM0OTM4NDIwZDUxNF8weGYzOWZkNmU1MWFhZDg4ZjZmNGNlNmFiODgyNzI3OWNmZmZiOTIyNjY=",
"type": "RECEIVE",
"blockNumber": 17278819,
"hash": "0xa91094497d15c36eb90ed3a24bed82466cf2b9131f1d5604b36bbfcb147a7088",
"status": "CONFIRMED",
"to": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266",
"from": "0xeda5e181146b1f9a7f40f85c0da334938420d514",
"nonce": 5,
"__typename": "TransactionDetails",
"assetChanges": [
{
"__typename": "TokenTransfer",
"id": "VG9rZW5UcmFuc2ZlcjoweGVkYTVlMTgxMTQ2YjFmOWE3ZjQwZjg1YzBkYTMzNDkzODQyMGQ1MTRfMHhmMzlmZDZlNTFhYWQ4OGY2ZjRjZTZhYjg4MjcyNzljZmZmYjkyMjY2XzB4YTkxMDk0NDk3ZDE1YzM2ZWI5MGVkM2EyNGJlZDgyNDY2Y2YyYjkxMzFmMWQ1NjA0YjM2YmJmY2IxNDdhNzA4OA==",
"asset": {
"id": "VG9rZW46RVRIRVJFVU1fbnVsbA==",
"name": "Ether",
"symbol": "ETH",
"address": null,
"decimals": 18,
"chain": "ETHEREUM",
"standard": null,
"project": {
"id": "VG9rZW5Qcm9qZWN0OkVUSEVSRVVNX251bGw=",
"isSpam": false,
"logo": {
"id": "SW1hZ2U6aHR0cHM6Ly90b2tlbi1pY29ucy5zMy5hbWF6b25hd3MuY29tL2V0aC5wbmc=",
"url": "https://token-icons.s3.amazonaws.com/eth.png",
"__typename": "Image"
},
"__typename": "TokenProject"
},
"__typename": "Token"
},
"tokenStandard": "NATIVE",
"quantity": "0.15",
"sender": "0xeda5e181146b1f9a7f40f85c0da334938420d514",
"recipient": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266",
"direction": "IN",
"transactedValue": {
"id": "QW1vdW50OjI3NC40NTA1X1VTRA==",
"currency": "USD",
"value": 274.4505,
"__typename": "Amount"
}
}
]
},
"__typename": "AssetActivity"
},
{
"id": "QXNzZXRBY3Rpdml0eTpWSEpoYm5OaFkzUnBiMjQ2TUhnMFkyUm1Nell6T0dRME1ERXdOV1U1WkRZMVlUZGxObUV6WVdFMlpHTXpNREZpWVRNNVpHTXlNV1ppT0dGaE5USTBNVFppT1ROaE5tWXhOVEUwTWpReVh6QjRaak01Wm1RMlpUVXhZV0ZrT0RobU5tWTBZMlUyWVdJNE9ESTNNamM1WTJabVptSTVNakkyTmw4d2VHUmxOR1F6WVRJME5XUXlZall4WW1WaE1tTmlaREl4TmpVNE1XVXlaR1ZrTmpWbFl6azFNRFE9",
"timestamp": 1684319903,
"chain": "ETHEREUM",
"details": {
"id": "VHJhbnNhY3Rpb246MHg0Y2RmMzYzOGQ0MDEwNWU5ZDY1YTdlNmEzYWE2ZGMzMDFiYTM5ZGMyMWZiOGFhNTI0MTZiOTNhNmYxNTE0MjQyXzB4ZjM5ZmQ2ZTUxYWFkODhmNmY0Y2U2YWI4ODI3Mjc5Y2ZmZmI5MjI2Nl8weGRlNGQzYTI0NWQyYjYxYmVhMmNiZDIxNjU4MWUyZGVkNjVlYzk1MDQ=",
"type": "SEND",
"blockNumber": 17278819,
"hash": "0x4cdf3638d40105e9d65a7e6a3aa6dc301ba39dc21fb8aa52416b93a6f1514242",
"status": "CONFIRMED",
"to": "0xde4d3a245d2b61bea2cbd216581e2ded65ec9504",
"from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266",
"nonce": 464,
"__typename": "TransactionDetails",
"assetChanges": [
{
"__typename": "TokenTransfer",
"id": "VG9rZW5UcmFuc2ZlcjoweGYzOWZkNmU1MWFhZDg4ZjZmNGNlNmFiODgyNzI3OWNmZmZiOTIyNjZfMHhkZTRkM2EyNDVkMmI2MWJlYTJjYmQyMTY1ODFlMmRlZDY1ZWM5NTA0XzB4NGNkZjM2MzhkNDAxMDVlOWQ2NWE3ZTZhM2FhNmRjMzAxYmEzOWRjMjFmYjhhYTUyNDE2YjkzYTZmMTUxNDI0Mg==",
"asset": {
"id": "VG9rZW46RVRIRVJFVU1fbnVsbA==",
"name": "Ether",
"symbol": "ETH",
"address": null,
"decimals": 18,
"chain": "ETHEREUM",
"standard": null,
"project": {
"id": "VG9rZW5Qcm9qZWN0OkVUSEVSRVVNX251bGw=",
"isSpam": false,
"logo": {
"id": "SW1hZ2U6aHR0cHM6Ly90b2tlbi1pY29ucy5zMy5hbWF6b25hd3MuY29tL2V0aC5wbmc=",
"url": "https://token-icons.s3.amazonaws.com/eth.png",
"__typename": "Image"
},
"__typename": "TokenProject"
},
"__typename": "Token"
},
"tokenStandard": "NATIVE",
"quantity": "0.00134999999999999",
"sender": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266",
"recipient": "0xde4d3a245d2b61bea2cbd216581e2ded65ec9504",
"direction": "OUT",
"transactedValue": {
"id": "QW1vdW50OjIuNDcwMDU0NDk5OTk5OTgyX1VTRA==",
"currency": "USD",
"value": 2.470054499999982,
"__typename": "Amount"
}
}
]
},
"__typename": "AssetActivity"
},
{
"id": "QXNzZXRBY3Rpdml0eTpWSEpoYm5OaFkzUnBiMjQ2TUhnM04yRXhPVGRoWmpjek9EUXpNRFk0WVRCaVlqUmlaV1V6WWpabFptWmxaakpsTkdZMFptTXlNR1UxWVRGbVltSTBOak14WXpoak1UQTROMk15WWpjM1h6QjRaak01Wm1RMlpUVXhZV0ZrT0RobU5tWTBZMlUyWVdJNE9ESTNNamM1WTJabVptSTVNakkyTmw4d2VHWTFZekZoTnpCbU5qY3pPV0k1TW1ZNU4yTmtOVE5qTXpFMk1ETTJNbU14TXpBMVpUa3hZVGc9",
"timestamp": 1684202579,
"chain": "ETHEREUM",
"details": {
"id": "VHJhbnNhY3Rpb246MHg3N2ExOTdhZjczODQzMDY4YTBiYjRiZWUzYjZlZmZlZjJlNGY0ZmMyMGU1YTFmYmI0NjMxYzhjMTA4N2MyYjc3XzB4ZjM5ZmQ2ZTUxYWFkODhmNmY0Y2U2YWI4ODI3Mjc5Y2ZmZmI5MjI2Nl8weGY1YzFhNzBmNjczOWI5MmY5N2NkNTNjMzE2MDM2MmMxMzA1ZTkxYTg=",
"type": "SEND",
"blockNumber": 17269191,
"hash": "0x77a197af73843068a0bb4bee3b6effef2e4f4fc20e5a1fbb4631c8c1087c2b77",
"status": "CONFIRMED",
"to": "0xf5c1a70f6739b92f97cd53c3160362c1305e91a8",
"from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266",
"nonce": 463,
"__typename": "TransactionDetails",
"assetChanges": [
{
"__typename": "TokenTransfer",
"id": "VG9rZW5UcmFuc2ZlcjoweGYzOWZkNmU1MWFhZDg4ZjZmNGNlNmFiODgyNzI3OWNmZmZiOTIyNjZfMHhmNWMxYTcwZjY3MzliOTJmOTdjZDUzYzMxNjAzNjJjMTMwNWU5MWE4XzB4NzdhMTk3YWY3Mzg0MzA2OGEwYmI0YmVlM2I2ZWZmZWYyZTRmNGZjMjBlNWExZmJiNDYzMWM4YzEwODdjMmI3Nw==",
"asset": {
"id": "VG9rZW46RVRIRVJFVU1fbnVsbA==",
"name": "Ether",
"symbol": "ETH",
"address": null,
"decimals": 18,
"chain": "ETHEREUM",
"standard": null,
"project": {
"id": "VG9rZW5Qcm9qZWN0OkVUSEVSRVVNX251bGw=",
"isSpam": false,
"logo": {
"id": "SW1hZ2U6aHR0cHM6Ly90b2tlbi1pY29ucy5zMy5hbWF6b25hd3MuY29tL2V0aC5wbmc=",
"url": "https://token-icons.s3.amazonaws.com/eth.png",
"__typename": "Image"
},
"__typename": "TokenProject"
},
"__typename": "Token"
},
"tokenStandard": "NATIVE",
"quantity": "0.001216034894406018",
"sender": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266",
"recipient": "0xf5c1a70f6739b92f97cd53c3160362c1305e91a8",
"direction": "OUT",
"transactedValue": {
"id": "QW1vdW50OjIuMjI0OTQyNTY1MjQ3ODU5X1VTRA==",
"currency": "USD",
"value": 2.224942565247859,
"__typename": "Amount"
}
}
]
},
"__typename": "AssetActivity"
},
{
"id": "QXNzZXRBY3Rpdml0eTpWSEpoYm5OaFkzUnBiMjQ2TUhnMlpXSmtZbVJrTVRZMk0yVmxNV1ZrT0RVeE16TXlZelUyWmpkall6YzJaV1ZqTVROaE5qTm1PVEkxTldOa1ltWXlZVEUxWWpReFl6azBPVGhrWW1Wa1h6QjROREZpTXpBNU1qTTJZemczWWpGaVl6Wm1ZVGhsWWpnMk5UZ3pNMlUwTkRFMU9HWmhPVGt4WVY4d2VHWXpPV1prTm1VMU1XRmhaRGc0WmpabU5HTmxObUZpT0RneU56STNPV05tWm1aaU9USXlOalk9",
"timestamp": 1684202579,
"chain": "ETHEREUM",
"details": {
"id": "VHJhbnNhY3Rpb246MHg2ZWJkYmRkMTY2M2VlMWVkODUxMzMyYzU2ZjdjYzc2ZWVjMTNhNjNmOTI1NWNkYmYyYTE1YjQxYzk0OThkYmVkXzB4NDFiMzA5MjM2Yzg3YjFiYzZmYThlYjg2NTgzM2U0NDE1OGZhOTkxYV8weGYzOWZkNmU1MWFhZDg4ZjZmNGNlNmFiODgyNzI3OWNmZmZiOTIyNjY=",
"type": "RECEIVE",
"blockNumber": 17269191,
"hash": "0x6ebdbdd1663ee1ed851332c56f7cc76eec13a63f9255cdbf2a15b41c9498dbed",
"status": "CONFIRMED",
"to": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266",
"from": "0x41b309236c87b1bc6fa8eb865833e44158fa991a",
"nonce": 111266,
"__typename": "TransactionDetails",
"assetChanges": [
{
"__typename": "TokenTransfer",
"id": "VG9rZW5UcmFuc2ZlcjoweDQxYjMwOTIzNmM4N2IxYmM2ZmE4ZWI4NjU4MzNlNDQxNThmYTk5MWFfMHhmMzlmZDZlNTFhYWQ4OGY2ZjRjZTZhYjg4MjcyNzljZmZmYjkyMjY2XzB4NmViZGJkZDE2NjNlZTFlZDg1MTMzMmM1NmY3Y2M3NmVlYzEzYTYzZjkyNTVjZGJmMmExNWI0MWM5NDk4ZGJlZA==",
"asset": {
"id": "VG9rZW46RVRIRVJFVU1fbnVsbA==",
"name": "Ether",
"symbol": "ETH",
"address": null,
"decimals": 18,
"chain": "ETHEREUM",
"standard": null,
"project": {
"id": "VG9rZW5Qcm9qZWN0OkVUSEVSRVVNX251bGw=",
"isSpam": false,
"logo": {
"id": "SW1hZ2U6aHR0cHM6Ly90b2tlbi1pY29ucy5zMy5hbWF6b25hd3MuY29tL2V0aC5wbmc=",
"url": "https://token-icons.s3.amazonaws.com/eth.png",
"__typename": "Image"
},
"__typename": "TokenProject"
},
"__typename": "Token"
},
"tokenStandard": "NATIVE",
"quantity": "0.00275365",
"sender": "0x41b309236c87b1bc6fa8eb865833e44158fa991a",
"recipient": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266",
"direction": "IN",
"transactedValue": {
"id": "QW1vdW50OjUuMDM4MjcwNzk1NV9VU0Q=",
"currency": "USD",
"value": 5.0382707955,
"__typename": "Amount"
}
}
]
},
"__typename": "AssetActivity"
},
{
"id": "QXNzZXRBY3Rpdml0eTpWSEpoYm5OaFkzUnBiMjQ2TUhnNU5EUmlNR00wTVROa1l6QmpNekU0TUdFelkyTTNZakUyT1RCbVlqZzBNRFExWm1FME9UTXpObUV5WmprNE16VmpORFpqTURsak1UY3lObUUzTm1aalh6QjRaak01Wm1RMlpUVXhZV0ZrT0RobU5tWTBZMlUyWVdJNE9ESTNNamM1WTJabVptSTVNakkyTmw4d2VEWXlNakJsTURoak9XUTJNMkZpTjJKaE1tVTFOalk0TXpsbU5ESTVaV1ZsWm1VeE9UbGlOMlU9",
"timestamp": 1684171943,
"chain": "ETHEREUM",
"details": {
"id": "VHJhbnNhY3Rpb246MHg5NDRiMGM0MTNkYzBjMzE4MGEzY2M3YjE2OTBmYjg0MDQ1ZmE0OTMzNmEyZjk4MzVjNDZjMDljMTcyNmE3NmZjXzB4ZjM5ZmQ2ZTUxYWFkODhmNmY0Y2U2YWI4ODI3Mjc5Y2ZmZmI5MjI2Nl8weDYyMjBlMDhjOWQ2M2FiN2JhMmU1NjY4MzlmNDI5ZWVlZmUxOTliN2U=",
"type": "SEND",
"blockNumber": 17266680,
"hash": "0x944b0c413dc0c3180a3cc7b1690fb84045fa49336a2f9835c46c09c1726a76fc",
"status": "CONFIRMED",
"to": "0x6220e08c9d63ab7ba2e566839f429eeefe199b7e",
"from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266",
"nonce": 462,
"__typename": "TransactionDetails",
"assetChanges": [
{
"__typename": "TokenTransfer",
"id": "VG9rZW5UcmFuc2ZlcjoweGYzOWZkNmU1MWFhZDg4ZjZmNGNlNmFiODgyNzI3OWNmZmZiOTIyNjZfMHg2MjIwZTA4YzlkNjNhYjdiYTJlNTY2ODM5ZjQyOWVlZWZlMTk5YjdlXzB4OTQ0YjBjNDEzZGMwYzMxODBhM2NjN2IxNjkwZmI4NDA0NWZhNDkzMzZhMmY5ODM1YzQ2YzA5YzE3MjZhNzZmYw==",
"asset": {
"id": "VG9rZW46RVRIRVJFVU1fbnVsbA==",
"name": "Ether",
"symbol": "ETH",
"address": null,
"decimals": 18,
"chain": "ETHEREUM",
"standard": null,
"project": {
"id": "VG9rZW5Qcm9qZWN0OkVUSEVSRVVNX251bGw=",
"isSpam": false,
"logo": {
"id": "SW1hZ2U6aHR0cHM6Ly90b2tlbi1pY29ucy5zMy5hbWF6b25hd3MuY29tL2V0aC5wbmc=",
"url": "https://token-icons.s3.amazonaws.com/eth.png",
"__typename": "Image"
},
"__typename": "TokenProject"
},
"__typename": "Token"
},
"tokenStandard": "NATIVE",
"quantity": "0.003476850926189204",
"sender": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266",
"recipient": "0x6220e08c9d63ab7ba2e566839f429eeefe199b7e",
"direction": "OUT",
"transactedValue": {
"id": "QW1vdW50OjYuMzYxNDg5ODM0MTIwNjAxX1VTRA==",
"currency": "USD",
"value": 6.361489834120601,
"__typename": "Amount"
}
}
]
},
"__typename": "AssetActivity"
},
{
"id": "QXNzZXRBY3Rpdml0eTpWSEpoYm5OaFkzUnBiMjQ2TUhneE0yRTRNRGxsT1RZd05USmhOVGxrWlRjNU56WXhObVZrTlRjME1qTTVNakV3WkRJMVpUY3hNRGhqTkRjek9EbG1NbVJoTnpjeU5qTXhZbVZpTUdZMlh6QjRaak01Wm1RMlpUVXhZV0ZrT0RobU5tWTBZMlUyWVdJNE9ESTNNamM1WTJabVptSTVNakkyTmw4d2VEWXlNakJsTURoak9XUTJNMkZpTjJKaE1tVTFOalk0TXpsbU5ESTVaV1ZsWm1VeE9UbGlOMlU9",
"timestamp": 1684171943,
"chain": "ETHEREUM",
"details": {
"id": "VHJhbnNhY3Rpb246MHgxM2E4MDllOTYwNTJhNTlkZTc5NzYxNmVkNTc0MjM5MjEwZDI1ZTcxMDhjNDczODlmMmRhNzcyNjMxYmViMGY2XzB4ZjM5ZmQ2ZTUxYWFkODhmNmY0Y2U2YWI4ODI3Mjc5Y2ZmZmI5MjI2Nl8weDYyMjBlMDhjOWQ2M2FiN2JhMmU1NjY4MzlmNDI5ZWVlZmUxOTliN2U=",
"type": "SEND",
"blockNumber": 17266680,
"hash": "0x13a809e96052a59de797616ed574239210d25e7108c47389f2da772631beb0f6",
"status": "CONFIRMED",
"to": "0x6220e08c9d63ab7ba2e566839f429eeefe199b7e",
"from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266",
"nonce": 461,
"__typename": "TransactionDetails",
"assetChanges": [
{
"__typename": "TokenTransfer",
"id": "VG9rZW5UcmFuc2ZlcjoweGYzOWZkNmU1MWFhZDg4ZjZmNGNlNmFiODgyNzI3OWNmZmZiOTIyNjZfMHg2MjIwZTA4YzlkNjNhYjdiYTJlNTY2ODM5ZjQyOWVlZWZlMTk5YjdlXzB4MTNhODA5ZTk2MDUyYTU5ZGU3OTc2MTZlZDU3NDIzOTIxMGQyNWU3MTA4YzQ3Mzg5ZjJkYTc3MjYzMWJlYjBmNg==",
"asset": {
"id": "VG9rZW46RVRIRVJFVU1fbnVsbA==",
"name": "Ether",
"symbol": "ETH",
"address": null,
"decimals": 18,
"chain": "ETHEREUM",
"standard": null,
"project": {
"id": "VG9rZW5Qcm9qZWN0OkVUSEVSRVVNX251bGw=",
"isSpam": false,
"logo": {
"id": "SW1hZ2U6aHR0cHM6Ly90b2tlbi1pY29ucy5zMy5hbWF6b25hd3MuY29tL2V0aC5wbmc=",
"url": "https://token-icons.s3.amazonaws.com/eth.png",
"__typename": "Image"
},
"__typename": "TokenProject"
},
"__typename": "Token"
},
"tokenStandard": "NATIVE",
"quantity": "0.000900000000000318",
"sender": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266",
"recipient": "0x6220e08c9d63ab7ba2e566839f429eeefe199b7e",
"direction": "OUT",
"transactedValue": {
"id": "QW1vdW50OjEuNjQ2NzAzMDAwMDAwNTgxOF9VU0Q=",
"currency": "USD",
"value": 1.6467030000005818,
"__typename": "Amount"
}
}
]
},
"__typename": "AssetActivity"
},
{
"id": "QXNzZXRBY3Rpdml0eTpWSEpoYm5OaFkzUnBiMjQ2TUhobFkyRTJNVEZrTlRVME1EZGxPVGt6WlRFM1lqWmtaVGhpWVRJMFlqWXlOREpqWVRSbFlXWTBORGN3TkRKbFpHRmtNRFE0TTJNNFptSTJabUU0WkRJNVh6QjROekU0WVRVeE5ESXhNR0kwTnpWaU9USXhOVGd6WldGaU5ERXlaV0ptTUdaaVlXUm1NMkl6T1Y4d2VHWXpPV1prTm1VMU1XRmhaRGc0WmpabU5HTmxObUZpT0RneU56STNPV05tWm1aaU9USXlOalk9",
"timestamp": 1684171931,
"chain": "ETHEREUM",
"details": {
"id": "VHJhbnNhY3Rpb246MHhlY2E2MTFkNTU0MDdlOTkzZTE3YjZkZThiYTI0YjYyNDJjYTRlYWY0NDcwNDJlZGFkMDQ4M2M4ZmI2ZmE4ZDI5XzB4NzE4YTUxNDIxMGI0NzViOTIxNTgzZWFiNDEyZWJmMGZiYWRmM2IzOV8weGYzOWZkNmU1MWFhZDg4ZjZmNGNlNmFiODgyNzI3OWNmZmZiOTIyNjY=",
"type": "RECEIVE",
"blockNumber": 17266679,
"hash": "0xeca611d55407e993e17b6de8ba24b6242ca4eaf447042edad0483c8fb6fa8d29",
"status": "CONFIRMED",
"to": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266",
"from": "0x718a514210b475b921583eab412ebf0fbadf3b39",
"nonce": 92,
"__typename": "TransactionDetails",
"assetChanges": [
{
"__typename": "TokenTransfer",
"id": "VG9rZW5UcmFuc2ZlcjoweDcxOGE1MTQyMTBiNDc1YjkyMTU4M2VhYjQxMmViZjBmYmFkZjNiMzlfMHhmMzlmZDZlNTFhYWQ4OGY2ZjRjZTZhYjg4MjcyNzljZmZmYjkyMjY2XzB4ZWNhNjExZDU1NDA3ZTk5M2UxN2I2ZGU4YmEyNGI2MjQyY2E0ZWFmNDQ3MDQyZWRhZDA0ODNjOGZiNmZhOGQyOQ==",
"asset": {
"id": "VG9rZW46RVRIRVJFVU1fbnVsbA==",
"name": "Ether",
"symbol": "ETH",
"address": null,
"decimals": 18,
"chain": "ETHEREUM",
"standard": null,
"project": {
"id": "VG9rZW5Qcm9qZWN0OkVUSEVSRVVNX251bGw=",
"isSpam": false,
"logo": {
"id": "SW1hZ2U6aHR0cHM6Ly90b2tlbi1pY29ucy5zMy5hbWF6b25hd3MuY29tL2V0aC5wbmc=",
"url": "https://token-icons.s3.amazonaws.com/eth.png",
"__typename": "Image"
},
"__typename": "TokenProject"
},
"__typename": "Token"
},
"tokenStandard": "NATIVE",
"quantity": "0.01",
"sender": "0x718a514210b475b921583eab412ebf0fbadf3b39",
"recipient": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266",
"direction": "IN",
"transactedValue": {
"id": "QW1vdW50OjE4LjI5NjdfVVNE",
"currency": "USD",
"value": 18.2967,
"__typename": "Amount"
}
}
]
},
"__typename": "AssetActivity"
},
{
"id": "QXNzZXRBY3Rpdml0eTpWSEpoYm5OaFkzUnBiMjQ2TUhnMllqTTJNelEwT1daaU1HWTROems0TkRnM1pqWmlOREkwTkRjMFkySXdNbVF5WlRVNE1EZ3dPVEpoWVRneE1EVm1ObUU0T1dOalpHTTBORGRsTURSa1h6QjRaak01Wm1RMlpUVXhZV0ZrT0RobU5tWTBZMlUyWVdJNE9ESTNNamM1WTJabVptSTVNakkyTmw4d2VEQXdNREF3TURBek1HWTBPV0ptTW1Vd01ESmxOakJqTm1Wa01UWTJNV1ppTWpNME5tUTRPREk9",
"timestamp": 1684085063,
"chain": "ETHEREUM",
"details": {
"id": "VHJhbnNhY3Rpb246MHg2YjM2MzQ0OWZiMGY4Nzk4NDg3ZjZiNDI0NDc0Y2IwMmQyZTU4MDgwOTJhYTgxMDVmNmE4OWNjZGM0NDdlMDRkXzB4ZjM5ZmQ2ZTUxYWFkODhmNmY0Y2U2YWI4ODI3Mjc5Y2ZmZmI5MjI2Nl8weDAwMDAwMDAzMGY0OWJmMmUwMDJlNjBjNmVkMTY2MWZiMjM0NmQ4ODI=",
"type": "UNKNOWN",
"blockNumber": 17259555,
"hash": "0x6b363449fb0f8798487f6b424474cb02d2e5808092aa8105f6a89ccdc447e04d",
"status": "CONFIRMED",
"to": "0x000000030f49bf2e002e60c6ed1661fb2346d882",
"from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266",
"nonce": 460,
"__typename": "TransactionDetails",
"assetChanges": []
},
"__typename": "AssetActivity"
},
{
"id": "QXNzZXRBY3Rpdml0eTpWSEpoYm5OaFkzUnBiMjQ2TUhnNFlXRTVNVFJqTkRjeU5qWTNNVGxqWkRFeE1EYzNOMkprTnpZek0yVTFOV1kyWkdWbVpXRmpPVEV4TlRjd09EZzNZVEEyWXpNNE5UTmxaV0kyTldZeVh6QjRaR0V4TTJRMk5HVmpPVFZqWkRZM056VXlPVEZpTVdNek1qRXdNamN4TWpGaVpUSXdPV1JtTUY4d2VHWXpPV1prTm1VMU1XRmhaRGc0WmpabU5HTmxObUZpT0RneU56STNPV05tWm1aaU9USXlOalk9",
"timestamp": 1684085051,
"chain": "ETHEREUM",
"details": {
"id": "VHJhbnNhY3Rpb246MHg4YWE5MTRjNDcyNjY3MTljZDExMDc3N2JkNzYzM2U1NWY2ZGVmZWFjOTExNTcwODg3YTA2YzM4NTNlZWI2NWYyXzB4ZGExM2Q2NGVjOTVjZDY3NzUyOTFiMWMzMjEwMjcxMjFiZTIwOWRmMF8weGYzOWZkNmU1MWFhZDg4ZjZmNGNlNmFiODgyNzI3OWNmZmZiOTIyNjY=",
"type": "RECEIVE",
"blockNumber": 17259554,
"hash": "0x8aa914c47266719cd110777bd7633e55f6defeac911570887a06c3853eeb65f2",
"status": "CONFIRMED",
"to": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266",
"from": "0xda13d64ec95cd6775291b1c321027121be209df0",
"nonce": 832,
"__typename": "TransactionDetails",
"assetChanges": [
{
"__typename": "TokenTransfer",
"id": "VG9rZW5UcmFuc2ZlcjoweGRhMTNkNjRlYzk1Y2Q2Nzc1MjkxYjFjMzIxMDI3MTIxYmUyMDlkZjBfMHhmMzlmZDZlNTFhYWQ4OGY2ZjRjZTZhYjg4MjcyNzljZmZmYjkyMjY2XzB4OGFhOTE0YzQ3MjY2NzE5Y2QxMTA3NzdiZDc2MzNlNTVmNmRlZmVhYzkxMTU3MDg4N2EwNmMzODUzZWViNjVmMg==",
"asset": {
"id": "VG9rZW46RVRIRVJFVU1fbnVsbA==",
"name": "Ether",
"symbol": "ETH",
"address": null,
"decimals": 18,
"chain": "ETHEREUM",
"standard": null,
"project": {
"id": "VG9rZW5Qcm9qZWN0OkVUSEVSRVVNX251bGw=",
"isSpam": false,
"logo": {
"id": "SW1hZ2U6aHR0cHM6Ly90b2tlbi1pY29ucy5zMy5hbWF6b25hd3MuY29tL2V0aC5wbmc=",
"url": "https://token-icons.s3.amazonaws.com/eth.png",
"__typename": "Image"
},
"__typename": "TokenProject"
},
"__typename": "Token"
},
"tokenStandard": "NATIVE",
"quantity": "0.00129866",
"sender": "0xda13d64ec95cd6775291b1c321027121be209df0",
"recipient": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266",
"direction": "IN",
"transactedValue": {
"id": "QW1vdW50OjIuMzc2MTE5MjQyMl9VU0Q=",
"currency": "USD",
"value": 2.3761192422,
"__typename": "Amount"
}
}
]
},
"__typename": "AssetActivity"
},
{
"id": "QXNzZXRBY3Rpdml0eTpWSEpoYm5OaFkzUnBiMjQ2TUhnM00yTXdZMlJpTnpReU9UVTJZVFUxWXpZd016YzBOemd6TkRRNVpUSmpNbVZtTURnM1lqUTVPRFl4TVdGak5EZ3dZalJrTVRFMU1UbGhZemRpTXpZNVh6QjRaak01Wm1RMlpUVXhZV0ZrT0RobU5tWTBZMlUyWVdJNE9ESTNNamM1WTJabVptSTVNakkyTmw4d2VHUXpaR1UwTkRneE5qTXlNakl5TURVME9UazJZVE0yTlRsaE5UTXlNR0k1TWpWbU5qUXhNR1k9",
"timestamp": 1684006019,
"chain": "ETHEREUM",
"details": {
"id": "VHJhbnNhY3Rpb246MHg3M2MwY2RiNzQyOTU2YTU1YzYwMzc0NzgzNDQ5ZTJjMmVmMDg3YjQ5ODYxMWFjNDgwYjRkMTE1MTlhYzdiMzY5XzB4ZjM5ZmQ2ZTUxYWFkODhmNmY0Y2U2YWI4ODI3Mjc5Y2ZmZmI5MjI2Nl8weGQzZGU0NDgxNjMyMjIyMDU0OTk2YTM2NTlhNTMyMGI5MjVmNjQxMGY=",
"type": "SEND",
"blockNumber": 17253116,
"hash": "0x73c0cdb742956a55c60374783449e2c2ef087b498611ac480b4d11519ac7b369",
"status": "CONFIRMED",
"to": "0xd3de4481632222054996a3659a5320b925f6410f",
"from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266",
"nonce": 459,
"__typename": "TransactionDetails",
"assetChanges": [
{
"__typename": "TokenTransfer",
"id": "VG9rZW5UcmFuc2ZlcjoweGYzOWZkNmU1MWFhZDg4ZjZmNGNlNmFiODgyNzI3OWNmZmZiOTIyNjZfMHhiZTgyODI1NjRlYzJiNzAwMDlmMmQ2ODk1NDAxMmViMDlmNDhiYzhkXzB4NzNjMGNkYjc0Mjk1NmE1NWM2MDM3NDc4MzQ0OWUyYzJlZjA4N2I0OTg2MTFhYzQ4MGI0ZDExNTE5YWM3YjM2OQ==",
"asset": {
"id": "VG9rZW46RVRIRVJFVU1fMHhkM2RlNDQ4MTYzMjIyMjA1NDk5NmEzNjU5YTUzMjBiOTI1ZjY0MTBm",
"name": "EL CHAPO",
"symbol": "CHAPO",
"address": "0xd3de4481632222054996a3659a5320b925f6410f",
"decimals": 18,
"chain": "ETHEREUM",
"standard": null,
"project": {
"id": "VG9rZW5Qcm9qZWN0OkVUSEVSRVVNXzB4ZDNkZTQ0ODE2MzIyMjIwNTQ5OTZhMzY1OWE1MzIwYjkyNWY2NDEwZg==",
"isSpam": true,
"logo": null,
"__typename": "TokenProject"
},
"__typename": "Token"
},
"tokenStandard": "ERC20",
"quantity": "50000000000000.002683081102196736",
"sender": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266",
"recipient": "0xbe8282564ec2b70009f2d68954012eb09f48bc8d",
"direction": "OUT",
"transactedValue": null
}
]
},
"__typename": "AssetActivity"
}
],
"__typename": "Portfolio"
}
]
},
"errors": []
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,102 @@
{
"data": {
"portfolios": [
{
"id": "UG9ydGZvbGlvOjB4ZjM5RmQ2ZTUxYWFkODhGNkY0Y2U2YUI4ODI3Mjc5Y2ZmRmI5MjI2Ng==",
"assetActivities": [
{
"id": "QXNzZXRBY3Rpdml0eTpWSEpoYm5OaFkzUnBiMjQ2TUhnNE9EZGpOemN5TlRRNU1qWTVNVEkwWVRkbVpUTXlNams1TjJJNU0yUTJabUV3TjJObE1UQXhOamxrTjJJd1pXUXhObUV6TldabU16SmtOMk13TWpBeVh6QjRaREkzTXpnek1EUTRaalF4WldZMlpXRXhaV1EzWWpBeFltVTVOemRqTjJVME1HSXdaRGswTmw4d2VEUTNZVFF5TVdKalpXTTJORE5oWWpSallURmpZamc0TmpOaU4yWm1PV0ppWm1SaU5HVmlNVE09",
"timestamp": 1691001923,
"type": "SWAP_ORDER",
"chain": "ETHEREUM",
"details": {
"__typename": "TransactionDetails",
"id": "VHJhbnNhY3Rpb246MHg4ODdjNzcyNTQ5MjY5MTI0YTdmZTMyMjk5N2I5M2Q2ZmEwN2NlMTAxNjlkN2IwZWQxNmEzNWZmMzJkN2MwMjAyXzB4ZDI3MzgzMDQ4ZjQxZWY2ZWExZWQ3YjAxYmU5NzdjN2U0MGIwZDk0Nl8weDQ3YTQyMWJjZWM2NDNhYjRjYTFjYjg4NjNiN2ZmOWJiZmRiNGViMTM=",
"type": "SWAP_ORDER",
"from": "0xd27383048f41ef6ea1ed7b01be977c7e40b0d946",
"to": "0x47a421bcec643ab4ca1cb8863b7ff9bbfdb4eb13",
"hash": "0x9f8382a94ee80ca119bc690908ab5f69c4c72f7497ee10f37e9ede0ded83cca6",
"nonce": 439,
"status": "CONFIRMED"
},
"assetChanges": [
{
"__typename": "TokenTransfer",
"id": "VG9rZW5UcmFuc2ZlcjoweDgwYmVjYjgwOGJmYWRlNDE0MzE4M2U1OGQxOGYyMDgwZTg0ZTU3YTFfMHg0N2E0MjFiY2VjNjQzYWI0Y2ExY2I4ODYzYjdmZjliYmZkYjRlYjEzXzB4ODg3Yzc3MjU0OTI2OTEyNGE3ZmUzMjI5OTdiOTNkNmZhMDdjZTEwMTY5ZDdiMGVkMTZhMzVmZjMyZDdjMDIwMg==",
"asset": {
"id": "VG9rZW46RVRIRVJFVU1fMHhhMGI4Njk5MWM2MjE4YjM2YzFkMTlkNGEyZTllYjBjZTM2MDZlYjQ4",
"name": "USD Coin",
"symbol": "USDC",
"address": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"decimals": 6,
"chain": "ETHEREUM",
"standard": null,
"project": {
"id": "VG9rZW5Qcm9qZWN0OkVUSEVSRVVNXzB4YTBiODY5OTFjNjIxOGIzNmMxZDE5ZDRhMmU5ZWIwY2UzNjA2ZWI0OA==",
"isSpam": false,
"logo": {
"id": "SW1hZ2U6aHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL1VuaXN3YXAvYXNzZXRzL21hc3Rlci9ibG9ja2NoYWlucy9ldGhlcmV1bS9hc3NldHMvMHhBMGI4Njk5MWM2MjE4YjM2YzFkMTlENGEyZTlFYjBjRTM2MDZlQjQ4L2xvZ28ucG5n",
"url": "https://raw.githubusercontent.com/Uniswap/assets/master/blockchains/ethereum/assets/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48/logo.png",
"__typename": "Image"
},
"__typename": "TokenProject"
},
"__typename": "Token"
},
"tokenStandard": "ERC20",
"quantity": "300.0",
"sender": "0x80becb808bfade4143183e58d18f2080e84e57a1",
"recipient": "0x47a421bcec643ab4ca1cb8863b7ff9bbfdb4eb13",
"direction": "OUT",
"transactedValue": {
"id": "QW1vdW50OjMwMC4xNDkxNTIwOTE5NDE2M19VU0Q=",
"currency": "USD",
"value": 300.14915209194163,
"__typename": "Amount"
}
},
{
"__typename": "TokenTransfer",
"id": "VG9rZW5UcmFuc2ZlcjoweDQ3YTQyMWJjZWM2NDNhYjRjYTFjYjg4NjNiN2ZmOWJiZmRiNGViMTNfMHg4MGJlY2I4MDhiZmFkZTQxNDMxODNlNThkMThmMjA4MGU4NGU1N2ExXzB4ODg3Yzc3MjU0OTI2OTEyNGE3ZmUzMjI5OTdiOTNkNmZhMDdjZTEwMTY5ZDdiMGVkMTZhMzVmZjMyZDdjMDIwMg==",
"asset": {
"id": "VG9rZW46RVRIRVJFVU1fMHg2YjE3NTQ3NGU4OTA5NGM0NGRhOThiOTU0ZWVkZWFjNDk1MjcxZDBm",
"name": "Dai Stablecoin",
"symbol": "DAI",
"address": "0x6b175474e89094c44da98b954eedeac495271d0f",
"decimals": 18,
"chain": "ETHEREUM",
"standard": null,
"project": {
"id": "VG9rZW5Qcm9qZWN0OkVUSEVSRVVNXzB4NmIxNzU0NzRlODkwOTRjNDRkYTk4Yjk1NGVlZGVhYzQ5NTI3MWQwZg==",
"isSpam": false,
"logo": {
"id": "SW1hZ2U6aHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL1VuaXN3YXAvYXNzZXRzL21hc3Rlci9ibG9ja2NoYWlucy9ldGhlcmV1bS9hc3NldHMvMHg2QjE3NTQ3NEU4OTA5NEM0NERhOThiOTU0RWVkZUFDNDk1MjcxZDBGL2xvZ28ucG5n",
"url": "https://raw.githubusercontent.com/Uniswap/assets/master/blockchains/ethereum/assets/0x6B175474E89094C44Da98b954EedeAC495271d0F/logo.png",
"__typename": "Image"
},
"__typename": "TokenProject"
},
"__typename": "Token"
},
"tokenStandard": "ERC20",
"quantity": "280.573117586837733376",
"sender": "0x47a421bcec643ab4ca1cb8863b7ff9bbfdb4eb13",
"recipient": "0x80becb808bfade4143183e58d18f2080e84e57a1",
"direction": "IN",
"transactedValue": {
"id": "QW1vdW50OjI4MC42ODc3OTU0NTg2ODE4X1VTRA==",
"currency": "USD",
"value": 280.6877954586818,
"__typename": "Amount"
}
}
],
"__typename": "AssetActivity"
}
],
"__typename": "Portfolio"
}
]
},
"errors": []
}

View File

@ -0,0 +1,26 @@
{
"orders": [
{
"outputs": [
{
"recipient": "0x80becb808bfade4143183e58d18f2080e84e57a1",
"startAmount": "91371770080538616664",
"endAmount": "90914911230135923580",
"token": "0x6B175474E89094C44Da98b954EedeAC495271d0F"
}
],
"encodedOrder": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000064837e2a0000000000000000000000000000000000000000000000000000000064837e6600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e1000000000000000000000000000000000000000000000000000000000005f5e1000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000bd7f9d0239f81c94b728d827a87b9864972661ec00000000000000000000000080becb808bfade4143183e58d18f2080e84e57a18e32c6335b6f657322448399bd12ff5c22b7b1aa770850ff4eed36c750e2de000000000000000000000000000000000000000000000000000000000064837e66000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000000000000000000000000004f409bcc7a52b6358000000000000000000000000000000000000000000000004edb2a613726c737c00000000000000000000000080becb808bfade4143183e58d18f2080e84e57a1",
"signature": "0x973882a290778b5c8aae691ef777385259928cde0513d224ea1131538379258d2db7a69804110320b08558380394879a31ab8dea61152c2dba7623acbfa11d0e1b",
"input": {
"endAmount": "100000000",
"token": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"startAmount": "100000000"
},
"orderStatus": "expired",
"createdAt": 1686339087,
"chainId": 1,
"orderHash": "0xa9dd6f05ad6d6c79bee654c31ede4d0d2392862711be0f3bc4a9124af24a6a19",
"type": "Dutch"
}
]
}

View File

@ -0,0 +1,562 @@
{
"routing": "DUTCH_LIMIT",
"quote": {
"orderInfo": {
"chainId": 1,
"permit2Address": "0x000000000022d473030f116ddee9f6b43ac78ba3",
"reactor": "0x6000da47483062A0D734Ba3dc7576Ce6A0B645C4",
"swapper": "0x0938a82F93D5DAB110Dc6277FC236b5b082DC10F",
"nonce": "1993353164669688581970088190602701610528397285201889446578254799128576197633",
"deadline": 1697481666,
"additionalValidationContract": "0x0000000000000000000000000000000000000000",
"additionalValidationData": "0x",
"decayStartTime": 1697481594,
"decayEndTime": 1697481654,
"exclusiveFiller": "0xaAFb85ad4a412dd8adC49611496a7695A22f4aeb",
"exclusivityOverrideBps": "100",
"input": {
"token": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"startAmount": "200000000",
"endAmount": "200000000"
},
"outputs": [
{
"token": "0x0000000000000000000000000000000000000000",
"startAmount": "123803169993201727",
"endAmount": "117908377342236273",
"recipient": "0x0938a82F93D5DAB110Dc6277FC236b5b082DC10F"
},
{
"token": "0x0000000000000000000000000000000000000000",
"startAmount": "185983730585681",
"endAmount": "177128258400955",
"recipient": "0x37a8f295612602f2774d331e562be9e61B83a327"
}
]
},
"encodedOrder": "0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000652d837a00000000000000000000000000000000000000000000000000000000652d83b6000000000000000000000000aafb85ad4a412dd8adc49611496a7695a22f4aeb0000000000000000000000000000000000000000000000000000000000000064000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000000000000bebc200000000000000000000000000000000000000000000000000000000000bebc20000000000000000000000000000000000000000000000000000000000000002000000000000000000000000006000da47483062a0d734ba3dc7576ce6a0b645c40000000000000000000000000938a82f93d5dab110dc6277fc236b5b082dc10f046832aa305880d33daa871e5041a0cd4853599a9ead518917239e206765040100000000000000000000000000000000000000000000000000000000652d83c2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001b7d653c183183f00000000000000000000000000000000000000000000000001a2e50b6386d6710000000000000000000000000938a82f93d5dab110dc6277fc236b5b082dc10f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a926b63210510000000000000000000000000000000000000000000000000000a118e2ebf2bb00000000000000000000000037a8f295612602f2774d331e562be9e61b83a327",
"quoteId": "7b924043-f2d8-4f2e-abaa-9f65fbe5f890",
"requestId": "a02ca0ca-7855-4dd0-9330-8b818aaeb59f",
"orderHash": "0xb5b4e3be188f6eb9dbe7e1489595829184a9ebfb5389185ed7ba7c03142278c9",
"startTimeBufferSecs": 45,
"auctionPeriodSecs": 60,
"deadlineBufferSecs": 12,
"slippageTolerance": "0.5",
"permitData": {
"domain": {
"name": "Permit2",
"chainId": 1,
"verifyingContract": "0x000000000022d473030f116ddee9f6b43ac78ba3"
},
"types": {
"PermitWitnessTransferFrom": [
{
"name": "permitted",
"type": "TokenPermissions"
},
{
"name": "spender",
"type": "address"
},
{
"name": "nonce",
"type": "uint256"
},
{
"name": "deadline",
"type": "uint256"
},
{
"name": "witness",
"type": "ExclusiveDutchOrder"
}
],
"TokenPermissions": [
{
"name": "token",
"type": "address"
},
{
"name": "amount",
"type": "uint256"
}
],
"ExclusiveDutchOrder": [
{
"name": "info",
"type": "OrderInfo"
},
{
"name": "decayStartTime",
"type": "uint256"
},
{
"name": "decayEndTime",
"type": "uint256"
},
{
"name": "exclusiveFiller",
"type": "address"
},
{
"name": "exclusivityOverrideBps",
"type": "uint256"
},
{
"name": "inputToken",
"type": "address"
},
{
"name": "inputStartAmount",
"type": "uint256"
},
{
"name": "inputEndAmount",
"type": "uint256"
},
{
"name": "outputs",
"type": "DutchOutput[]"
}
],
"OrderInfo": [
{
"name": "reactor",
"type": "address"
},
{
"name": "swapper",
"type": "address"
},
{
"name": "nonce",
"type": "uint256"
},
{
"name": "deadline",
"type": "uint256"
},
{
"name": "additionalValidationContract",
"type": "address"
},
{
"name": "additionalValidationData",
"type": "bytes"
}
],
"DutchOutput": [
{
"name": "token",
"type": "address"
},
{
"name": "startAmount",
"type": "uint256"
},
{
"name": "endAmount",
"type": "uint256"
},
{
"name": "recipient",
"type": "address"
}
]
},
"values": {
"permitted": {
"token": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"amount": {
"type": "BigNumber",
"hex": "0x0bebc200"
}
},
"spender": "0x6000da47483062A0D734Ba3dc7576Ce6A0B645C4",
"nonce": {
"type": "BigNumber",
"hex": "0x046832aa305880d33daa871e5041a0cd4853599a9ead518917239e2067650401"
},
"deadline": 1697481666,
"witness": {
"info": {
"reactor": "0x6000da47483062A0D734Ba3dc7576Ce6A0B645C4",
"swapper": "0x0938a82F93D5DAB110Dc6277FC236b5b082DC10F",
"nonce": {
"type": "BigNumber",
"hex": "0x046832aa305880d33daa871e5041a0cd4853599a9ead518917239e2067650401"
},
"deadline": 1697481666,
"additionalValidationContract": "0x0000000000000000000000000000000000000000",
"additionalValidationData": "0x"
},
"decayStartTime": 1697481594,
"decayEndTime": 1697481654,
"exclusiveFiller": "0xaAFb85ad4a412dd8adC49611496a7695A22f4aeb",
"exclusivityOverrideBps": {
"type": "BigNumber",
"hex": "0x64"
},
"inputToken": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"inputStartAmount": {
"type": "BigNumber",
"hex": "0x0bebc200"
},
"inputEndAmount": {
"type": "BigNumber",
"hex": "0x0bebc200"
},
"outputs": [
{
"token": "0x0000000000000000000000000000000000000000",
"startAmount": {
"type": "BigNumber",
"hex": "0x01b7d653c183183f"
},
"endAmount": {
"type": "BigNumber",
"hex": "0x01a2e50b6386d671"
},
"recipient": "0x0938a82F93D5DAB110Dc6277FC236b5b082DC10F"
},
{
"token": "0x0000000000000000000000000000000000000000",
"startAmount": {
"type": "BigNumber",
"hex": "0xa926b6321051"
},
"endAmount": {
"type": "BigNumber",
"hex": "0xa118e2ebf2bb"
},
"recipient": "0x37a8f295612602f2774d331e562be9e61B83a327"
}
]
}
}
},
"portionBips": 15,
"portionAmount": "185983730585681",
"portionRecipient": "0x37a8f295612602f2774d331e562be9e61B83a327"
},
"requestId": "a02ca0ca-7855-4dd0-9330-8b818aaeb59f",
"allQuotes": [
{
"routing": "DUTCH_LIMIT",
"quote": {
"orderInfo": {
"chainId": 1,
"permit2Address": "0x000000000022d473030f116ddee9f6b43ac78ba3",
"reactor": "0x6000da47483062A0D734Ba3dc7576Ce6A0B645C4",
"swapper": "0x0938a82F93D5DAB110Dc6277FC236b5b082DC10F",
"nonce": "1993353164669688581970088190602701610528397285201889446578254799128576197633",
"deadline": 1697481666,
"additionalValidationContract": "0x0000000000000000000000000000000000000000",
"additionalValidationData": "0x",
"decayStartTime": 1697481594,
"decayEndTime": 1697481654,
"exclusiveFiller": "0xaAFb85ad4a412dd8adC49611496a7695A22f4aeb",
"exclusivityOverrideBps": "100",
"input": {
"token": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"startAmount": "200000000",
"endAmount": "200000000"
},
"outputs": [
{
"token": "0x0000000000000000000000000000000000000000",
"startAmount": "123803169993201727",
"endAmount": "117908377342236273",
"recipient": "0x0938a82F93D5DAB110Dc6277FC236b5b082DC10F"
},
{
"token": "0x0000000000000000000000000000000000000000",
"startAmount": "185983730585681",
"endAmount": "177128258400955",
"recipient": "0x37a8f295612602f2774d331e562be9e61B83a327"
}
]
},
"encodedOrder": "0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000652d837a00000000000000000000000000000000000000000000000000000000652d83b6000000000000000000000000aafb85ad4a412dd8adc49611496a7695a22f4aeb0000000000000000000000000000000000000000000000000000000000000064000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000000000000bebc200000000000000000000000000000000000000000000000000000000000bebc20000000000000000000000000000000000000000000000000000000000000002000000000000000000000000006000da47483062a0d734ba3dc7576ce6a0b645c40000000000000000000000000938a82f93d5dab110dc6277fc236b5b082dc10f046832aa305880d33daa871e5041a0cd4853599a9ead518917239e206765040100000000000000000000000000000000000000000000000000000000652d83c2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001b7d653c183183f00000000000000000000000000000000000000000000000001a2e50b6386d6710000000000000000000000000938a82f93d5dab110dc6277fc236b5b082dc10f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a926b63210510000000000000000000000000000000000000000000000000000a118e2ebf2bb00000000000000000000000037a8f295612602f2774d331e562be9e61b83a327",
"quoteId": "7b924043-f2d8-4f2e-abaa-9f65fbe5f890",
"requestId": "a02ca0ca-7855-4dd0-9330-8b818aaeb59f",
"orderHash": "0xb5b4e3be188f6eb9dbe7e1489595829184a9ebfb5389185ed7ba7c03142278c9",
"startTimeBufferSecs": 45,
"auctionPeriodSecs": 60,
"deadlineBufferSecs": 12,
"slippageTolerance": "0.5",
"permitData": {
"domain": {
"name": "Permit2",
"chainId": 1,
"verifyingContract": "0x000000000022d473030f116ddee9f6b43ac78ba3"
},
"types": {
"PermitWitnessTransferFrom": [
{
"name": "permitted",
"type": "TokenPermissions"
},
{
"name": "spender",
"type": "address"
},
{
"name": "nonce",
"type": "uint256"
},
{
"name": "deadline",
"type": "uint256"
},
{
"name": "witness",
"type": "ExclusiveDutchOrder"
}
],
"TokenPermissions": [
{
"name": "token",
"type": "address"
},
{
"name": "amount",
"type": "uint256"
}
],
"ExclusiveDutchOrder": [
{
"name": "info",
"type": "OrderInfo"
},
{
"name": "decayStartTime",
"type": "uint256"
},
{
"name": "decayEndTime",
"type": "uint256"
},
{
"name": "exclusiveFiller",
"type": "address"
},
{
"name": "exclusivityOverrideBps",
"type": "uint256"
},
{
"name": "inputToken",
"type": "address"
},
{
"name": "inputStartAmount",
"type": "uint256"
},
{
"name": "inputEndAmount",
"type": "uint256"
},
{
"name": "outputs",
"type": "DutchOutput[]"
}
],
"OrderInfo": [
{
"name": "reactor",
"type": "address"
},
{
"name": "swapper",
"type": "address"
},
{
"name": "nonce",
"type": "uint256"
},
{
"name": "deadline",
"type": "uint256"
},
{
"name": "additionalValidationContract",
"type": "address"
},
{
"name": "additionalValidationData",
"type": "bytes"
}
],
"DutchOutput": [
{
"name": "token",
"type": "address"
},
{
"name": "startAmount",
"type": "uint256"
},
{
"name": "endAmount",
"type": "uint256"
},
{
"name": "recipient",
"type": "address"
}
]
},
"values": {
"permitted": {
"token": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"amount": {
"type": "BigNumber",
"hex": "0x0bebc200"
}
},
"spender": "0x6000da47483062A0D734Ba3dc7576Ce6A0B645C4",
"nonce": {
"type": "BigNumber",
"hex": "0x046832aa305880d33daa871e5041a0cd4853599a9ead518917239e2067650401"
},
"deadline": 1697481666,
"witness": {
"info": {
"reactor": "0x6000da47483062A0D734Ba3dc7576Ce6A0B645C4",
"swapper": "0x0938a82F93D5DAB110Dc6277FC236b5b082DC10F",
"nonce": {
"type": "BigNumber",
"hex": "0x046832aa305880d33daa871e5041a0cd4853599a9ead518917239e2067650401"
},
"deadline": 1697481666,
"additionalValidationContract": "0x0000000000000000000000000000000000000000",
"additionalValidationData": "0x"
},
"decayStartTime": 1697481594,
"decayEndTime": 1697481654,
"exclusiveFiller": "0xaAFb85ad4a412dd8adC49611496a7695A22f4aeb",
"exclusivityOverrideBps": {
"type": "BigNumber",
"hex": "0x64"
},
"inputToken": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"inputStartAmount": {
"type": "BigNumber",
"hex": "0x0bebc200"
},
"inputEndAmount": {
"type": "BigNumber",
"hex": "0x0bebc200"
},
"outputs": [
{
"token": "0x0000000000000000000000000000000000000000",
"startAmount": {
"type": "BigNumber",
"hex": "0x01b7d653c183183f"
},
"endAmount": {
"type": "BigNumber",
"hex": "0x01a2e50b6386d671"
},
"recipient": "0x0938a82F93D5DAB110Dc6277FC236b5b082DC10F"
},
{
"token": "0x0000000000000000000000000000000000000000",
"startAmount": {
"type": "BigNumber",
"hex": "0xa926b6321051"
},
"endAmount": {
"type": "BigNumber",
"hex": "0xa118e2ebf2bb"
},
"recipient": "0x37a8f295612602f2774d331e562be9e61B83a327"
}
]
}
}
},
"portionBips": 15,
"portionAmount": "185983730585681",
"portionRecipient": "0x37a8f295612602f2774d331e562be9e61B83a327"
}
},
{
"routing": "CLASSIC",
"quote": {
"methodParameters": {
"calldata": "0x3593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000652d85d0000000000000000000000000000000000000000000000000000000000000000308060c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000bebc20000000000000000000000000000000000000000000000000001bdf1285753b47400000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000060000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000037a8f295612602f2774d331e562be9e61b83a327000000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000938a82f93d5dab110dc6277fc236b5b082dc10f00000000000000000000000000000000000000000000000001bd45ea74e458eb",
"value": "0x00",
"to": "0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD"
},
"blockNumber": "18364784",
"amount": "200000000",
"amountDecimals": "200",
"quote": "126149127803342909",
"quoteDecimals": "0.126149127803342909",
"quoteGasAdjusted": "122888348391508943",
"quoteGasAdjustedDecimals": "0.122888348391508943",
"quoteGasAndPortionAdjusted": "122699124699803928",
"quoteGasAndPortionAdjustedDecimals": "0.122699124699803928",
"gasUseEstimateQuote": "3260779411833966",
"gasUseEstimateQuoteDecimals": "0.003260779411833966",
"gasUseEstimate": "240911",
"gasUseEstimateUSD": "5.153332510477604328",
"simulationStatus": "SUCCESS",
"simulationError": false,
"gasPriceWei": "13535203506",
"route": [
[
{
"type": "v2-pool",
"address": "0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc",
"tokenIn": {
"chainId": 1,
"decimals": "6",
"address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"symbol": "USDC"
},
"tokenOut": {
"chainId": 1,
"decimals": "18",
"address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
"symbol": "WETH"
},
"reserve0": {
"token": {
"chainId": 1,
"decimals": "6",
"address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"symbol": "USDC"
},
"quotient": "27487668611269"
},
"reserve1": {
"token": {
"chainId": 1,
"decimals": "18",
"address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
"symbol": "WETH"
},
"quotient": "17390022942803382004255"
},
"amountIn": "200000000",
"amountOut": "125959904111637894"
}
]
],
"routeString": "[V2] 100.00% = USDC -- [0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc] --> WETH",
"quoteId": "f46cf31c-251e-470c-bd57-13209015694e",
"portionBips": 15,
"portionRecipient": "0x37a8f295612602f2774d331e562be9e61B83a327",
"portionAmount": "189223691705014",
"portionAmountDecimals": "0.000189223691705014",
"requestId": "a02ca0ca-7855-4dd0-9330-8b818aaeb59f",
"tradeType": "EXACT_INPUT",
"slippage": 0.5
}
}
]
}

View File

@ -0,0 +1,114 @@
{
"to": "0xbD7F9D0239f81C94b728d827a87b9864972661eC",
"from": "0xa17Fbb0b5a251A7ACA3BD7377e7eCC4F700A2C09",
"contractAddress": null,
"transactionIndex": 61,
"gasUsed": {
"type": "BigNumber",
"hex": "0x03e0c8"
},
"logsBloom":
"0x00000000000000000000008000200100000020000000000000000000000000000000000000000000000000010000000000000000000020000000000001000000000280000000000808000008000000000000000000000000000000000000200010000000100000000008000000000004402000080000000000000010000800000000000000000800000800000000000000000000010000000000000000000000000000000000200000000000005000000000000000000000000000000000000000000002000000000000000000000000040002000000000000000100000000090000000400000000000400000020080000000000000000000000000000000000",
"blockHash": "0x79cf0785f317f984eeaf737c592afff806cabf4fe0c46a84f62a4a0212cfab5c",
"transactionHash": "0x9f8382a94ee80ca119bc690908ab5f69c4c72f7497ee10f37e9ede0ded83cca6",
"logs": [
{
"transactionIndex": 61,
"blockNumber": 17444757,
"transactionHash": "0x9f8382a94ee80ca119bc690908ab5f69c4c72f7497ee10f37e9ede0ded83cca6",
"address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"topics": [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"0x00000000000000000000000080becb808bfade4143183e58d18f2080e84e57a1",
"0x000000000000000000000000c59938e2d9ff9a0ecccbedf39031b1600d008eaf"
],
"data": "0x0000000000000000000000000000000000000000000000000000000005f5e100",
"logIndex": 103,
"blockHash": "0x79cf0785f317f984eeaf737c592afff806cabf4fe0c46a84f62a4a0212cfab5c"
},
{
"transactionIndex": 61,
"blockNumber": 17444757,
"transactionHash": "0x9f8382a94ee80ca119bc690908ab5f69c4c72f7497ee10f37e9ede0ded83cca6",
"address": "0xbD7F9D0239f81C94b728d827a87b9864972661eC",
"topics": [
"0x78ad7ec0e9f89e74012afa58738b6b661c024cb0fd185ee2f616c0a28924bd66",
"0xd10e1d90145460003d98ba4b788564e9549cc93c65a12c9b297720a9d6a586de",
"0x000000000000000000000000a17fbb0b5a251a7aca3bd7377e7ecc4f700a2c09",
"0x00000000000000000000000080becb808bfade4143183e58d18f2080e84e57a1"
],
"data": "0x8e32c6335b6f657322448399bd12ff5c22b7b1aa770850ff4eed36c750e2de00",
"logIndex": 104,
"blockHash": "0x79cf0785f317f984eeaf737c592afff806cabf4fe0c46a84f62a4a0212cfab5c"
},
{
"transactionIndex": 61,
"blockNumber": 17444757,
"transactionHash": "0x9f8382a94ee80ca119bc690908ab5f69c4c72f7497ee10f37e9ede0ded83cca6",
"address": "0x6B175474E89094C44Da98b954EedeAC495271d0F",
"topics": [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"0x0000000000000000000000005777d92f208679db4b9778590fa3cab3ac9e2168",
"0x000000000000000000000000c59938e2d9ff9a0ecccbedf39031b1600d008eaf"
],
"data": "0x0000000000000000000000000000000000000000000000056b9a675be430b502",
"logIndex": 105,
"blockHash": "0x79cf0785f317f984eeaf737c592afff806cabf4fe0c46a84f62a4a0212cfab5c"
},
{
"transactionIndex": 61,
"blockNumber": 17444757,
"transactionHash": "0x9f8382a94ee80ca119bc690908ab5f69c4c72f7497ee10f37e9ede0ded83cca6",
"address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"topics": [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"0x000000000000000000000000c59938e2d9ff9a0ecccbedf39031b1600d008eaf",
"0x0000000000000000000000005777d92f208679db4b9778590fa3cab3ac9e2168"
],
"data": "0x0000000000000000000000000000000000000000000000000000000005f5e100",
"logIndex": 106,
"blockHash": "0x79cf0785f317f984eeaf737c592afff806cabf4fe0c46a84f62a4a0212cfab5c"
},
{
"transactionIndex": 61,
"blockNumber": 17444757,
"transactionHash": "0x9f8382a94ee80ca119bc690908ab5f69c4c72f7497ee10f37e9ede0ded83cca6",
"address": "0x5777d92f208679DB4b9778590Fa3CAB3aC9e2168",
"topics": [
"0xc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67",
"0x00000000000000000000000068b3465833fb72a70ecdf485e0e4c7bd8665fc45",
"0x000000000000000000000000c59938e2d9ff9a0ecccbedf39031b1600d008eaf"
],
"data": "0xfffffffffffffffffffffffffffffffffffffffffffffffa946598a41bcf4afe0000000000000000000000000000000000000000000000000000000005f5e1000000000000000000000000000000000000000000000010c7063b90a5e90d13830000000000000000000000000000000000000000000071b57cb2bb0b5b28224ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbc89c",
"logIndex": 107,
"blockHash": "0x79cf0785f317f984eeaf737c592afff806cabf4fe0c46a84f62a4a0212cfab5c"
},
{
"transactionIndex": 61,
"blockNumber": 17444757,
"transactionHash": "0x9f8382a94ee80ca119bc690908ab5f69c4c72f7497ee10f37e9ede0ded83cca6",
"address": "0x6B175474E89094C44Da98b954EedeAC495271d0F",
"topics": [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"0x000000000000000000000000c59938e2d9ff9a0ecccbedf39031b1600d008eaf",
"0x00000000000000000000000080becb808bfade4143183e58d18f2080e84e57a1"
],
"data": "0x000000000000000000000000000000000000000000000004f409bcc7a52b6358",
"logIndex": 108,
"blockHash": "0x79cf0785f317f984eeaf737c592afff806cabf4fe0c46a84f62a4a0212cfab5c"
}
],
"blockNumber": 17444757,
"confirmations": 392238,
"cumulativeGasUsed": {
"type": "BigNumber",
"hex": "0x4065ac"
},
"effectiveGasPrice": {
"type": "BigNumber",
"hex": "0x04aa792df0"
},
"status": 1,
"type": 2,
"byzantium": true
}

View File

@ -0,0 +1,33 @@
{
"orders": [
{
"outputs": [
{
"recipient": "0x80becb808bfade4143183e58d18f2080e84e57a1",
"startAmount": "91371770080538616664",
"endAmount": "90914911230135923580",
"token": "0x6B175474E89094C44Da98b954EedeAC495271d0F"
}
],
"encodedOrder": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000064837e2a0000000000000000000000000000000000000000000000000000000064837e6600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e1000000000000000000000000000000000000000000000000000000000005f5e1000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000bd7f9d0239f81c94b728d827a87b9864972661ec00000000000000000000000080becb808bfade4143183e58d18f2080e84e57a18e32c6335b6f657322448399bd12ff5c22b7b1aa770850ff4eed36c750e2de000000000000000000000000000000000000000000000000000000000064837e66000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000000000000000000000000004f409bcc7a52b6358000000000000000000000000000000000000000000000004edb2a613726c737c00000000000000000000000080becb808bfade4143183e58d18f2080e84e57a1",
"signature": "0x973882a290778b5c8aae691ef777385259928cde0513d224ea1131538379258d2db7a69804110320b08558380394879a31ab8dea61152c2dba7623acbfa11d0e1b",
"input": {
"endAmount": "100000000",
"token": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"startAmount": "100000000"
},
"settledAmounts": [
{
"tokenOut": "0x6B175474E89094C44Da98b954EedeAC495271d0F",
"amountOut": "91371770080538616664"
}
],
"orderStatus": "filled",
"txHash": "0x9f8382a94ee80ca119bc690908ab5f69c4c72f7497ee10f37e9ede0ded83cca6",
"createdAt": 1686339087,
"chainId": 1,
"orderHash": "0xa9dd6f05ad6d6c79bee654c31ede4d0d2392862711be0f3bc4a9124af24a6a19",
"type": "Dutch"
}
]
}

View File

@ -0,0 +1,26 @@
{
"orders": [
{
"outputs": [
{
"recipient": "0x80becb808bfade4143183e58d18f2080e84e57a1",
"startAmount": "91371770080538616664",
"endAmount": "90914911230135923580",
"token": "0x6B175474E89094C44Da98b954EedeAC495271d0F"
}
],
"encodedOrder": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000064837e2a0000000000000000000000000000000000000000000000000000000064837e6600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e1000000000000000000000000000000000000000000000000000000000005f5e1000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000bd7f9d0239f81c94b728d827a87b9864972661ec00000000000000000000000080becb808bfade4143183e58d18f2080e84e57a18e32c6335b6f657322448399bd12ff5c22b7b1aa770850ff4eed36c750e2de000000000000000000000000000000000000000000000000000000000064837e66000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000000000000000000000000004f409bcc7a52b6358000000000000000000000000000000000000000000000004edb2a613726c737c00000000000000000000000080becb808bfade4143183e58d18f2080e84e57a1",
"signature": "0x973882a290778b5c8aae691ef777385259928cde0513d224ea1131538379258d2db7a69804110320b08558380394879a31ab8dea61152c2dba7623acbfa11d0e1b",
"input": {
"endAmount": "100000000",
"token": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"startAmount": "100000000"
},
"orderStatus": "insufficient-funds",
"createdAt": 1686339087,
"chainId": 1,
"orderHash": "0xa9dd6f05ad6d6c79bee654c31ede4d0d2392862711be0f3bc4a9124af24a6a19",
"type": "Dutch"
}
]
}

View File

@ -0,0 +1,26 @@
{
"orders": [
{
"outputs": [
{
"recipient": "0x80becb808bfade4143183e58d18f2080e84e57a1",
"startAmount": "91371770080538616664",
"endAmount": "90914911230135923580",
"token": "0x6B175474E89094C44Da98b954EedeAC495271d0F"
}
],
"encodedOrder": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000064837e2a0000000000000000000000000000000000000000000000000000000064837e6600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e1000000000000000000000000000000000000000000000000000000000005f5e1000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000bd7f9d0239f81c94b728d827a87b9864972661ec00000000000000000000000080becb808bfade4143183e58d18f2080e84e57a18e32c6335b6f657322448399bd12ff5c22b7b1aa770850ff4eed36c750e2de000000000000000000000000000000000000000000000000000000000064837e66000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000000000000000000000000004f409bcc7a52b6358000000000000000000000000000000000000000000000004edb2a613726c737c00000000000000000000000080becb808bfade4143183e58d18f2080e84e57a1",
"signature": "0x973882a290778b5c8aae691ef777385259928cde0513d224ea1131538379258d2db7a69804110320b08558380394879a31ab8dea61152c2dba7623acbfa11d0e1b",
"input": {
"endAmount": "100000000",
"token": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"startAmount": "100000000"
},
"orderStatus": "open",
"createdAt": 1686339087,
"chainId": 1,
"orderHash": "0xa9dd6f05ad6d6c79bee654c31ede4d0d2392862711be0f3bc4a9124af24a6a19",
"type": "Dutch"
}
]
}

View File

@ -0,0 +1 @@
{"hash":"0xa9dd6f05ad6d6c79bee654c31ede4d0d2392862711be0f3bc4a9124af24a6a19"}

View File

@ -0,0 +1,493 @@
{
"routing": "DUTCH_LIMIT",
"quote": {
"orderInfo": {
"chainId": 1,
"permit2Address": "0x000000000022d473030f116ddee9f6b43ac78ba3",
"reactor": "0x6000da47483062A0D734Ba3dc7576Ce6A0B645C4",
"swapper": "0x67d615D6bccAA1562B1cca9786384b4840597ecD",
"nonce": "57335948072881703373319552024074512292695687510330025934414357004397546394368",
"deadline": 1690902198,
"additionalValidationContract": "0x0000000000000000000000000000000000000000",
"additionalValidationData": "0x",
"decayStartTime": 1690902126,
"decayEndTime": 1690902186,
"exclusiveFiller": "0x0000000000000000000000000000000000000000",
"exclusivityOverrideBps": "0",
"input": {
"token": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"startAmount": "300000000",
"endAmount": "300000000"
},
"outputs": [
{
"token": "0x6B175474E89094C44Da98b954EedeAC495271d0F",
"startAmount": "289951120815684452958",
"endAmount": "267060007981523637666",
"recipient": "0x67d615D6bccAA1562B1cca9786384b4840597ecD"
}
]
},
"encodedOrder": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000064c91e6e0000000000000000000000000000000000000000000000000000000064c91eaa00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000011e1a3000000000000000000000000000000000000000000000000000000000011e1a30000000000000000000000000000000000000000000000000000000000000002000000000000000000000000006000da47483062a0d734ba3dc7576ce6a0b645c400000000000000000000000067d615d6bccaa1562b1cca9786384b4840597ecd7ec2ff20796a08922e11fd828e3871a6aa9a80e6495e30cd41be24b7e37953000000000000000000000000000000000000000000000000000000000064c91eb6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000fb7e15027ad3e025e00000000000000000000000000000000000000000000000e7a33be508bb395a200000000000000000000000067d615d6bccaa1562b1cca9786384b4840597ecd",
"quoteId": "f9f47cd7-a62c-4622-9ac7-51d0e662245a",
"requestId": "2d16f993-6429-4755-ba50-1383789459dc",
"auctionPeriodSecs": 60,
"startTimeBufferSecs": 30,
"deadlineBufferSecs": 12,
"slippageTolerance": "0.5",
"permitData": {
"domain": {
"name": "Permit2",
"chainId": 1,
"verifyingContract": "0x000000000022d473030f116ddee9f6b43ac78ba3"
},
"types": {
"PermitWitnessTransferFrom": [
{
"name": "permitted",
"type": "TokenPermissions"
},
{
"name": "spender",
"type": "address"
},
{
"name": "nonce",
"type": "uint256"
},
{
"name": "deadline",
"type": "uint256"
},
{
"name": "witness",
"type": "ExclusiveDutchOrder"
}
],
"TokenPermissions": [
{
"name": "token",
"type": "address"
},
{
"name": "amount",
"type": "uint256"
}
],
"ExclusiveDutchOrder": [
{
"name": "info",
"type": "OrderInfo"
},
{
"name": "decayStartTime",
"type": "uint256"
},
{
"name": "decayEndTime",
"type": "uint256"
},
{
"name": "exclusiveFiller",
"type": "address"
},
{
"name": "exclusivityOverrideBps",
"type": "uint256"
},
{
"name": "inputToken",
"type": "address"
},
{
"name": "inputStartAmount",
"type": "uint256"
},
{
"name": "inputEndAmount",
"type": "uint256"
},
{
"name": "outputs",
"type": "DutchOutput[]"
}
],
"OrderInfo": [
{
"name": "reactor",
"type": "address"
},
{
"name": "swapper",
"type": "address"
},
{
"name": "nonce",
"type": "uint256"
},
{
"name": "deadline",
"type": "uint256"
},
{
"name": "additionalValidationContract",
"type": "address"
},
{
"name": "additionalValidationData",
"type": "bytes"
}
],
"DutchOutput": [
{
"name": "token",
"type": "address"
},
{
"name": "startAmount",
"type": "uint256"
},
{
"name": "endAmount",
"type": "uint256"
},
{
"name": "recipient",
"type": "address"
}
]
},
"values": {
"permitted": {
"token": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"amount": {
"type": "BigNumber",
"hex": "0x11e1a300"
}
},
"spender": "0x6000da47483062A0D734Ba3dc7576Ce6A0B645C4",
"nonce": {
"type": "BigNumber",
"hex": "0x7ec2ff20796a08922e11fd828e3871a6aa9a80e6495e30cd41be24b7e3795300"
},
"deadline": 1690902198,
"witness": {
"info": {
"reactor": "0x6000da47483062A0D734Ba3dc7576Ce6A0B645C4",
"swapper": "0x67d615D6bccAA1562B1cca9786384b4840597ecD",
"nonce": {
"type": "BigNumber",
"hex": "0x7ec2ff20796a08922e11fd828e3871a6aa9a80e6495e30cd41be24b7e3795300"
},
"deadline": 1690902198,
"additionalValidationContract": "0x0000000000000000000000000000000000000000",
"additionalValidationData": "0x"
},
"decayStartTime": 1690902126,
"decayEndTime": 1690902186,
"exclusiveFiller": "0x0000000000000000000000000000000000000000",
"exclusivityOverrideBps": {
"type": "BigNumber",
"hex": "0x00"
},
"inputToken": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"inputStartAmount": {
"type": "BigNumber",
"hex": "0x11e1a300"
},
"inputEndAmount": {
"type": "BigNumber",
"hex": "0x11e1a300"
},
"outputs": [
{
"token": "0x6B175474E89094C44Da98b954EedeAC495271d0F",
"startAmount": {
"type": "BigNumber",
"hex": "0x0fb7e15027ad3e025e"
},
"endAmount": {
"type": "BigNumber",
"hex": "0x0e7a33be508bb395a2"
},
"recipient": "0x67d615D6bccAA1562B1cca9786384b4840597ecD"
}
]
}
}
}
},
"requestId": "2d16f993-6429-4755-ba50-1383789459dc",
"allQuotes": [
{
"routing": "DUTCH_LIMIT",
"quote": {
"orderInfo": {
"chainId": 1,
"permit2Address": "0x000000000022d473030f116ddee9f6b43ac78ba3",
"reactor": "0x6000da47483062A0D734Ba3dc7576Ce6A0B645C4",
"swapper": "0x67d615D6bccAA1562B1cca9786384b4840597ecD",
"nonce": "57335948072881703373319552024074512292695687510330025934414357004397546394368",
"deadline": 1690902198,
"additionalValidationContract": "0x0000000000000000000000000000000000000000",
"additionalValidationData": "0x",
"decayStartTime": 1690902126,
"decayEndTime": 1690902186,
"exclusiveFiller": "0x0000000000000000000000000000000000000000",
"exclusivityOverrideBps": "0",
"input": {
"token": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"startAmount": "300000000",
"endAmount": "300000000"
},
"outputs": [
{
"token": "0x6B175474E89094C44Da98b954EedeAC495271d0F",
"startAmount": "289951120815684452958",
"endAmount": "267060007981523637666",
"recipient": "0x67d615D6bccAA1562B1cca9786384b4840597ecD"
}
]
},
"encodedOrder": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000064c91e6e0000000000000000000000000000000000000000000000000000000064c91eaa00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000011e1a3000000000000000000000000000000000000000000000000000000000011e1a30000000000000000000000000000000000000000000000000000000000000002000000000000000000000000006000da47483062a0d734ba3dc7576ce6a0b645c400000000000000000000000067d615d6bccaa1562b1cca9786384b4840597ecd7ec2ff20796a08922e11fd828e3871a6aa9a80e6495e30cd41be24b7e37953000000000000000000000000000000000000000000000000000000000064c91eb6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000fb7e15027ad3e025e00000000000000000000000000000000000000000000000e7a33be508bb395a200000000000000000000000067d615d6bccaa1562b1cca9786384b4840597ecd",
"quoteId": "f9f47cd7-a62c-4622-9ac7-51d0e662245a",
"requestId": "2d16f993-6429-4755-ba50-1383789459dc",
"auctionPeriodSecs": 60,
"startTimeBufferSecs": 30,
"deadlineBufferSecs": 12,
"slippageTolerance": "0.5",
"permitData": {
"domain": {
"name": "Permit2",
"chainId": 1,
"verifyingContract": "0x000000000022d473030f116ddee9f6b43ac78ba3"
},
"types": {
"PermitWitnessTransferFrom": [
{
"name": "permitted",
"type": "TokenPermissions"
},
{
"name": "spender",
"type": "address"
},
{
"name": "nonce",
"type": "uint256"
},
{
"name": "deadline",
"type": "uint256"
},
{
"name": "witness",
"type": "ExclusiveDutchOrder"
}
],
"TokenPermissions": [
{
"name": "token",
"type": "address"
},
{
"name": "amount",
"type": "uint256"
}
],
"ExclusiveDutchOrder": [
{
"name": "info",
"type": "OrderInfo"
},
{
"name": "decayStartTime",
"type": "uint256"
},
{
"name": "decayEndTime",
"type": "uint256"
},
{
"name": "exclusiveFiller",
"type": "address"
},
{
"name": "exclusivityOverrideBps",
"type": "uint256"
},
{
"name": "inputToken",
"type": "address"
},
{
"name": "inputStartAmount",
"type": "uint256"
},
{
"name": "inputEndAmount",
"type": "uint256"
},
{
"name": "outputs",
"type": "DutchOutput[]"
}
],
"OrderInfo": [
{
"name": "reactor",
"type": "address"
},
{
"name": "swapper",
"type": "address"
},
{
"name": "nonce",
"type": "uint256"
},
{
"name": "deadline",
"type": "uint256"
},
{
"name": "additionalValidationContract",
"type": "address"
},
{
"name": "additionalValidationData",
"type": "bytes"
}
],
"DutchOutput": [
{
"name": "token",
"type": "address"
},
{
"name": "startAmount",
"type": "uint256"
},
{
"name": "endAmount",
"type": "uint256"
},
{
"name": "recipient",
"type": "address"
}
]
},
"values": {
"permitted": {
"token": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"amount": {
"type": "BigNumber",
"hex": "0x11e1a300"
}
},
"spender": "0x6000da47483062A0D734Ba3dc7576Ce6A0B645C4",
"nonce": {
"type": "BigNumber",
"hex": "0x7ec2ff20796a08922e11fd828e3871a6aa9a80e6495e30cd41be24b7e3795300"
},
"deadline": 1690902198,
"witness": {
"info": {
"reactor": "0x6000da47483062A0D734Ba3dc7576Ce6A0B645C4",
"swapper": "0x67d615D6bccAA1562B1cca9786384b4840597ecD",
"nonce": {
"type": "BigNumber",
"hex": "0x7ec2ff20796a08922e11fd828e3871a6aa9a80e6495e30cd41be24b7e3795300"
},
"deadline": 1690902198,
"additionalValidationContract": "0x0000000000000000000000000000000000000000",
"additionalValidationData": "0x"
},
"decayStartTime": 1690902126,
"decayEndTime": 1690902186,
"exclusiveFiller": "0x0000000000000000000000000000000000000000",
"exclusivityOverrideBps": {
"type": "BigNumber",
"hex": "0x00"
},
"inputToken": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"inputStartAmount": {
"type": "BigNumber",
"hex": "0x11e1a300"
},
"inputEndAmount": {
"type": "BigNumber",
"hex": "0x11e1a300"
},
"outputs": [
{
"token": "0x6B175474E89094C44Da98b954EedeAC495271d0F",
"startAmount": {
"type": "BigNumber",
"hex": "0x0fb7e15027ad3e025e"
},
"endAmount": {
"type": "BigNumber",
"hex": "0x0e7a33be508bb395a2"
},
"recipient": "0x67d615D6bccAA1562B1cca9786384b4840597ecD"
}
]
}
}
}
}
},
{
"routing": "CLASSIC",
"quote": {
"blockNumber": "17820918",
"amount": "300000000",
"amountDecimals": "300",
"quote": "299952256425393549464",
"quoteDecimals": "299.952256425393549464",
"quoteGasAdjusted": "289922128602824170541",
"quoteGasAdjustedDecimals": "289.922128602824170541",
"gasUseEstimateQuote": "10030127822569378922",
"gasUseEstimateQuoteDecimals": "10.030127822569378922",
"gasUseEstimate": "128000",
"gasUseEstimateUSD": "10.031724",
"simulationStatus": "UNATTEMPTED",
"simulationError": false,
"gasPriceWei": "42803167855",
"route": [
[
{
"type": "v3-pool",
"address": "0x5777d92f208679DB4b9778590Fa3CAB3aC9e2168",
"tokenIn": {
"chainId": 1,
"decimals": "6",
"address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"symbol": "USDC"
},
"tokenOut": {
"chainId": 1,
"decimals": "18",
"address": "0x6B175474E89094C44Da98b954EedeAC495271d0F",
"symbol": "DAI"
},
"fee": "100",
"liquidity": "534676532046235168447130",
"sqrtRatioX96": "79230505815006815109584",
"tickCurrent": "-276324",
"amountIn": "300000000",
"amountOut": "299952256425393549464"
}
]
],
"routeString": "[V3] 100.00% = USDC -- 0.01% [0x5777d92f208679DB4b9778590Fa3CAB3aC9e2168] --> DAI",
"quoteId": "1dd3bd14-780e-41c6-88e1-30a763f97482",
"requestId": "2d16f993-6429-4755-ba50-1383789459dc",
"tradeType": "EXACT_INPUT",
"slippage": 0.5
}
}
]
}

View File

@ -0,0 +1,493 @@
{
"routing": "DUTCH_LIMIT",
"quote": {
"orderInfo": {
"chainId": 1,
"permit2Address": "0x000000000022d473030f116ddee9f6b43ac78ba3",
"reactor": "0x6000da47483062A0D734Ba3dc7576Ce6A0B645C4",
"swapper": "0x0000000000000000000000000000000000000000",
"nonce": "1993350209834725680308575292465150260730647098062962750049345504775310970881",
"deadline": 1691176812,
"additionalValidationContract": "0x0000000000000000000000000000000000000000",
"additionalValidationData": "0x",
"decayStartTime": 1691176740,
"decayEndTime": 1691176800,
"exclusiveFiller": "0x165D98de005d2818176B99B1A93b9325dBE58181",
"exclusivityOverrideBps": "100",
"input": {
"token": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
"startAmount": "1000000000000000000",
"endAmount": "1000000000000000000"
},
"outputs": [
{
"token": "0x6B175474E89094C44Da98b954EedeAC495271d0F",
"startAmount": "929502510517534478575",
"endAmount": "919795986077127665276",
"recipient": "0x0000000000000000000000000000000000000000"
}
]
},
"encodedOrder": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000064cd4f240000000000000000000000000000000000000000000000000000000064cd4f60000000000000000000000000165d98de005d2818176b99b1a93b9325dbe581810000000000000000000000000000000000000000000000000000000000000064000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000006000da47483062a0d734ba3dc7576ce6a0b645c400000000000000000000000000000000000000000000000000000000000000000468323c9682990e3dc0646f899b437e62fbfb52a63cc8de721280222d8090010000000000000000000000000000000000000000000000000000000064cd4f6c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000092d6c1e31e14520e676a687f0a93788b716beff500000000000000000000000000000000000000000000003263704899af6e50ef000000000000000000000000000000000000000000000031dcbbc80c9555e67c0000000000000000000000000000000000000000000000000000000000000000",
"quoteId": "09ce28b7-1ddf-4317-a28d-d21092be9f84",
"requestId": "f00535d4-461a-4363-afbe-7a5ab7061cd1",
"auctionPeriodSecs": 60,
"startTimeBufferSecs": 30,
"deadlineBufferSecs": 12,
"slippageTolerance": "0.5",
"permitData": {
"domain": {
"name": "Permit2",
"chainId": 1,
"verifyingContract": "0x000000000022d473030f116ddee9f6b43ac78ba3"
},
"types": {
"PermitWitnessTransferFrom": [
{
"name": "permitted",
"type": "TokenPermissions"
},
{
"name": "spender",
"type": "address"
},
{
"name": "nonce",
"type": "uint256"
},
{
"name": "deadline",
"type": "uint256"
},
{
"name": "witness",
"type": "ExclusiveDutchOrder"
}
],
"TokenPermissions": [
{
"name": "token",
"type": "address"
},
{
"name": "amount",
"type": "uint256"
}
],
"ExclusiveDutchOrder": [
{
"name": "info",
"type": "OrderInfo"
},
{
"name": "decayStartTime",
"type": "uint256"
},
{
"name": "decayEndTime",
"type": "uint256"
},
{
"name": "exclusiveFiller",
"type": "address"
},
{
"name": "exclusivityOverrideBps",
"type": "uint256"
},
{
"name": "inputToken",
"type": "address"
},
{
"name": "inputStartAmount",
"type": "uint256"
},
{
"name": "inputEndAmount",
"type": "uint256"
},
{
"name": "outputs",
"type": "DutchOutput[]"
}
],
"OrderInfo": [
{
"name": "reactor",
"type": "address"
},
{
"name": "swapper",
"type": "address"
},
{
"name": "nonce",
"type": "uint256"
},
{
"name": "deadline",
"type": "uint256"
},
{
"name": "additionalValidationContract",
"type": "address"
},
{
"name": "additionalValidationData",
"type": "bytes"
}
],
"DutchOutput": [
{
"name": "token",
"type": "address"
},
{
"name": "startAmount",
"type": "uint256"
},
{
"name": "endAmount",
"type": "uint256"
},
{
"name": "recipient",
"type": "address"
}
]
},
"values": {
"permitted": {
"token": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
"amount": {
"type": "BigNumber",
"hex": "0x0de0b6b3a7640000"
}
},
"spender": "0x6000da47483062A0D734Ba3dc7576Ce6A0B645C4",
"nonce": {
"type": "BigNumber",
"hex": "0x0468323c9682990e3dc0646f899b437e62fbfb52a63cc8de721280222d809001"
},
"deadline": 1691176812,
"witness": {
"info": {
"reactor": "0x6000da47483062A0D734Ba3dc7576Ce6A0B645C4",
"swapper": "0x0000000000000000000000000000000000000000",
"nonce": {
"type": "BigNumber",
"hex": "0x0468323c9682990e3dc0646f899b437e62fbfb52a63cc8de721280222d809001"
},
"deadline": 1691176812,
"additionalValidationContract": "0x0000000000000000000000000000000000000000",
"additionalValidationData": "0x"
},
"decayStartTime": 1691176740,
"decayEndTime": 1691176800,
"exclusiveFiller": "0x165D98de005d2818176B99B1A93b9325dBE58181",
"exclusivityOverrideBps": {
"type": "BigNumber",
"hex": "0x64"
},
"inputToken": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
"inputStartAmount": {
"type": "BigNumber",
"hex": "0x0de0b6b3a7640000"
},
"inputEndAmount": {
"type": "BigNumber",
"hex": "0x0de0b6b3a7640000"
},
"outputs": [
{
"token": "0x6B175474E89094C44Da98b954EedeAC495271d0F",
"startAmount": {
"type": "BigNumber",
"hex": "0x3263704899af6e50ef"
},
"endAmount": {
"type": "BigNumber",
"hex": "0x31dcbbc80c9555e67c"
},
"recipient": "0x0000000000000000000000000000000000000000"
}
]
}
}
}
},
"requestId": "f00535d4-461a-4363-afbe-7a5ab7061cd1",
"allQuotes": [
{
"routing": "DUTCH_LIMIT",
"quote": {
"orderInfo": {
"chainId": 1,
"permit2Address": "0x000000000022d473030f116ddee9f6b43ac78ba3",
"reactor": "0x6000da47483062A0D734Ba3dc7576Ce6A0B645C4",
"swapper": "0x0000000000000000000000000000000000000000",
"nonce": "1993350209834725680308575292465150260730647098062962750049345504775310970881",
"deadline": 1691176812,
"additionalValidationContract": "0x0000000000000000000000000000000000000000",
"additionalValidationData": "0x",
"decayStartTime": 1691176740,
"decayEndTime": 1691176800,
"exclusiveFiller": "0x165D98de005d2818176B99B1A93b9325dBE58181",
"exclusivityOverrideBps": "100",
"input": {
"token": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
"startAmount": "1000000000000000000",
"endAmount": "1000000000000000000"
},
"outputs": [
{
"token": "0x6B175474E89094C44Da98b954EedeAC495271d0F",
"startAmount": "929502510517534478575",
"endAmount": "919795986077127665276",
"recipient": "0x0000000000000000000000000000000000000000"
}
]
},
"encodedOrder": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000064cd4f240000000000000000000000000000000000000000000000000000000064cd4f60000000000000000000000000165d98de005d2818176b99b1a93b9325dbe581810000000000000000000000000000000000000000000000000000000000000064000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000006000da47483062a0d734ba3dc7576ce6a0b645c400000000000000000000000000000000000000000000000000000000000000000468323c9682990e3dc0646f899b437e62fbfb52a63cc8de721280222d8090010000000000000000000000000000000000000000000000000000000064cd4f6c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000092d6c1e31e14520e676a687f0a93788b716beff500000000000000000000000000000000000000000000003263704899af6e50ef000000000000000000000000000000000000000000000031dcbbc80c9555e67c0000000000000000000000000000000000000000000000000000000000000000",
"quoteId": "09ce28b7-1ddf-4317-a28d-d21092be9f84",
"requestId": "f00535d4-461a-4363-afbe-7a5ab7061cd1",
"auctionPeriodSecs": 60,
"startTimeBufferSecs": 30,
"deadlineBufferSecs": 12,
"slippageTolerance": "0.5",
"permitData": {
"domain": {
"name": "Permit2",
"chainId": 1,
"verifyingContract": "0x000000000022d473030f116ddee9f6b43ac78ba3"
},
"types": {
"PermitWitnessTransferFrom": [
{
"name": "permitted",
"type": "TokenPermissions"
},
{
"name": "spender",
"type": "address"
},
{
"name": "nonce",
"type": "uint256"
},
{
"name": "deadline",
"type": "uint256"
},
{
"name": "witness",
"type": "ExclusiveDutchOrder"
}
],
"TokenPermissions": [
{
"name": "token",
"type": "address"
},
{
"name": "amount",
"type": "uint256"
}
],
"ExclusiveDutchOrder": [
{
"name": "info",
"type": "OrderInfo"
},
{
"name": "decayStartTime",
"type": "uint256"
},
{
"name": "decayEndTime",
"type": "uint256"
},
{
"name": "exclusiveFiller",
"type": "address"
},
{
"name": "exclusivityOverrideBps",
"type": "uint256"
},
{
"name": "inputToken",
"type": "address"
},
{
"name": "inputStartAmount",
"type": "uint256"
},
{
"name": "inputEndAmount",
"type": "uint256"
},
{
"name": "outputs",
"type": "DutchOutput[]"
}
],
"OrderInfo": [
{
"name": "reactor",
"type": "address"
},
{
"name": "swapper",
"type": "address"
},
{
"name": "nonce",
"type": "uint256"
},
{
"name": "deadline",
"type": "uint256"
},
{
"name": "additionalValidationContract",
"type": "address"
},
{
"name": "additionalValidationData",
"type": "bytes"
}
],
"DutchOutput": [
{
"name": "token",
"type": "address"
},
{
"name": "startAmount",
"type": "uint256"
},
{
"name": "endAmount",
"type": "uint256"
},
{
"name": "recipient",
"type": "address"
}
]
},
"values": {
"permitted": {
"token": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
"amount": {
"type": "BigNumber",
"hex": "0x0de0b6b3a7640000"
}
},
"spender": "0x6000da47483062A0D734Ba3dc7576Ce6A0B645C4",
"nonce": {
"type": "BigNumber",
"hex": "0x0468323c9682990e3dc0646f899b437e62fbfb52a63cc8de721280222d809001"
},
"deadline": 1691176812,
"witness": {
"info": {
"reactor": "0x6000da47483062A0D734Ba3dc7576Ce6A0B645C4",
"swapper": "0x0000000000000000000000000000000000000000",
"nonce": {
"type": "BigNumber",
"hex": "0x0468323c9682990e3dc0646f899b437e62fbfb52a63cc8de721280222d809001"
},
"deadline": 1691176812,
"additionalValidationContract": "0x0000000000000000000000000000000000000000",
"additionalValidationData": "0x"
},
"decayStartTime": 1691176740,
"decayEndTime": 1691176800,
"exclusiveFiller": "0x165D98de005d2818176B99B1A93b9325dBE58181",
"exclusivityOverrideBps": {
"type": "BigNumber",
"hex": "0x64"
},
"inputToken": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
"inputStartAmount": {
"type": "BigNumber",
"hex": "0x0de0b6b3a7640000"
},
"inputEndAmount": {
"type": "BigNumber",
"hex": "0x0de0b6b3a7640000"
},
"outputs": [
{
"token": "0x6B175474E89094C44Da98b954EedeAC495271d0F",
"startAmount": {
"type": "BigNumber",
"hex": "0x3263704899af6e50ef"
},
"endAmount": {
"type": "BigNumber",
"hex": "0x31dcbbc80c9555e67c"
},
"recipient": "0x0000000000000000000000000000000000000000"
}
]
}
}
}
}
},
{
"routing": "CLASSIC",
"quote": {
"blockNumber": "17843654",
"amount": "1000000000000000000",
"amountDecimals": "1",
"quote": "931181529570145926787",
"quoteDecimals": "931.181529570145926787",
"quoteGasAdjusted": "929033336026294051828",
"quoteGasAdjustedDecimals": "929.033336026294051828",
"gasUseEstimateQuote": "2148193543851874958",
"gasUseEstimateQuoteDecimals": "2.148193543851874958",
"gasUseEstimate": "128000",
"gasUseEstimateUSD": "4.174934",
"simulationStatus": "UNATTEMPTED",
"simulationError": false,
"gasPriceWei": "17811260539",
"route": [
[
{
"type": "v3-pool",
"address": "0xD8de6af55F618a7Bc69835D55DDC6582220c36c0",
"tokenIn": {
"chainId": 1,
"decimals": "18",
"address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
"symbol": "WETH"
},
"tokenOut": {
"chainId": 1,
"decimals": "18",
"address": "0x6B175474E89094C44Da98b954EedeAC495271d0F",
"symbol": "DAI"
},
"fee": "3000",
"liquidity": "62287359628325896425115",
"sqrtRatioX96": "2591813593283507889384697884",
"tickCurrent": "-68403",
"amountIn": "1000000000000000000",
"amountOut": "931181529570145926787"
}
]
],
"routeString": "[V3] 100.00% = WETH -- 0.3% [0xD8de6af55F618a7Bc69835D55DDC6582220c36c0] --> DAI",
"quoteId": "414e5f1c-120a-4e35-9760-c54d4b09e91d",
"requestId": "f00535d4-461a-4363-afbe-7a5ab7061cd1",
"tradeType": "EXACT_INPUT",
"slippage": 0.5
}
}
]
}

View File

@ -0,0 +1,19 @@
import { getTestSelector } from '../utils'
describe('translations', () => {
it('loads locale from the query param', () => {
cy.visit('/?lng=fr-FR')
cy.contains('Échanger')
cy.contains('Uniswap disponible en : English')
})
it('loads locale from menu', () => {
cy.visit('/')
cy.get(getTestSelector('web3-status-connected')).click()
cy.get(getTestSelector('wallet-settings')).click()
cy.get(getTestSelector('wallet-language-item')).contains('français').click({ force: true })
cy.location('search').should('match', /\?lng=fr-FR$/)
cy.contains('Échanger')
cy.contains('Uniswap disponible en : English')
})
})

View File

@ -0,0 +1,91 @@
import 'cypress-hardhat/lib/browser'
import { Eip1193Bridge } from '@ethersproject/experimental/lib/eip1193-bridge'
import { FeatureFlag } from '../../src/featureFlags'
import { initialState, UserState } from '../../src/state/user/reducer'
import { CONNECTED_WALLET_USER_STATE, setInitialUserState } from '../utils/user-state'
declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace Cypress {
interface ApplicationWindow {
ethereum: Eip1193Bridge
}
interface Chainable<Subject> {
/**
* Wait for a specific event to be sent to amplitude. If the event is found, the subject will be the event.
*
* @param {string} eventName - The type of the event to search for e.g. SwapEventName.SWAP_TRANSACTION_COMPLETED
* @param {number} timeout - The maximum amount of time (in ms) to wait for the event.
* @returns {Chainable<Subject>}
*/
waitForAmplitudeEvent(eventName: string, timeout?: number): Chainable<Subject>
}
interface VisitOptions {
serviceWorker?: true
featureFlags?: Array<{ name: FeatureFlag; value: boolean }>
/**
* Initial user state.
* @default {@type import('../utils/user-state').CONNECTED_WALLET_USER_STATE}
*/
userState?: Partial<UserState>
}
}
}
// 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>) => {
if (typeof url !== 'string') throw new Error('Invalid arguments. The first argument to cy.visit must be the path.')
return cy
.intercept('/service-worker.js', options?.serviceWorker ? undefined : { statusCode: 404 })
.provider()
.then((provider) =>
original({
...options,
url,
onBeforeLoad(win) {
options?.onBeforeLoad?.(win)
setInitialUserState(win, {
...initialState,
...CONNECTED_WALLET_USER_STATE,
...(options?.userState ?? {}),
})
// Set feature flags, if configured.
if (options?.featureFlags) {
const featureFlags = options.featureFlags.reduce(
(flags, flag) => ({ ...flags, [flag.name]: flag.value ? 'enabled' : 'control' }),
{}
)
win.localStorage.setItem('featureFlags', JSON.stringify(featureFlags))
}
// Inject the mock ethereum provider.
win.ethereum = provider
},
})
)
}
)
Cypress.Commands.add('waitForAmplitudeEvent', (eventName) => {
function checkRequest() {
return cy.wait('@amplitude').then((interception) => {
const events = interception.request.body.events
const event = events.find((event: any) => event.event_type === eventName)
if (event) {
return cy.wrap(event)
} else {
return checkRequest()
}
})
}
return checkRequest()
})

View File

@ -5,90 +5,17 @@
// https://on.cypress.io/configuration
// ***********************************************************
// Import commands.ts using ES2015 syntax:
import '@cypress/code-coverage/support'
import './commands'
import './setupTests'
import assert from 'assert'
import { FeatureFlag } from '../../src/featureFlags/flags/featureFlags'
import { injected } from './ethereum'
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) +
`${url.includes('?') ? '&' : '?'}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.alias = res.body.method
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()
})
})
// Squelch logs from fetches, as they clutter the logs so much as to make them unusable.
// See https://docs.cypress.io/api/commands/intercept#Disabling-logs-for-a-request.
// TODO(https://github.com/cypress-io/cypress/issues/26069): Squelch only wildcard logs once Cypress allows it.
const log = Cypress.log
Cypress.log = function (options, ...args) {
if (options.displayName === 'script' || options.name === 'request') return
return log(options, ...args)
} as typeof log
Cypress.on('uncaught:exception', () => {
// returning false here prevents Cypress from failing the test

View File

@ -1,74 +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'
import { SupportedChainId } from '../../src/constants/chains'
// 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 CHAIN_ID = SupportedChainId.GOERLI
const HEXLIFIED_CHAIN_ID = `0x${CHAIN_ID.toString(16)}`
const provider = new JsonRpcProvider('https://goerli.infura.io/v3/4bf032f2d38a4ed6bb975b80d6340847', 5)
const signer = new Wallet(TEST_PRIVATE_KEY, provider)
export const injected = new (class extends Eip1193Bridge {
chainId = CHAIN_ID
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: HEXLIFIED_CHAIN_ID })
} else {
return Promise.resolve(HEXLIFIED_CHAIN_ID)
}
}
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

@ -0,0 +1,66 @@
// @ts-ignore
import TokenListJSON from '@uniswap/default-token-list'
import { CyHttpMessages } from 'cypress/types/net-stubbing'
beforeEach(() => {
// Many API calls enforce that requests come from our app, so we must mock Origin and Referer.
cy.intercept('*', (req) => {
req.headers['referer'] = 'https://app.uniswap.org'
req.headers['origin'] = 'https://app.uniswap.org'
})
// Network RPCs are disabled for cypress tests - calls should be routed through the connected wallet instead.
cy.intercept(/infura.io/, { statusCode: 404 })
cy.intercept(/quiknode.pro/, { statusCode: 404 })
// Log requests to hardhat.
cy.intercept(/:8545/, logJsonRpc)
// Mock analytics responses to avoid analytics in tests.
cy.intercept('https://api.uniswap.org/v1/amplitude-proxy', (req) => {
const requestBody = JSON.stringify(req.body)
const byteSize = new Blob([requestBody]).size
req.alias = 'amplitude'
req.reply(
JSON.stringify({
code: 200,
server_upload_time: Date.now(),
payload_size_bytes: byteSize,
events_ingested: req.body.events.length,
}),
{
'origin-country': 'US',
}
)
}).intercept('https://*.sentry.io', { statusCode: 200 })
// Mock statsig to allow us to mock flags.
cy.intercept(/statsig/, { statusCode: 409 })
// Mock our own token list responses to avoid the latency of IPFS.
cy.intercept('https://gateway.ipfs.io/ipns/tokens.uniswap.org', TokenListJSON)
.intercept('https://gateway.ipfs.io/ipns/extendedtokens.uniswap.org', { statusCode: 404 })
.intercept('https://gateway.ipfs.io/ipns/unsupportedtokens.uniswap.org', { statusCode: 404 })
// Reset hardhat between tests to ensure isolation.
// This resets the fork, as well as options like automine.
cy.hardhat().then((hardhat) => hardhat.reset())
})
function logJsonRpc(req: CyHttpMessages.IncomingHttpRequest) {
req.alias = req.body.method
const log = Cypress.log({
autoEnd: false,
name: req.body.method,
message: req.body.params?.map((param: any) =>
typeof param === 'object' ? '{...}' : param?.toString().substring(0, 10)
),
})
req.on('after:response', (res) => {
if (res.statusCode === 200) {
log.end()
} else {
log.error(new Error(`${res.statusCode}: ${res.statusMessage}`))
}
})
}

View File

@ -1,17 +1,13 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"esModuleInterop": true,
"composite": false,
"incremental": true,
"lib": ["DOM", "DOM.Iterable", "ESNext"],
"noEmit": true,
"strict": true,
"target": "ES5",
"isolatedModules": false,
"noImplicitAny": false,
"target": "ES6",
"tsBuildInfoFile": "../node_modules/.cache/tsbuildinfo/cypress", // avoid clobbering the build tsbuildinfo
"types": ["cypress", "node"]
"types": ["cypress", "node"],
},
"exclude": ["node_modules"],
"include": ["**/*.ts"],
"watchOptions": {
"excludeDirectories": ["node_modules"]
}
}

View File

@ -1,5 +1,13 @@
import { Currency } from '@uniswap/sdk-core'
export const getTestSelector = (selectorId: string) => `[data-testid=${selectorId}]`
export const getTestSelectorStartsWith = (selectorId: string) => `[data-testid^=${selectorId}]`
export const getClassContainsSelector = (selectorId: string) => `[class*=${selectorId}]`
/** Gets the balance of a token as a Chainable. */
export function getBalance(token: Currency) {
return cy
.hardhat()
.then((hardhat) => hardhat.getBalance(hardhat.wallet, token))
.then((balance) => Number(balance.toFixed(1)))
}

View File

@ -0,0 +1,42 @@
import { connectionMetaKey } from '../../src/connection/meta'
import { ConnectionType } from '../../src/connection/types'
import { UserState } from '../../src/state/user/reducer'
export const CONNECTED_WALLET_USER_STATE: Partial<UserState> = { selectedWallet: ConnectionType.INJECTED }
export const DISCONNECTED_WALLET_USER_STATE: Partial<UserState> = { selectedWallet: undefined }
/**
* This sets the initial value of the "user" slice in IndexedDB.
* Other persisted slices are not set, so they will be filled with their respective initial values
* when the app runs.
*/
export function setInitialUserState(win: Cypress.AUTWindow, state: UserState) {
// Selected wallet should also be reflected in localStorage, so that eager connections work.
if (state.selectedWallet) {
win.localStorage.setItem(
connectionMetaKey,
JSON.stringify({
type: state.selectedWallet,
})
)
}
win.indexedDB.deleteDatabase('redux')
const dbRequest = win.indexedDB.open('redux')
dbRequest.onsuccess = function () {
const db = dbRequest.result
const transaction = db.transaction('keyvaluepairs', 'readwrite')
const store = transaction.objectStore('keyvaluepairs')
store.put(
{
user: state,
},
'persist:interface'
)
}
dbRequest.onupgradeneeded = function () {
const db = dbRequest.result
db.createObjectStore('keyvaluepairs')
}
}

View File

@ -0,0 +1,44 @@
/* eslint-env node */
module.exports = {
meta: {
type: 'suggestion',
docs: {
description: 'Enforce the use of optional object fields',
category: 'Best Practices',
recommended: true,
},
fixable: 'code',
schema: [],
},
create(context) {
return {
'TSPropertySignature > TSTypeAnnotation > TSUnionType': (node) => {
const types = node.types
const hasUndefined = types.some((typeNode) => typeNode.type === 'TSUndefinedKeyword')
if (hasUndefined) {
const typesWithoutUndefined = types.filter((typeNode) => typeNode.type !== 'TSUndefinedKeyword')
// If there is more than one type left after removing 'undefined',
// join them together with ' | ' to create a new union type.
const newTypeSource =
typesWithoutUndefined.length > 1
? typesWithoutUndefined.map((typeNode) => context.getSourceCode().getText(typeNode)).join(' | ')
: context.getSourceCode().getText(typesWithoutUndefined[0])
context.report({
node,
message: `Prefer optional properties to "Type | undefined".`,
fix(fixer) {
const propertySignature = node.parent.parent
const isAlreadyOptional = propertySignature.optional
const newTypeAnnotation = isAlreadyOptional ? `: ${newTypeSource}` : `?: ${newTypeSource}`
return fixer.replaceText(node.parent, newTypeAnnotation)
},
})
}
},
}
},
}

50
functions/README.md Normal file
View File

@ -0,0 +1,50 @@
# Cloudflare Cloud Functions
## Purpose
These functions utilize Cloudflare Functions to dynamically inject meta tags server side for richer link sharing capabilities.
## Functions
Currently, there are 2 types of cloudflare functions developed
- Meta Data Injectors - Workers that inject [Open Graph](https://ogp.me/) standardized meta tags into the `header` of specific webpages.
- Currently we support this functionaltiy for three separate webpages: NFT Assets, NFT Collections, and Token Detail Pages
- These functions query data from GraphQL and then formats them into HTML `meta` tags to be injected
- Dynamically Generated Images - Utilizes Vercel's [Open Graph Image Generation Library](https://vercel.com/docs/concepts/functions/edge-functions/og-image-generation) to create custom thumbnails for specific webpages
- Currently supports NFT Assets, NFT Collections, and Token Detail Pages
- These functions query data from GraphQL, and utilize `Satori` to convert HTML into a png image response which is then returned when the api is called.
- Can be found in the `api/image` folder.
## Testing
Testing is done utilizing a custom jest environment as well as Cloudflare's local tester: `wrangler`. Wrangler enables testing locally by running a proxy to wrap `localhost`. Tests run against a proxy server, so you'll need to start it before running tests:
- Manually run `yarn start:cloud` to setup wrangler on `localhost:3000`
- Run unit tests with `yarn test:cloud`
## Deployment
Functions will be deployed to Cloudlfare where they will be ran automatically when the appropriate route is hit.
## Miscellaneous
- Caching: In order to speed up webpage requests, repeated GraphQL queries will be saved and pulled using Cloudflare's Cache API.
## Scripts
- `yarn start:cloud` (NODE_OPTIONS=--dns-result-order=ipv4first PORT=3001 npx wrangler pages dev --node-compat --proxy=3001 --port=3000 -- yarn start), script to start local wrangler environment
- `npx wrangler pages dev`: this basis of this command which starts a local instance of wrangler to test cloud functions
- `--node-compat`: wrangler option that enables compatibility with Node.js modules
- `--proxy:3001`: telling the proxy to listen on port 3001
- `--port=3000`: telling wrangler to run our proxy on port 3000
- `NODE_OPTIONS=--dns-result-order=ipv4first`: wrangler still serves to IPv4 which isn't compatible with Node 18 which default resolves to IPv6 so we need to specify to serve to IPv4
- `PORT-3001 --yarn start`: runs default yarn start on port 3001
- `yarn test:cloud` (NODE_OPTIONS=--experimental-vm-modules yarn jest functions --watch --config=functions/jest.config.json), script to test cloud functions with jest
- `NODE_OPTIONS=--experimental-vm-modules`: support for ES Modules and Web Assembly
- `--config=functions/jest.config.json`: specifying which config file to use
## Additional Documents
- [Open Graph Protocol](https://ogp.me/)
- [Open Graph Image Generation](https://vercel.com/docs/concepts/functions/edge-functions/og-image-generation)
- [Cloudflare Workers](https://developers.cloudflare.com/workers/)
- [HTML Rewriter](https://developers.cloudflare.com/workers/runtime-apis/html-rewriter/)
- [Cache API](https://developers.cloudflare.com/workers/runtime-apis/cache/)

18
functions/[[index]].ts Normal file
View File

@ -0,0 +1,18 @@
/* eslint-disable import/no-unused-modules */
import { MetaTagInjector } from './components/metaTagInjector'
export const onRequest: PagesFunction = async ({ request, next }) => {
const imageUri = new URL(request.url).origin + '/images/1200x630_Rich_Link_Preview_Image.png'
const data = {
title: 'Uniswap Interface',
image: imageUri,
url: request.url,
description: 'Swap or provide liquidity on the Uniswap Protocol',
}
const res = next()
try {
return new HTMLRewriter().on('head', new MetaTagInjector(data, request)).transform(await res)
} catch (e) {
return res
}
}

View File

@ -0,0 +1,76 @@
/* eslint-disable import/no-unused-modules */
import { ImageResponse } from '@vercel/og'
import React from 'react'
import { blocklistedCollections } from '../../../../../src/nft/utils/blocklist'
import { WATERMARK_URL } from '../../../../constants'
import getAsset from '../../../../utils/getAsset'
import getFont from '../../../../utils/getFont'
import { getRequest } from '../../../../utils/getRequest'
export const onRequest: PagesFunction = async ({ params, request }) => {
try {
const origin = new URL(request.url).origin
const { index } = params
const collectionAddress = index[0]?.toString()
const tokenId = index[1]?.toString()
const cacheUrl = origin + '/nfts/asset/' + collectionAddress + '/' + tokenId
if (blocklistedCollections.includes(collectionAddress)) {
return new Response('Collection unsupported.', { status: 404 })
}
const data = await getRequest(
cacheUrl,
() => getAsset(collectionAddress, tokenId, cacheUrl),
(data): data is NonNullable<Awaited<ReturnType<typeof getAsset>>> => Boolean(data.ogImage)
)
if (!data) {
return new Response('Asset not found.', { status: 404 })
}
const fontData = await getFont(origin)
return new ImageResponse(
(
<div
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'column',
width: '1200px',
height: '630px',
}}
>
<img src={data.ogImage} alt={data.title} width="1200px" />
<div
style={{
position: 'absolute',
bottom: '72px',
right: '72px',
display: 'flex',
gap: '24px',
}}
>
<img src={WATERMARK_URL} alt="Uniswap" height="72px" width="324px" />
</div>
</div>
),
{
width: 1200,
height: 630,
fonts: [
{
name: 'Inter',
data: fontData,
style: 'normal',
},
],
}
) as Response
} catch (error: any) {
return new Response(error.message || error.toString(), { status: 500 })
}
}

View File

@ -0,0 +1,29 @@
const assetImageUrl = [
'http://127.0.0.1:3000/api/image/nfts/asset/0xed5af388653567af2f388e6224dc7c4b3241c544/804',
'http://127.0.0.1:3000/api/image/nfts/asset/0xb47e3cd837ddf8e4c57f05d70ab865de6e193bbb/3947',
]
test.each(assetImageUrl)('assetImageUrl', async (url) => {
const response = await fetch(new Request(url))
expect(response.status).toBe(200)
expect(response.headers.get('content-type')).toBe('image/png')
})
const invalidAssetImageUrl = [
'http://127.0.0.1:3000/api/image/nfts/asset/0xed5af388653567af2f388e6224dc7c4b3241c544/10001',
'http://127.0.0.1:3000/api/image/nfts/asset/0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d/44700',
]
test.each(invalidAssetImageUrl)('invalidAssetImageUrl', async (url) => {
const response = await fetch(new Request(url))
expect(response.status).toBe(404)
})
const blockedAssetImageUrl = [
'http://127.0.0.1:3000/api/image/nfts/asset/0xd4d871419714b778ebec2e22c7c53572b573706e/276',
]
test.each(blockedAssetImageUrl)('blockedAssetImageUrl', async (url) => {
const response = await fetch(new Request(url))
expect(response.status).toBe(404)
})

View File

@ -0,0 +1,122 @@
/* eslint-disable import/no-unused-modules */
import { ImageResponse } from '@vercel/og'
import React from 'react'
import { blocklistedCollections } from '../../../../../src/nft/utils/blocklist'
import { getColor } from '../../../../../src/utils/getColor'
import { CHECK_URL, WATERMARK_URL } from '../../../../constants'
import getCollection from '../../../../utils/getCollection'
import getFont from '../../../../utils/getFont'
import { getRequest } from '../../../../utils/getRequest'
export const onRequest: PagesFunction = async ({ params, request }) => {
try {
const origin = new URL(request.url).origin
const { index } = params
const collectionAddress = index?.toString()
const cacheUrl = origin + '/nfts/collection/' + collectionAddress
if (blocklistedCollections.includes(collectionAddress)) {
return new Response('Collection unsupported.', { status: 404 })
}
const data = await getRequest(
cacheUrl,
() => getCollection(collectionAddress, cacheUrl),
(data): data is NonNullable<Awaited<ReturnType<typeof getCollection>>> =>
Boolean(data.ogImage && data.name && data.isVerified)
)
if (!data) {
return new Response('Collection not found.', { status: 404 })
}
const [fontData, palette] = await Promise.all([getFont(origin), getColor(data.ogImage)])
// Split name into words to wrap them since satori does not support inline text wrapping
const words = data.name.split(' ')
return new ImageResponse(
(
<div
style={{
backgroundColor: 'black',
display: 'flex',
width: '1200px',
height: '630px',
}}
>
<div
style={{
display: 'flex',
alignItems: 'center',
backgroundColor: `rgba(${palette[0]}, ${palette[1]}, ${palette[2]}, 0.75)`,
padding: '72px',
}}
>
<div
style={{
display: 'flex',
flexDirection: 'row',
alignItems: 'flex-end',
gap: '48px',
width: '100%',
}}
>
<img
src={data.ogImage}
alt={data.name}
width="500px"
height="500px"
style={{
borderRadius: '60px',
objectFit: 'cover',
}}
/>
<div
style={{
display: 'flex',
flexDirection: 'column',
gap: '32px',
width: '45%',
}}
>
<div
style={{
gap: '12px',
fontSize: '72px',
fontFamily: 'Inter',
color: 'white',
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
flexWrap: 'wrap',
}}
>
{words.map((word: string) => (
<text key={word + index}>{word}</text>
))}
{data.isVerified && <img src={CHECK_URL} height="54px" />}
</div>
<img src={WATERMARK_URL} alt="Uniswap" height="72px" width="324px" />
</div>
</div>
</div>
</div>
),
{
width: 1200,
height: 630,
fonts: [
{
name: 'Inter',
data: fontData,
style: 'normal',
},
],
}
) as Response
} catch (error: any) {
return new Response(error.message || error.toString(), { status: 500 })
}
}

View File

@ -0,0 +1,34 @@
import * as matchers from 'jest-extended'
expect.extend(matchers)
const collectionImageUrls = [
'http://127.0.0.1:3000/api/image/nfts/collection/0xed5af388653567af2f388e6224dc7c4b3241c544',
'http://127.0.0.1:3000/api/image/nfts/collection/0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d',
'http://127.0.0.1:3000/api/image/nfts/collection/0x49cf6f5d44e70224e2e23fdcdd2c053f30ada28b',
]
test.each([...collectionImageUrls])('collectionImageUrl', async (url) => {
const response = await fetch(new Request(url))
expect(response.status).toBe(200)
expect(response.headers.get('content-type')).toBe('image/png')
})
const nonexistentImageUrls = [
'http://127.0.0.1:3000/api/image/nfts/collection/0xed5af388653567af2f388e6224dc7c4b3241c545',
]
const invalidCollectionImageUrls = ['http://127.0.0.1:3000/api/image/nfts/collection/0xd3adb33f']
test.each([...invalidCollectionImageUrls, ...nonexistentImageUrls])('invalidAssetImageUrl', async (url) => {
const response = await fetch(new Request(url))
expect(response.status).toBeOneOf([404, 500])
})
const blockedCollectionImageUrls = [
'http://127.0.0.1:3000/api/image/nfts/collection/0xd4d871419714b778ebec2e22c7c53572b573706e',
]
test.each(blockedCollectionImageUrls)('blockedCollectionImageUrl', async (url) => {
const response = await fetch(new Request(url))
expect(response.status).toBeOneOf([404, 500])
})

View File

@ -0,0 +1,177 @@
/* eslint-disable import/no-unused-modules */
import { ImageResponse } from '@vercel/og'
import React from 'react'
import { getColor } from '../../../../src/utils/getColor'
import { WATERMARK_URL } from '../../../constants'
import getFont from '../../../utils/getFont'
import getNetworkLogoUrl from '../../../utils/getNetworkLogoURL'
import { getRequest } from '../../../utils/getRequest'
import getToken from '../../../utils/getToken'
export const onRequest: PagesFunction = async ({ params, request }) => {
try {
const origin = new URL(request.url).origin
const { index } = params
const networkName = String(index[0])
const tokenAddress = String(index[1])
const cacheUrl = origin + '/tokens/' + networkName + '/' + tokenAddress
const data = await getRequest(
cacheUrl,
() => getToken(networkName, tokenAddress, cacheUrl),
(data): data is NonNullable<Awaited<ReturnType<typeof getToken>>> => Boolean(data.symbol && data.name)
)
if (!data) {
return new Response('Token not found.', { status: 404 })
}
const [fontData, palette] = await Promise.all([getFont(origin), getColor(data.ogImage, true)])
const networkLogo = getNetworkLogoUrl(networkName.toUpperCase(), origin)
// Capitalize name such that each word starts with a capital letter
let words = data.name.split(' ')
words = words.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
let name = words.join(' ')
name = name.trim()
return new ImageResponse(
(
<div
style={{
backgroundColor: 'black',
display: 'flex',
width: '1200px',
height: '630px',
}}
>
<div
style={{
display: 'flex',
backgroundColor: `rgba(${palette[0]}, ${palette[1]}, ${palette[2]})`,
alignItems: 'center',
height: '100%',
padding: '72px',
}}
>
<div
style={{
display: 'flex',
flexDirection: 'column',
justifyContent: 'space-between',
alignItems: 'flex-start',
width: '100%',
height: '100%',
color: 'white',
}}
>
{data.ogImage ? (
<img src={data.ogImage} width="144px" style={{ borderRadius: '100%' }}>
{networkLogo != '' && (
<img
src={networkLogo}
width="48px"
style={{
position: 'absolute',
right: '2px',
bottom: '0px',
borderRadius: '100%',
}}
/>
)}
</img>
) : (
<div
style={{
width: '144px',
height: '144px',
borderRadius: '100%',
backgroundColor: 'rgba(255, 255, 255, 0.12)',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}
>
<div
style={{
fontFamily: 'Inter',
fontSize: '48px',
lineHeight: '58px',
color: 'white',
}}
>
{data.name.slice(0, 3).toUpperCase()}
</div>
{networkLogo != '' && (
<img
src={networkLogo}
width="48px"
style={{
position: 'absolute',
right: '2px',
bottom: '0px',
borderRadius: '100%',
}}
/>
)}
</div>
)}
<div
style={{
fontFamily: 'Inter',
fontSize: '72px',
lineHeight: '72px',
marginLeft: '-5px',
marginTop: '24px',
}}
>
{name}
</div>
<div
style={{
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'flex-end',
width: '100%',
}}
>
<div
style={{
fontFamily: 'Inter',
fontSize: '168px',
lineHeight: '133px',
marginLeft: '-13px',
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
width: '100%',
}}
>
{data.symbol}
</div>
<img src={WATERMARK_URL} alt="Uniswap" height="72px" width="324px" />
</div>
</div>
</div>
</div>
),
{
width: 1200,
height: 630,
fonts: [
{
name: 'Inter',
data: fontData,
style: 'normal',
},
],
}
) as Response
} catch (error: any) {
return new Response(error.message || error.toString(), { status: 500 })
}
}

View File

@ -0,0 +1,22 @@
const tokenImageUrl = [
'http://127.0.0.1:3000/api/image/tokens/ethereum/0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
'http://127.0.0.1:3000/api/image/tokens/ethereum/NATIVE',
]
test.each(tokenImageUrl)('tokenImageUrl', async (url) => {
const response = await fetch(new Request(url))
expect(response.status).toBe(200)
expect(response.headers.get('content-type')).toBe('image/png')
})
const invalidTokenImageUrl = [
'http://127.0.0.1:3000/api/image/tokens/ethereum/0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb49',
'http://127.0.0.1:3000/api/image/tokens/ethereum',
'http://127.0.0.1:3000/api/image/tokens/ethereun',
'http://127.0.0.1:3000/api/image/tokens/potato/?potato=1',
]
test.each(invalidTokenImageUrl)('invalidAssetImageUrl', async (url) => {
const response = await fetch(new Request(url))
expect(response.status).toBe(404)
})

View File

@ -0,0 +1 @@
export const presets = ['@babel/preset-env']

20
functions/client.ts Normal file
View File

@ -0,0 +1,20 @@
import { ApolloClient, InMemoryCache } from '@apollo/client'
const GRAPHQL_ENDPOINT = 'https://api.uniswap.org/v1/graphql'
//TODO: Figure out how to make ApolloClient global variable
export default new ApolloClient({
connectToDevTools: true,
uri: GRAPHQL_ENDPOINT,
headers: {
'Content-Type': 'application/json',
Origin: 'https://app.uniswap.org',
'User-Agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.110 Safari/537.36',
},
cache: new InMemoryCache(),
defaultOptions: {
watchQuery: {
fetchPolicy: 'cache-first',
},
},
})

View File

@ -0,0 +1,60 @@
import { MetaTagInjector } from './metaTagInjector'
test('should append meta tag to element', () => {
const element = {
append: jest.fn(),
} as unknown as Element
const property = 'property'
const content = 'content'
const injector = new MetaTagInjector(
{
title: 'test',
url: 'testUrl',
image: 'testImage',
description: 'testDescription',
},
new Request('http://localhost')
)
injector.append(element, property, content)
expect(element.append).toHaveBeenCalledWith(`<meta property="${property}" content="${content}"/>`, { html: true })
injector.element(element)
expect(element.append).toHaveBeenCalledWith(`<meta property="og:title" content="test"/>`, { html: true })
expect(element.append).toHaveBeenCalledWith(`<meta property="og:description" content="testDescription"/>`, {
html: true,
})
expect(element.append).toHaveBeenCalledWith(`<meta property="og:image" content="testImage"/>`, { html: true })
expect(element.append).toHaveBeenCalledWith(`<meta property="og:image:width" content="1200"/>`, { html: true })
expect(element.append).toHaveBeenCalledWith(`<meta property="og:image:height" content="630"/>`, { html: true })
expect(element.append).toHaveBeenCalledWith(`<meta property="og:image:alt" content="test"/>`, { html: true })
expect(element.append).toHaveBeenCalledWith(`<meta property="og:type" content="website"/>`, { html: true })
expect(element.append).toHaveBeenCalledWith(`<meta property="og:url" content="testUrl"/>`, { html: true })
expect(element.append).toHaveBeenCalledWith(`<meta property="twitter:card" content="summary_large_image"/>`, {
html: true,
})
expect(element.append).toHaveBeenCalledWith(`<meta property="twitter:title" content="test"/>`, { html: true })
expect(element.append).toHaveBeenCalledWith(`<meta property="twitter:image" content="testImage"/>`, { html: true })
expect(element.append).toHaveBeenCalledWith(`<meta property="twitter:image:alt" content="test"/>`, { html: true })
expect(element.append).toHaveBeenCalledTimes(13)
})
test('should pass through header blocked paths', () => {
const element = {
append: jest.fn(),
} as unknown as Element
const request = new Request('http://localhost')
request.headers.set('x-blocked-paths', '/')
const injector = new MetaTagInjector(
{
title: 'test',
url: 'testUrl',
image: 'testImage',
description: 'testDescription',
},
request
)
injector.element(element)
expect(element.append).toHaveBeenCalledWith(`<meta property="x:blocked-paths" content="/"/>`, { html: true })
})

View File

@ -0,0 +1,47 @@
type MetaTagInjectorInput = {
title: string
image?: string
url: string
description?: string
}
/**
* Listener class for Cloudflare's HTMLRewriter {@link https://developers.cloudflare.com/workers/runtime-apis/html-rewriter}
* to inject meta tags into the <head> of an HTML document.
*/
export class MetaTagInjector implements HTMLRewriterElementContentHandlers {
constructor(private input: MetaTagInjectorInput, private request: Request) {}
append(element: Element, property: string, content: string) {
element.append(`<meta property="${property}" content="${content}"/>`, { html: true })
}
element(element: Element) {
//Open Graph Tags
this.append(element, 'og:title', this.input.title)
if (this.input.description) {
this.append(element, 'og:description', this.input.description)
}
if (this.input.image) {
this.append(element, 'og:image', this.input.image)
this.append(element, 'og:image:width', '1200')
this.append(element, 'og:image:height', '630')
this.append(element, 'og:image:alt', this.input.title)
}
this.append(element, 'og:type', 'website')
this.append(element, 'og:url', this.input.url)
//Twitter Tags
this.append(element, 'twitter:card', 'summary_large_image')
this.append(element, 'twitter:title', this.input.title)
if (this.input.image) {
this.append(element, 'twitter:image', this.input.image)
this.append(element, 'twitter:image:alt', this.input.title)
}
const blockedPaths = this.request.headers.get('x-blocked-paths')
if (blockedPaths) {
this.append(element, 'x:blocked-paths', blockedPaths)
}
}
}

2
functions/constants.ts Normal file
View File

@ -0,0 +1,2 @@
export const WATERMARK_URL = 'https://app.uniswap.org/images/324x74_App_Watermark.png'
export const CHECK_URL = 'https://app.uniswap.org/images/54x54_Verified_Check.svg'

22
functions/default.test.ts Normal file
View File

@ -0,0 +1,22 @@
const defaultUrls = ['http://127.0.0.1:3000/', 'http://127.0.0.1:3000/swap', 'http://127.0.0.1:3000/pools']
test.each(defaultUrls)('should inject metadata for valid collections', async (defaultUrl) => {
const body = await fetch(new Request(defaultUrl)).then((res) => res.text())
expect(body).toContain(`<meta property="og:title" content="Uniswap Interface"/>`)
expect(body).toContain(
`<meta property="og:description" content="Swap or provide liquidity on the Uniswap Protocol"/>`
)
expect(body).toContain(
`<meta property="og:image" content="http://127.0.0.1:3000/images/1200x630_Rich_Link_Preview_Image.png"/>`
)
expect(body).toContain(`<meta property="og:image:width" content="1200"/>`)
expect(body).toContain(`<meta property="og:image:height" content="630"/>`)
expect(body).toContain(`<meta property="og:type" content="website"/>`)
expect(body).toContain(`<meta property="og:image:alt" content="Uniswap Interface"/>`)
expect(body).toContain(`<meta property="twitter:card" content="summary_large_image"/>`)
expect(body).toContain(`<meta property="twitter:title" content="Uniswap Interface"/>`)
expect(body).toContain(
`<meta property="twitter:image" content="http://127.0.0.1:3000/images/1200x630_Rich_Link_Preview_Image.png"/>`
)
expect(body).toContain(`<meta property="twitter:image:alt" content="Uniswap Interface"/>`)
})

View File

@ -0,0 +1,10 @@
{
"setupFilesAfterEnv": ["<rootDir>/setupAfterEnv.ts"],
"preset": "ts-jest",
"transform": {
"'^.+\\.(ts|tsx)?$'": "ts-jest",
"^.+\\.(js|jsx)$": "babel-jest"
},
"testTimeout": 360000,
"cacheDirectory": "../node_modules/.cache/cloud-jest"
}

View File

@ -0,0 +1,15 @@
/* eslint-disable import/no-unused-modules */
import getAsset from '../../utils/getAsset'
import { getMetadataRequest } from '../../utils/getRequest'
export const onRequest: PagesFunction = async ({ params, request, next }) => {
const res = next()
try {
const { index } = params
const collectionAddress = index[0]?.toString()
const tokenId = index[1]?.toString()
return getMetadataRequest(res, request, () => getAsset(collectionAddress, tokenId, request.url))
} catch (e) {
return res
}
}

View File

@ -0,0 +1,445 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`should inject metadata for valid assets 1`] = `
"<!DOCTYPE html>
<html translate="no">
<head>
<meta charset="utf-8" />
<title>Uniswap Interface</title>
<!--
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="/favicon.png" />
<link rel="apple-touch-icon" sizes="192x192" href="/images/192x192_App_Icon.png" />
<link rel="apple-touch-icon" sizes="512x512" href="/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="#fff" />
<meta
http-equiv="Content-Security-Policy"
content="script-src 'self' 'unsafe-inline'"
/>
<!--
Apple Smart App Banner for Safari on iOS
https://developer.apple.com/documentation/webkit/promoting_apps_with_smart_app_banners
-->
<meta name="apple-itunes-app" content="app-id=6443944476">
<!--
manifest.json provides metadata used when the app is installed as a PWA.
See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="/manifest.json" />
<link rel="preconnect" href="https://api.uniswap.org/" crossorigin/>
<link rel="preconnect" href="https://mainnet.infura.io/" crossorigin/>
<link rel="preload" href="/fonts/Basel-Book.woff" as="font" type="font/woff" crossorigin />
<link rel="preload" href="/fonts/Basel-Book.woff2" as="font" type="font/woff2" crossorigin />
<link rel="preload" href="/fonts/Basel-Medium.woff" as="font" type="font/woff" crossorigin />
<link rel="preload" href="/fonts/Basel-Medium.woff2" as="font" type="font/woff2" crossorigin />
<style>
* {
font-family: 'Basel', sans-serif;
box-sizing: border-box;
}
/**
Explicitly load Basel var from public/ so it does not block LCP's critical path.
*/
@font-face {
font-family: 'Basel';
font-weight: 535;
font-style: normal;
font-display: block;
src:
url('/fonts/Basel-Medium.woff2') format('woff2'),
url('/fonts/Basel-Medium.woff') format('woff');
}
@font-face {
font-family: 'Basel';
font-weight: 485;
font-style: normal;
font-display: block;
src:
url('/fonts/Basel-Book.woff') format('woff2'),
url('/fonts/Basel-Book.woff') format('woff');
}
@supports (font-variation-settings: normal) {
* {
font-family: 'Basel', sans-serif;
}
}
html,
body {
margin: 0;
padding: 0;
}
button {
user-select: none;
}
html {
font-size: 16px;
font-weight: 485;
font-variant: none;
font-smooth: always;
text-rendering: optimizeLegibility !important;
-webkit-font-smoothing: antialiased !important;
-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(rgb(19, 19, 19) 0%, rgb(19, 19, 19) 100%);
}
}
@media (prefers-color-scheme: light) {
html {
background: radial-gradient(100% 100% at 50% 0%, rgba(255, 184, 226, 0) 0%, rgba(255, 255, 255, 0) 100%), rgb(255, 255, 255);
}
}
</style>
<script defer src="/static/js/bundle.js"></script><meta property="og:title" content="Azuki #2550"/><meta property="og:image" content="http://127.0.0.1:3000/api/image/nfts/asset/0xed5af388653567af2f388e6224dc7c4b3241c544/2550"/><meta property="og:image:width" content="1200"/><meta property="og:image:height" content="630"/><meta property="og:image:alt" content="Azuki #2550"/><meta property="og:type" content="website"/><meta property="og:url" content="http://127.0.0.1:3000/nfts/asset/0xed5af388653567af2f388e6224dc7c4b3241c544/2550"/><meta property="twitter:card" content="summary_large_image"/><meta property="twitter:title" content="Azuki #2550"/><meta property="twitter:image" content="http://127.0.0.1:3000/api/image/nfts/asset/0xed5af388653567af2f388e6224dc7c4b3241c544/2550"/><meta property="twitter:image:alt" content="Azuki #2550"/></head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root">
<!-- Triggers the font to load immediately and then is replaced by the app -->
<div>&emsp;</div>
</div>
<div id="background-radial-gradient"></div>
</body>
</html>
"
`;
exports[`should inject metadata for valid assets 2`] = `
"<!DOCTYPE html>
<html translate="no">
<head>
<meta charset="utf-8" />
<title>Uniswap Interface</title>
<!--
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="/favicon.png" />
<link rel="apple-touch-icon" sizes="192x192" href="/images/192x192_App_Icon.png" />
<link rel="apple-touch-icon" sizes="512x512" href="/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="#fff" />
<meta
http-equiv="Content-Security-Policy"
content="script-src 'self' 'unsafe-inline'"
/>
<!--
Apple Smart App Banner for Safari on iOS
https://developer.apple.com/documentation/webkit/promoting_apps_with_smart_app_banners
-->
<meta name="apple-itunes-app" content="app-id=6443944476">
<!--
manifest.json provides metadata used when the app is installed as a PWA.
See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="/manifest.json" />
<link rel="preconnect" href="https://api.uniswap.org/" crossorigin/>
<link rel="preconnect" href="https://mainnet.infura.io/" crossorigin/>
<link rel="preload" href="/fonts/Basel-Book.woff" as="font" type="font/woff" crossorigin />
<link rel="preload" href="/fonts/Basel-Book.woff2" as="font" type="font/woff2" crossorigin />
<link rel="preload" href="/fonts/Basel-Medium.woff" as="font" type="font/woff" crossorigin />
<link rel="preload" href="/fonts/Basel-Medium.woff2" as="font" type="font/woff2" crossorigin />
<style>
* {
font-family: 'Basel', sans-serif;
box-sizing: border-box;
}
/**
Explicitly load Basel var from public/ so it does not block LCP's critical path.
*/
@font-face {
font-family: 'Basel';
font-weight: 535;
font-style: normal;
font-display: block;
src:
url('/fonts/Basel-Medium.woff2') format('woff2'),
url('/fonts/Basel-Medium.woff') format('woff');
}
@font-face {
font-family: 'Basel';
font-weight: 485;
font-style: normal;
font-display: block;
src:
url('/fonts/Basel-Book.woff') format('woff2'),
url('/fonts/Basel-Book.woff') format('woff');
}
@supports (font-variation-settings: normal) {
* {
font-family: 'Basel', sans-serif;
}
}
html,
body {
margin: 0;
padding: 0;
}
button {
user-select: none;
}
html {
font-size: 16px;
font-weight: 485;
font-variant: none;
font-smooth: always;
text-rendering: optimizeLegibility !important;
-webkit-font-smoothing: antialiased !important;
-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(rgb(19, 19, 19) 0%, rgb(19, 19, 19) 100%);
}
}
@media (prefers-color-scheme: light) {
html {
background: radial-gradient(100% 100% at 50% 0%, rgba(255, 184, 226, 0) 0%, rgba(255, 255, 255, 0) 100%), rgb(255, 255, 255);
}
}
</style>
<script defer src="/static/js/bundle.js"></script><meta property="og:title" content="Bored Ape Yacht Club #3735"/><meta property="og:image" content="http://127.0.0.1:3000/api/image/nfts/asset/0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d/3735"/><meta property="og:image:width" content="1200"/><meta property="og:image:height" content="630"/><meta property="og:image:alt" content="Bored Ape Yacht Club #3735"/><meta property="og:type" content="website"/><meta property="og:url" content="http://127.0.0.1:3000/nfts/asset/0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d/3735"/><meta property="twitter:card" content="summary_large_image"/><meta property="twitter:title" content="Bored Ape Yacht Club #3735"/><meta property="twitter:image" content="http://127.0.0.1:3000/api/image/nfts/asset/0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d/3735"/><meta property="twitter:image:alt" content="Bored Ape Yacht Club #3735"/></head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root">
<!-- Triggers the font to load immediately and then is replaced by the app -->
<div>&emsp;</div>
</div>
<div id="background-radial-gradient"></div>
</body>
</html>
"
`;
exports[`should inject metadata for valid assets 3`] = `
"<!DOCTYPE html>
<html translate="no">
<head>
<meta charset="utf-8" />
<title>Uniswap Interface</title>
<!--
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="/favicon.png" />
<link rel="apple-touch-icon" sizes="192x192" href="/images/192x192_App_Icon.png" />
<link rel="apple-touch-icon" sizes="512x512" href="/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="#fff" />
<meta
http-equiv="Content-Security-Policy"
content="script-src 'self' 'unsafe-inline'"
/>
<!--
Apple Smart App Banner for Safari on iOS
https://developer.apple.com/documentation/webkit/promoting_apps_with_smart_app_banners
-->
<meta name="apple-itunes-app" content="app-id=6443944476">
<!--
manifest.json provides metadata used when the app is installed as a PWA.
See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="/manifest.json" />
<link rel="preconnect" href="https://api.uniswap.org/" crossorigin/>
<link rel="preconnect" href="https://mainnet.infura.io/" crossorigin/>
<link rel="preload" href="/fonts/Basel-Book.woff" as="font" type="font/woff" crossorigin />
<link rel="preload" href="/fonts/Basel-Book.woff2" as="font" type="font/woff2" crossorigin />
<link rel="preload" href="/fonts/Basel-Medium.woff" as="font" type="font/woff" crossorigin />
<link rel="preload" href="/fonts/Basel-Medium.woff2" as="font" type="font/woff2" crossorigin />
<style>
* {
font-family: 'Basel', sans-serif;
box-sizing: border-box;
}
/**
Explicitly load Basel var from public/ so it does not block LCP's critical path.
*/
@font-face {
font-family: 'Basel';
font-weight: 535;
font-style: normal;
font-display: block;
src:
url('/fonts/Basel-Medium.woff2') format('woff2'),
url('/fonts/Basel-Medium.woff') format('woff');
}
@font-face {
font-family: 'Basel';
font-weight: 485;
font-style: normal;
font-display: block;
src:
url('/fonts/Basel-Book.woff') format('woff2'),
url('/fonts/Basel-Book.woff') format('woff');
}
@supports (font-variation-settings: normal) {
* {
font-family: 'Basel', sans-serif;
}
}
html,
body {
margin: 0;
padding: 0;
}
button {
user-select: none;
}
html {
font-size: 16px;
font-weight: 485;
font-variant: none;
font-smooth: always;
text-rendering: optimizeLegibility !important;
-webkit-font-smoothing: antialiased !important;
-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(rgb(19, 19, 19) 0%, rgb(19, 19, 19) 100%);
}
}
@media (prefers-color-scheme: light) {
html {
background: radial-gradient(100% 100% at 50% 0%, rgba(255, 184, 226, 0) 0%, rgba(255, 255, 255, 0) 100%), rgb(255, 255, 255);
}
}
</style>
<script defer src="/static/js/bundle.js"></script><meta property="og:title" content="CryptoPunk #3947"/><meta property="og:image" content="http://127.0.0.1:3000/api/image/nfts/asset/0xb47e3cd837ddf8e4c57f05d70ab865de6e193bbb/3947"/><meta property="og:image:width" content="1200"/><meta property="og:image:height" content="630"/><meta property="og:image:alt" content="CryptoPunk #3947"/><meta property="og:type" content="website"/><meta property="og:url" content="http://127.0.0.1:3000/nfts/asset/0xb47e3cd837ddf8e4c57f05d70ab865de6e193bbb/3947"/><meta property="twitter:card" content="summary_large_image"/><meta property="twitter:title" content="CryptoPunk #3947"/><meta property="twitter:image" content="http://127.0.0.1:3000/api/image/nfts/asset/0xb47e3cd837ddf8e4c57f05d70ab865de6e193bbb/3947"/><meta property="twitter:image:alt" content="CryptoPunk #3947"/></head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root">
<!-- Triggers the font to load immediately and then is replaced by the app -->
<div>&emsp;</div>
</div>
<div id="background-radial-gradient"></div>
</body>
</html>
"
`;

View File

@ -0,0 +1,62 @@
const assets = [
{
address: '0xed5af388653567af2f388e6224dc7c4b3241c544',
assetId: '2550',
collectionName: 'Azuki',
image: 'http://127.0.0.1:3000/api/image/nfts/asset/0xed5af388653567af2f388e6224dc7c4b3241c544/2550',
},
{
address: '0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d',
assetId: '3735',
collectionName: 'Bored Ape Yacht Club',
image: 'http://127.0.0.1:3000/api/image/nfts/asset/0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d/3735',
},
{
address: '0xb47e3cd837ddf8e4c57f05d70ab865de6e193bbb',
assetId: '3947',
collectionName: 'CryptoPunk',
image: 'http://127.0.0.1:3000/api/image/nfts/asset/0xb47e3cd837ddf8e4c57f05d70ab865de6e193bbb/3947',
},
]
test.each(assets)('should inject metadata for valid assets', async (nft) => {
const url = 'http://127.0.0.1:3000/nfts/asset/' + nft.address + '/' + nft.assetId
const body = await fetch(new Request(url)).then((res) => res.text())
expect(body).toMatchSnapshot()
expect(body).toContain(`<meta property="og:title" content="${nft.collectionName} #${nft.assetId}"/>`)
expect(body).not.toContain(`<meta property="og:description"`)
expect(body).toContain(`<meta property="og:image" content="${nft.image}"/>`)
expect(body).toContain(`<meta property="og:image:width" content="1200"/>`)
expect(body).toContain(`<meta property="og:image:height" content="630"/>`)
expect(body).toContain(`<meta property="og:type" content="website"/>`)
expect(body).toContain(`<meta property="og:url" content="${url}"/>`)
expect(body).toContain(`<meta property="og:image:alt" content="${nft.collectionName} #${nft.assetId}"/>`)
expect(body).toContain(`<meta property="twitter:card" content="summary_large_image"/>`)
expect(body).toContain(`<meta property="twitter:title" content="${nft.collectionName} #${nft.assetId}"/>`)
expect(body).toContain(`<meta property="twitter:image" content="${nft.image}"/>`)
expect(body).toContain(`<meta property="twitter:image:alt" content="${nft.collectionName} #${nft.assetId}"/>`)
})
const invalidAssets = [
'http://127.0.0.1:3000/nfts/asset/0xed5af388653567af2f388e6224dc7c4b3241c544/100000',
'http://127.0.0.1:3000/nfts/asset/0xed5af388653567af2f388e6224dc7c4b3241c544',
'http://127.0.0.1:3000/nfts/asset/0xed5af388653567af2f388e6224dc7c4b3241c545',
'http://127.0.0.1:3000/nfts/asset/0xed5af388653567af2f388e6224dc7c4b3241c544/-1',
'http://127.0.0.1:3000/nfts/asset/0xed5af388653567af2f388e6224dc7c4b3241c544//',
'http://127.0.0.1:3000/nfts/asset/0xed5af388653567af2f388e6224dc7c4b3241c544//2550',
]
test.each(invalidAssets)('should not inject metadata for invalid asset calls', async (url) => {
const body = await fetch(new Request(url)).then((res) => res.text())
expect(body).not.toContain('og:title')
expect(body).not.toContain('og:image')
expect(body).not.toContain('og:image:width')
expect(body).not.toContain('og:image:height')
expect(body).not.toContain('og:type')
expect(body).not.toContain('og:url')
expect(body).not.toContain('og:image:alt')
expect(body).not.toContain('twitter:card')
expect(body).not.toContain('twitter:title')
expect(body).not.toContain('twitter:image')
expect(body).not.toContain('twitter:image:alt')
})

View File

@ -0,0 +1,14 @@
/* eslint-disable import/no-unused-modules */
import getCollection from '../../utils/getCollection'
import { getMetadataRequest } from '../../utils/getRequest'
export const onRequest: PagesFunction = async ({ params, request, next }) => {
const res = next()
try {
const { index } = params
const collectionAddress = index?.toString()
return getMetadataRequest(res, request, () => getCollection(collectionAddress, request.url))
} catch (e) {
return res
}
}

View File

@ -0,0 +1,445 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`should inject metadata for collections 1`] = `
"<!DOCTYPE html>
<html translate="no">
<head>
<meta charset="utf-8" />
<title>Uniswap Interface</title>
<!--
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="/favicon.png" />
<link rel="apple-touch-icon" sizes="192x192" href="/images/192x192_App_Icon.png" />
<link rel="apple-touch-icon" sizes="512x512" href="/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="#fff" />
<meta
http-equiv="Content-Security-Policy"
content="script-src 'self' 'unsafe-inline'"
/>
<!--
Apple Smart App Banner for Safari on iOS
https://developer.apple.com/documentation/webkit/promoting_apps_with_smart_app_banners
-->
<meta name="apple-itunes-app" content="app-id=6443944476">
<!--
manifest.json provides metadata used when the app is installed as a PWA.
See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="/manifest.json" />
<link rel="preconnect" href="https://api.uniswap.org/" crossorigin/>
<link rel="preconnect" href="https://mainnet.infura.io/" crossorigin/>
<link rel="preload" href="/fonts/Basel-Book.woff" as="font" type="font/woff" crossorigin />
<link rel="preload" href="/fonts/Basel-Book.woff2" as="font" type="font/woff2" crossorigin />
<link rel="preload" href="/fonts/Basel-Medium.woff" as="font" type="font/woff" crossorigin />
<link rel="preload" href="/fonts/Basel-Medium.woff2" as="font" type="font/woff2" crossorigin />
<style>
* {
font-family: 'Basel', sans-serif;
box-sizing: border-box;
}
/**
Explicitly load Basel var from public/ so it does not block LCP's critical path.
*/
@font-face {
font-family: 'Basel';
font-weight: 535;
font-style: normal;
font-display: block;
src:
url('/fonts/Basel-Medium.woff2') format('woff2'),
url('/fonts/Basel-Medium.woff') format('woff');
}
@font-face {
font-family: 'Basel';
font-weight: 485;
font-style: normal;
font-display: block;
src:
url('/fonts/Basel-Book.woff') format('woff2'),
url('/fonts/Basel-Book.woff') format('woff');
}
@supports (font-variation-settings: normal) {
* {
font-family: 'Basel', sans-serif;
}
}
html,
body {
margin: 0;
padding: 0;
}
button {
user-select: none;
}
html {
font-size: 16px;
font-weight: 485;
font-variant: none;
font-smooth: always;
text-rendering: optimizeLegibility !important;
-webkit-font-smoothing: antialiased !important;
-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(rgb(19, 19, 19) 0%, rgb(19, 19, 19) 100%);
}
}
@media (prefers-color-scheme: light) {
html {
background: radial-gradient(100% 100% at 50% 0%, rgba(255, 184, 226, 0) 0%, rgba(255, 255, 255, 0) 100%), rgb(255, 255, 255);
}
}
</style>
<script defer src="/static/js/bundle.js"></script><meta property="og:title" content="Azuki on Uniswap"/><meta property="og:image" content="http://127.0.0.1:3000/api/image/nfts/collection/0xed5af388653567af2f388e6224dc7c4b3241c544"/><meta property="og:image:width" content="1200"/><meta property="og:image:height" content="630"/><meta property="og:image:alt" content="Azuki on Uniswap"/><meta property="og:type" content="website"/><meta property="og:url" content="http://127.0.0.1:3000/nfts/collection/0xed5af388653567af2f388e6224dc7c4b3241c544"/><meta property="twitter:card" content="summary_large_image"/><meta property="twitter:title" content="Azuki on Uniswap"/><meta property="twitter:image" content="http://127.0.0.1:3000/api/image/nfts/collection/0xed5af388653567af2f388e6224dc7c4b3241c544"/><meta property="twitter:image:alt" content="Azuki on Uniswap"/></head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root">
<!-- Triggers the font to load immediately and then is replaced by the app -->
<div>&emsp;</div>
</div>
<div id="background-radial-gradient"></div>
</body>
</html>
"
`;
exports[`should inject metadata for collections 2`] = `
"<!DOCTYPE html>
<html translate="no">
<head>
<meta charset="utf-8" />
<title>Uniswap Interface</title>
<!--
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="/favicon.png" />
<link rel="apple-touch-icon" sizes="192x192" href="/images/192x192_App_Icon.png" />
<link rel="apple-touch-icon" sizes="512x512" href="/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="#fff" />
<meta
http-equiv="Content-Security-Policy"
content="script-src 'self' 'unsafe-inline'"
/>
<!--
Apple Smart App Banner for Safari on iOS
https://developer.apple.com/documentation/webkit/promoting_apps_with_smart_app_banners
-->
<meta name="apple-itunes-app" content="app-id=6443944476">
<!--
manifest.json provides metadata used when the app is installed as a PWA.
See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="/manifest.json" />
<link rel="preconnect" href="https://api.uniswap.org/" crossorigin/>
<link rel="preconnect" href="https://mainnet.infura.io/" crossorigin/>
<link rel="preload" href="/fonts/Basel-Book.woff" as="font" type="font/woff" crossorigin />
<link rel="preload" href="/fonts/Basel-Book.woff2" as="font" type="font/woff2" crossorigin />
<link rel="preload" href="/fonts/Basel-Medium.woff" as="font" type="font/woff" crossorigin />
<link rel="preload" href="/fonts/Basel-Medium.woff2" as="font" type="font/woff2" crossorigin />
<style>
* {
font-family: 'Basel', sans-serif;
box-sizing: border-box;
}
/**
Explicitly load Basel var from public/ so it does not block LCP's critical path.
*/
@font-face {
font-family: 'Basel';
font-weight: 535;
font-style: normal;
font-display: block;
src:
url('/fonts/Basel-Medium.woff2') format('woff2'),
url('/fonts/Basel-Medium.woff') format('woff');
}
@font-face {
font-family: 'Basel';
font-weight: 485;
font-style: normal;
font-display: block;
src:
url('/fonts/Basel-Book.woff') format('woff2'),
url('/fonts/Basel-Book.woff') format('woff');
}
@supports (font-variation-settings: normal) {
* {
font-family: 'Basel', sans-serif;
}
}
html,
body {
margin: 0;
padding: 0;
}
button {
user-select: none;
}
html {
font-size: 16px;
font-weight: 485;
font-variant: none;
font-smooth: always;
text-rendering: optimizeLegibility !important;
-webkit-font-smoothing: antialiased !important;
-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(rgb(19, 19, 19) 0%, rgb(19, 19, 19) 100%);
}
}
@media (prefers-color-scheme: light) {
html {
background: radial-gradient(100% 100% at 50% 0%, rgba(255, 184, 226, 0) 0%, rgba(255, 255, 255, 0) 100%), rgb(255, 255, 255);
}
}
</style>
<script defer src="/static/js/bundle.js"></script><meta property="og:title" content="Bored Ape Yacht Club on Uniswap"/><meta property="og:image" content="http://127.0.0.1:3000/api/image/nfts/collection/0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d"/><meta property="og:image:width" content="1200"/><meta property="og:image:height" content="630"/><meta property="og:image:alt" content="Bored Ape Yacht Club on Uniswap"/><meta property="og:type" content="website"/><meta property="og:url" content="http://127.0.0.1:3000/nfts/collection/0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d"/><meta property="twitter:card" content="summary_large_image"/><meta property="twitter:title" content="Bored Ape Yacht Club on Uniswap"/><meta property="twitter:image" content="http://127.0.0.1:3000/api/image/nfts/collection/0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d"/><meta property="twitter:image:alt" content="Bored Ape Yacht Club on Uniswap"/></head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root">
<!-- Triggers the font to load immediately and then is replaced by the app -->
<div>&emsp;</div>
</div>
<div id="background-radial-gradient"></div>
</body>
</html>
"
`;
exports[`should inject metadata for collections 3`] = `
"<!DOCTYPE html>
<html translate="no">
<head>
<meta charset="utf-8" />
<title>Uniswap Interface</title>
<!--
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="/favicon.png" />
<link rel="apple-touch-icon" sizes="192x192" href="/images/192x192_App_Icon.png" />
<link rel="apple-touch-icon" sizes="512x512" href="/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="#fff" />
<meta
http-equiv="Content-Security-Policy"
content="script-src 'self' 'unsafe-inline'"
/>
<!--
Apple Smart App Banner for Safari on iOS
https://developer.apple.com/documentation/webkit/promoting_apps_with_smart_app_banners
-->
<meta name="apple-itunes-app" content="app-id=6443944476">
<!--
manifest.json provides metadata used when the app is installed as a PWA.
See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="/manifest.json" />
<link rel="preconnect" href="https://api.uniswap.org/" crossorigin/>
<link rel="preconnect" href="https://mainnet.infura.io/" crossorigin/>
<link rel="preload" href="/fonts/Basel-Book.woff" as="font" type="font/woff" crossorigin />
<link rel="preload" href="/fonts/Basel-Book.woff2" as="font" type="font/woff2" crossorigin />
<link rel="preload" href="/fonts/Basel-Medium.woff" as="font" type="font/woff" crossorigin />
<link rel="preload" href="/fonts/Basel-Medium.woff2" as="font" type="font/woff2" crossorigin />
<style>
* {
font-family: 'Basel', sans-serif;
box-sizing: border-box;
}
/**
Explicitly load Basel var from public/ so it does not block LCP's critical path.
*/
@font-face {
font-family: 'Basel';
font-weight: 535;
font-style: normal;
font-display: block;
src:
url('/fonts/Basel-Medium.woff2') format('woff2'),
url('/fonts/Basel-Medium.woff') format('woff');
}
@font-face {
font-family: 'Basel';
font-weight: 485;
font-style: normal;
font-display: block;
src:
url('/fonts/Basel-Book.woff') format('woff2'),
url('/fonts/Basel-Book.woff') format('woff');
}
@supports (font-variation-settings: normal) {
* {
font-family: 'Basel', sans-serif;
}
}
html,
body {
margin: 0;
padding: 0;
}
button {
user-select: none;
}
html {
font-size: 16px;
font-weight: 485;
font-variant: none;
font-smooth: always;
text-rendering: optimizeLegibility !important;
-webkit-font-smoothing: antialiased !important;
-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(rgb(19, 19, 19) 0%, rgb(19, 19, 19) 100%);
}
}
@media (prefers-color-scheme: light) {
html {
background: radial-gradient(100% 100% at 50% 0%, rgba(255, 184, 226, 0) 0%, rgba(255, 255, 255, 0) 100%), rgb(255, 255, 255);
}
}
</style>
<script defer src="/static/js/bundle.js"></script><meta property="og:title" content="CLONE X - X TAKASHI MURAKAMI on Uniswap"/><meta property="og:image" content="http://127.0.0.1:3000/api/image/nfts/collection/0x49cf6f5d44e70224e2e23fdcdd2c053f30ada28b"/><meta property="og:image:width" content="1200"/><meta property="og:image:height" content="630"/><meta property="og:image:alt" content="CLONE X - X TAKASHI MURAKAMI on Uniswap"/><meta property="og:type" content="website"/><meta property="og:url" content="http://127.0.0.1:3000/nfts/collection/0x49cf6f5d44e70224e2e23fdcdd2c053f30ada28b"/><meta property="twitter:card" content="summary_large_image"/><meta property="twitter:title" content="CLONE X - X TAKASHI MURAKAMI on Uniswap"/><meta property="twitter:image" content="http://127.0.0.1:3000/api/image/nfts/collection/0x49cf6f5d44e70224e2e23fdcdd2c053f30ada28b"/><meta property="twitter:image:alt" content="CLONE X - X TAKASHI MURAKAMI on Uniswap"/></head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root">
<!-- Triggers the font to load immediately and then is replaced by the app -->
<div>&emsp;</div>
</div>
<div id="background-radial-gradient"></div>
</body>
</html>
"
`;

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