forked from moonshotcollective/tokenstream.party
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
User can add custom ERC20 token for the stream.
closes issue moonshotcollective#22
- Loading branch information
1 parent
0dc9dbd
commit 3bf29ba
Showing
4 changed files
with
195 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
import { Select } from "antd"; | ||
import { useState, useMemo, useEffect } from "react"; | ||
import { ethers } from "ethers"; | ||
import axios from "axios"; | ||
import searchico from "searchico"; | ||
|
||
// helpers to load token name and symbol for unlisted tokens | ||
const ERC20ABI = ["function symbol() view returns (string)", "function name() view returns (string)"]; | ||
|
||
const loadERC20 = async (address, p) => { | ||
try { | ||
// load token information here | ||
const r = new ethers.Contract(address, ERC20ABI, p); | ||
const name = await r.name?.(); | ||
const symbol = await r.symbol?.(); | ||
|
||
return { name, symbol }; | ||
} catch (error) { | ||
return {}; | ||
} | ||
}; | ||
|
||
/* | ||
<TokenSelect | ||
chainId={1} | ||
onChange={setToAddress} | ||
localProvider={localProvider} | ||
nativeToken={{ name: 'Native token', symbol: 'ETH' }} | ||
/> | ||
*/ | ||
export default function TokenSelect({ onChange, chainId = 1, nativeToken = {}, localProvider, ...props }) { | ||
const [value, setValue] = useState(null); | ||
const [list, setList] = useState([]); | ||
const [searchResults, setSearchResults] = useState([]); | ||
|
||
const listCollection = useMemo(() => { | ||
return searchico(list, { keys: ["address", "name", "symbol"] }); | ||
}, [list.length]); | ||
|
||
const children = useMemo(() => { | ||
if (searchResults.length < 1) { | ||
return []; | ||
} | ||
|
||
// use search result to format children | ||
return searchResults.map(i => ( | ||
<Select.Option key={i.address} style={{ paddingTop: "5px", paddingBottom: "5px" }} value={i.address}> | ||
<div style={{ display: "flex", alignItems: "center" }}> | ||
{i.logoURI && ( | ||
<div style={{ marginRight: "5px" }}> | ||
<img src={i.logoURI} alt={`${i.name} (${i.symbol})`} /> | ||
</div> | ||
)} | ||
{i.name} - {i.symbol} {i.address?.substr(0, 5) + "..." + i.address?.substr(-4)}{" "} | ||
{i.unlisted && <span style={{ fontStyle: "italic", fontSize: "12px", marginLeft: "3px" }}> (unlisted) </span>} | ||
</div> | ||
</Select.Option> | ||
)); | ||
}, [JSON.stringify(searchResults)]); | ||
|
||
const handleSearch = async val => { | ||
let collectionResult = []; | ||
|
||
if (val.length > 0) { | ||
// TODO : Do all search & filtering here | ||
collectionResult = (listCollection?.find(val) || []).filter(i => i.chainId === chainId); | ||
|
||
if (collectionResult.length < 1) { | ||
const nativeTokenObj = { | ||
chainId: chainId, | ||
decimals: 18, | ||
name: "Default Token", | ||
symbol: "GTC", | ||
address: "0xde30da39c46104798bb5aa3fe8b9e0e1f348163f", | ||
logoURI: "https://assets.coingecko.com/coins/images/15810/thumb/gitcoin.png?1621992929", | ||
...nativeToken, | ||
}; | ||
|
||
collectionResult.push(nativeTokenObj); | ||
|
||
try { | ||
const checksumAddress = ethers.utils.getAddress(val); | ||
// load contract and try to get name and symbol if there's a provider given | ||
const tokenInfo = localProvider ? await loadERC20(checksumAddress, localProvider) : {}; | ||
collectionResult = [ | ||
{ | ||
chainId: chainId, | ||
name: null, | ||
unlisted: true, | ||
symbol: null, | ||
address: checksumAddress, | ||
logoURI: "", | ||
...tokenInfo, | ||
}, | ||
]; | ||
} catch (error) { | ||
console.log(`Could not identify this token`); | ||
} | ||
} | ||
} | ||
|
||
setSearchResults(collectionResult); | ||
}; | ||
|
||
const handleOnChange = async e => { | ||
setSearchResults([]); | ||
|
||
// TODO : check if it's an address that's not on list & Add as unlisted | ||
|
||
setValue(e); | ||
|
||
if (typeof onChange === "function") { | ||
onChange(e.value); | ||
} | ||
}; | ||
|
||
const loadList = async () => { | ||
// https://tokens.coingecko.com/uniswap/all.json | ||
const res = await axios.get("https://tokens.coingecko.com/uniswap/all.json"); | ||
const { tokens } = res.data; | ||
|
||
setList(tokens); | ||
}; | ||
|
||
useEffect(() => { | ||
loadList(); | ||
}, []); | ||
|
||
return ( | ||
<div> | ||
<Select | ||
showSearch | ||
size="large" | ||
showArrow={false} | ||
defaultActiveFirstOption={false} | ||
onSearch={handleSearch} | ||
filterOption={false} | ||
labelInValue={true} | ||
id="0xERC20TokenSelect" // name it something other than address for auto fill doxxing | ||
name="0xERC20TokenSelect" // name it something other than address for auto fill doxxing | ||
placeholder={props.placeholder ? props.placeholder : "Token search... Eg: GTC"} | ||
value={value} | ||
onChange={handleOnChange} | ||
notFoundContent={null} | ||
style={{ width: "100%" }} | ||
> | ||
{children} | ||
</Select> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters