diff --git a/src/main/kotlin/org/ethereum/lists/chains/ChainChecker.kt b/src/main/kotlin/org/ethereum/lists/chains/ChainChecker.kt deleted file mode 100644 index 4f2f4222..00000000 --- a/src/main/kotlin/org/ethereum/lists/chains/ChainChecker.kt +++ /dev/null @@ -1,117 +0,0 @@ -package org.ethereum.lists.chains - -import com.beust.klaxon.JsonObject -import com.beust.klaxon.Klaxon -import com.squareup.moshi.Moshi -import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory -import org.ethereum.lists.chains.model.Chain -import org.kethereum.erc55.isValid -import org.kethereum.model.Address -import org.kethereum.rpc.HttpEthereumRPC -import java.io.File - -val mandatory_fields = listOf( - "name", - "shortName", - "chain", - "network", - "chainId", - "networkId", - "rpc", - "faucets", - "infoURL", - "nativeCurrency" -) -val optionalFields = listOf( - "slip44", - "ens" -) - -class FileNameMustMatchChainId : Exception("chainId must match the filename") -class ExtensionMustBeJSON : Exception("filename extension must be json") -class ShouldHaveNoExtraFields(fields: Set) : Exception("should have no extra field $fields") -class ShouldHaveNoMissingFields(fields: Set) : Exception("missing field(s) $fields") -class RPCMustBeList : Exception("rpc must be a list") -class RPCMustBeListOfStrings : Exception("rpc must be a list of strings") -class ENSMustBeObject: Exception("ens must be an object") -class ENSMustHaveOnlyRegistry: Exception("ens can only have a registry currently") -class ENSRegistryAddressMustBeValid: Exception("ens registry must have valid address") - -fun checkChain(it: File, connectRPC: Boolean) { - println("processing $it") - - parseWithMoshi(it) - - val jsonObject = Klaxon().parseJsonObject(it.reader()) - val chainAsLong = getNumber(jsonObject, "chainId") - - if (chainAsLong != it.nameWithoutExtension.toLongOrNull()) { - throw(FileNameMustMatchChainId()) - } - - if (it.extension != "json") { - throw(ExtensionMustBeJSON()) - } - - getNumber(jsonObject, "networkId") - - val extraFields = jsonObject.map.keys.subtract(mandatory_fields).subtract(optionalFields) - if (extraFields.isNotEmpty()) { - throw ShouldHaveNoExtraFields(extraFields) - } - - val missingFields = mandatory_fields.subtract(jsonObject.map.keys) - if (missingFields.isNotEmpty()) { - throw ShouldHaveNoMissingFields(missingFields) - } - - jsonObject["ens"]?.let { - if (it !is JsonObject) { - throw ENSMustBeObject() - } - if (it.keys != mutableSetOf("registry")) { - throw ENSMustHaveOnlyRegistry() - } - - val address = Address(it["registry"] as String) - if (!address.isValid()) { - throw ENSRegistryAddressMustBeValid() - } - } - - if (connectRPC) { - if (jsonObject["rpc"] is List<*>) { - (jsonObject["rpc"] as List<*>).forEach { - if (it !is String) { - throw(RPCMustBeListOfStrings()) - } else { - println("connecting to $it") - val ethereumRPC = HttpEthereumRPC(it) - println("Client:" + ethereumRPC.clientVersion()) - println("BlockNumber:" + ethereumRPC.blockNumber()) - println("GasPrice:" + ethereumRPC.gasPrice()) - } - } - println() - } else { - throw(RPCMustBeList()) - } - } -} - -/* -moshi fails for extra commas -https://github.com/ethereum-lists/chains/issues/126 -*/ -private fun parseWithMoshi(fileToParse: File) { - val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build() - moshi.adapter(Chain::class.java).fromJson(fileToParse.readText()) -} - -private fun getNumber(jsonObject: JsonObject, field: String): Long { - return when (val chainId = jsonObject[field]) { - is Int -> chainId.toLong() - is Long -> chainId - else -> throw(Exception("chain_id must be a number")) - } -} diff --git a/src/main/kotlin/org/ethereum/lists/chains/Env.kt b/src/main/kotlin/org/ethereum/lists/chains/Env.kt new file mode 100644 index 00000000..2d8824d9 --- /dev/null +++ b/src/main/kotlin/org/ethereum/lists/chains/Env.kt @@ -0,0 +1,23 @@ +package org.ethereum.lists.chains + +import com.squareup.moshi.Moshi +import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory + +val mandatory_fields = listOf( + "name", + "shortName", + "chain", + "network", + "chainId", + "networkId", + "rpc", + "faucets", + "infoURL", + "nativeCurrency" +) +val optionalFields = listOf( + "slip44", + "ens" +) + +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 61976648..952e2e9b 100644 --- a/src/main/kotlin/org/ethereum/lists/chains/Main.kt +++ b/src/main/kotlin/org/ethereum/lists/chains/Main.kt @@ -1,7 +1,12 @@ package org.ethereum.lists.chains import java.io.File - +import com.beust.klaxon.JsonObject +import com.beust.klaxon.Klaxon +import org.ethereum.lists.chains.model.* +import org.kethereum.erc55.isValid +import org.kethereum.model.Address +import org.kethereum.rpc.HttpEthereumRPC fun main(args: Array) { @@ -10,3 +15,81 @@ fun main(args: Array) { } } + +fun checkChain(it: File, connectRPC: Boolean) { + println("processing $it") + + parseWithMoshi(it) + + val jsonObject = Klaxon().parseJsonObject(it.reader()) + val chainAsLong = getNumber(jsonObject, "chainId") + + if (chainAsLong != it.nameWithoutExtension.toLongOrNull()) { + throw(FileNameMustMatchChainId()) + } + + if (it.extension != "json") { + throw(ExtensionMustBeJSON()) + } + + getNumber(jsonObject, "networkId") + + val extraFields = jsonObject.map.keys.subtract(mandatory_fields).subtract(optionalFields) + if (extraFields.isNotEmpty()) { + throw ShouldHaveNoExtraFields(extraFields) + } + + val missingFields = mandatory_fields.subtract(jsonObject.map.keys) + if (missingFields.isNotEmpty()) { + throw ShouldHaveNoMissingFields(missingFields) + } + + jsonObject["ens"]?.let { + if (it !is JsonObject) { + throw ENSMustBeObject() + } + if (it.keys != mutableSetOf("registry")) { + throw ENSMustHaveOnlyRegistry() + } + + val address = Address(it["registry"] as String) + if (!address.isValid()) { + throw ENSRegistryAddressMustBeValid() + } + } + + if (connectRPC) { + if (jsonObject["rpc"] is List<*>) { + (jsonObject["rpc"] as List<*>).forEach { + if (it !is String) { + throw(RPCMustBeListOfStrings()) + } else { + println("connecting to $it") + val ethereumRPC = HttpEthereumRPC(it) + println("Client:" + ethereumRPC.clientVersion()) + println("BlockNumber:" + ethereumRPC.blockNumber()) + println("GasPrice:" + ethereumRPC.gasPrice()) + } + } + println() + } else { + throw(RPCMustBeList()) + } + } +} + +/* +moshi fails for extra commas +https://github.com/ethereum-lists/chains/issues/126 +*/ +private fun parseWithMoshi(fileToParse: File) { + moshi.adapter(Chain::class.java).fromJson(fileToParse.readText()) +} + +private fun getNumber(jsonObject: JsonObject, field: String): Long { + return when (val chainId = jsonObject[field]) { + is Int -> chainId.toLong() + is Long -> chainId + else -> throw(Exception("chain_id must be a number")) + } +} \ No newline at end of file diff --git a/src/main/kotlin/org/ethereum/lists/chains/model/Exceptions.kt b/src/main/kotlin/org/ethereum/lists/chains/model/Exceptions.kt new file mode 100644 index 00000000..e02fc556 --- /dev/null +++ b/src/main/kotlin/org/ethereum/lists/chains/model/Exceptions.kt @@ -0,0 +1,11 @@ +package org.ethereum.lists.chains.model + +class FileNameMustMatchChainId : Exception("chainId must match the filename") +class ExtensionMustBeJSON : Exception("filename extension must be json") +class ShouldHaveNoExtraFields(fields: Set) : Exception("should have no extra field $fields") +class ShouldHaveNoMissingFields(fields: Set) : Exception("missing field(s) $fields") +class RPCMustBeList : Exception("rpc must be a list") +class RPCMustBeListOfStrings : Exception("rpc must be a list of strings") +class ENSMustBeObject: Exception("ens must be an object") +class ENSMustHaveOnlyRegistry: Exception("ens can only have a registry currently") +class ENSRegistryAddressMustBeValid: Exception("ens registry must have valid address") diff --git a/src/test/kotlin/TheChainChecker.kt b/src/test/kotlin/TheChainChecker.kt index 1ac12ce7..c1c2ccf6 100644 --- a/src/test/kotlin/TheChainChecker.kt +++ b/src/test/kotlin/TheChainChecker.kt @@ -1,5 +1,6 @@ import com.squareup.moshi.JsonEncodingException import org.ethereum.lists.chains.* +import org.ethereum.lists.chains.model.* import org.junit.Test import java.io.File