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
a60ea703
Unverified
Commit
a60ea703
authored
Feb 16, 2022
by
Zach Pomerantz
Committed by
GitHub
Feb 16, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix: token select ux (#3321)
parent
ae664dc2
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
188 additions
and
39 deletions
+188
-39
index.tsx
src/lib/components/Swap/index.tsx
+7
-6
TokenSelect.fixture.tsx
src/lib/components/TokenSelect.fixture.tsx
+2
-2
TokenOptions.tsx
src/lib/components/TokenSelect/TokenOptions.tsx
+10
-1
TokenOptionsSkeleton.tsx
src/lib/components/TokenSelect/TokenOptionsSkeleton.tsx
+66
-0
index.tsx
src/lib/components/TokenSelect/index.tsx
+43
-4
index.ts
src/lib/hooks/useTokenList/index.ts
+60
-26
No files found.
src/lib/components/Swap/index.tsx
View file @
a60ea703
...
@@ -8,7 +8,7 @@ import useSyncSwapDefaults from 'lib/hooks/swap/useSyncSwapDefaults'
...
@@ -8,7 +8,7 @@ import useSyncSwapDefaults from 'lib/hooks/swap/useSyncSwapDefaults'
import
{
usePendingTransactions
}
from
'
lib/hooks/transactions
'
import
{
usePendingTransactions
}
from
'
lib/hooks/transactions
'
import
useActiveWeb3React
from
'
lib/hooks/useActiveWeb3React
'
import
useActiveWeb3React
from
'
lib/hooks/useActiveWeb3React
'
import
useHasFocus
from
'
lib/hooks/useHasFocus
'
import
useHasFocus
from
'
lib/hooks/useHasFocus
'
import
useTokenList
from
'
lib/hooks/useTokenList
'
import
useTokenList
,
{
useSyncTokenList
}
from
'
lib/hooks/useTokenList
'
import
{
displayTxHashAtom
}
from
'
lib/state/swap
'
import
{
displayTxHashAtom
}
from
'
lib/state/swap
'
import
{
SwapTransactionInfo
,
Transaction
,
TransactionType
}
from
'
lib/state/transactions
'
import
{
SwapTransactionInfo
,
Transaction
,
TransactionType
}
from
'
lib/state/transactions
'
import
{
useMemo
,
useState
}
from
'
react
'
import
{
useMemo
,
useState
}
from
'
react
'
...
@@ -50,7 +50,7 @@ export interface SwapProps {
...
@@ -50,7 +50,7 @@ export interface SwapProps {
}
}
export
default
function
Swap
(
props
:
SwapProps
)
{
export
default
function
Swap
(
props
:
SwapProps
)
{
const
list
=
use
TokenList
(
props
.
tokenList
)
useSync
TokenList
(
props
.
tokenList
)
useSyncSwapDefaults
(
props
)
useSyncSwapDefaults
(
props
)
useSyncConvenienceFee
(
props
)
useSyncConvenienceFee
(
props
)
...
@@ -61,16 +61,17 @@ export default function Swap(props: SwapProps) {
...
@@ -61,16 +61,17 @@ export default function Swap(props: SwapProps) {
const
pendingTxs
=
usePendingTransactions
()
const
pendingTxs
=
usePendingTransactions
()
const
displayTx
=
getSwapTx
(
pendingTxs
,
displayTxHash
)
const
displayTx
=
getSwapTx
(
pendingTxs
,
displayTxHash
)
const
onSupportedChain
=
useMemo
(
const
tokenList
=
useTokenList
()
()
=>
chainId
&&
ALL_SUPPORTED_CHAIN_IDS
.
includes
(
chainId
)
&&
list
.
some
((
token
)
=>
token
.
chainId
===
chainId
),
const
isSwapSupported
=
useMemo
(
[
chainId
,
list
]
()
=>
Boolean
(
chainId
&&
ALL_SUPPORTED_CHAIN_IDS
.
includes
(
chainId
)
&&
tokenList
?.
length
),
[
chainId
,
tokenList
]
)
)
const
focused
=
useHasFocus
(
wrapper
)
const
focused
=
useHasFocus
(
wrapper
)
return
(
return
(
<
SwapPropValidator
{
...
props
}
>
<
SwapPropValidator
{
...
props
}
>
{
onSupportedChain
&&
<
SwapInfoUpdater
/>
}
{
isSwapSupported
&&
<
SwapInfoUpdater
/>
}
<
Header
title=
{
<
Trans
>
Swap
</
Trans
>
}
>
<
Header
title=
{
<
Trans
>
Swap
</
Trans
>
}
>
{
active
&&
<
Wallet
disabled=
{
!
account
}
onClick=
{
props
.
onConnectWallet
}
/>
}
{
active
&&
<
Wallet
disabled=
{
!
account
}
onClick=
{
props
.
onConnectWallet
}
/>
}
<
Settings
disabled=
{
!
active
}
/>
<
Settings
disabled=
{
!
active
}
/>
...
...
src/lib/components/TokenSelect.fixture.tsx
View file @
a60ea703
import
DEFAULT_TOKEN_LIST
from
'
@uniswap/default-token-list
'
import
DEFAULT_TOKEN_LIST
from
'
@uniswap/default-token-list
'
import
useTokenList
from
'
lib/hooks/useTokenList
'
import
{
useSyncTokenList
}
from
'
lib/hooks/useTokenList
'
import
{
Modal
}
from
'
./Dialog
'
import
{
Modal
}
from
'
./Dialog
'
import
{
TokenSelectDialog
}
from
'
./TokenSelect
'
import
{
TokenSelectDialog
}
from
'
./TokenSelect
'
export
default
function
Fixture
()
{
export
default
function
Fixture
()
{
useTokenList
(
DEFAULT_TOKEN_LIST
.
tokens
)
use
Sync
TokenList
(
DEFAULT_TOKEN_LIST
.
tokens
)
return
(
return
(
<
Modal
color=
"module"
>
<
Modal
color=
"module"
>
...
...
src/lib/components/TokenSelect/TokenOptions.tsx
View file @
a60ea703
...
@@ -69,6 +69,13 @@ interface BubbledEvent extends SyntheticEvent {
...
@@ -69,6 +69,13 @@ interface BubbledEvent extends SyntheticEvent {
ref
?:
HTMLButtonElement
ref
?:
HTMLButtonElement
}
}
const
TokenBalance
=
styled
.
div
<
{
isLoading
:
boolean
}
>
`
background-color:
${({
theme
,
isLoading
})
=>
isLoading
&&
theme
.
secondary
}
;
border-radius: 0.25em;
padding: 0.375em 0;
width: 1.5em;
`
function
TokenOption
({
index
,
value
,
style
}:
TokenOptionProps
)
{
function
TokenOption
({
index
,
value
,
style
}:
TokenOptionProps
)
{
const
{
i18n
}
=
useLingui
()
const
{
i18n
}
=
useLingui
()
const
ref
=
useRef
<
HTMLButtonElement
>
(
null
)
const
ref
=
useRef
<
HTMLButtonElement
>
(
null
)
...
@@ -103,7 +110,9 @@ function TokenOption({ index, value, style }: TokenOptionProps) {
...
@@ -103,7 +110,9 @@ function TokenOption({ index, value, style }: TokenOptionProps) {
<
ThemedText
.
Caption
color=
"secondary"
>
{
value
.
name
}
</
ThemedText
.
Caption
>
<
ThemedText
.
Caption
color=
"secondary"
>
{
value
.
name
}
</
ThemedText
.
Caption
>
</
Column
>
</
Column
>
</
Row
>
</
Row
>
<
TokenBalance
isLoading=
{
Boolean
(
account
)
&&
!
balance
}
>
{
balance
?.
greaterThan
(
0
)
&&
formatCurrencyAmount
(
balance
,
2
,
i18n
.
locale
)
}
{
balance
?.
greaterThan
(
0
)
&&
formatCurrencyAmount
(
balance
,
2
,
i18n
.
locale
)
}
</
TokenBalance
>
</
Row
>
</
Row
>
</
ThemedText
.
Body1
>
</
ThemedText
.
Body1
>
</
TokenButton
>
</
TokenButton
>
...
...
src/lib/components/TokenSelect/TokenOptionsSkeleton.tsx
0 → 100644
View file @
a60ea703
import
styled
,
{
ThemedText
}
from
'
lib/theme
'
import
Column
from
'
../Column
'
import
Row
from
'
../Row
'
const
Img
=
styled
.
div
`
clip-path: circle(50%);
height: 1.5em;
width: 1.5em;
`
const
Symbol
=
styled
.
div
`
height: 0.75em;
width: 7em;
`
const
Name
=
styled
.
div
`
height: 0.5em;
width: 5.5em;
`
const
Balance
=
styled
.
div
`
padding: 0.375em 0;
width: 1.5em;
`
const
TokenRow
=
styled
.
div
`
outline: none;
padding: 0.6875em 0.75em;
${
Img
}
,
${
Symbol
}
,
${
Name
}
,
${
Balance
}
{
background-color:
${({
theme
})
=>
theme
.
secondary
}
;
border-radius: 0.25em;
}
`
function
TokenOption
()
{
return
(
<
TokenRow
>
<
ThemedText
.
Body1
>
<
Row
>
<
Row
gap=
{
0.5
}
>
<
Img
/>
<
Column
flex
gap=
{
0.125
}
align=
"flex-start"
justify=
"flex-center"
>
<
ThemedText
.
Subhead1
style=
{
{
display
:
'
flex
'
}
}
>
<
Symbol
/>
</
ThemedText
.
Subhead1
>
<
ThemedText
.
Caption
style=
{
{
display
:
'
flex
'
}
}
>
<
Name
/>
</
ThemedText
.
Caption
>
</
Column
>
</
Row
>
<
Balance
/>
</
Row
>
</
ThemedText
.
Body1
>
</
TokenRow
>
)
}
export
default
function
TokenOptionsSkeleton
()
{
return
(
<
Column
>
<
TokenOption
/>
<
TokenOption
/>
<
TokenOption
/>
<
TokenOption
/>
<
TokenOption
/>
</
Column
>
)
}
src/lib/components/TokenSelect/index.tsx
View file @
a60ea703
import
{
t
,
Trans
}
from
'
@lingui/macro
'
import
{
t
,
Trans
}
from
'
@lingui/macro
'
import
{
Currency
}
from
'
@uniswap/sdk-core
'
import
{
Currency
}
from
'
@uniswap/sdk-core
'
import
{
useQueryTokenList
}
from
'
lib/hooks/useTokenList
'
import
useActiveWeb3React
from
'
lib/hooks/useActiveWeb3React
'
import
{
useCurrencyBalances
}
from
'
lib/hooks/useCurrencyBalance
'
import
useNativeCurrency
from
'
lib/hooks/useNativeCurrency
'
import
useTokenList
,
{
useIsTokenListLoaded
,
useQueryCurrencies
}
from
'
lib/hooks/useTokenList
'
import
styled
,
{
ThemedText
}
from
'
lib/theme
'
import
styled
,
{
ThemedText
}
from
'
lib/theme
'
import
{
ElementRef
,
useCallback
,
useEffect
,
useMemo
,
useRef
,
useState
}
from
'
react
'
import
{
ElementRef
,
useCallback
,
useEffect
,
useMemo
,
useRef
,
useState
}
from
'
react
'
import
{
currencyId
}
from
'
utils/currencyId
'
import
{
currencyId
}
from
'
utils/currencyId
'
...
@@ -13,11 +16,29 @@ import Rule from '../Rule'
...
@@ -13,11 +16,29 @@ import Rule from '../Rule'
import
TokenBase
from
'
./TokenBase
'
import
TokenBase
from
'
./TokenBase
'
import
TokenButton
from
'
./TokenButton
'
import
TokenButton
from
'
./TokenButton
'
import
TokenOptions
from
'
./TokenOptions
'
import
TokenOptions
from
'
./TokenOptions
'
import
TokenOptionsSkeleton
from
'
./TokenOptionsSkeleton
'
const
SearchInput
=
styled
(
StringInput
)
`
const
SearchInput
=
styled
(
StringInput
)
`
${
inputCss
}
${
inputCss
}
`
`
function
usePrefetchBalances
()
{
const
{
account
}
=
useActiveWeb3React
()
const
tokenList
=
useTokenList
()
const
[
prefetchedTokenList
,
setPrefetchedTokenList
]
=
useState
(
tokenList
)
useEffect
(()
=>
setPrefetchedTokenList
(
tokenList
),
[
tokenList
])
useCurrencyBalances
(
account
,
tokenList
!==
prefetchedTokenList
?
tokenList
:
undefined
)
}
function
useAreBalancesLoaded
():
boolean
{
const
{
account
}
=
useActiveWeb3React
()
const
tokens
=
useTokenList
()
const
native
=
useNativeCurrency
()
const
currencies
=
useMemo
(()
=>
[
native
,
...
tokens
],
[
native
,
tokens
])
const
balances
=
useCurrencyBalances
(
account
,
currencies
).
filter
(
Boolean
)
return
!
account
||
currencies
.
length
===
balances
.
length
}
interface
TokenSelectDialogProps
{
interface
TokenSelectDialogProps
{
value
?:
Currency
value
?:
Currency
onSelect
:
(
token
:
Currency
)
=>
void
onSelect
:
(
token
:
Currency
)
=>
void
...
@@ -25,8 +46,24 @@ interface TokenSelectDialogProps {
...
@@ -25,8 +46,24 @@ interface TokenSelectDialogProps {
export
function
TokenSelectDialog
({
value
,
onSelect
}:
TokenSelectDialogProps
)
{
export
function
TokenSelectDialog
({
value
,
onSelect
}:
TokenSelectDialogProps
)
{
const
[
query
,
setQuery
]
=
useState
(
''
)
const
[
query
,
setQuery
]
=
useState
(
''
)
const
queriedTokens
=
useQueryTokenList
(
query
)
const
queriedTokens
=
useQueryCurrencies
(
query
)
const
tokens
=
useMemo
(()
=>
queriedTokens
.
filter
((
token
)
=>
token
!==
value
),
[
queriedTokens
,
value
])
const
tokens
=
useMemo
(()
=>
queriedTokens
?.
filter
((
token
)
=>
token
!==
value
),
[
queriedTokens
,
value
])
const
isTokenListLoaded
=
useIsTokenListLoaded
()
const
areBalancesLoaded
=
useAreBalancesLoaded
()
const
[
isLoaded
,
setIsLoaded
]
=
useState
(
isTokenListLoaded
&&
areBalancesLoaded
)
// Give the balance-less tokens a small block period to avoid layout thrashing from re-sorting.
useEffect
(()
=>
{
if
(
!
isLoaded
)
{
const
timeout
=
setTimeout
(()
=>
setIsLoaded
(
true
),
1500
)
return
()
=>
clearTimeout
(
timeout
)
}
return
},
[
isLoaded
])
useEffect
(
()
=>
setIsLoaded
(
Boolean
(
query
)
||
(
isTokenListLoaded
&&
areBalancesLoaded
)),
[
query
,
areBalancesLoaded
,
isTokenListLoaded
]
)
const
baseTokens
:
Currency
[]
=
[]
// TODO(zzmp): Add base tokens to token list functionality
const
baseTokens
:
Currency
[]
=
[]
// TODO(zzmp): Add base tokens to token list functionality
...
@@ -60,7 +97,7 @@ export function TokenSelectDialog({ value, onSelect }: TokenSelectDialogProps) {
...
@@ -60,7 +97,7 @@ export function TokenSelectDialog({ value, onSelect }: TokenSelectDialogProps) {
)
}
)
}
<
Rule
padded
/>
<
Rule
padded
/>
</
Column
>
</
Column
>
<
TokenOptions
tokens=
{
tokens
}
onSelect=
{
onSelect
}
ref=
{
setOptions
}
/>
{
isLoaded
?
<
TokenOptions
tokens=
{
tokens
}
onSelect=
{
onSelect
}
ref=
{
setOptions
}
/>
:
<
TokenOptionsSkeleton
/>
}
</>
</>
)
)
}
}
...
@@ -73,6 +110,8 @@ interface TokenSelectProps {
...
@@ -73,6 +110,8 @@ interface TokenSelectProps {
}
}
export
default
function
TokenSelect
({
value
,
collapsed
,
disabled
,
onSelect
}:
TokenSelectProps
)
{
export
default
function
TokenSelect
({
value
,
collapsed
,
disabled
,
onSelect
}:
TokenSelectProps
)
{
usePrefetchBalances
()
const
[
open
,
setOpen
]
=
useState
(
false
)
const
[
open
,
setOpen
]
=
useState
(
false
)
const
selectAndClose
=
useCallback
(
const
selectAndClose
=
useCallback
(
(
value
:
Currency
)
=>
{
(
value
:
Currency
)
=>
{
...
...
src/lib/hooks/useTokenList/index.ts
View file @
a60ea703
import
{
Token
}
from
'
@uniswap/sdk-core
'
import
{
NativeCurrency
,
Token
}
from
'
@uniswap/sdk-core
'
import
{
TokenInfo
,
TokenList
}
from
'
@uniswap/token-lists
'
import
{
TokenInfo
,
TokenList
}
from
'
@uniswap/token-lists
'
import
{
atom
,
useAtom
}
from
'
jotai
'
import
{
atom
}
from
'
jotai
'
import
{
useAtomValue
}
from
'
jotai/utils
'
import
{
useAtomValue
,
useUpdateAtom
}
from
'
jotai/utils
'
import
useActiveWeb3React
from
'
lib/hooks/useActiveWeb3React
'
import
useActiveWeb3React
from
'
lib/hooks/useActiveWeb3React
'
import
resolveENSContentHash
from
'
lib/utils/resolveENSContentHash
'
import
resolveENSContentHash
from
'
lib/utils/resolveENSContentHash
'
import
{
useEffect
,
useMemo
,
useState
}
from
'
react
'
import
{
use
Callback
,
use
Effect
,
useMemo
,
useState
}
from
'
react
'
import
{
WrappedTokenInfo
}
from
'
state/lists/wrappedTokenInfo
'
import
{
WrappedTokenInfo
}
from
'
state/lists/wrappedTokenInfo
'
import
fetchTokenList
from
'
./fetchTokenList
'
import
fetchTokenList
from
'
./fetchTokenList
'
...
@@ -12,38 +12,70 @@ import { useQueryTokens } from './querying'
...
@@ -12,38 +12,70 @@ import { useQueryTokens } from './querying'
import
{
ChainTokenMap
,
tokensToChainTokenMap
}
from
'
./utils
'
import
{
ChainTokenMap
,
tokensToChainTokenMap
}
from
'
./utils
'
import
{
validateTokens
}
from
'
./validateTokenList
'
import
{
validateTokens
}
from
'
./validateTokenList
'
export
{
DEFAULT_TOKEN_LIST
}
from
'
./fetchTokenList
'
export
const
DEFAULT_TOKEN_LIST
=
'
https://gateway.ipfs.io/ipns/tokens.uniswap.org
'
const
chainTokenMapAtom
=
atom
<
ChainTokenMap
>
({}
)
const
chainTokenMapAtom
=
atom
<
ChainTokenMap
|
undefined
>
(
undefined
)
export
default
function
useTokenList
(
list
?:
string
|
TokenInfo
[]):
WrappedTokenInfo
[]
{
export
function
useIsTokenListLoaded
()
{
return
Boolean
(
useAtomValue
(
chainTokenMapAtom
))
}
export
function
useSyncTokenList
(
list
:
string
|
TokenInfo
[]
=
DEFAULT_TOKEN_LIST
):
void
{
const
{
chainId
,
library
}
=
useActiveWeb3React
()
const
{
chainId
,
library
}
=
useActiveWeb3React
()
const
[
chainTokenMap
,
setChainTokenMap
]
=
us
eAtom
(
chainTokenMapAtom
)
const
setChainTokenMap
=
useUpdat
eAtom
(
chainTokenMapAtom
)
// Error boundaries will not catch (non-rendering) async errors, but it should still be shown
// Error boundaries will not catch (non-rendering) async errors, but it should still be shown
const
[
error
,
setError
]
=
useState
<
Error
>
()
const
[
error
,
setError
]
=
useState
<
Error
>
()
if
(
error
)
throw
error
if
(
error
)
throw
error
useEffect
(()
=>
{
const
resolver
=
useCallback
(
if
(
list
!==
undefined
)
{
(
ensName
:
string
)
=>
{
let
tokens
:
Promise
<
TokenList
|
TokenInfo
[]
>
if
(
typeof
list
===
'
string
'
)
{
tokens
=
fetchTokenList
(
list
,
(
ensName
:
string
)
=>
{
if
(
library
&&
chainId
===
1
)
{
if
(
library
&&
chainId
===
1
)
{
// TODO(zzmp): Use network resolver when wallet is not on chainId === 1.
return
resolveENSContentHash
(
ensName
,
library
)
return
resolveENSContentHash
(
ensName
,
library
)
}
}
throw
new
Error
(
'
Could not construct mainnet ENS resolver
'
)
throw
new
Error
(
'
Could not construct mainnet ENS resolver
'
)
})
},
[
chainId
,
library
]
)
useEffect
(()
=>
{
let
stale
=
false
activateList
(
list
)
return
()
=>
{
stale
=
true
}
async
function
activateList
(
list
:
string
|
TokenInfo
[])
{
try
{
let
tokens
:
TokenList
|
TokenInfo
[]
if
(
typeof
list
===
'
string
'
)
{
tokens
=
await
fetchTokenList
(
list
,
resolver
)
}
else
{
}
else
{
tokens
=
validateTokens
(
list
)
tokens
=
await
validateTokens
(
list
)
}
const
tokenMap
=
tokensToChainTokenMap
(
tokens
)
// also caches the fetched tokens, so it is invoked even if stale
if
(
!
stale
)
{
setChainTokenMap
(
tokenMap
)
setError
(
undefined
)
}
}
catch
(
e
:
unknown
)
{
if
(
!
stale
)
{
setChainTokenMap
(
undefined
)
setError
(
e
as
Error
)
}
}
}
tokens
.
then
(
tokensToChainTokenMap
).
then
(
setChainTokenMap
).
catch
(
setError
)
}
}
},
[
chainId
,
library
,
list
,
setChainTokenMap
])
},
[
list
,
resolver
,
setChainTokenMap
])
}
export
default
function
useTokenList
():
WrappedTokenInfo
[]
{
const
{
chainId
}
=
useActiveWeb3React
()
const
chainTokenMap
=
useAtomValue
(
chainTokenMapAtom
)
const
tokenMap
=
chainId
&&
chainTokenMap
?.[
chainId
]
return
useMemo
(()
=>
{
return
useMemo
(()
=>
{
return
Object
.
values
((
chainId
&&
chainTokenMap
[
chainId
])
||
{}).
map
(({
token
})
=>
token
)
if
(
!
tokenMap
)
return
[]
},
[
chainId
,
chainTokenMap
])
return
Object
.
values
(
tokenMap
).
map
(({
token
})
=>
token
)
},
[
tokenMap
])
}
}
export
type
TokenMap
=
{
[
address
:
string
]:
Token
}
export
type
TokenMap
=
{
[
address
:
string
]:
Token
}
...
@@ -51,14 +83,16 @@ export type TokenMap = { [address: string]: Token }
...
@@ -51,14 +83,16 @@ export type TokenMap = { [address: string]: Token }
export
function
useTokenMap
():
TokenMap
{
export
function
useTokenMap
():
TokenMap
{
const
{
chainId
}
=
useActiveWeb3React
()
const
{
chainId
}
=
useActiveWeb3React
()
const
chainTokenMap
=
useAtomValue
(
chainTokenMapAtom
)
const
chainTokenMap
=
useAtomValue
(
chainTokenMapAtom
)
const
tokenMap
=
chainId
&&
chainTokenMap
?.[
chainId
]
return
useMemo
(()
=>
{
return
useMemo
(()
=>
{
return
Object
.
entries
((
chainId
&&
chainTokenMap
[
chainId
])
||
{}).
reduce
((
map
,
[
address
,
{
token
}])
=>
{
if
(
!
tokenMap
)
return
{}
return
Object
.
entries
(
tokenMap
).
reduce
((
map
,
[
address
,
{
token
}])
=>
{
map
[
address
]
=
token
map
[
address
]
=
token
return
map
return
map
},
{}
as
TokenMap
)
},
{}
as
TokenMap
)
},
[
chainId
,
chainT
okenMap
])
},
[
t
okenMap
])
}
}
export
function
useQuery
TokenList
(
query
:
string
)
{
export
function
useQuery
Currencies
(
query
=
''
):
(
WrappedTokenInfo
|
NativeCurrency
)[]
{
return
useQueryTokens
(
query
,
useTokenList
())
return
useQueryTokens
(
query
,
useTokenList
())
}
}
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