mirror of
https://github.com/Instadapp/trustwallet-assets.git
synced 2024-07-29 22:37:31 +00:00
7da5daa51e
* Rename tronscan.org to tronscan.io * Make explorer links in checksum. * Fix explorer links. * Add explorerUrl check. Co-authored-by: Catenocrypt <catenocrypt@users.noreply.github.com>
129 lines
4.5 KiB
TypeScript
129 lines
4.5 KiB
TypeScript
import {
|
|
allChains,
|
|
getChainAssetsList,
|
|
getChainAssetsPath,
|
|
getChainAssetInfoPath
|
|
} from "./repo-structure";
|
|
import {
|
|
readFileSync,
|
|
isPathExistsSync
|
|
} from "./filesystem";
|
|
import { arrayDiff } from "./types";
|
|
import { isValidJSON, writeJsonFile } from "../generic/json";
|
|
import { ActionInterface, CheckStepInterface } from "../generic/interface";
|
|
import * as bluebird from "bluebird";
|
|
|
|
const requiredKeys = ["explorer", "name", "website", "short_description"];
|
|
|
|
function isAssetInfoHasAllKeys(info: any, path: string): [boolean, string] {
|
|
const infoKeys = Object.keys(info);
|
|
|
|
const hasAllKeys = requiredKeys.every(k => Object.prototype.hasOwnProperty.call(info, k));
|
|
|
|
if (!hasAllKeys) {
|
|
return [false, `Info at path '${path}' missing next key(s): ${arrayDiff(requiredKeys, infoKeys)}`];
|
|
}
|
|
|
|
const isKeysCorrentType =
|
|
typeof info.explorer === "string" && info.explorer != ""
|
|
&& typeof info.name === "string" && info.name != ""
|
|
&& typeof info.website === "string"
|
|
&& typeof info.short_description === "string";
|
|
|
|
return [isKeysCorrentType, `Check keys '${requiredKeys}' vs. '${infoKeys}'`];
|
|
}
|
|
|
|
function explorerUrl(chain: string, contract: string): string {
|
|
if (contract) {
|
|
switch (chain.toLowerCase()) {
|
|
case "ethereum":
|
|
return `https://etherscan.io/token/${contract}`;
|
|
|
|
case "tron":
|
|
if (contract.startsWith("10")) {
|
|
// trc10
|
|
return `https://tronscan.io/#/token/${contract}`;
|
|
}
|
|
// trc20
|
|
return `https://tronscan.io/#/token20/${contract}`;
|
|
|
|
case "binance":
|
|
return `https://explorer.binance.org/asset/${contract}`;
|
|
|
|
case "smartchain":
|
|
return `https://bscscan.com/token/${contract}`;
|
|
|
|
case "neo":
|
|
return `https://neo.tokenview.com/fr/token/0x${contract}`;
|
|
|
|
case "nuls":
|
|
return `https://nulscan.io/token/info?contractAddress=${contract}`;
|
|
|
|
case "wanchain":
|
|
return `https://www.wanscan.org/token/${contract}`;
|
|
}
|
|
}
|
|
return "";
|
|
}
|
|
|
|
function isAssetInfoOK(chain: string, address: string, errors: string[], warnings: string[]): void {
|
|
const assetInfoPath = getChainAssetInfoPath(chain, address);
|
|
if (!isPathExistsSync(assetInfoPath)) {
|
|
// Info file doesn't exist, no need to check
|
|
return;
|
|
}
|
|
|
|
if (!isValidJSON(assetInfoPath)) {
|
|
console.log(`JSON at path: '${assetInfoPath}' is invalid`);
|
|
errors.push(`JSON at path: '${assetInfoPath}' is invalid`);
|
|
return;
|
|
}
|
|
|
|
const info = JSON.parse(readFileSync(assetInfoPath));
|
|
const [hasAllKeys, msg] = isAssetInfoHasAllKeys(info, assetInfoPath);
|
|
if (!hasAllKeys) {
|
|
console.log(msg);
|
|
errors.push(msg);
|
|
}
|
|
|
|
const hasExplorer = Object.prototype.hasOwnProperty.call(info, 'explorer');
|
|
if (!hasExplorer) {
|
|
errors.push(`Missing explorer key`);
|
|
} else {
|
|
const explorerActual = info['explorer'];
|
|
const explorerExpected = explorerUrl(chain, address);
|
|
if (explorerActual != explorerExpected) {
|
|
warnings.push(`Unexpected explorer, ${explorerActual} instead of ${explorerExpected}`);
|
|
}
|
|
}
|
|
}
|
|
|
|
export class AssetInfos implements ActionInterface {
|
|
getName(): string { return "Asset Infos"; }
|
|
|
|
getSanityChecks(): CheckStepInterface[] {
|
|
const steps: CheckStepInterface[] = [];
|
|
allChains.forEach(chain => {
|
|
// only if there is no assets subfolder
|
|
if (isPathExistsSync(getChainAssetsPath(chain))) {
|
|
steps.push(
|
|
{
|
|
getName: () => { return `Info.json's for chain ${chain}`;},
|
|
check: async () => {
|
|
const errors: string[] = [];
|
|
const warnings: string[] = [];
|
|
const assetsList = getChainAssetsList(chain);
|
|
//console.log(` Found ${assetsList.length} assets for chain ${chain}`);
|
|
await bluebird.each(assetsList, async (address) => {
|
|
isAssetInfoOK(chain, address, errors, warnings);
|
|
});
|
|
return [errors, warnings];
|
|
}
|
|
}
|
|
);
|
|
}
|
|
});
|
|
return steps;
|
|
}
|
|
}
|