Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
I
interface
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
LuckySwap
interface
Commits
9b2fe0bd
Unverified
Commit
9b2fe0bd
authored
May 08, 2020
by
Moody Salem
Committed by
GitHub
May 08, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use best trade to get the best route (#731)
parent
cb00e0ba
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
286 additions
and
321 deletions
+286
-321
index.tsx
src/components/ExchangePage/index.tsx
+158
-189
swap-store.ts
src/components/ExchangePage/swap-store.ts
+36
-0
Application.tsx
src/contexts/Application.tsx
+28
-12
Routes.tsx
src/contexts/Routes.tsx
+0
-110
Transactions.tsx
src/contexts/Transactions.tsx
+9
-3
Trades.ts
src/hooks/Trades.ts
+51
-0
index.tsx
src/index.tsx
+3
-6
index.ts
src/utils/index.ts
+1
-1
No files found.
src/components/ExchangePage/index.tsx
View file @
9b2fe0bd
import
React
,
{
useState
,
useReducer
,
useCallback
,
useEffect
}
from
'
react
'
import
React
,
{
useState
,
useCallback
,
useEffect
}
from
'
react
'
import
{
parseEther
,
parseUnits
}
from
'
@ethersproject/units
'
import
{
Fraction
,
JSBI
,
Percent
,
TokenAmount
,
TradeType
,
WETH
}
from
'
@uniswap/sdk
'
import
{
ArrowDown
,
ChevronDown
,
ChevronUp
,
Repeat
}
from
'
react-feather
'
import
{
withRouter
}
from
'
react-router-dom
'
import
{
withRouter
}
from
'
react-router-dom
'
import
{
parseUnits
,
parseEther
}
from
'
@ethersproject/units
'
import
{
BigNumber
}
from
'
@ethersproject/bignumber
'
import
{
BigNumber
}
from
'
@ethersproject/bignumber
'
import
{
Zero
,
MaxUint256
}
from
'
@ethersproject/constants
'
import
{
Zero
,
MaxUint256
}
from
'
@ethersproject/constants
'
import
{
Contract
}
from
'
@ethersproject/contracts
'
import
{
Contract
}
from
'
@ethersproject/contracts
'
import
{
WETH
,
TradeType
,
Pair
,
Trade
,
TokenAmount
,
JSBI
,
Percent
,
Fraction
}
from
'
@uniswap/sdk
'
import
{
Field
,
SwapAction
,
useSwapStateReducer
}
from
'
./swap-store
'
import
{
Text
}
from
'
rebass
'
import
{
Field
,
initializeSwapState
,
reducer
,
SwapAction
}
from
'
./swap-store
'
import
Card
,
{
BlueCard
,
GreyCard
,
YellowCard
}
from
'
../../components/Card
'
import
{
AutoColumn
,
ColumnCenter
}
from
'
../../components/Column
'
import
{
AutoRow
,
RowBetween
,
RowFixed
}
from
'
../../components/Row
'
import
{
ROUTER_ADDRESS
}
from
'
../../constants
'
import
{
useAddressAllowance
}
from
'
../../contexts/Allowances
'
import
{
useUserAdvanced
}
from
'
../../contexts/Application
'
import
{
useAddressBalance
,
useAllBalances
}
from
'
../../contexts/Balances
'
import
{
useDarkModeManager
,
useLocalStorageTokens
}
from
'
../../contexts/LocalStorage
'
import
{
usePair
}
from
'
../../contexts/Pairs
'
import
{
useAllTokens
,
useToken
}
from
'
../../contexts/Tokens
'
import
{
usePendingApproval
,
useTransactionAdder
}
from
'
../../contexts/Transactions
'
import
{
useTokenContract
,
useWeb3React
}
from
'
../../hooks
'
import
{
useTradeExactIn
,
useTradeExactOut
}
from
'
../../hooks/Trades
'
import
{
Hover
,
theme
,
TYPE
}
from
'
../../theme
'
import
{
Link
}
from
'
../../theme/components
'
import
{
calculateGasMargin
,
getEtherscanLink
,
getProviderOrSigner
,
getRouterContract
,
isWETH
}
from
'
../../utils
'
import
Copy
from
'
../AccountDetails/Copy
'
import
AddressInputPanel
from
'
../AddressInputPanel
'
import
{
ButtonError
,
ButtonLight
,
ButtonPrimary
}
from
'
../Button
'
import
ConfirmationModal
from
'
../ConfirmationModal
'
import
CurrencyInputPanel
from
'
../CurrencyInputPanel
'
import
QuestionHelper
from
'
../Question
'
import
SlippageTabs
from
'
../SlippageTabs
'
import
TokenLogo
from
'
../TokenLogo
'
import
{
import
{
AdvancedDropwdown
,
AdvancedDropwdown
,
ArrowWrapper
,
ArrowWrapper
,
...
@@ -22,36 +47,8 @@ import {
...
@@ -22,36 +47,8 @@ import {
TruncatedText
,
TruncatedText
,
Wrapper
Wrapper
}
from
'
./styleds
'
}
from
'
./styleds
'
import
Copy
from
'
../AccountDetails/Copy
'
import
TokenLogo
from
'
../TokenLogo
'
import
SlippageTabs
from
'
../SlippageTabs
'
import
QuestionHelper
from
'
../Question
'
import
AddressInputPanel
from
'
../AddressInputPanel
'
import
ConfirmationModal
from
'
../ConfirmationModal
'
import
CurrencyInputPanel
from
'
../CurrencyInputPanel
'
// import BalanceCard from '../BalanceCard'
import
{
Link
}
from
'
../../theme/components
'
import
{
Text
}
from
'
rebass
'
import
{
theme
,
TYPE
,
Hover
}
from
'
../../theme
'
import
{
AutoColumn
,
ColumnCenter
}
from
'
../../components/Column
'
import
{
RowBetween
,
RowFixed
,
AutoRow
}
from
'
../../components/Row
'
import
{
ArrowDown
,
ChevronDown
,
ChevronUp
,
Repeat
}
from
'
react-feather
'
import
{
ButtonPrimary
,
ButtonError
,
ButtonLight
}
from
'
../Button
'
import
Card
,
{
GreyCard
,
BlueCard
,
YellowCard
}
from
'
../../components/Card
'
import
{
usePair
}
from
'
../../contexts/Pairs
'
// import BalanceCard from '../BalanceCard'
import
{
useRoute
}
from
'
../../contexts/Routes
'
import
{
useAddressAllowance
}
from
'
../../contexts/Allowances
'
import
{
useToken
,
useAllTokens
}
from
'
../../contexts/Tokens
'
import
{
useWeb3React
,
useTokenContract
}
from
'
../../hooks
'
import
{
useAddressBalance
,
useAllBalances
}
from
'
../../contexts/Balances
'
import
{
useTransactionAdder
,
usePendingApproval
}
from
'
../../contexts/Transactions
'
import
{
useUserAdvanced
}
from
'
../../contexts/Application
'
import
{
ROUTER_ADDRESS
}
from
'
../../constants
'
import
{
getRouterContract
,
calculateGasMargin
,
getProviderOrSigner
,
getEtherscanLink
,
isWETH
}
from
'
../../utils
'
import
{
useLocalStorageTokens
}
from
'
../../contexts/LocalStorage
'
import
{
useDarkModeManager
}
from
'
../../contexts/LocalStorage
'
function
hex
(
value
:
JSBI
)
{
function
hex
(
value
:
JSBI
)
{
return
BigNumber
.
from
(
value
.
toString
())
return
BigNumber
.
from
(
value
.
toString
())
...
@@ -79,7 +76,6 @@ const ALLOWED_SLIPPAGE_HIGH = 500
...
@@ -79,7 +76,6 @@ const ALLOWED_SLIPPAGE_HIGH = 500
function
ExchangePage
({
sendingInput
=
false
,
history
,
params
})
{
function
ExchangePage
({
sendingInput
=
false
,
history
,
params
})
{
// text translation
// text translation
// const { t } = useTranslation()
// const { t } = useTranslation()
const
{
chainId
,
account
,
library
}
=
useWeb3React
()
const
{
chainId
,
account
,
library
}
=
useWeb3React
()
// adding notifications on txns
// adding notifications on txns
...
@@ -92,33 +88,7 @@ function ExchangePage({ sendingInput = false, history, params }) {
...
@@ -92,33 +88,7 @@ function ExchangePage({ sendingInput = false, history, params }) {
const
[
ENS
,
setENS
]
=
useState
<
string
>
(
''
)
const
[
ENS
,
setENS
]
=
useState
<
string
>
(
''
)
// trade details, check query params for initial state
// trade details, check query params for initial state
const
[
state
,
dispatch
]
=
useReducer
(
const
[
state
,
dispatch
]
=
useSwapStateReducer
(
params
)
reducer
,
{
independentField
:
params
.
outputTokenAddress
&&
!
params
.
inputTokenAddress
?
Field
.
OUTPUT
:
Field
.
INPUT
,
inputTokenAddress
:
params
.
inputTokenAddress
?
params
.
inputTokenAddress
:
WETH
[
chainId
].
address
,
outputTokenAddress
:
params
.
outputTokenAddress
?
params
.
outputTokenAddress
:
''
,
typedValue
:
params
.
inputTokenAddress
&&
!
params
.
outputTokenAddress
?
params
.
inputTokenAmount
?
params
.
inputTokenAmount
:
''
:
!
params
.
inputTokenAddress
&&
params
.
outputTokenAddress
?
params
.
outputTokenAmount
?
params
.
outputTokenAmount
:
''
:
params
.
inputTokenAddress
&&
params
.
outputTokenAddress
?
params
.
inputTokenAmount
?
params
.
inputTokenAmount
:
''
:
''
?
''
:
''
?
''
:
''
},
initializeSwapState
)
const
{
independentField
,
typedValue
,
...
fieldData
}
=
state
const
{
independentField
,
typedValue
,
...
fieldData
}
=
state
const
dependentField
:
Field
=
independentField
===
Field
.
INPUT
?
Field
.
OUTPUT
:
Field
.
INPUT
const
dependentField
:
Field
=
independentField
===
Field
.
INPUT
?
Field
.
OUTPUT
:
Field
.
INPUT
...
@@ -161,13 +131,6 @@ function ExchangePage({ sendingInput = false, history, params }) {
...
@@ -161,13 +131,6 @@ function ExchangePage({ sendingInput = false, history, params }) {
// check on pending approvals for token amounts
// check on pending approvals for token amounts
const
pendingApprovalInput
=
usePendingApproval
(
tokens
[
Field
.
INPUT
]?.
address
)
const
pendingApprovalInput
=
usePendingApproval
(
tokens
[
Field
.
INPUT
]?.
address
)
// entities for swap
const
pair
:
Pair
=
usePair
(
tokens
[
Field
.
INPUT
],
tokens
[
Field
.
OUTPUT
])
const
route
=
useRoute
(
tokens
[
Field
.
INPUT
],
tokens
[
Field
.
OUTPUT
])
// check for invalid selection
const
noRoute
:
boolean
=
!
route
&&
!!
tokens
[
Field
.
INPUT
]
&&
!!
tokens
[
Field
.
OUTPUT
]
// modal and loading
// modal and loading
const
[
showConfirm
,
setShowConfirm
]
=
useState
<
boolean
>
(
false
)
const
[
showConfirm
,
setShowConfirm
]
=
useState
<
boolean
>
(
false
)
const
[
showAdvanced
,
setShowAdvanced
]
=
useState
<
boolean
>
(
false
)
const
[
showAdvanced
,
setShowAdvanced
]
=
useState
<
boolean
>
(
false
)
...
@@ -202,14 +165,16 @@ function ExchangePage({ sendingInput = false, history, params }) {
...
@@ -202,14 +165,16 @@ function ExchangePage({ sendingInput = false, history, params }) {
}
}
}
}
// get trade
const
pair
=
usePair
(
tokens
[
Field
.
INPUT
],
tokens
[
Field
.
OUTPUT
])
let
trade
:
Trade
let
bestTradeExactIn
=
useTradeExactIn
(
tradeType
===
TradeType
.
EXACT_INPUT
?
parsedAmounts
[
independentField
]
:
null
,
tokens
[
Field
.
OUTPUT
])
try
{
let
bestTradeExactOut
=
useTradeExactOut
(
tokens
[
Field
.
INPUT
],
tradeType
===
TradeType
.
EXACT_OUTPUT
?
parsedAmounts
[
independentField
]
:
null
)
trade
=
!!
route
&&
!!
parsedAmounts
[
independentField
]
const
trade
=
tradeType
===
TradeType
.
EXACT_INPUT
?
bestTradeExactIn
:
bestTradeExactOut
?
new
Trade
(
route
,
parsedAmounts
[
independentField
],
tradeType
)
const
route
=
trade
?.
route
:
undefined
const
userHasSpecifiedInputOutput
=
!!
parsedAmounts
[
independentField
]
&&
}
catch
(
error
)
{}
parsedAmounts
[
independentField
].
greaterThan
(
JSBI
.
BigInt
(
0
))
&&
!!
tokens
[
Field
.
INPUT
]
&&
!!
tokens
[
Field
.
OUTPUT
]
const
noRoute
=
!
route
const
slippageFromTrade
:
Percent
=
trade
&&
trade
.
slippage
const
slippageFromTrade
:
Percent
=
trade
&&
trade
.
slippage
...
@@ -241,18 +206,18 @@ function ExchangePage({ sendingInput = false, history, params }) {
...
@@ -241,18 +206,18 @@ function ExchangePage({ sendingInput = false, history, params }) {
type
:
SwapAction
.
SELECT_TOKEN
,
type
:
SwapAction
.
SELECT_TOKEN
,
payload
:
{
field
,
address
}
payload
:
{
field
,
address
}
})
})
},
[])
},
[
dispatch
])
const
onSwapTokens
=
useCallback
(()
=>
{
const
onSwapTokens
=
useCallback
(()
=>
{
dispatch
({
dispatch
({
type
:
SwapAction
.
SWITCH_TOKENS
,
type
:
SwapAction
.
SWITCH_TOKENS
,
payload
:
undefined
payload
:
undefined
})
})
},
[])
},
[
dispatch
])
const
onUserInput
=
useCallback
((
field
:
Field
,
typedValue
:
string
)
=>
{
const
onUserInput
=
useCallback
((
field
:
Field
,
typedValue
:
string
)
=>
{
dispatch
({
type
:
SwapAction
.
TYPE
,
payload
:
{
field
,
typedValue
}
})
dispatch
({
type
:
SwapAction
.
TYPE
,
payload
:
{
field
,
typedValue
}
})
},
[])
},
[
dispatch
])
const
onMaxInput
=
useCallback
((
typedValue
:
string
)
=>
{
const
onMaxInput
=
useCallback
((
typedValue
:
string
)
=>
{
dispatch
({
dispatch
({
...
@@ -262,7 +227,7 @@ function ExchangePage({ sendingInput = false, history, params }) {
...
@@ -262,7 +227,7 @@ function ExchangePage({ sendingInput = false, history, params }) {
typedValue
typedValue
}
}
})
})
},
[])
},
[
dispatch
])
const
onMaxOutput
=
useCallback
((
typedValue
:
string
)
=>
{
const
onMaxOutput
=
useCallback
((
typedValue
:
string
)
=>
{
dispatch
({
dispatch
({
...
@@ -272,7 +237,7 @@ function ExchangePage({ sendingInput = false, history, params }) {
...
@@ -272,7 +237,7 @@ function ExchangePage({ sendingInput = false, history, params }) {
typedValue
typedValue
}
}
})
})
},
[])
},
[
dispatch
])
// reset field if sending with with swap is cancled
// reset field if sending with with swap is cancled
useEffect
(()
=>
{
useEffect
(()
=>
{
...
@@ -295,7 +260,8 @@ function ExchangePage({ sendingInput = false, history, params }) {
...
@@ -295,7 +260,8 @@ function ExchangePage({ sendingInput = false, history, params }) {
?
userBalances
[
Field
.
INPUT
].
subtract
(
MIN_ETHER
)
?
userBalances
[
Field
.
INPUT
].
subtract
(
MIN_ETHER
)
:
userBalances
[
Field
.
INPUT
]
:
userBalances
[
Field
.
INPUT
]
:
undefined
:
undefined
}
catch
{}
}
catch
{
}
const
atMaxAmountInput
:
boolean
=
const
atMaxAmountInput
:
boolean
=
!!
maxAmountInput
&&
!!
parsedAmounts
[
Field
.
INPUT
]
!!
maxAmountInput
&&
!!
parsedAmounts
[
Field
.
INPUT
]
...
@@ -340,7 +306,7 @@ function ExchangePage({ sendingInput = false, history, params }) {
...
@@ -340,7 +306,7 @@ function ExchangePage({ sendingInput = false, history, params }) {
return
null
return
null
}
}
const
slippageAdjustedAmounts
:
{
[
field
:
number
]:
TokenAmount
}
=
{
const
slippageAdjustedAmounts
:
{
[
field
in
Field
]:
TokenAmount
}
=
{
[
Field
.
INPUT
]:
[
Field
.
INPUT
]:
Field
.
INPUT
===
independentField
Field
.
INPUT
===
independentField
?
parsedAmounts
[
Field
.
INPUT
]
?
parsedAmounts
[
Field
.
INPUT
]
...
@@ -582,7 +548,6 @@ function ExchangePage({ sendingInput = false, history, params }) {
...
@@ -582,7 +548,6 @@ function ExchangePage({ sendingInput = false, history, params }) {
if
(
if
(
parsedAmounts
[
Field
.
INPUT
]
&&
parsedAmounts
[
Field
.
INPUT
]
&&
pair
&&
route
&&
route
&&
JSBI
.
greaterThan
(
parsedAmounts
[
Field
.
INPUT
].
raw
,
route
.
pairs
[
0
].
reserveOf
(
tokens
[
Field
.
INPUT
]).
raw
)
JSBI
.
greaterThan
(
parsedAmounts
[
Field
.
INPUT
].
raw
,
route
.
pairs
[
0
].
reserveOf
(
tokens
[
Field
.
INPUT
]).
raw
)
)
{
)
{
...
@@ -593,7 +558,6 @@ function ExchangePage({ sendingInput = false, history, params }) {
...
@@ -593,7 +558,6 @@ function ExchangePage({ sendingInput = false, history, params }) {
if
(
if
(
!
ignoreOutput
&&
!
ignoreOutput
&&
parsedAmounts
[
Field
.
OUTPUT
]
&&
parsedAmounts
[
Field
.
OUTPUT
]
&&
pair
&&
route
&&
route
&&
JSBI
.
greaterThan
(
JSBI
.
greaterThan
(
parsedAmounts
[
Field
.
OUTPUT
].
raw
,
parsedAmounts
[
Field
.
OUTPUT
].
raw
,
...
@@ -631,11 +595,10 @@ function ExchangePage({ sendingInput = false, history, params }) {
...
@@ -631,11 +595,10 @@ function ExchangePage({ sendingInput = false, history, params }) {
dependentField
,
dependentField
,
ignoreOutput
,
ignoreOutput
,
independentField
,
independentField
,
pair
,
parsedAmounts
,
parsedAmounts
,
recipientError
,
recipientError
,
route
,
tokens
,
tokens
,
route
,
trade
,
trade
,
userBalances
userBalances
])
])
...
@@ -669,7 +632,7 @@ function ExchangePage({ sendingInput = false, history, params }) {
...
@@ -669,7 +632,7 @@ function ExchangePage({ sendingInput = false, history, params }) {
<
Text
fontSize=
{
36
}
fontWeight=
{
500
}
>
<
Text
fontSize=
{
36
}
fontWeight=
{
500
}
>
{
parsedAmounts
[
Field
.
INPUT
]?.
toSignificant
(
6
)
}
{
tokens
[
Field
.
INPUT
]?.
symbol
}
{
parsedAmounts
[
Field
.
INPUT
]?.
toSignificant
(
6
)
}
{
tokens
[
Field
.
INPUT
]?.
symbol
}
</
Text
>
</
Text
>
<
TokenLogo
address=
{
tokens
[
Field
.
INPUT
]?.
address
}
size=
{
'
30px
'
}
/>
<
TokenLogo
address=
{
tokens
[
Field
.
INPUT
]?.
address
}
size=
{
'
30px
'
}
/>
</
RowBetween
>
</
RowBetween
>
<
TYPE
.
darkGray
fontSize=
{
20
}
>
To
</
TYPE
.
darkGray
>
<
TYPE
.
darkGray
fontSize=
{
20
}
>
To
</
TYPE
.
darkGray
>
{
ENS
?
(
{
ENS
?
(
...
@@ -681,7 +644,7 @@ function ExchangePage({ sendingInput = false, history, params }) {
...
@@ -681,7 +644,7 @@ function ExchangePage({ sendingInput = false, history, params }) {
{
recipient
?.
slice
(
0
,
8
)
}
...
{
recipient
?.
slice
(
34
,
42
)
}
↗
{
recipient
?.
slice
(
0
,
8
)
}
...
{
recipient
?.
slice
(
34
,
42
)
}
↗
</
TYPE
.
blue
>
</
TYPE
.
blue
>
</
Link
>
</
Link
>
<
Copy
toCopy=
{
recipient
}
/>
<
Copy
toCopy=
{
recipient
}
/>
</
AutoRow
>
</
AutoRow
>
</
AutoColumn
>
</
AutoColumn
>
)
:
(
)
:
(
...
@@ -691,7 +654,7 @@ function ExchangePage({ sendingInput = false, history, params }) {
...
@@ -691,7 +654,7 @@ function ExchangePage({ sendingInput = false, history, params }) {
{
recipient
?.
slice
(
0
,
6
)
}
...
{
recipient
?.
slice
(
36
,
42
)
}
↗
{
recipient
?.
slice
(
0
,
6
)
}
...
{
recipient
?.
slice
(
36
,
42
)
}
↗
</
TYPE
.
blue
>
</
TYPE
.
blue
>
</
Link
>
</
Link
>
<
Copy
toCopy=
{
recipient
}
/>
<
Copy
toCopy=
{
recipient
}
/>
</
AutoRow
>
</
AutoRow
>
)
}
)
}
</
AutoColumn
>
</
AutoColumn
>
...
@@ -703,7 +666,7 @@ function ExchangePage({ sendingInput = false, history, params }) {
...
@@ -703,7 +666,7 @@ function ExchangePage({ sendingInput = false, history, params }) {
<
AutoColumn
gap=
"lg"
style=
{
{
marginTop
:
'
40px
'
}
}
>
<
AutoColumn
gap=
"lg"
style=
{
{
marginTop
:
'
40px
'
}
}
>
<
AutoColumn
gap=
"sm"
>
<
AutoColumn
gap=
"sm"
>
<
AutoRow
gap=
"10px"
>
<
AutoRow
gap=
"10px"
>
<
TokenLogo
address=
{
tokens
[
Field
.
OUTPUT
]?.
address
}
size=
{
'
30px
'
}
/>
<
TokenLogo
address=
{
tokens
[
Field
.
OUTPUT
]?.
address
}
size=
{
'
30px
'
}
/>
<
Text
fontSize=
{
36
}
fontWeight=
{
500
}
>
<
Text
fontSize=
{
36
}
fontWeight=
{
500
}
>
{
slippageAdjustedAmounts
[
Field
.
OUTPUT
]?.
toSignificant
(
4
)
}
{
tokens
[
Field
.
OUTPUT
]?.
symbol
}
{
slippageAdjustedAmounts
[
Field
.
OUTPUT
]?.
toSignificant
(
4
)
}
{
tokens
[
Field
.
OUTPUT
]?.
symbol
}
</
Text
>
</
Text
>
...
@@ -731,14 +694,14 @@ function ExchangePage({ sendingInput = false, history, params }) {
...
@@ -731,14 +694,14 @@ function ExchangePage({ sendingInput = false, history, params }) {
{
/* {!!slippageAdjustedAmounts[Field.INPUT] && slippageAdjustedAmounts[Field.INPUT].toSignificant(6)} */
}
{
/* {!!slippageAdjustedAmounts[Field.INPUT] && slippageAdjustedAmounts[Field.INPUT].toSignificant(6)} */
}
</
TruncatedText
>
</
TruncatedText
>
<
RowFixed
gap=
"4px"
>
<
RowFixed
gap=
"4px"
>
<
TokenLogo
address=
{
tokens
[
Field
.
INPUT
]?.
address
}
size=
{
'
24px
'
}
/>
<
TokenLogo
address=
{
tokens
[
Field
.
INPUT
]?.
address
}
size=
{
'
24px
'
}
/>
<
Text
fontSize=
{
24
}
fontWeight=
{
500
}
style=
{
{
marginLeft
:
'
10px
'
}
}
>
<
Text
fontSize=
{
24
}
fontWeight=
{
500
}
style=
{
{
marginLeft
:
'
10px
'
}
}
>
{
tokens
[
Field
.
INPUT
]?.
symbol
||
''
}
{
tokens
[
Field
.
INPUT
]?.
symbol
||
''
}
</
Text
>
</
Text
>
</
RowFixed
>
</
RowFixed
>
</
RowBetween
>
</
RowBetween
>
<
RowFixed
>
<
RowFixed
>
<
ArrowDown
size=
"16"
color=
{
theme
(
isDark
).
text2
}
/>
<
ArrowDown
size=
"16"
color=
{
theme
(
isDark
).
text2
}
/>
</
RowFixed
>
</
RowFixed
>
<
RowBetween
align=
"flex-end"
>
<
RowBetween
align=
"flex-end"
>
<
TruncatedText
fontSize=
{
24
}
fontWeight=
{
500
}
color=
{
warningHigh
?
theme
(
isDark
).
red1
:
''
}
>
<
TruncatedText
fontSize=
{
24
}
fontWeight=
{
500
}
color=
{
warningHigh
?
theme
(
isDark
).
red1
:
''
}
>
...
@@ -747,7 +710,7 @@ function ExchangePage({ sendingInput = false, history, params }) {
...
@@ -747,7 +710,7 @@ function ExchangePage({ sendingInput = false, history, params }) {
{
/* {!!slippageAdjustedAmounts[Field.OUTPUT] && slippageAdjustedAmounts[Field.OUTPUT].toSignificant(6)} */
}
{
/* {!!slippageAdjustedAmounts[Field.OUTPUT] && slippageAdjustedAmounts[Field.OUTPUT].toSignificant(6)} */
}
</
TruncatedText
>
</
TruncatedText
>
<
RowFixed
gap=
"4px"
>
<
RowFixed
gap=
"4px"
>
<
TokenLogo
address=
{
tokens
[
Field
.
OUTPUT
]?.
address
}
size=
{
'
24px
'
}
/>
<
TokenLogo
address=
{
tokens
[
Field
.
OUTPUT
]?.
address
}
size=
{
'
24px
'
}
/>
<
Text
fontSize=
{
24
}
fontWeight=
{
500
}
style=
{
{
marginLeft
:
'
10px
'
}
}
>
<
Text
fontSize=
{
24
}
fontWeight=
{
500
}
style=
{
{
marginLeft
:
'
10px
'
}
}
>
{
tokens
[
Field
.
OUTPUT
]?.
symbol
||
''
}
{
tokens
[
Field
.
OUTPUT
]?.
symbol
||
''
}
</
Text
>
</
Text
>
...
@@ -805,19 +768,19 @@ function ExchangePage({ sendingInput = false, history, params }) {
...
@@ -805,19 +768,19 @@ function ExchangePage({ sendingInput = false, history, params }) {
color=
{
theme
(
isDark
).
text2
}
color=
{
theme
(
isDark
).
text2
}
style=
{
{
justifyContent
:
'
center
'
,
alignItems
:
'
center
'
,
display
:
'
flex
'
}
}
style=
{
{
justifyContent
:
'
center
'
,
alignItems
:
'
center
'
,
display
:
'
flex
'
}
}
>
>
{
pair
&&
showInverted
{
trade
&&
showInverted
?
route
.
midPrice
.
invert
().
toSignificant
(
6
)
+
?
(
trade
?.
executionPrice
?.
invert
()?.
toSignificant
(
6
)
??
''
)
+
'
'
+
'
'
+
tokens
[
Field
.
INPUT
]?.
symbol
+
tokens
[
Field
.
INPUT
]?.
symbol
+
'
/
'
+
'
/
'
+
tokens
[
Field
.
OUTPUT
]?.
symbol
tokens
[
Field
.
OUTPUT
]?.
symbol
:
route
.
midPrice
.
toSignificant
(
6
)
+
:
(
trade
?.
executionPrice
?.
toSignificant
(
6
)
??
''
)
+
'
'
+
'
'
+
tokens
[
Field
.
OUTPUT
]?.
symbol
+
tokens
[
Field
.
OUTPUT
]?.
symbol
+
'
/
'
+
'
/
'
+
tokens
[
Field
.
INPUT
]?.
symbol
}
tokens
[
Field
.
INPUT
]?.
symbol
}
<
StyledBalanceMaxMini
onClick=
{
()
=>
setShowInverted
(
!
showInverted
)
}
>
<
StyledBalanceMaxMini
onClick=
{
()
=>
setShowInverted
(
!
showInverted
)
}
>
<
Repeat
size=
{
14
}
/>
<
Repeat
size=
{
14
}
/>
</
StyledBalanceMaxMini
>
</
StyledBalanceMaxMini
>
</
Text
>
</
Text
>
</
RowBetween
>
</
RowBetween
>
...
@@ -827,7 +790,8 @@ function ExchangePage({ sendingInput = false, history, params }) {
...
@@ -827,7 +790,8 @@ function ExchangePage({ sendingInput = false, history, params }) {
<
TYPE
.
black
fontSize=
{
14
}
fontWeight=
{
400
}
>
<
TYPE
.
black
fontSize=
{
14
}
fontWeight=
{
400
}
>
{
independentField
===
Field
.
INPUT
?
(
sending
?
'
Min sent
'
:
'
Minimum received
'
)
:
'
Maximum sold
'
}
{
independentField
===
Field
.
INPUT
?
(
sending
?
'
Min sent
'
:
'
Minimum received
'
)
:
'
Maximum sold
'
}
</
TYPE
.
black
>
</
TYPE
.
black
>
<
QuestionHelper
text=
"A boundary is set so you are protected from large price movements after you submit your trade."
/>
<
QuestionHelper
text=
"A boundary is set so you are protected from large price movements after you submit your trade."
/>
</
RowFixed
>
</
RowFixed
>
<
RowFixed
>
<
RowFixed
>
<
TYPE
.
black
fontSize=
{
14
}
>
<
TYPE
.
black
fontSize=
{
14
}
>
...
@@ -857,7 +821,7 @@ function ExchangePage({ sendingInput = false, history, params }) {
...
@@ -857,7 +821,7 @@ function ExchangePage({ sendingInput = false, history, params }) {
<
TYPE
.
black
color=
{
theme
(
isDark
).
text1
}
fontSize=
{
14
}
fontWeight=
{
400
}
>
<
TYPE
.
black
color=
{
theme
(
isDark
).
text1
}
fontSize=
{
14
}
fontWeight=
{
400
}
>
Price impact
Price impact
</
TYPE
.
black
>
</
TYPE
.
black
>
<
QuestionHelper
text=
"The difference between the market price and your price due to trade size."
/>
<
QuestionHelper
text=
"The difference between the market price and your price due to trade size."
/>
</
RowFixed
>
</
RowFixed
>
<
ErrorText
<
ErrorText
fontWeight=
{
500
}
fontWeight=
{
500
}
...
@@ -878,7 +842,8 @@ function ExchangePage({ sendingInput = false, history, params }) {
...
@@ -878,7 +842,8 @@ function ExchangePage({ sendingInput = false, history, params }) {
<
TYPE
.
black
fontSize=
{
14
}
fontWeight=
{
400
}
>
<
TYPE
.
black
fontSize=
{
14
}
fontWeight=
{
400
}
>
Liquidity Provider Fee
Liquidity Provider Fee
</
TYPE
.
black
>
</
TYPE
.
black
>
<
QuestionHelper
text=
"A portion of each trade (0.3%) goes to liquidity providers to incentivize liquidity on the protocol."
/>
<
QuestionHelper
text=
"A portion of each trade (0.3%) goes to liquidity providers to incentivize liquidity on the protocol."
/>
</
RowFixed
>
</
RowFixed
>
<
TYPE
.
black
fontSize=
{
14
}
>
<
TYPE
.
black
fontSize=
{
14
}
>
{
feeTimesInputFormatted
{
feeTimesInputFormatted
...
@@ -900,12 +865,12 @@ function ExchangePage({ sendingInput = false, history, params }) {
...
@@ -900,12 +865,12 @@ function ExchangePage({ sendingInput = false, history, params }) {
}
}
}
}
const
PriceBar
=
function
()
{
const
PriceBar
=
function
()
{
return
(
return
(
<
AutoRow
justify=
"space-between"
>
<
AutoRow
justify=
"space-between"
>
<
AutoColumn
justify=
"center"
>
<
AutoColumn
justify=
"center"
>
<
Text
fontWeight=
{
500
}
fontSize=
{
16
}
color=
{
theme
(
isDark
).
text2
}
>
<
Text
fontWeight=
{
500
}
fontSize=
{
16
}
color=
{
theme
(
isDark
).
text2
}
>
{
pair
?
`${route.mid
Price.toSignificant(6)} `
:
'
-
'
}
{
trade
?
`${trade.execution
Price.toSignificant(6)} `
:
'
-
'
}
</
Text
>
</
Text
>
<
Text
fontWeight=
{
500
}
fontSize=
{
16
}
color=
{
theme
(
isDark
).
text3
}
pt=
{
1
}
>
<
Text
fontWeight=
{
500
}
fontSize=
{
16
}
color=
{
theme
(
isDark
).
text3
}
pt=
{
1
}
>
{
tokens
[
Field
.
OUTPUT
]?.
symbol
}
/
{
tokens
[
Field
.
INPUT
]?.
symbol
}
{
tokens
[
Field
.
OUTPUT
]?.
symbol
}
/
{
tokens
[
Field
.
INPUT
]?.
symbol
}
...
@@ -913,7 +878,7 @@ function ExchangePage({ sendingInput = false, history, params }) {
...
@@ -913,7 +878,7 @@ function ExchangePage({ sendingInput = false, history, params }) {
</
AutoColumn
>
</
AutoColumn
>
<
AutoColumn
justify=
"center"
>
<
AutoColumn
justify=
"center"
>
<
Text
fontWeight=
{
500
}
fontSize=
{
16
}
color=
{
theme
(
isDark
).
text2
}
>
<
Text
fontWeight=
{
500
}
fontSize=
{
16
}
color=
{
theme
(
isDark
).
text2
}
>
{
pair
?
`${route.mid
Price.invert().toSignificant(6)} `
:
'
-
'
}
{
trade
?
`${trade.execution
Price.invert().toSignificant(6)} `
:
'
-
'
}
</
Text
>
</
Text
>
<
Text
fontWeight=
{
500
}
fontSize=
{
16
}
color=
{
theme
(
isDark
).
text3
}
pt=
{
1
}
>
<
Text
fontWeight=
{
500
}
fontSize=
{
16
}
color=
{
theme
(
isDark
).
text3
}
pt=
{
1
}
>
{
tokens
[
Field
.
INPUT
]?.
symbol
}
/
{
tokens
[
Field
.
OUTPUT
]?.
symbol
}
{
tokens
[
Field
.
INPUT
]?.
symbol
}
/
{
tokens
[
Field
.
OUTPUT
]?.
symbol
}
...
@@ -1002,7 +967,7 @@ function ExchangePage({ sendingInput = false, history, params }) {
...
@@ -1002,7 +967,7 @@ function ExchangePage({ sendingInput = false, history, params }) {
Max
Max
</MaxButton>
</MaxButton>
)}
)}
<StyledNumerical value={formattedAmounts[Field.INPUT]} onUserInput={val => onUserInput(Field.INPUT, val)}
/>
<StyledNumerical value={formattedAmounts[Field.INPUT]} onUserInput={val => onUserInput(Field.INPUT, val)}/>
<CurrencyInputPanel
<CurrencyInputPanel
field={Field.INPUT}
field={Field.INPUT}
value={formattedAmounts[Field.INPUT]}
value={formattedAmounts[Field.INPUT]}
...
@@ -1048,7 +1013,7 @@ function ExchangePage({ sendingInput = false, history, params }) {
...
@@ -1048,7 +1013,7 @@ function ExchangePage({ sendingInput = false, history, params }) {
<ColumnCenter>
<ColumnCenter>
<RowBetween padding="0 12px">
<RowBetween padding="0 12px">
<ArrowWrapper onClick={onSwapTokens}>
<ArrowWrapper onClick={onSwapTokens}>
<ArrowDown size="16" color={theme(isDark).text2} onClick={onSwapTokens}
/>
<ArrowDown size="16" color={theme(isDark).text2} onClick={onSwapTokens}/>
</ArrowWrapper>
</ArrowWrapper>
<StyledBalanceMaxMini onClick={() => setSendingWithSwap(false)} style={{ marginRight: '0px' }}>
<StyledBalanceMaxMini onClick={() => setSendingWithSwap(false)} style={{ marginRight: '0px' }}>
<TYPE.blue>Remove Swap</TYPE.blue>
<TYPE.blue>Remove Swap</TYPE.blue>
...
@@ -1086,7 +1051,7 @@ function ExchangePage({ sendingInput = false, history, params }) {
...
@@ -1086,7 +1051,7 @@ function ExchangePage({ sendingInput = false, history, params }) {
/>
/>
{sendingWithSwap && (
{sendingWithSwap && (
<RowBetween padding="0 12px">
<RowBetween padding="0 12px">
<ArrowDown size="16"
/>
<ArrowDown size="16"/>
</RowBetween>
</RowBetween>
)}
)}
</>
</>
...
@@ -1118,7 +1083,7 @@ function ExchangePage({ sendingInput = false, history, params }) {
...
@@ -1118,7 +1083,7 @@ function ExchangePage({ sendingInput = false, history, params }) {
{!noRoute && tokens[Field.OUTPUT] && tokens[Field.INPUT] && (
{!noRoute && tokens[Field.OUTPUT] && tokens[Field.INPUT] && (
<Card padding={advanced ? '.25rem 1.25rem 0 .75rem' : '.25rem .7rem .25rem 1.25rem'} borderRadius={'20px'}>
<Card padding={advanced ? '.25rem 1.25rem 0 .75rem' : '.25rem .7rem .25rem 1.25rem'} borderRadius={'20px'}>
{advanced ? (
{advanced ? (
<PriceBar
/>
<PriceBar/>
) : (
) : (
<AutoColumn gap="4px">
<AutoColumn gap="4px">
{' '}
{' '}
...
@@ -1132,23 +1097,23 @@ function ExchangePage({ sendingInput = false, history, params }) {
...
@@ -1132,23 +1097,23 @@ function ExchangePage({ sendingInput = false, history, params }) {
color={theme(isDark).text2}
color={theme(isDark).text2}
style={{ justifyContent: 'center', alignItems: 'center', display: 'flex' }}
style={{ justifyContent: 'center', alignItems: 'center', display: 'flex' }}
>
>
{
pair
&& showInverted
{
trade
&& showInverted
?
route.midPrice.invert().toSignificant(6
) +
?
(trade?.executionPrice?.invert()?.toSignificant(6) ?? ''
) +
' ' +
' ' +
tokens[Field.INPUT]?.symbol +
tokens[Field.INPUT]?.symbol +
' per ' +
' per ' +
tokens[Field.OUTPUT]?.symbol
tokens[Field.OUTPUT]?.symbol
:
route.midPrice.toSignificant(6
) +
:
(trade?.executionPrice?.toSignificant(6) ?? ''
) +
' ' +
' ' +
tokens[Field.OUTPUT]?.symbol +
tokens[Field.OUTPUT]?.symbol +
' per ' +
' per ' +
tokens[Field.INPUT]?.symbol}
tokens[Field.INPUT]?.symbol}
<StyledBalanceMaxMini onClick={() => setShowInverted(!showInverted)}>
<StyledBalanceMaxMini onClick={() => setShowInverted(!showInverted)}>
<Repeat size={14}
/>
<Repeat size={14}/>
</StyledBalanceMaxMini>
</StyledBalanceMaxMini>
</Text>
</Text>
</RowBetween>
</RowBetween>
{
pair
&& (warningHigh || warningMedium) && (
{
trade
&& (warningHigh || warningMedium) && (
<RowBetween>
<RowBetween>
<TYPE.main
<TYPE.main
style={{ justifyContent: 'center', alignItems: 'center', display: 'flex' }}
style={{ justifyContent: 'center', alignItems: 'center', display: 'flex' }}
...
@@ -1164,7 +1129,8 @@ function ExchangePage({ sendingInput = false, history, params }) {
...
@@ -1164,7 +1129,8 @@ function ExchangePage({ sendingInput = false, history, params }) {
: priceSlippage.toFixed(4) + '%'
: priceSlippage.toFixed(4) + '%'
: '-'}{' '}
: '-'}{' '}
</ErrorText>
</ErrorText>
<QuestionHelper text="The difference between the market price and your quoted price due to trade size." />
<QuestionHelper
text="The difference between the market price and your quoted price due to trade size."/>
</RowFixed>
</RowFixed>
</RowBetween>
</RowBetween>
)}
)}
...
@@ -1174,7 +1140,7 @@ function ExchangePage({ sendingInput = false, history, params }) {
...
@@ -1174,7 +1140,7 @@ function ExchangePage({ sendingInput = false, history, params }) {
)}
)}
</AutoColumn>
</AutoColumn>
<BottomGrouping>
<BottomGrouping>
{noRoute ? (
{noRoute
&& userHasSpecifiedInputOutput
? (
<GreyCard style={{ textAlign: 'center' }}>
<GreyCard style={{ textAlign: 'center' }}>
<TYPE.main>No path found.</TYPE.main>
<TYPE.main>No path found.</TYPE.main>
...
@@ -1240,7 +1206,7 @@ function ExchangePage({ sendingInput = false, history, params }) {
...
@@ -1240,7 +1206,7 @@ function ExchangePage({ sendingInput = false, history, params }) {
<Text fontSize={16} fontWeight={500} style={{ userSelect: 'none' }}>
<Text fontSize={16} fontWeight={500} style={{ userSelect: 'none' }}>
Show Advanced
Show Advanced
</Text>
</Text>
<ChevronDown color={theme(isDark).text2}
/>
<ChevronDown color={theme(isDark).text2}/>
</RowBetween>
</RowBetween>
</Hover>
</Hover>
)}
)}
...
@@ -1251,10 +1217,10 @@ function ExchangePage({ sendingInput = false, history, params }) {
...
@@ -1251,10 +1217,10 @@ function ExchangePage({ sendingInput = false, history, params }) {
<Text fontSize={16} color={theme(isDark).text2} fontWeight={500} style={{ userSelect: 'none' }}>
<Text fontSize={16} color={theme(isDark).text2} fontWeight={500} style={{ userSelect: 'none' }}>
Hide Advanced
Hide Advanced
</Text>
</Text>
<ChevronUp color={theme(isDark).text2}
/>
<ChevronUp color={theme(isDark).text2}/>
</RowBetween>
</RowBetween>
</Hover>
</Hover>
<SectionBreak
/>
<SectionBreak/>
<AutoColumn style={{ padding: '0 20px' }}>
<AutoColumn style={{ padding: '0 20px' }}>
<RowBetween>
<RowBetween>
<RowFixed>
<RowFixed>
...
@@ -1307,7 +1273,8 @@ function ExchangePage({ sendingInput = false, history, params }) {
...
@@ -1307,7 +1273,8 @@ function ExchangePage({ sendingInput = false, history, params }) {
<TYPE.black fontSize={14} fontWeight={400} color={theme(isDark).text1}>
<TYPE.black fontSize={14} fontWeight={400} color={theme(isDark).text1}>
Price Impact
Price Impact
</TYPE.black>
</TYPE.black>
<QuestionHelper text="The difference between the market price and your quoted price due to trade size." />
<QuestionHelper
text="The difference between the market price and your quoted price due to trade size."/>
</RowFixed>
</RowFixed>
<ErrorText
<ErrorText
fontWeight={500}
fontWeight={500}
...
@@ -1328,7 +1295,8 @@ function ExchangePage({ sendingInput = false, history, params }) {
...
@@ -1328,7 +1295,8 @@ function ExchangePage({ sendingInput = false, history, params }) {
<TYPE.black fontSize={14} fontWeight={400} color={theme(isDark).text1}>
<TYPE.black fontSize={14} fontWeight={400} color={theme(isDark).text1}>
Liquidity Provider Fee
Liquidity Provider Fee
</TYPE.black>
</TYPE.black>
<QuestionHelper text="A portion of each trade (0.03%) goes to liquidity providers to incentivize liquidity on the protocol." />
<QuestionHelper
text="A portion of each trade (0.03%) goes to liquidity providers to incentivize liquidity on the protocol."/>
</RowFixed>
</RowFixed>
<TYPE.black fontSize={14} color={theme(isDark).text1}>
<TYPE.black fontSize={14} color={theme(isDark).text1}>
{feeTimesInputFormatted
{feeTimesInputFormatted
...
@@ -1337,12 +1305,13 @@ function ExchangePage({ sendingInput = false, history, params }) {
...
@@ -1337,12 +1305,13 @@ function ExchangePage({ sendingInput = false, history, params }) {
</TYPE.black>
</TYPE.black>
</RowBetween>
</RowBetween>
</AutoColumn>
</AutoColumn>
<SectionBreak
/>
<SectionBreak/>
<RowFixed padding={'0 20px'}>
<RowFixed padding={'0 20px'}>
<TYPE.black fontWeight={400} fontSize={14} color={theme(isDark).text1}>
<TYPE.black fontWeight={400} fontSize={14} color={theme(isDark).text1}>
Set front running resistance
Set front running resistance
</TYPE.black>
</TYPE.black>
<QuestionHelper text="Your transaction will revert if the price changes more than this amount after you submit your trade." />
<QuestionHelper
text="Your transaction will revert if the price changes more than this amount after you submit your trade."/>
</RowFixed>
</RowFixed>
<SlippageTabs
<SlippageTabs
rawSlippage={allowedSlippage}
rawSlippage={allowedSlippage}
...
...
src/components/ExchangePage/swap-store.ts
View file @
9b2fe0bd
import
{
WETH
}
from
'
@uniswap/sdk
'
import
{
useReducer
}
from
'
react
'
import
{
useWeb3React
}
from
'
../../hooks
'
import
{
QueryParams
}
from
'
../../utils
'
export
enum
Field
{
export
enum
Field
{
INPUT
,
INPUT
,
OUTPUT
OUTPUT
...
@@ -93,3 +98,34 @@ export function reducer(
...
@@ -93,3 +98,34 @@ export function reducer(
}
}
}
}
}
}
export
function
useSwapStateReducer
(
params
:
QueryParams
)
{
const
{
chainId
}
=
useWeb3React
()
return
useReducer
(
reducer
,
{
independentField
:
params
.
outputTokenAddress
&&
!
params
.
inputTokenAddress
?
Field
.
OUTPUT
:
Field
.
INPUT
,
inputTokenAddress
:
params
.
inputTokenAddress
?
params
.
inputTokenAddress
:
WETH
[
chainId
].
address
,
outputTokenAddress
:
params
.
outputTokenAddress
?
params
.
outputTokenAddress
:
''
,
typedValue
:
params
.
inputTokenAddress
&&
!
params
.
outputTokenAddress
?
params
.
inputTokenAmount
?
params
.
inputTokenAmount
:
''
:
!
params
.
inputTokenAddress
&&
params
.
outputTokenAddress
?
params
.
outputTokenAmount
?
params
.
outputTokenAmount
:
''
:
params
.
inputTokenAddress
&&
params
.
outputTokenAddress
?
params
.
inputTokenAmount
?
params
.
inputTokenAmount
:
''
:
''
?
''
:
''
?
''
:
''
},
initializeSwapState
)
}
src/contexts/Application.
js
→
src/contexts/Application.
tsx
View file @
9b2fe0bd
...
@@ -16,13 +16,29 @@ const ADD_POPUP = 'ADD_POPUP'
...
@@ -16,13 +16,29 @@ const ADD_POPUP = 'ADD_POPUP'
const
USER_ADVANCED
=
'
USER_ADVANCED
'
const
USER_ADVANCED
=
'
USER_ADVANCED
'
const
TOGGLE_USER_ADVANCED
=
'
TOGGLE_USER_ADVANCED
'
const
TOGGLE_USER_ADVANCED
=
'
TOGGLE_USER_ADVANCED
'
const
ApplicationContext
=
createContext
()
interface
ApplicationState
{
BLOCK_NUMBER
:
{},
USD_PRICE
:
{},
POPUP_LIST
:
Array
<
{
key
:
number
;
show
:
boolean
;
content
:
React
.
ReactElement
}
>
,
POPUP_KEY
:
number
,
WALLET_MODAL_OPEN
:
boolean
,
USER_ADVANCED
:
boolean
}
const
ApplicationContext
=
createContext
<
[
ApplicationState
,
{
[
updater
:
string
]:
(...
args
:
any
[])
=>
void
}]
>
([{
[
BLOCK_NUMBER
]:
{},
[
USD_PRICE
]:
{},
[
POPUP_LIST
]:
[],
[
POPUP_KEY
]:
0
,
[
WALLET_MODAL_OPEN
]:
false
,
[
USER_ADVANCED
]:
false
},
{}])
function
useApplicationContext
()
{
function
useApplicationContext
()
{
return
useContext
(
ApplicationContext
)
return
useContext
(
ApplicationContext
)
}
}
function
reducer
(
state
,
{
type
,
payload
})
{
function
reducer
(
state
:
ApplicationState
,
{
type
,
payload
}):
ApplicationState
{
switch
(
type
)
{
switch
(
type
)
{
case
UPDATE_BLOCK_NUMBER
:
{
case
UPDATE_BLOCK_NUMBER
:
{
const
{
networkId
,
blockNumber
}
=
payload
const
{
networkId
,
blockNumber
}
=
payload
...
@@ -66,19 +82,19 @@ export default function Provider({ children }) {
...
@@ -66,19 +82,19 @@ export default function Provider({ children }) {
const
updateBlockNumber
=
useCallback
((
networkId
,
blockNumber
)
=>
{
const
updateBlockNumber
=
useCallback
((
networkId
,
blockNumber
)
=>
{
dispatch
({
type
:
UPDATE_BLOCK_NUMBER
,
payload
:
{
networkId
,
blockNumber
}
})
dispatch
({
type
:
UPDATE_BLOCK_NUMBER
,
payload
:
{
networkId
,
blockNumber
}
})
},
[])
},
[
dispatch
])
const
toggleWalletModal
=
useCallback
(()
=>
{
const
toggleWalletModal
=
useCallback
(()
=>
{
dispatch
({
type
:
TOGGLE_WALLET_MODAL
})
dispatch
({
type
:
TOGGLE_WALLET_MODAL
,
payload
:
null
})
},
[])
},
[
dispatch
])
const
toggleUserAdvanced
=
useCallback
(()
=>
{
const
toggleUserAdvanced
=
useCallback
(()
=>
{
dispatch
({
type
:
TOGGLE_USER_ADVANCED
})
dispatch
({
type
:
TOGGLE_USER_ADVANCED
,
payload
:
null
})
},
[])
},
[
dispatch
])
const
setPopups
=
useCallback
(
newList
=>
{
const
setPopups
=
useCallback
(
newList
=>
{
dispatch
({
type
:
ADD_POPUP
,
payload
:
{
newList
}
})
dispatch
({
type
:
ADD_POPUP
,
payload
:
{
newList
}
})
},
[])
},
[
dispatch
])
return
(
return
(
<
ApplicationContext
.
Provider
<
ApplicationContext
.
Provider
...
@@ -105,7 +121,7 @@ export function Updater() {
...
@@ -105,7 +121,7 @@ export function Updater() {
if
(
library
)
{
if
(
library
)
{
let
stale
=
false
let
stale
=
false
function
update
()
{
const
update
=
()
=>
{
library
library
.
getBlockNumber
()
.
getBlockNumber
()
.
then
(
blockNumber
=>
{
.
then
(
blockNumber
=>
{
...
@@ -164,13 +180,13 @@ export function useToggleUserAdvanced() {
...
@@ -164,13 +180,13 @@ export function useToggleUserAdvanced() {
return
toggleUserAdvanced
return
toggleUserAdvanced
}
}
export
function
usePopups
()
{
export
function
usePopups
()
:
[
ApplicationState
[
'
POPUP_LIST
'
],
(
content
:
React
.
ReactElement
)
=>
void
,
(
key
:
number
)
=>
void
]
{
const
[
state
,
{
setPopups
}]
=
useApplicationContext
()
const
[
state
,
{
setPopups
}]
=
useApplicationContext
()
const
index
=
state
[
POPUP_KEY
]
const
index
=
state
[
POPUP_KEY
]
const
currentPopups
=
state
[
POPUP_LIST
]
const
currentPopups
=
state
[
POPUP_LIST
]
function
addPopup
(
content
)
{
function
addPopup
(
content
:
React
.
ReactElement
):
void
{
const
newItem
=
{
const
newItem
=
{
show
:
true
,
show
:
true
,
key
:
index
,
key
:
index
,
...
@@ -180,7 +196,7 @@ export function usePopups() {
...
@@ -180,7 +196,7 @@ export function usePopups() {
setPopups
(
currentPopups
)
setPopups
(
currentPopups
)
}
}
function
removePopup
(
key
)
{
function
removePopup
(
key
:
number
):
void
{
currentPopups
.
map
(
item
=>
{
currentPopups
.
map
(
item
=>
{
if
(
key
===
item
.
key
)
{
if
(
key
===
item
.
key
)
{
item
.
show
=
false
item
.
show
=
false
...
...
src/contexts/Routes.tsx
deleted
100644 → 0
View file @
cb00e0ba
import
React
,
{
createContext
,
useContext
,
useReducer
,
useMemo
,
useCallback
,
useEffect
}
from
'
react
'
import
{
WETH
,
Token
,
Route
,
JSBI
}
from
'
@uniswap/sdk
'
import
{
useWeb3React
}
from
'
../hooks
'
import
{
usePair
}
from
'
../contexts/Pairs
'
import
{
isWETH
}
from
'
../utils
'
const
UPDATE
=
'
UPDATE
'
interface
RouteState
{
[
chainId
:
number
]:
{
[
tokenAddress
:
string
]:
{
[
tokenAddress
:
string
]:
{
route
:
Route
}
}
}
}
const
RouteContext
=
createContext
<
[
RouteState
,
{
[
k
:
string
]:
(...
args
:
any
)
=>
void
}]
>
([{},
{}])
function
useRouteContext
()
{
return
useContext
(
RouteContext
)
}
function
reducer
(
state
:
RouteState
,
{
type
,
payload
})
{
switch
(
type
)
{
case
UPDATE
:
{
const
{
tokens
,
route
,
chainId
}
=
payload
return
{
...
state
,
[
chainId
]:
{
...
state
[
chainId
],
[
tokens
[
0
]]:
{
...
state
[
chainId
]?.[
tokens
[
0
]],
[
tokens
[
1
]]:
{
route
}
}
}
}
}
default
:
{
throw
Error
(
`Unexpected action type in ExchangesContext reducer: '
${
type
}
'.`
)
}
}
}
export
default
function
Provider
({
children
})
{
const
[
state
,
dispatch
]
=
useReducer
(
reducer
,
{})
const
update
=
useCallback
((
tokens
,
route
,
chainId
)
=>
{
dispatch
({
type
:
UPDATE
,
payload
:
{
tokens
,
route
,
chainId
}
})
},
[])
return
(
<
RouteContext
.
Provider
value=
{
useMemo
(()
=>
[
state
,
{
update
}],
[
state
,
update
])
}
>
{
children
}
</
RouteContext
.
Provider
>
)
}
/**
* @param tokenA input to token to be sold
* @param tokenB output token to be bought
*
* This hook finds either a direct pair between tokenA and tokenB or,
* a one-hop route that goes through token<->WETH pairs
*
* if neither exists returns null
*/
export
function
useRoute
(
tokenA
:
Token
,
tokenB
:
Token
)
{
const
[
state
,
{
update
}]
=
useRouteContext
()
const
{
chainId
}
=
useWeb3React
()
let
route
:
Route
=
state
?.[
chainId
]?.[
tokenA
?.
address
]?.[
tokenB
?.
address
]?.
route
// check for direct pair between tokens
const
defaultPair
=
usePair
(
tokenA
,
tokenB
)
// get token<->WETH pairs
const
aToETH
=
usePair
(
tokenA
&&
!
isWETH
(
tokenA
)
?
tokenA
:
null
,
WETH
[
chainId
])
const
bToETH
=
usePair
(
tokenB
&&
!
isWETH
(
tokenB
)
?
tokenB
:
null
,
WETH
[
chainId
])
// needs to route through WETH
const
requiresHop
=
defaultPair
&&
JSBI
.
equal
(
defaultPair
?.
reserve0
?.
raw
,
JSBI
.
BigInt
(
0
))
&&
JSBI
.
equal
(
defaultPair
?.
reserve1
?.
raw
,
JSBI
.
BigInt
(
0
))
useEffect
(()
=>
{
if
(
!
route
&&
tokenA
&&
tokenB
)
{
if
(
!
requiresHop
&&
defaultPair
)
{
update
([
tokenA
.
address
,
tokenB
.
address
],
new
Route
([
defaultPair
],
tokenA
),
chainId
)
}
if
(
requiresHop
&&
aToETH
&&
bToETH
&&
// check there is liquidity in both token<->ETH pairs
JSBI
.
notEqual
(
JSBI
.
BigInt
(
0
),
aToETH
.
reserve0
.
raw
)
&&
JSBI
.
notEqual
(
JSBI
.
BigInt
(
0
),
bToETH
.
reserve0
.
raw
)
)
{
const
routeThroughETH
=
new
Route
([
aToETH
,
bToETH
],
tokenA
)
update
([
tokenA
.
address
,
tokenB
.
address
],
routeThroughETH
,
chainId
)
}
}
},
[
route
,
requiresHop
,
update
,
chainId
,
tokenA
,
tokenB
,
defaultPair
,
aToETH
,
bToETH
])
return
useMemo
(()
=>
route
,
[
route
])
}
src/contexts/Transactions.
js
→
src/contexts/Transactions.
tsx
View file @
9b2fe0bd
...
@@ -16,7 +16,11 @@ const ADD = 'ADD'
...
@@ -16,7 +16,11 @@ const ADD = 'ADD'
const
CHECK
=
'
CHECK
'
const
CHECK
=
'
CHECK
'
const
FINALIZE
=
'
FINALIZE
'
const
FINALIZE
=
'
FINALIZE
'
const
TransactionsContext
=
createContext
()
interface
TransactionState
{
}
const
TransactionsContext
=
createContext
<
[
TransactionState
,
{
[
updater
:
string
]:
(...
args
:
any
[])
=>
void
}]
>
([{},
{}])
export
function
useTransactionsContext
()
{
export
function
useTransactionsContext
()
{
return
useContext
(
TransactionsContext
)
return
useContext
(
TransactionsContext
)
...
@@ -134,10 +138,12 @@ export function Updater() {
...
@@ -134,10 +138,12 @@ export function Updater() {
finalize
(
chainId
,
hash
,
receipt
)
finalize
(
chainId
,
hash
,
receipt
)
// add success or failure popup
// add success or failure popup
if
(
receipt
.
status
===
1
)
{
if
(
receipt
.
status
===
1
)
{
addPopup
(
<
TxnPopup
hash
=
{
hash
}
success
=
{
true
}
summary
=
{
allTransactions
[
hash
]?.
response
?.
summary
}
/>
)
addPopup
(<
TxnPopup
popKey=
{
1
}
hash=
{
hash
}
success=
{
true
}
summary=
{
allTransactions
[
hash
]?.
response
?.
summary
}
/>)
}
else
{
}
else
{
addPopup
(
addPopup
(
<
TxnPopup
hash
=
{
hash
}
success
=
{
false
}
summary
=
{
allTransactions
[
hash
]?.
response
?.
summary
}
/
>
<
TxnPopup
popKey=
{
2
}
hash=
{
hash
}
success=
{
false
}
summary=
{
allTransactions
[
hash
]?.
response
?.
summary
}
/>
)
)
}
}
}
}
...
...
src/hooks/Trades.ts
0 → 100644
View file @
9b2fe0bd
import
{
useMemo
}
from
'
react
'
import
{
WETH
,
Token
,
TokenAmount
,
Trade
}
from
'
@uniswap/sdk
'
import
{
useWeb3React
}
from
'
./index
'
import
{
usePair
}
from
'
../contexts/Pairs
'
import
{
isWETH
}
from
'
../utils
'
/**
* Returns the best trade for the exact amount of tokens in to the given token out
*/
export
function
useTradeExactIn
(
amountIn
?:
TokenAmount
,
tokenOut
?:
Token
):
Trade
|
null
{
const
{
chainId
}
=
useWeb3React
()
// check for direct pair between tokens
const
pairBetween
=
usePair
(
amountIn
?.
token
,
tokenOut
)
// get token<->WETH pairs
const
aToETH
=
usePair
(
amountIn
&&
!
isWETH
(
amountIn
.
token
)
?
amountIn
.
token
:
null
,
WETH
[
chainId
])
const
bToETH
=
usePair
(
tokenOut
&&
!
isWETH
(
tokenOut
)
?
tokenOut
:
null
,
WETH
[
chainId
])
return
useMemo
(()
=>
{
const
allPairs
=
[
pairBetween
,
aToETH
,
bToETH
].
filter
(
p
=>
!!
p
)
if
(
amountIn
&&
allPairs
.
length
>
0
&&
tokenOut
)
{
return
Trade
.
bestTradeExactIn
(
allPairs
,
amountIn
,
tokenOut
)[
0
]
??
null
}
return
null
},
[
aToETH
,
bToETH
,
pairBetween
,
amountIn
,
tokenOut
])
}
/**
* Returns the best trade for the token in to the exact amount of token out
*/
export
function
useTradeExactOut
(
tokenIn
?:
Token
,
amountOut
?:
TokenAmount
):
Trade
|
null
{
const
{
chainId
}
=
useWeb3React
()
// check for direct pair between tokens
const
pairBetween
=
usePair
(
amountOut
?.
token
,
tokenIn
)
// get token<->WETH pairs
const
aToETH
=
usePair
(
amountOut
&&
!
isWETH
(
amountOut
.
token
)
?
amountOut
.
token
:
null
,
WETH
[
chainId
])
const
bToETH
=
usePair
(
tokenIn
&&
!
isWETH
(
tokenIn
)
?
tokenIn
:
null
,
WETH
[
chainId
])
return
useMemo
(()
=>
{
const
allPairs
=
[
pairBetween
,
aToETH
,
bToETH
].
filter
(
p
=>
!!
p
)
if
(
amountOut
&&
allPairs
.
length
>
0
&&
tokenIn
)
{
return
Trade
.
bestTradeExactOut
(
allPairs
,
tokenIn
,
amountOut
)[
0
]
??
null
}
return
null
},
[
pairBetween
,
aToETH
,
bToETH
,
amountOut
,
tokenIn
])
}
src/index.tsx
View file @
9b2fe0bd
...
@@ -12,7 +12,6 @@ import TransactionContextProvider, { Updater as TransactionContextUpdater } from
...
@@ -12,7 +12,6 @@ import TransactionContextProvider, { Updater as TransactionContextUpdater } from
import
BalancesContextProvider
,
{
Updater
as
BalancesContextUpdater
}
from
'
./contexts/Balances
'
import
BalancesContextProvider
,
{
Updater
as
BalancesContextUpdater
}
from
'
./contexts/Balances
'
import
ExchangesContextProvider
from
'
./contexts/Pairs
'
import
ExchangesContextProvider
from
'
./contexts/Pairs
'
import
AllowancesContextProvider
from
'
./contexts/Allowances
'
import
AllowancesContextProvider
from
'
./contexts/Allowances
'
import
RoutesContextProvider
from
'
./contexts/Routes
'
import
App
from
'
./pages/App
'
import
App
from
'
./pages/App
'
import
ThemeProvider
,
{
GlobalStyle
}
from
'
./theme
'
import
ThemeProvider
,
{
GlobalStyle
}
from
'
./theme
'
import
'
./i18n
'
import
'
./i18n
'
...
@@ -42,11 +41,9 @@ function ContextProviders({ children }) {
...
@@ -42,11 +41,9 @@ function ContextProviders({ children }) {
<
ApplicationContextProvider
>
<
ApplicationContextProvider
>
<
TransactionContextProvider
>
<
TransactionContextProvider
>
<
ExchangesContextProvider
>
<
ExchangesContextProvider
>
<
RoutesContextProvider
>
<
BalancesContextProvider
>
<
BalancesContextProvider
>
<
AllowancesContextProvider
>
{
children
}
</
AllowancesContextProvider
>
<
AllowancesContextProvider
>
{
children
}
</
AllowancesContextProvider
>
</
BalancesContextProvider
>
</
BalancesContextProvider
>
</
RoutesContextProvider
>
</
ExchangesContextProvider
>
</
ExchangesContextProvider
>
</
TransactionContextProvider
>
</
TransactionContextProvider
>
</
ApplicationContextProvider
>
</
ApplicationContextProvider
>
...
...
src/utils/index.ts
View file @
9b2fe0bd
...
@@ -69,7 +69,7 @@ function parseUrlTokenAmount(paramName: string): string {
...
@@ -69,7 +69,7 @@ function parseUrlTokenAmount(paramName: string): string {
return
value
return
value
}
}
interface
QueryParams
{
export
interface
QueryParams
{
readonly
inputTokenAddress
:
string
readonly
inputTokenAddress
:
string
readonly
outputTokenAddress
:
string
readonly
outputTokenAddress
:
string
readonly
inputTokenAmount
:
string
readonly
inputTokenAmount
:
string
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment