mirror of
https://github.com/Instadapp/chains.git
synced 2024-07-29 22:37:19 +00:00
Add ability to download icons
This commit is contained in:
parent
33b37d0113
commit
8bd6563b9a
|
@ -18,5 +18,7 @@ dependencies {
|
||||||
|
|
||||||
testImplementation "org.jetbrains.kotlin:kotlin-test:${KOTLIN_VERSION}"
|
testImplementation "org.jetbrains.kotlin:kotlin-test:${KOTLIN_VERSION}"
|
||||||
testImplementation "org.jetbrains.kotlin:kotlin-test-junit:${KOTLIN_VERSION}"
|
testImplementation "org.jetbrains.kotlin:kotlin-test-junit:${KOTLIN_VERSION}"
|
||||||
|
|
||||||
|
implementation 'com.github.ligi:ipfs-api-kotlin:0.15'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,29 +2,43 @@ package org.ethereum.lists.chains
|
||||||
|
|
||||||
import com.squareup.moshi.JsonAdapter
|
import com.squareup.moshi.JsonAdapter
|
||||||
import com.squareup.moshi.Moshi
|
import com.squareup.moshi.Moshi
|
||||||
|
import io.ipfs.kotlin.IPFS
|
||||||
|
import io.ipfs.kotlin.IPFSConfiguration
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
import org.ethereum.lists.chains.model.Chain
|
import org.ethereum.lists.chains.model.Chain
|
||||||
|
import java.time.Duration
|
||||||
|
|
||||||
val mandatory_fields = listOf(
|
val mandatory_fields = listOf(
|
||||||
"name",
|
"name",
|
||||||
"shortName",
|
"shortName",
|
||||||
"chain",
|
"chain",
|
||||||
"chainId",
|
"chainId",
|
||||||
"networkId",
|
"networkId",
|
||||||
"rpc",
|
"rpc",
|
||||||
"faucets",
|
"faucets",
|
||||||
"infoURL",
|
"infoURL",
|
||||||
"nativeCurrency"
|
"nativeCurrency"
|
||||||
)
|
)
|
||||||
val optionalFields = listOf(
|
val optionalFields = listOf(
|
||||||
"slip44",
|
"slip44",
|
||||||
"ens",
|
"ens",
|
||||||
"icon",
|
"icon",
|
||||||
"explorers",
|
"explorers",
|
||||||
"title",
|
"title",
|
||||||
"network",
|
"network",
|
||||||
"parent",
|
"parent",
|
||||||
"status"
|
"status"
|
||||||
)
|
)
|
||||||
|
|
||||||
val moshi: Moshi = Moshi.Builder().build()
|
val moshi: Moshi = Moshi.Builder().build()
|
||||||
val chainAdapter: JsonAdapter<Chain> = moshi.adapter(Chain::class.java)
|
val chainAdapter: JsonAdapter<Chain> = moshi.adapter(Chain::class.java)
|
||||||
|
|
||||||
|
val ipfs by lazy {
|
||||||
|
IPFS(
|
||||||
|
IPFSConfiguration(
|
||||||
|
"http://127.0.0.1:5001/api/v0/",
|
||||||
|
OkHttpClient.Builder().readTimeout(Duration.ofMinutes(1)).build(),
|
||||||
|
Moshi.Builder().build()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
|
@ -4,10 +4,15 @@ import com.beust.klaxon.JsonArray
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import com.beust.klaxon.JsonObject
|
import com.beust.klaxon.JsonObject
|
||||||
import com.beust.klaxon.Klaxon
|
import com.beust.klaxon.Klaxon
|
||||||
|
import com.squareup.moshi.Moshi
|
||||||
|
import io.ipfs.kotlin.IPFS
|
||||||
|
import io.ipfs.kotlin.IPFSConfiguration
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
import org.ethereum.lists.chains.model.*
|
import org.ethereum.lists.chains.model.*
|
||||||
import org.kethereum.erc55.isValid
|
import org.kethereum.erc55.isValid
|
||||||
import org.kethereum.model.Address
|
import org.kethereum.model.Address
|
||||||
import org.kethereum.rpc.HttpEthereumRPC
|
import org.kethereum.rpc.HttpEthereumRPC
|
||||||
|
import java.time.Duration
|
||||||
|
|
||||||
val parsedShortNames = mutableSetOf<String>()
|
val parsedShortNames = mutableSetOf<String>()
|
||||||
val parsedNames = mutableSetOf<String>()
|
val parsedNames = mutableSetOf<String>()
|
||||||
|
@ -15,6 +20,7 @@ val parsedNames = mutableSetOf<String>()
|
||||||
val basePath = File("..")
|
val basePath = File("..")
|
||||||
val dataPath = File(basePath, "_data")
|
val dataPath = File(basePath, "_data")
|
||||||
val iconsPath = File(dataPath, "icons")
|
val iconsPath = File(dataPath, "icons")
|
||||||
|
val iconsDownloadPath = File(dataPath, "iconsDownload")
|
||||||
|
|
||||||
val chainsPath = File(dataPath, "chains")
|
val chainsPath = File(dataPath, "chains")
|
||||||
private val allFiles = chainsPath.listFiles() ?: error("${chainsPath.absolutePath} must contain the chain json files - but it does not")
|
private val allFiles = chainsPath.listFiles() ?: error("${chainsPath.absolutePath} must contain the chain json files - but it does not")
|
||||||
|
@ -22,8 +28,7 @@ private val allChainFiles = allFiles.filter { !it.isDirectory }
|
||||||
|
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
|
|
||||||
doChecks(doRPCConnect = args.contains("rpcConnect"))
|
doChecks(doRPCConnect = args.contains("rpcConnect"), doIconDownload = args.contains("iconDownload"))
|
||||||
|
|
||||||
createOutputFiles()
|
createOutputFiles()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,14 +88,14 @@ private fun createOutputFiles() {
|
||||||
File(buildPath, "CNAME").writeText("chainid.network")
|
File(buildPath, "CNAME").writeText("chainid.network")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun doChecks(doRPCConnect: Boolean) {
|
private fun doChecks(doRPCConnect: Boolean, doIconDownload: Boolean) {
|
||||||
allChainFiles.forEach {
|
allChainFiles.forEach {
|
||||||
checkChain(it, doRPCConnect)
|
checkChain(it, doRPCConnect)
|
||||||
}
|
}
|
||||||
|
|
||||||
val allIcons = iconsPath.listFiles() ?: return
|
val allIcons = iconsPath.listFiles() ?: return
|
||||||
allIcons.forEach {
|
allIcons.forEach {
|
||||||
checkIcon(it)
|
checkIcon(it, doIconDownload)
|
||||||
}
|
}
|
||||||
|
|
||||||
allFiles.filter { it.isDirectory }.forEach { _ ->
|
allFiles.filter { it.isDirectory }.forEach { _ ->
|
||||||
|
@ -98,7 +103,7 @@ private fun doChecks(doRPCConnect: Boolean) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun checkIcon(icon: File) {
|
fun checkIcon(icon: File, withIconDownload: Boolean) {
|
||||||
println("checking Icon " + icon.name)
|
println("checking Icon " + icon.name)
|
||||||
val obj: JsonArray<*> = Klaxon().parseJsonArray(icon.reader())
|
val obj: JsonArray<*> = Klaxon().parseJsonArray(icon.reader())
|
||||||
println("found variants " + obj.size)
|
println("found variants " + obj.size)
|
||||||
|
@ -113,6 +118,25 @@ fun checkIcon(icon: File) {
|
||||||
error("url must start with ipfs://")
|
error("url must start with ipfs://")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (withIconDownload) {
|
||||||
|
|
||||||
|
|
||||||
|
val iconCID = url.removePrefix("ipfs://")
|
||||||
|
try {
|
||||||
|
|
||||||
|
println("fetching Icon from IPFS $iconCID")
|
||||||
|
|
||||||
|
val iconBytes = ipfs.get.catBytes(iconCID)
|
||||||
|
println("Icon size" + iconBytes.size)
|
||||||
|
|
||||||
|
val outFile = File(iconsDownloadPath, iconCID)
|
||||||
|
outFile.createNewFile()
|
||||||
|
outFile.writeBytes(iconBytes)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
println("could not fetch icon from IPFS")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val width = it["width"]
|
val width = it["width"]
|
||||||
val height = it["height"]
|
val height = it["height"]
|
||||||
if (width != null || height != null) {
|
if (width != null || height != null) {
|
||||||
|
@ -143,14 +167,14 @@ fun checkChain(chainFile: File, connectRPC: Boolean) {
|
||||||
|
|
||||||
if (chainFile.nameWithoutExtension.startsWith("eip155-")) {
|
if (chainFile.nameWithoutExtension.startsWith("eip155-")) {
|
||||||
if (chainAsLong != chainFile.nameWithoutExtension.replace("eip155-", "").toLongOrNull()) {
|
if (chainAsLong != chainFile.nameWithoutExtension.replace("eip155-", "").toLongOrNull()) {
|
||||||
throw(FileNameMustMatchChainId())
|
throw (FileNameMustMatchChainId())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw(UnsupportedNamespace())
|
throw (UnsupportedNamespace())
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chainFile.extension != "json") {
|
if (chainFile.extension != "json") {
|
||||||
throw(ExtensionMustBeJSON())
|
throw (ExtensionMustBeJSON())
|
||||||
}
|
}
|
||||||
|
|
||||||
getNumber(jsonObject, "networkId")
|
getNumber(jsonObject, "networkId")
|
||||||
|
@ -183,7 +207,7 @@ fun checkChain(chainFile: File, connectRPC: Boolean) {
|
||||||
if (symbol.length >= 7) {
|
if (symbol.length >= 7) {
|
||||||
throw NativeCurrencySymbolMustHaveLessThan7Chars()
|
throw NativeCurrencySymbolMustHaveLessThan7Chars()
|
||||||
}
|
}
|
||||||
if (it.keys != setOf("symbol","decimals","name")) {
|
if (it.keys != setOf("symbol", "decimals", "name")) {
|
||||||
throw NativeCurrencyCanOnlyHaveSymbolNameAndDecimals()
|
throw NativeCurrencyCanOnlyHaveSymbolNameAndDecimals()
|
||||||
}
|
}
|
||||||
if (it["decimals"] !is Int) {
|
if (it["decimals"] !is Int) {
|
||||||
|
@ -205,20 +229,20 @@ fun checkChain(chainFile: File, connectRPC: Boolean) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (explorer["name"] == null) {
|
if (explorer["name"] == null) {
|
||||||
throw(ExplorerMustHaveName())
|
throw (ExplorerMustHaveName())
|
||||||
}
|
}
|
||||||
|
|
||||||
val url = explorer["url"]
|
val url = explorer["url"]
|
||||||
if (url == null || url !is String || !url.startsWith("https://")) {
|
if (url == null || url !is String || !url.startsWith("https://")) {
|
||||||
throw(ExplorerMustWithHttps())
|
throw (ExplorerMustWithHttps())
|
||||||
}
|
}
|
||||||
|
|
||||||
if (url.endsWith("/")) {
|
if (url.endsWith("/")) {
|
||||||
throw(ExplorerCannotEndInSlash())
|
throw (ExplorerCannotEndInSlash())
|
||||||
}
|
}
|
||||||
|
|
||||||
if (explorer["standard"] != "EIP3091" && explorer["standard"] != "none") {
|
if (explorer["standard"] != "EIP3091" && explorer["standard"] != "none") {
|
||||||
throw(ExplorerStandardMustBeEIP3091OrNone())
|
throw (ExplorerStandardMustBeEIP3091OrNone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -239,7 +263,7 @@ fun checkChain(chainFile: File, connectRPC: Boolean) {
|
||||||
if (it !is String) {
|
if (it !is String) {
|
||||||
throw StatusMustBeString()
|
throw StatusMustBeString()
|
||||||
}
|
}
|
||||||
if (!setOf("incubating","active","deprecated").contains(it)) {
|
if (!setOf("incubating", "active", "deprecated").contains(it)) {
|
||||||
throw StatusMustBeIncubatingActiveOrDeprecated()
|
throw StatusMustBeIncubatingActiveOrDeprecated()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -286,7 +310,7 @@ fun checkChain(chainFile: File, connectRPC: Boolean) {
|
||||||
if (jsonObject["rpc"] is List<*>) {
|
if (jsonObject["rpc"] is List<*>) {
|
||||||
(jsonObject["rpc"] as List<*>).forEach {
|
(jsonObject["rpc"] as List<*>).forEach {
|
||||||
if (it !is String) {
|
if (it !is String) {
|
||||||
throw(RPCMustBeListOfStrings())
|
throw (RPCMustBeListOfStrings())
|
||||||
} else {
|
} else {
|
||||||
println("connecting to $it")
|
println("connecting to $it")
|
||||||
val ethereumRPC = HttpEthereumRPC(it)
|
val ethereumRPC = HttpEthereumRPC(it)
|
||||||
|
@ -297,7 +321,7 @@ fun checkChain(chainFile: File, connectRPC: Boolean) {
|
||||||
}
|
}
|
||||||
println()
|
println()
|
||||||
} else {
|
} else {
|
||||||
throw(RPCMustBeList())
|
throw (RPCMustBeList())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -328,6 +352,6 @@ private fun getNumber(jsonObject: JsonObject, field: String): Long {
|
||||||
return when (val chainId = jsonObject[field]) {
|
return when (val chainId = jsonObject[field]) {
|
||||||
is Int -> chainId.toLong()
|
is Int -> chainId.toLong()
|
||||||
is Long -> chainId
|
is Long -> chainId
|
||||||
else -> throw(Exception("chain_id must be a number"))
|
else -> throw (Exception("chain_id must be a number"))
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user