Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Readme and some tests to :erc961 #157

Merged
merged 2 commits into from
Oct 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions erc831/src/main/kotlin/org/kethereum/erc831/ERC831.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package org.kethereum.erc831

// as defined in http://eips.ethereum.org/EIPS/eip-831

/**
* as defined in [EIP-831](https://eips.ethereum.org/EIPS/eip-831)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do I understand that 831 is not yet approved ERC, but still EIP?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yea - still need to push this through the EIP process

*/
data class ERC831(
var scheme: String? = null,
var prefix: String? = null,
var payload: String? = null
var scheme: String? = null,
var prefix: String? = null,
var payload: String? = null
)
9 changes: 5 additions & 4 deletions erc831/src/main/kotlin/org/kethereum/erc831/ERC831Parser.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ private enum class ParseState {
PAYLOAD
}

fun EthereumURI.toERC831() = ERC831().apply {
fun EthereumURI.toERC831(): ERC831 = ERC831().apply {

var currentSegment = ""

Expand Down Expand Up @@ -39,12 +39,13 @@ fun EthereumURI.toERC831() = ERC831().apply {
}
}

if (!currentSegment.isBlank()) {
if (currentSegment.isNotBlank()) {
stateTransition(PAYLOAD)
}

}

private fun String.hasPrefix() = contains('-') && (!contains("0x") || indexOf('-') < indexOf("0x"))
private fun String.hasPrefix(): Boolean =
contains('-') && (!contains("0x") || indexOf('-') < indexOf("0x"))

fun parseERC831(url: String) = EthereumURI(url).toERC831()
fun parseERC831(url: String): ERC831 = EthereumURI(url).toERC831()
33 changes: 33 additions & 0 deletions erc961/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
This module provides and implements methods for working with [EIP-961](https://github.com/ethereum/EIPs/pull/961)

### Installation
[![](https://jitpack.io/v/komputing/kethereum.svg)](https://jitpack.io/#komputing/kethereum)
```groovy
implementation("com.github.komputing.kethereum:model:$KETHEREUM_VERSION")
implementation("com.github.komputing.kethereum:erc961:$KETHEREUM_VERSION")
```

### Usage
#### Generating EIP-961 token URL
```kotlin
val address = Address(0x00AB42)
val chainId = ChainId(4)
val erc20Token = Token("TST", address, chainId)
val eip651Url: String = erc20Token.generateURL()

println(eip651Url) // ethereum:token_info-0x00AB42@4?symbol=TST
```

#### Working with EIP-961 token URL
```kotlin
val exampleUrl = "ethereum:token_info-0x00AB42@4?symbol=TST"

println(isEthereumTokenURI(exampleUri)) // true
val tokenFromUrl: Token = parseTokenFromEthereumURI(exampleUrl)
println(tokenFromUrl) // Token(symbol="TST", address=0x00AB42, chainId=4, decimals=18)

// also there are extension methods for EthereumURI class
val uri = EthereumURI(exampleUrl)
println(uri.isTokenURI()) // true
println(uri.parseToken()) // Token(symbol="TST", address=0x00AB42, chainId=4, decimals=18)
```
13 changes: 11 additions & 2 deletions erc961/src/main/kotlin/org/kethereum/erc961/ERC961Generator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,20 @@ package org.kethereum.erc961

import org.kethereum.model.Token

private const val EIP_961_DEFAULT_DECIMALS = 18

/**
* Create URL in [EIP-961](https://github.com/ethereum/EIPs/pull/961) format
*
* e.g. ethereum:token_info-0x00AB42@4?symbol=TST
*/
fun Token.generateURL(): String {

val params = mutableListOf<String>()

params.add("symbol=$symbol")

if (decimals != 18) {
if (decimals != EIP_961_DEFAULT_DECIMALS) {
params.add("decimals=$decimals")
}

Expand All @@ -20,5 +27,7 @@ fun Token.generateURL(): String {
params.add("type=$it")
}

return "ethereum:token_info-$address@${chain.value}?" + params.joinToString("&")
val joinedParams = params.joinToString("&")

return "ethereum:token_info-$address@${chain.value}?$joinedParams"
}
11 changes: 7 additions & 4 deletions erc961/src/main/kotlin/org/kethereum/erc961/ERC961Parser.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@ class InvalidTokenURIException : IllegalArgumentException("invalid token")
private const val TOKEN_INFO_PREFIX = "token_info"
private const val FULL_URI_PREFIX = "ethereum:$TOKEN_INFO_PREFIX"

fun isEthereumTokenURI(uri: String) = uri.startsWith(FULL_URI_PREFIX)
fun isEthereumTokenURI(uri: String): Boolean = uri.startsWith(FULL_URI_PREFIX)

/**
* @throws InvalidTokenURIException if the URL doesn't implement EIP-961 standard
*/
fun parseTokenFromEthereumURI(uri: String): Token {
val commonEthereumURI = EthereumURI(uri).parseCommonURI()
val queryMap = commonEthereumURI.query.toMap()
Expand All @@ -23,13 +26,13 @@ fun parseTokenFromEthereumURI(uri: String): Token {

return Token(
symbol = queryMap["symbol"] ?: "SYM",
address = Address(commonEthereumURI.address ?: ""),
address = Address(commonEthereumURI.address.orEmpty()),
chain = commonEthereumURI.chainId ?: ChainId(1),
name = queryMap["name"],
decimals = queryMap["decimals"]?.toInt() ?: 18,
type = queryMap["type"]
)
}

fun EthereumURI.parseToken() = parseTokenFromEthereumURI(uri)
fun EthereumURI.isTokenURI() = isEthereumTokenURI(uri)
fun EthereumURI.parseToken(): Token = parseTokenFromEthereumURI(uri)
fun EthereumURI.isTokenURI(): Boolean = isEthereumTokenURI(uri)
63 changes: 52 additions & 11 deletions erc961/src/test/kotlin/org/kethereum/erc961/TheERC961Parser.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,56 +4,99 @@ import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Assertions.assertThrows
import org.junit.jupiter.api.Test
import org.kethereum.model.Address
import org.kethereum.model.ChainDefinition
import org.kethereum.model.ChainId
import org.kethereum.model.EthereumURI

class TheERC961Parser {

@Test
fun canParseAddress() {
assertThat(parseTokenFromEthereumURI("ethereum:token_info-0x00AB42@4?symbol=TST").address)
.isEqualTo(Address("0x00AB42"))
.isEqualTo(Address("0x00AB42"))
}

@Test
fun canParseAddressAsExtension() {
val address = EthereumURI("ethereum:token_info-0x00AB42@4?symbol=TST")
assertThat(address.parseToken().address).isEqualTo(Address("0x00AB42"))
}

@Test
fun canParseChain() {
assertThat(parseTokenFromEthereumURI("ethereum:token_info-0x00AB42@425?symbol=TST").chain)
.isEqualTo(ChainId(425))
.isEqualTo(ChainId(425))
}

@Test
fun canParseChainAsExtension() {
val address = EthereumURI("ethereum:token_info-0x00AB42@425?symbol=TST")
assertThat(address.parseToken().chain).isEqualTo(ChainId(425))
}

@Test
fun canParseSymbol() {
assertThat(parseTokenFromEthereumURI("ethereum:token_info-0x00AB42@4?symbol=TST").symbol)
.isEqualTo("TST")
.isEqualTo("TST")
}

@Test
fun canParseSymbolAsExtension() {
val address = EthereumURI("ethereum:token_info-0x00AB42@4?symbol=TST")
assertThat(address.parseToken().symbol).isEqualTo("TST")
}

@Test
fun decimalsDefaultTo18() {
assertThat(parseTokenFromEthereumURI("ethereum:token_info-0x00AB42@4").decimals)
.isEqualTo(18)
.isEqualTo(18)
}

@Test
fun decimalsDefaultTo18AsExtension() {
val address = EthereumURI("ethereum:token_info-0x00AB42@4")
assertThat(address.parseToken().decimals).isEqualTo(18)
}

@Test
fun canParseDecimals() {
assertThat(parseTokenFromEthereumURI("ethereum:token_info-0x00AB42@4?decimals=5").decimals)
.isEqualTo(5)
.isEqualTo(5)
}

@Test
fun canParseDecimalsAsExtension() {
val address = EthereumURI("ethereum:token_info-0x00AB42@4?decimals=5")
assertThat(address.parseToken().decimals).isEqualTo(5)
}

@Test
fun canParseName() {
assertThat(parseTokenFromEthereumURI("ethereum:token_info-0x00AB42@4?name=yolo").name)
.isEqualTo("yolo")
.isEqualTo("yolo")
}

@Test
fun canParseNameAsExtension() {
val address = EthereumURI("ethereum:token_info-0x00AB42@4?name=yolo")
assertThat(address.parseToken().name).isEqualTo("yolo")
}

@Test
fun canParseType() {
assertThat(parseTokenFromEthereumURI("ethereum:token_info-0x00AB42@4?type=FOO").type)
.isEqualTo("FOO")
.isEqualTo("FOO")
}

@Test
fun canParseTypeAsExtension() {
val address = EthereumURI("ethereum:token_info-0x00AB42@4?type=FOO")
assertThat(address.parseToken().type).isEqualTo("FOO")
}

@Test
fun canParseFull() {
val parseTokenFromEthereumURI = parseTokenFromEthereumURI("ethereum:token_info-0x00AB43@425?type=TypTest&name=NameTest&decimals=2&symbol=SymbolTest")
val parseTokenFromEthereumURI =
parseTokenFromEthereumURI("ethereum:token_info-0x00AB43@425?type=TypTest&name=NameTest&decimals=2&symbol=SymbolTest")
assertThat(parseTokenFromEthereumURI.address).isEqualTo(Address("0x00AB43"))
assertThat(parseTokenFromEthereumURI.chain).isEqualTo(ChainId(425))
assertThat(parseTokenFromEthereumURI.type).isEqualTo("TypTest")
Expand All @@ -62,12 +105,10 @@ class TheERC961Parser {
assertThat(parseTokenFromEthereumURI.decimals).isEqualTo(2)
}


@Test
fun failsForInvalidScheme() {
assertThrows(InvalidTokenURIException::class.java) {
parseTokenFromEthereumURI("ethereUUm:token_info")
}
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.kethereum.model

data class SignedTransaction(
var transaction: Transaction,
var signatureData: SignatureData
var transaction: Transaction,
var signatureData: SignatureData
)
14 changes: 8 additions & 6 deletions model/src/main/kotlin/org/kethereum/model/Token.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package org.kethereum.model

data class Token(val symbol: String,
val address: Address,
val chain: ChainId,
val decimals: Int = 18,
val type: String? = null,
val name: String? = null)
data class Token(
val symbol: String,
val address: Address,
val chain: ChainId,
val decimals: Int = 18,
val type: String? = null,
val name: String? = null
)
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ package org.kethereum.uri.common
import org.kethereum.model.ChainId

data class CommonEthereumURIData(
var valid: Boolean = true,
var scheme: String? = null,
var prefix: String? = null,
var chainId: ChainId? = null,
var address: String? = null,
var function: String? = null,
var query: List<Pair<String, String>> = listOf()
var valid: Boolean = true,
var scheme: String? = null,
var prefix: String? = null,
var chainId: ChainId? = null,
var address: String? = null,
var function: String? = null,
var query: List<Pair<String, String>> = listOf()
)
Loading