[Internal] When auto-adding Binance tokens, also create info.json (#8256)

* [Internal] When auto-adding Binance tokens, also create info.json

* Text fix

Co-authored-by: Catenocrypt <catenocrypt@users.noreply.github.com>
This commit is contained in:
Adam R 2021-05-17 17:02:45 +02:00 committed by GitHub
parent 595e726883
commit d756cd28d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 61 additions and 27 deletions

View File

@ -7,24 +7,34 @@ import * as config from "../config";
import { ActionInterface, CheckStepInterface } from "../generic/interface"; import { ActionInterface, CheckStepInterface } from "../generic/interface";
import { Binance } from "../generic/blockchains"; import { Binance } from "../generic/blockchains";
import { readDirSync } from "../generic/filesystem"; import { readDirSync } from "../generic/filesystem";
import { readJsonFile } from "../generic/json"; import { readJsonFile, writeJsonFile } from "../generic/json";
import { TokenItem, Pair, createTokensList, writeToFileWithUpdate } from "../generic/tokenlists"; import { TokenItem, Pair, createTokensList, writeToFileWithUpdate } from "../generic/tokenlists";
import { import {
getChainAssetLogoPath, getChainAssetLogoPath,
getChainAssetsPath, getChainAssetsPath,
getChainDenylistPath, getChainDenylistPath,
getChainAssetInfoPath,
getChainTokenlistPath getChainTokenlistPath
} from "../generic/repo-structure"; } from "../generic/repo-structure";
import { CoinType } from "@trustwallet/wallet-core"; import { CoinType } from "@trustwallet/wallet-core";
import { toSatoshis } from "../generic/numbers"; import { toSatoshis } from "../generic/numbers";
import { assetIdSymbol, logoURI, tokenType } from "../generic/asset"; import { assetIdSymbol, logoURI, tokenType } from "../generic/asset";
import { TokenType } from "../generic/tokentype"; import { TokenType } from "../generic/tokentype";
import { explorerUrl } from "../generic/asset-infos";
const binanceChain = "binance"; const binanceChain = "binance";
const binanceUrlTokenAssets = config.binanceUrlTokenAssets; const binanceUrlTokenAssets = config.binanceUrlTokenAssets;
let cachedAssets = []; let cachedAssets = [];
async function retrieveBep2AssetList(): Promise<unknown[]> { export class BinanceTokenInfo {
asset: string
name: string
assetImg: string
mappedAsset: string
decimals: number
}
async function retrieveBep2AssetList(): Promise<BinanceTokenInfo[]> {
console.log(`Retrieving token asset infos from: ${binanceUrlTokenAssets}`); console.log(`Retrieving token asset infos from: ${binanceUrlTokenAssets}`);
const { assetInfoList } = await axios.get(binanceUrlTokenAssets) const { assetInfoList } = await axios.get(binanceUrlTokenAssets)
.then(r => r.data) .then(r => r.data)
@ -53,7 +63,7 @@ export async function retrieveAssetSymbols(): Promise<string[]> {
return symbols; return symbols;
} }
function fetchImage(url) { async function fetchImage(url) {
return axios.get(url, { responseType: "stream" }) return axios.get(url, { responseType: "stream" })
.then(r => r.data) .then(r => r.data)
.catch(err => { .catch(err => {
@ -62,20 +72,20 @@ function fetchImage(url) {
} }
/// Return: array with images to fetch; {asset, assetImg} /// Return: array with images to fetch; {asset, assetImg}
export function findImagesToFetch(assetInfoList: unknown[], denylist: string[]): unknown[] { export function findImagesToFetch(assetInfoList: BinanceTokenInfo[], denylist: string[]): BinanceTokenInfo[] {
const toFetch: unknown[] = []; const toFetch: BinanceTokenInfo[] = [];
console.log(`Checking for asset images to be fetched`); console.log(`Checking for asset images to be fetched`);
assetInfoList.forEach(({asset, assetImg}) => { assetInfoList.forEach((tokenInfo) => {
process.stdout.write(`.${asset} `); process.stdout.write(`.${tokenInfo.asset} `);
if (assetImg) { if (tokenInfo.assetImg) {
if (denylist.indexOf(asset) != -1) { if (denylist.indexOf(tokenInfo.asset) != -1) {
console.log(); console.log();
console.log(`${asset} is denylisted`); console.log(`${tokenInfo.asset} is denylisted`);
} else { } else {
const imagePath = getChainAssetLogoPath(binanceChain, asset); const imagePath = getChainAssetLogoPath(binanceChain, tokenInfo.asset);
if (!fs.existsSync(imagePath)) { if (!fs.existsSync(imagePath)) {
console.log(chalk.red(`Missing image: ${asset}`)); console.log(chalk.red(`Missing image: ${tokenInfo.asset}`));
toFetch.push({asset, assetImg}); toFetch.push(tokenInfo);
} }
} }
} }
@ -85,21 +95,37 @@ export function findImagesToFetch(assetInfoList: unknown[], denylist: string[]):
return toFetch; return toFetch;
} }
async function createInfoJson(tokenInfo: BinanceTokenInfo): Promise<void> {
//console.log(tokenInfo);
const info = {
name: tokenInfo.name,
type: "BEP2",
symbol: tokenInfo.mappedAsset,
decimals: tokenInfo.decimals,
website: '',
description: '-',
explorer: explorerUrl(binanceChain, tokenInfo.asset),
status: 'active',
id: tokenInfo.asset
};
const infoPath = getChainAssetInfoPath(binanceChain, tokenInfo.asset);
writeJsonFile(infoPath, info);
}
async function fetchMissingImages(toFetch: unknown[]): Promise<string[]> { async function fetchMissingImages(toFetch: BinanceTokenInfo[]): Promise<string[]> {
console.log(`Attempting to fetch ${toFetch.length} asset image(s)`); console.log(`Attempting to fetch ${toFetch.length} asset image(s)`);
const fetchedAssets: string[] = []; const fetchedAssets: string[] = [];
await bluebird.each(toFetch, async ({ asset, assetImg }) => { await bluebird.each(toFetch, async (tokenInfo) => {
if (assetImg) { if (tokenInfo && tokenInfo.asset && tokenInfo.assetImg) {
const imagePath = getChainAssetLogoPath(binanceChain, asset); const imagePath = getChainAssetLogoPath(binanceChain, tokenInfo.asset);
fs.mkdir(path.dirname(imagePath), err => { fs.mkdir(path.dirname(imagePath), err => {
if (err && err.code != `EEXIST`) throw err; if (err && err.code != `EEXIST`) throw err;
}); });
await fetchImage(assetImg).then(buffer => { const buffer = await fetchImage(tokenInfo.assetImg);
buffer.pipe(fs.createWriteStream(imagePath)); await buffer.pipe(fs.createWriteStream(imagePath));
fetchedAssets.push(asset) await createInfoJson(tokenInfo);
console.log(`Fetched image ${asset} ${imagePath} from ${assetImg}`) fetchedAssets.push(tokenInfo.asset)
}); console.log(`Token ${tokenInfo.asset} ${tokenInfo.mappedAsset}: Fetched image, created info.json (${tokenInfo.assetImg})`)
} }
}); });
console.log(); console.log();

View File

@ -20,7 +20,10 @@ import {
arrayEqual, arrayEqual,
reverseCase reverseCase
} from "../script/generic/types"; } from "../script/generic/types";
import { findImagesToFetch } from "../script/blockchain/binance"; import {
BinanceTokenInfo,
findImagesToFetch
} from "../script/blockchain/binance";
import { isValidStatusValue } from "../script/generic/status-values"; import { isValidStatusValue } from "../script/generic/status-values";
import { isValidTagValue, isValidTagValues } from "../script/generic/tag-values"; import { isValidTagValue, isValidTagValues } from "../script/generic/tag-values";
@ -126,12 +129,17 @@ describe("Test type helpers", () => {
describe("Test blockchain binance", () => { describe("Test blockchain binance", () => {
test(`Test findImagesToFetch`, () => { test(`Test findImagesToFetch`, () => {
const assetsInfoListNonexisting = [{asset: "A1", assetImg: "imgurl1"}, {asset: "A2", assetImg: "imgurl2"}]; const infoA1: BinanceTokenInfo = {asset: "A1-11", name: "A 1", mappedAsset: "A1", assetImg: "imgurl1", decimals: 8};
const assetsInfoListExisting = [{asset: "BUSD-BD1", assetImg: "imgurlBUSD"}, {asset: "ETH-1C9", assetImg: "imgurlETH"}]; const infoA2: BinanceTokenInfo = {asset: "A2-12", name: "A 2", mappedAsset: "A2", assetImg: "imgurl2", decimals: 8};
const assetsInfoListNonexisting: BinanceTokenInfo[] = [infoA1, infoA2];
const assetsInfoListExisting: BinanceTokenInfo[] = [
{asset: "BUSD-BD1", name: "Binance USD", mappedAsset: "BUSD", assetImg: "imgurlBUSD", decimals: 8},
{asset: "ETH-1C9", name: "Binance Ethereum", mappedAsset: "BETH", assetImg: "imgurlETH", decimals: 8}
];
const denyListEmpty: string[] = []; const denyListEmpty: string[] = [];
const denyListA1: string[] = ["A1"]; const denyListA1: string[] = ["A1-11"];
expect(findImagesToFetch(assetsInfoListNonexisting, denyListEmpty), `2 nonexisting`).toEqual(assetsInfoListNonexisting); expect(findImagesToFetch(assetsInfoListNonexisting, denyListEmpty), `2 nonexisting`).toEqual(assetsInfoListNonexisting);
expect(findImagesToFetch(assetsInfoListNonexisting, denyListA1), `2 nonexisting with 1 denylisted`).toEqual([{asset: "A2", assetImg: "imgurl2"}]); expect(findImagesToFetch(assetsInfoListNonexisting, denyListA1), `2 nonexisting with 1 denylisted`).toEqual([infoA2]);
expect(findImagesToFetch(assetsInfoListExisting, denyListEmpty), `2 existing`).toEqual([]); expect(findImagesToFetch(assetsInfoListExisting, denyListEmpty), `2 existing`).toEqual([]);
expect(findImagesToFetch([], []), `empty`).toEqual([]); expect(findImagesToFetch([], []), `empty`).toEqual([]);
}); });