diff --git a/src/main/kotlin/org/ethereum/lists/chains/Env.kt b/src/main/kotlin/org/ethereum/lists/chains/Env.kt index f96c8d02..1c35811c 100644 --- a/src/main/kotlin/org/ethereum/lists/chains/Env.kt +++ b/src/main/kotlin/org/ethereum/lists/chains/Env.kt @@ -19,7 +19,8 @@ val mandatory_fields = listOf( ) val optionalFields = listOf( "slip44", - "ens" + "ens", + "icon" ) val moshi: Moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build() diff --git a/src/main/kotlin/org/ethereum/lists/chains/Main.kt b/src/main/kotlin/org/ethereum/lists/chains/Main.kt index 74cee68a..6bf1537e 100644 --- a/src/main/kotlin/org/ethereum/lists/chains/Main.kt +++ b/src/main/kotlin/org/ethereum/lists/chains/Main.kt @@ -1,5 +1,6 @@ package org.ethereum.lists.chains +import com.beust.klaxon.JsonArray import java.io.File import com.beust.klaxon.JsonObject import com.beust.klaxon.Klaxon @@ -8,16 +9,23 @@ import org.kethereum.erc55.isValid import org.kethereum.model.Address import org.kethereum.rpc.HttpEthereumRPC -val parsedShortNames= mutableSetOf() -val parsedNames= mutableSetOf() +val parsedShortNames = mutableSetOf() +val parsedNames = mutableSetOf() + +val iconsPath = File("_data/icons") fun main(args: Array) { - val allFiles = File("_data/chains").listFiles()?:return + val allFiles = File("_data/chains").listFiles() ?: return allFiles.filter { !it.isDirectory }.forEach { checkChain(it, args.contains("rpcConnect")) } + val allIcons = iconsPath.listFiles() ?: return + allIcons.forEach { + checkIcon(it) + } + allFiles.filter { it.isDirectory }.forEach { if (it.name != "deprecated") { error("the only directory allowed is 'deprecated'") @@ -25,23 +33,60 @@ fun main(args: Array) { } } -fun checkChain(it: File, connectRPC: Boolean) { - println("processing $it") +fun checkIcon(icon: File) { + println("checking Icon " + icon.name) + val obj: JsonArray<*> = Klaxon().parseJsonArray(icon.reader()) + println("found variants " + obj.size) + obj.forEach { it -> + if (it !is JsonObject) { + error("Icon variant must be an object") + } - parseWithMoshi(it) + val url = it["url"] ?: error("Icon must have a URL") - val jsonObject = Klaxon().parseJsonObject(it.reader()) + if (url !is String || !url.startsWith("ipfs://")) { + error("url must start with ipfs://") + } + + val width = it["width"] + val height = it["height"] + if (width != null || height != null) { + if (height == null || width == null) { + error("If icon has width or height it needs to have both") + } + + if (width !is Int) { + error("Icon width must be Int") + } + if (height !is Int) { + error("Icon height must be Int") + } + } + + val format = it["format"] + if (format !is String || (format != "png" && format != "svg")) { + error("Icon format must be a png or svg but was $format") + } + } +} + +fun checkChain(chainFile: File, connectRPC: Boolean) { + println("processing $chainFile") + + parseWithMoshi(chainFile) + + val jsonObject = Klaxon().parseJsonObject(chainFile.reader()) val chainAsLong = getNumber(jsonObject, "chainId") - if (it.nameWithoutExtension.startsWith("eip155-")) { - if (chainAsLong != it.nameWithoutExtension.replace("eip155-","").toLongOrNull()) { + if (chainFile.nameWithoutExtension.startsWith("eip155-")) { + if (chainAsLong != chainFile.nameWithoutExtension.replace("eip155-", "").toLongOrNull()) { throw(FileNameMustMatchChainId()) } } else { throw(UnsupportedNamespace()) } - if (it.extension != "json") { + if (chainFile.extension != "json") { throw(ExtensionMustBeJSON()) } @@ -57,6 +102,12 @@ fun checkChain(it: File, connectRPC: Boolean) { throw ShouldHaveNoMissingFields(missingFields) } + jsonObject["icon"]?.let { + if (!File(iconsPath,"$it.json").exists()) { + error("The Icon $it does not exist - was used in ${chainFile.name}") + } + } + jsonObject["ens"]?.let { if (it !is JsonObject) { throw ENSMustBeObject()