diff --git a/README.md b/README.md index 8f1c5c58..36e82d2a 100644 --- a/README.md +++ b/README.md @@ -25,33 +25,33 @@ yarn build # build token lists -| Chain | Chain Id | Link | Viewer | -| --------------- | ----------: | ------------------------------ | ------------------------------------ | -| Mainnet | 1 | [latest][link-mainnet] | [token-list][viewer-mainnet] | -| Ropsten | 3 | [latest][link-ropsten] | [token-list][viewer-ropsten] | -| Rinkeby | 4 | [latest][link-rinkeby] | [token-list][viewer-rinkeby] | -| Optimistic | 10 | [latest][link-optimistic] | [token-list][viewer-optimistic] | -| Kardiachain | 24 | [latest][link-kardiachain] | [token-list][viewer-kardiachain] | -| BNB | 56 | [latest][link-bnb] | [token-list][viewer-bnb] | -| Chapel | 97 | [latest][link-chapel] | [token-list][viewer-chapel] | -| xDai | 100 | [latest][link-xdai] | [token-list][viewer-xdai] | -| Sokol | 77 | [latest][link-sokol] | [token-list][viewer-sokol] | -| Fuse | 122 | [latest][link-fuse] | [token-list][viewer-fuse] | -| Heco | 128 | [latest][link-heco] | [token-list][viewer-heco] | -| Fantom | 250 | [latest][link-fantom] | [token-list][viewer-fantom] | -| Boba | 288 | [latest][link-boba] | [token-list][viewer-boba] | -| Polygon | 137 | [latest][link-polygon] | [token-list][viewer-polygon] | -| Mumbai | 80001 | [latest][link-mumbai] | [token-list][viewer-mumbai] | -| Conflux | 1030 | [latest][link-conflux] | [token-list][viewer-conflux] | -| Moonbeam | 1284 | [latest][link-moonbeam] | [token-list][viewer-moonbeam] | -| Moonriver | 1285 | [latest][link-moonriver] | [token-list][viewer-moonriver] | -| Arbiturm | 42161 | [latest][link-arbiturm] | [token-list][viewer-arbiturm] | -| Celo | 42220 | [latest][link-celo] | [token-list][viewer-celo] | -| Avalanche | 43114 | [latest][link-avalanche] | [token-list][viewer-avalanche] | -| Aurora | 1313161554 | [latest][link-aurora] | [token-list][viewer-aurora] | -| Harmony | 1666600000 | [latest][link-harmony] | [token-list][viewer-harmony] | -| Harmony_Testnet | 1666700000 | [latest][link-harmony_testnet] | [token-list][viewer-harmony_testnet] | -| Palm | 11297108109 | [latest][link-palm] | [token-list][viewer-palm] | +| Chain | Chain Id | Link | Viewer | +| --------------- | ---------: | ------------------------------ | ------------------------------------ | +| Mainnet | 1 | [latest][link-mainnet] | [token-list][viewer-mainnet] | +| Ropsten | 3 | [latest][link-ropsten] | [token-list][viewer-ropsten] | +| Rinkeby | 4 | [latest][link-rinkeby] | [token-list][viewer-rinkeby] | +| Optimistic | 10 | [latest][link-optimistic] | [token-list][viewer-optimistic] | +| Kardiachain | 24 | [latest][link-kardiachain] | [token-list][viewer-kardiachain] | +| BNB | 56 | [latest][link-bnb] | [token-list][viewer-bnb] | +| Chapel | 97 | [latest][link-chapel] | [token-list][viewer-chapel] | +| xDai | 100 | [latest][link-xdai] | [token-list][viewer-xdai] | +| Sokol | 77 | [latest][link-sokol] | [token-list][viewer-sokol] | +| Fuse | 122 | [latest][link-fuse] | [token-list][viewer-fuse] | +| Heco | 128 | [latest][link-heco] | [token-list][viewer-heco] | +| Fantom | 250 | [latest][link-fantom] | [token-list][viewer-fantom] | +| Boba | 288 | [latest][link-boba] | [token-list][viewer-boba] | +| Polygon | 137 | [latest][link-polygon] | [token-list][viewer-polygon] | +| Mumbai | 80001 | [latest][link-mumbai] | [token-list][viewer-mumbai] | +| Conflux | 1030 | [latest][link-conflux] | [token-list][viewer-conflux] | +| Moonbeam | 1284 | [latest][link-moonbeam] | [token-list][viewer-moonbeam] | +| Arbiturm | 42161 | [latest][link-arbiturm] | [token-list][viewer-arbiturm] | +| Celo | 42220 | [latest][link-celo] | [token-list][viewer-celo] | +| Avalanche | 43114 | [latest][link-avalanche] | [token-list][viewer-avalanche] | +| Aurora | 1313161554 | [latest][link-aurora] | [token-list][viewer-aurora] | +| Harmony | 1666600000 | [latest][link-harmony] | [token-list][viewer-harmony] | +| Harmony_Testnet | 1666700000 | [latest][link-harmony_testnet] | [token-list][viewer-harmony_testnet] | +| Metis | 1088 | [latest][link-metis] | [token-list][viewer-metis] | +| Stardust | 588 | [latest][link-stardust] | [token-list][viewer-stardust] | [link-mainnet]: https://tokens.r2d2.to/latest/1/tokens.json [link-ropsten]: https://tokens.r2d2.to/latest/3/tokens.json @@ -78,8 +78,8 @@ yarn build # build token lists [link-cronos]: https://tokens.r2d2.to/latest/25/tokens.json [link-harmony]: https://tokens.r2d2.to/latest/1666600000/tokens.json [link-harmony_testnet]: https://tokens.r2d2.to/latest/1666700000/tokens.json -[link-palm]: https://tokens.r2d2.to/latest/11297108109/tokens.json -[link-astar]: https://tokens.r2d2.to/latest/592/tokens.json +[link-metis]: https://tokens.r2d2.to/latest/1088/tokens.json +[link-stardust]: https://tokens.r2d2.to/latest/588/tokens.json [viewer-mainnet]: https://tokenlists.org/token-list?url=https://tokens.r2d2.to/latest/1/tokens.json [viewer-ropsten]: https://tokenlists.org/token-list?url=https://tokens.r2d2.to/latest/3/tokens.json [viewer-rinkeby]: https://tokenlists.org/token-list?url=https://tokens.r2d2.to/latest/4/tokens.json @@ -105,7 +105,7 @@ yarn build # build token lists [viewer-cronos]: https://tokenlists.org/token-list?url=https://tokens.r2d2.to/latest/25/tokens.json [viewer-harmony]: https://tokenlists.org/token-list?url=https://tokens.r2d2.to/latest/1666600000/tokens.json [viewer-harmony_testnet]: https://tokenlists.org/token-list?url=https://tokens.r2d2.to/latest/1666700000/tokens.json -[viewer-palm]: https://tokenlists.org/token-list?url=https://tokens.r2d2.to/latest/11297108109/tokens.json -[viewer-astar]: https://tokenlists.org/token-list?url=https://tokens.r2d2.to/latest/592/tokens.json +[viewer-metis]: https://tokenlists.org/token-list?url=https://tokens.r2d2.to/latest/1088/tokens.json +[viewer-stardust]: https://tokenlists.org/token-list?url=https://tokens.r2d2.to/latest/588/tokens.json diff --git a/package.json b/package.json index 2c14a260..dcfdca7f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mask-token-lists", - "version": "0.0.38", + "version": "0.0.39", "repository": "https://github.com/DimensionDev/Mask-Token-Lists.git", "license": "MIT", "author": "guanbinrui ", diff --git a/scripts/build.sh b/scripts/build.sh new file mode 100755 index 00000000..9106f4b5 --- /dev/null +++ b/scripts/build.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +# read versionn +VERSION=$(node -p -e "require('./package.json').version") + +CHAIN[0]=dist/v$VERSION + + +for i in {1,3,4,10,56,97,100,122,128,137,250,288,588,1030,1088,42161,42220,43114,80001,1313161554}; do + CHAIN[$i]=dist/v$VERSION/$i +done + +mkdir -p dist +mkdir -p latest + +# build the latest version +for i in "${!CHAIN[@]}"; do + printf "Generate for chain id %s to folder: %s\n" "$i" "${CHAIN[$i]}" + mkdir -p "${CHAIN[$i]}" + touch "${CHAIN[$i]}/tokens.json" + node scripts/generate-erc20.js $i > "${CHAIN[$i]}/tokens.json" + + if [ $? -ne 0 ]; then + exit 1; + fi + + node scripts/risk-check.js $i > "${CHAIN[$i]}/riskInfo.json" +done + +node scripts/generate-erc721.js > "dist/mask_nft.json" + +# build the current version +#cp dist/v${VERSION}/tokens.json "dist/mask.json" +cp -r dist/v"${VERSION}/" "dist/latest" +cp dist/mask_nft.json "dist/mask_nft_v_$(echo $VERSION | sed "s/\./_/g").json" + +echo "v${VERSION} is built." diff --git a/scripts/generate-erc20.js b/scripts/generate-erc20.js new file mode 100644 index 00000000..21f47fad --- /dev/null +++ b/scripts/generate-erc20.js @@ -0,0 +1,168 @@ +const Ajv = require("ajv"); +const { EthereumAddress } = require("wallet.ts"); +const { schema } = require("@uniswap/token-lists"); +const metadata = require("../src/erc20/contract-metadata.json"); +const Mainnet = require("../src/erc20/mainnet.json"); +const Ropsten = require("../src/erc20/ropsten.json"); +const Rinkeby = require("../src/erc20/rinkeby.json"); +const Optimistic = require("../src/erc20/optimistic.json"); +const Fuse = require("../src/erc20/fuse.json"); +const Bsc = require("../src/erc20/bsc.json"); +const Chapel = require("../src/erc20/chapel.json"); +const xDai = require("../src/erc20/xdai.json"); +const Fantom = require("../src/erc20/fantom.json"); +const Celo = require("../src/erc20/celo.json"); +const Matic = require("../src/erc20/matic.json"); +const Arbiturm = require("../src/erc20/arbiturm.json"); +const Mumbai = require("../src/erc20/mumbai.json"); +const Aurora = require("../src/erc20/aurora.json"); +const Avalanche = require("../src/erc20/avalanche.json"); +const Boba = require("../src/erc20/boba.json"); +const Heco = require("../src/erc20/heco.json"); +const Pancake = require("../src/erc20/pancake.json"); +const Metis = require("../src/erc20/metis.json"); +const Stardust = require("../src/erc20/stardust.json"); +const QucikSwapTokens = require("../src/erc20/quickswap.json"); +const ConfluxTokens = require("../src/erc20/conflux.json"); +const { fetchDebankLogoURI } = require("./fetch-debank-logo-uri"); +const { addChainId, generateTokenList } = require("./shared"); + +const getMetaMaskLogoURL = (url) => + `https://raw.githubusercontent.com/MetaMask/contract-metadata/master/images/${url}`; + +const chainId = Number.parseInt(process.argv.slice(2)[0]); + +const MetaMask = Object.keys(metadata) + .filter((key) => { + const record = metadata[key]; + return ( + typeof record.symbol === "string" && + typeof record.decimals === "number" && + typeof record.name === "string" && + new RegExp("^[ \\w.'+\\-%/À-ÖØ-öø-ÿ]+$").test(record.name) && + EthereumAddress.isValid(key) + ); + }) + .map((key) => ({ + chainId: 1, + address: key, + symbol: metadata[key].symbol, + decimals: metadata[key].decimals, + name: metadata[key].name, + logo: metadata[key].logo, + })); + +const QuickSwap = QucikSwapTokens.tokens.map( + ({ name, address, symbol, decimals, logoURI }) => ({ + name, + address, + symbol, + decimals, + logoURI, + }) +); + +const chainIdToTokensMapping = { + 1: [MetaMask, Mainnet], + 3: [Ropsten], + 4: [Rinkeby], + 10: [Optimistic], + 56: [Bsc, Pancake], + 97: [Chapel], + 100: [xDai], + 122: [Fuse], + 128: [Heco], + 250: [Fantom], + 288: [Boba], + 137: [Matic, QuickSwap], + 588: [Stardust], + 1030: [ConfluxTokens], + 1088: [Metis], + 42161: [Arbiturm], + 42220: [Celo], + 43114: [Avalanche], + 80001: [Mumbai], + 1313161554: [Aurora], +}; + +const getUntreatedTokens = async () => { + const baseTokens = + chainId === 0 + ? Object.entries(chainIdToTokensMapping) + .map(([key, value]) => { + return value.map((x) => addChainId(x, Number.parseInt(key))); + }) + .flat() + .flat() + : chainIdToTokensMapping[chainId] + .map((x) => addChainId(x, chainId)) + .flat(); + + const debankTokens = await fetchDebankLogoURI( + chainId, + baseTokens.map((x) => x.address) + ); + + return baseTokens.map((token) => { + const { logo, ...rest } = token; + const tokenWithLogoURI = debankTokens.find( + (x) => x.address.toLowerCase() === token.address.toLowerCase() + ); + const logoURI = + tokenWithLogoURI?.logoURI || + (logo && getMetaMaskLogoURL(logo)) || + token.logoURI; + + return logoURI ? { ...rest, logoURI } : { ...rest }; + }); +}; + +const start = async () => { + const tokens = await getUntreatedTokens(); + const MaskTokenList = generateTokenList( + tokens + .map((x) => ({ + ...x, + address: EthereumAddress.checksumAddress(x.address), + })) + .sort((a, z) => { + if (a.name > z.name) return 1; + if (a.name < z.name) return -1; + return 0; + }), + { + name: "Mask Network", + logoURI: + "https://raw.githubusercontent.com/DimensionDev/Maskbook-Website/master/img/MB--CircleCanvas--WhiteOverBlue.svg", + keywords: [ + "browser extension", + "web3", + "peer to peer", + "encryption", + "cryptography", + "gundb", + "privacy protection", + "ownyourdata", + "social network", + "blockchain", + "crypto", + "dweb", + ], + timestamp: new Date().toISOString(), + } + ); + + const ajv = new Ajv(); + schema.definitions.TokenInfo.properties.symbol.pattern = + "^[a-zA-Z0-9+\\-%/\\$\\.]+$"; + const validate = ajv.compile(schema); + if (validate(MaskTokenList)) { + process.stdout.write(JSON.stringify(MaskTokenList)); + } else { + console.error("Failed to build ERC20 token list."); + console.error(validate.errors); + process.exit(1); + } +}; + +start(); diff --git a/src/fungible-tokens/metis.json b/src/fungible-tokens/metis.json new file mode 100644 index 00000000..39a4054a --- /dev/null +++ b/src/fungible-tokens/metis.json @@ -0,0 +1,66 @@ +[ + { + "chainId": 1088, + "address": "0xea32a96608495e54156ae48931a7c20f0dcc1a21", + "decimals": 6, + "name": "USDC Token", + "symbol": "m.USDC", + "logoURI": "https://raw.githubusercontent.com/MetisProtocol/metis-bridge-resources/master/tokens/USDC/logo.png" + }, + { + "chainId": 1088, + "address": "0xbb06dca3ae6887fabf931640f67cab3e3a16f4dc", + "decimals": 6, + "name": "USDT Token", + "symbol": "m.USDT", + "logoURI": "https://raw.githubusercontent.com/MetisProtocol/metis-bridge-resources/master/tokens/USDT/logo.png" + }, + { + "chainId": 1088, + "address": "0x5ce34d9abe4bf239cbc08b89287c87f4cd6d80b7", + "decimals": 18, + "name": "WOW Token", + "symbol": "m.WOW", + "logoURI": "https://raw.githubusercontent.com/MetisProtocol/metis-bridge-resources/master/tokens/WOW/logo.png" + }, + { + "chainId": 1088, + "address": "0xf5f66d5daa89c090a7afa10e6c1553b2887a9a33", + "decimals": 18, + "name": "LINK Token", + "symbol": "m.LINK", + "logoURI": "https://raw.githubusercontent.com/MetisProtocol/metis-bridge-resources/master/tokens/LINK/logo.png" + }, + { + "chainId": 1088, + "address": "0x420000000000000000000000000000000000000a", + "decimals": 18, + "name": "Ether", + "symbol": "WETH", + "logoURI": "https://raw.githubusercontent.com/MetisProtocol/metis-bridge-resources/master/tokens/ETH/logo.png" + }, + { + "chainId": 1088, + "address": "0x68D97B7A961a5239B9F911DA8dEb57F6eF6e5e28", + "decimals": 18, + "name": "AAVE Token", + "symbol": "AAVE", + "logoURI": "https://raw.githubusercontent.com/MetisProtocol/metis-bridge-resources/master/tokens/AAVE/logo.png" + }, + { + "chainId": 1088, + "address": "0x87DD4a7Ad23B95cD9fF9C26B5cF325905CaF8663", + "decimals": 18, + "name": "Curve DAO Token", + "symbol": "CRV", + "logoURI": "https://raw.githubusercontent.com/MetisProtocol/metis-bridge-resources/master/tokens/CRV/logo.png" + }, + { + "chainId": 1088, + "address": "0x90fE084F877C65e1b577c7b2eA64B8D8dd1AB278", + "decimals": 18, + "name": "Netswap Token", + "symbol": "NETT", + "logoURI": "https://raw.githubusercontent.com/Netswap/tokens/master/assets/0x90fe084f877c65e1b577c7b2ea64b8d8dd1ab278/logo.png" + } +] diff --git a/src/fungible-tokens/stardust.json b/src/fungible-tokens/stardust.json new file mode 100644 index 00000000..1aa6b455 --- /dev/null +++ b/src/fungible-tokens/stardust.json @@ -0,0 +1,42 @@ +[ + { + "chainId": 588, + "address": "0xF02Efd44B57d143c38A329dD299683bf24Cf8aE0", + "decimals": 6, + "name": "Test USDT", + "symbol": "TUSDT", + "logoURI": "https://raw.githubusercontent.com/MetisProtocol/metis-bridge-resources/master/tokens/USDT/logo.png" + }, + { + "chainId": 588, + "address": "0x48c754c7A6ED973FB10d04aDbb15C91BC704F72A", + "decimals": 6, + "name": "Test USDC", + "symbol": "TUSDC", + "logoURI": "https://raw.githubusercontent.com/MetisProtocol/metis-bridge-resources/master/tokens/USDC/logo.png" + }, + { + "chainId": 588, + "address": "0x5ee1167Cc431ce2A99710f7173e28Da2D90593c9", + "decimals": 8, + "name": "Test WBTC", + "symbol": "TWBTC", + "logoURI": "https://raw.githubusercontent.com/MetisProtocol/metis-bridge-resources/master/tokens/WBTC/logo.png" + }, + { + "chainId": 588, + "address": "0x3Aa437CB25bf718a8952603B24c2ACe332185d95", + "decimals": 18, + "name": "Test LINK", + "symbol": "TLINK", + "logoURI": "https://raw.githubusercontent.com/MetisProtocol/metis-bridge-resources/master/tokens/LINK/logo.png" + }, + { + "chainId": 588, + "address": "0xd9c952C7900B92b2b4E1De4b77348D71f3A2FD29", + "decimals": 18, + "name": "Test UNI", + "symbol": "TUNI", + "logoURI": "https://raw.githubusercontent.com/MetisProtocol/metis-bridge-resources/master/tokens/UNI/logo.png" + } +] diff --git a/src/generate-fungible-tokens.ts b/src/generate-fungible-tokens.ts index 49deae7f..f7e4c625 100644 --- a/src/generate-fungible-tokens.ts +++ b/src/generate-fungible-tokens.ts @@ -23,6 +23,8 @@ import Moonbeam from "./fungible-tokens/moonbeam.json"; import Pancake from "./fungible-tokens/pancake.json"; import QucikSwapTokens from "./fungible-tokens/quickswap.json"; import Conflux from "./fungible-tokens/conflux.json"; +import Metis from "./fungible-tokens/metis.json"; +import Stardust from "./fungible-tokens/stardust.json"; import Cronos from "./fungible-tokens/cronos.json"; import Harmony from "./fungible-tokens/harmony.json"; import HarmonyTestnet from "./fungible-tokens/harmony-testnet.json"; @@ -87,6 +89,8 @@ function getFungibleTokenLists(): Record { [ChainId.Celo]: [Celo], [ChainId.Avalanche]: [Avalanche], [ChainId.Aurora]: [Aurora], + [ChainId.Metis]: [Metis], + [ChainId.Stardust]: [Stardust], [ChainId.Cronos]: [Cronos], [ChainId.Moonbeam]: [Moonbeam], [ChainId.Moonriver]: [Moonriver], diff --git a/src/types.ts b/src/types.ts index 87f58a50..13fc385b 100644 --- a/src/types.ts +++ b/src/types.ts @@ -24,6 +24,8 @@ export enum ChainId { Aurora = 1313161554, Harmony = 1666600000, Harmony_Testnet = 1666700000, + Metis = 1088, + Stardust = 588, Palm = 11297108109, Astar = 592, }