solution: erc20 tokens config

This commit is contained in:
Igor Artamonov
2020-07-03 00:06:48 -04:00
parent 61f07b8b43
commit 6dbe8b96ec
6 changed files with 184 additions and 0 deletions

View File

@@ -22,5 +22,6 @@ class MainConfig {
var cache: CacheConfig? = null
var proxy: ProxyConfig? = null
var upstreams: UpstreamsConfig? = null
var tokens: TokensConfig? = null
}

View File

@@ -32,6 +32,7 @@ class MainConfigReader(
private val proxyConfigReader = ProxyConfigReader()
private val upstreamsConfigReader = UpstreamsConfigReader(fileResolver)
private val cacheConfigReader = CacheConfigReader()
private val tokensConfigReader = TokensConfigReader()
fun read(input: InputStream): MainConfig? {
val configNode = readNode(input)
@@ -59,6 +60,9 @@ class MainConfigReader(
cacheConfigReader.read(input)?.let {
config.cache = it
}
tokensConfigReader.read(input)?.let {
config.tokens = it
}
return config
}

View File

@@ -0,0 +1,55 @@
/**
* Copyright (c) 2020 EmeraldPay, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.emeraldpay.dshackle.config
import io.emeraldpay.dshackle.BlockchainType
import io.emeraldpay.grpc.Chain
import io.infinitape.etherjar.domain.Address
class TokensConfig(
val tokens: List<Token>
) {
class Token {
// reference id, used by get balance and others
var id: String? = null
var blockchain: Chain? = null
// coin name
var name: String? = null
var type: Type? = null;
var address: String? = null
fun validate(): String? {
return when {
id.isNullOrBlank() -> "id"
blockchain == null -> "blockchain"
name.isNullOrBlank() -> "name"
type == null -> type
address.isNullOrBlank() -> "address"
blockchain != null
&& BlockchainType.fromBlockchain(blockchain!!) == BlockchainType.ETHEREUM
&& !Address.isValidAddress(address) -> "address"
else -> null
}
}
}
enum class Type {
ERC20
}
}

View File

@@ -0,0 +1,63 @@
/**
* Copyright (c) 2020 EmeraldPay, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.emeraldpay.dshackle.config
import org.slf4j.LoggerFactory
import org.yaml.snakeyaml.nodes.MappingNode
import java.io.InputStream
class TokensConfigReader : YamlConfigReader(), ConfigReader<TokensConfig> {
private val log = LoggerFactory.getLogger(TokensConfigReader::class.java)
fun read(input: InputStream): TokensConfig? {
val configNode = readNode(input)
return read(configNode)
}
override fun read(input: MappingNode?): TokensConfig? {
val tokens = getList<MappingNode>(input, "tokens")?.value?.map { node ->
val token = TokensConfig.Token()
token.id = getValueAsString(node, "id")
token.blockchain = getValueAsString(node, "blockchain")?.let {
getBlockchain(it)
}
token.address = getValueAsString(node, "address")
token.name = getValueAsString(node, "name")
token.type = getValueAsString(node, "type")?.let {
if (it.toUpperCase() == "ERC-20") {
TokensConfig.Type.ERC20
} else {
log.warn("Invalid token type: $it")
null
}
}
token
}?.filter { token ->
val invalidField = token.validate()
if (invalidField != null) {
log.error("Failed to parse token ${token.id}. Invalid field: $invalidField")
false
} else {
true
}
}
return tokens?.let {
TokensConfig(it)
}
}
}

View File

@@ -0,0 +1,50 @@
/**
* Copyright (c) 2020 EmeraldPay, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.emeraldpay.dshackle.config
import io.emeraldpay.grpc.Chain
import spock.lang.Specification
class TokensConfigReaderSpec extends Specification {
TokensConfigReader reader = new TokensConfigReader()
def "Read basic"() {
setup:
def config = this.class.getClassLoader().getResourceAsStream("tokens/basic.yaml")
when:
def act = reader.read(config)
then:
act != null
act.tokens.size() == 2
with(act.tokens[0]) {
id == "dai"
blockchain == Chain.ETHEREUM
name == "DAI"
type == TokensConfig.Type.ERC20
address == "0x6B175474E89094C44Da98b954EedeAC495271d0F"
}
with(act.tokens[1]) {
id == "tether"
blockchain == Chain.ETHEREUM
name == "Tether"
type == TokensConfig.Type.ERC20
address == "0xdac17f958d2ee523a2206206994597c13d831ec7"
}
}
}

View File

@@ -0,0 +1,11 @@
tokens:
- id: dai
blockchain: ethereum
name: DAI
type: ERC-20
address: 0x6B175474E89094C44Da98b954EedeAC495271d0F
- id: tether
blockchain: ethereum
name: Tether
type: ERC-20
address: 0xdac17f958d2ee523a2206206994597c13d831ec7