Skip to content

Commit 866db8b

Browse files
committed
Version 1.0.0 PoC
1 parent 6f19dc8 commit 866db8b

22 files changed

+1135
-268
lines changed

.gitignore

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,60 @@
1+
# Built application files
2+
*.apk
3+
*.ap_
4+
5+
# Files for the ART/Dalvik VM
6+
*.dex
7+
8+
# Java class files
9+
*.class
10+
11+
# Generated files
12+
bin/
13+
gen/
14+
out/
15+
16+
# Gradle files
17+
.gradle/
118
build/
2-
out/
19+
20+
# Local configuration file (sdk path, etc)
21+
local.properties
22+
23+
# Fabric plugin
24+
fabric.properties
25+
26+
# Proguard folder generated by Eclipse
27+
proguard/
28+
29+
# Log Files
30+
*.log
31+
32+
# Android Studio Navigation editor temp files
33+
.navigation/
34+
35+
# Android Studio captures folder
36+
captures/
37+
38+
*.iml
39+
.idea
40+
41+
# Keystore files
42+
*.jks
43+
44+
# External native build folder generated in Android Studio 2.2 and later
45+
.externalNativeBuild
46+
47+
# Google Services (e.g. APIs or Firebase)
48+
google-services.json
49+
50+
# Coverage reports
51+
jacoco.exec
52+
53+
# Freeline
54+
freeline.py
55+
freeline/
56+
freeline_project_description.json
57+
58+
secrets.tar
59+
project_keys
60+
.DS_STORE

build.gradle

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
buildscript {
22
ext {
3-
KOTLIN_VERSION = "1.3.21"
3+
versions = [
4+
kotlin: "1.3.21",
5+
moshi : '1.8.0',
6+
okhttp: '3.11.0',
7+
]
48
}
59

610
repositories {
711
mavenCentral()
812
}
913

1014
dependencies {
11-
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${KOTLIN_VERSION}"
15+
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$versions.kotlin"
1216
}
1317
}

lib/build.gradle

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,18 @@ repositories {
66
}
77

88
dependencies {
9-
implementation "org.jetbrains.kotlin:kotlin-stdlib:${KOTLIN_VERSION}"
10-
11-
implementation "com.github.walleth.kethereum:erc55:0.70"
12-
implementation "com.github.walleth.kethereum:erc1328:0.70"
9+
implementation "org.jetbrains.kotlin:kotlin-stdlib:$versions.kotlin"
1310

1411
implementation "com.github.walleth:khex:0.6"
1512

1613
implementation 'org.bouncycastle:bcprov-jdk15on:1.60'
1714

1815
implementation 'com.squareup.moshi:moshi:1.8.0'
16+
// TODO: it would be better to use the generated adapter by moshi
17+
// but for that we should move the implementations in different modules
18+
//kapt "com.squareup.moshi:moshi-kotlin-codegen:$versions.moshi"
1919

20-
def okhttpVersion = '3.12.0'
21-
implementation 'com.squareup.okhttp3:okhttp:' + okhttpVersion
20+
implementation "com.squareup.okhttp3:okhttp:$versions.okhttp"
2221

2322
implementation group: 'org.slf4j', name: 'slf4j-log4j12', version: "1.7.25"
2423

@@ -28,9 +27,9 @@ dependencies {
2827
testRuntime 'org.junit.jupiter:junit-jupiter-engine:5.3.2'
2928

3029

31-
testImplementation 'com.squareup.okhttp3:mockwebserver:' + okhttpVersion
30+
testImplementation "com.squareup.okhttp3:mockwebserver:$versions.okhttp"
3231
}
3332

3433
test {
3534
useJUnitPlatform()
36-
}
35+
}
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
package org.walletconnect
2+
3+
import java.net.URLDecoder
4+
5+
interface Session {
6+
fun init()
7+
fun approve(accounts: List<String>, chainId: Long)
8+
fun reject()
9+
fun update(accounts: List<String>, chainId: Long)
10+
fun kill()
11+
12+
fun peerMeta(): PayloadAdapter.PeerMeta?
13+
fun approvedAccounts(): List<String>?
14+
15+
fun approveRequest(id: Long, response: Any)
16+
fun rejectRequest(id: Long, errorCode: Long, errorMsg: String)
17+
18+
fun addCallback(cb: Session.Callback)
19+
fun removeCallback(cb: Session.Callback)
20+
21+
data class Config(
22+
val handshakeTopic: String,
23+
val bridge: String,
24+
val key: String,
25+
val protocol: String = "wc",
26+
val version: Int = 1
27+
) {
28+
companion object {
29+
fun fromWCUri(uri: String): Config {
30+
val protocolSeparator = uri.indexOf(':')
31+
val handshakeTopicSeparator = uri.indexOf('@', startIndex = protocolSeparator)
32+
val versionSeparator = uri.indexOf('?')
33+
val protocol = uri.substring(0, protocolSeparator)
34+
val handshakeTopic = uri.substring(protocolSeparator + 1, handshakeTopicSeparator)
35+
val version = Integer.valueOf(uri.substring(handshakeTopicSeparator + 1, versionSeparator))
36+
val params = uri.substring(versionSeparator + 1).split("&").associate {
37+
it.split("=").let { param -> param.first() to URLDecoder.decode(param[1], "UTF-8") }
38+
}
39+
val bridge = params["bridge"] ?: throw IllegalArgumentException("Missing bridge param in URI")
40+
val key = params["key"] ?: throw IllegalArgumentException("Missing key param in URI")
41+
return Config(handshakeTopic, bridge, key, protocol, version)
42+
}
43+
}
44+
}
45+
46+
interface Callback {
47+
48+
fun sendTransaction(
49+
id: Long,
50+
from: String,
51+
to: String,
52+
nonce: String?,
53+
gasPrice: String?,
54+
gasLimit: String?,
55+
value: String,
56+
data: String
57+
)
58+
59+
fun signMessage(id: Long, address: String, message: String)
60+
61+
fun sessionRequest(peer: PayloadAdapter.PeerData)
62+
63+
fun sessionApproved()
64+
65+
fun sessionClosed(msg: String?)
66+
}
67+
68+
interface PayloadAdapter {
69+
fun parse(payload: String, key: String): MethodCall
70+
fun prepare(data: MethodCall, key: String): String
71+
72+
sealed class MethodCall(private val internalId: Long) {
73+
fun id() = internalId
74+
75+
data class SessionRequest(val id: Long, val peer: PeerData) : MethodCall(id)
76+
77+
data class SessionUpdate(val id: Long, val params: SessionParams) : MethodCall(id)
78+
79+
data class ExchangeKey(val id: Long, val nextKey: String, val peer: PeerData) : MethodCall(id)
80+
81+
data class SendTransaction(
82+
val id: Long,
83+
val from: String,
84+
val to: String,
85+
val nonce: String?,
86+
val gasPrice: String?,
87+
val gasLimit: String?,
88+
val value: String,
89+
val data: String
90+
) : MethodCall(id)
91+
92+
data class SignMessage(val id: Long, val address: String, val message: String) : MethodCall(id)
93+
94+
data class Response(val id: Long, val result: Any?, val error: Error? = null) : MethodCall(id)
95+
}
96+
97+
data class PeerData(val id: String, val meta: PeerMeta?)
98+
data class PeerMeta(
99+
val url: String? = null,
100+
val name: String? = null,
101+
val description: String? = null,
102+
val icons: List<String>? = null,
103+
val ssl: Boolean? = null
104+
)
105+
106+
data class SessionParams(val approved: Boolean, val chainId: Long?, val accounts: List<String>?, val message: String?)
107+
108+
data class Error(val code: Long, val message: String)
109+
110+
}
111+
112+
interface Transport {
113+
114+
fun connect(): Boolean
115+
116+
fun send(message: Message)
117+
118+
fun status(): Status
119+
120+
fun close()
121+
122+
enum class Status {
123+
CONNECTED,
124+
DISCONNECTED
125+
}
126+
127+
data class Message(
128+
val topic: String,
129+
val type: String,
130+
val payload: String
131+
)
132+
133+
interface Builder {
134+
fun build(
135+
url: String,
136+
statusHandler: (Session.Transport.Status) -> Unit,
137+
messageHandler: (Session.Transport.Message) -> Unit
138+
): Transport
139+
}
140+
141+
}
142+
143+
sealed class MethodCallException(val id: Long, val code: Long, message: String) : IllegalArgumentException(message) {
144+
// TODO define proper error codes
145+
class InvalidMethod(id: Long, method: String) : MethodCallException(id, 42, "Unknown method: $method")
146+
class InvalidRequest(id: Long, request: String) : MethodCallException(id, 23, "Invalid request: $request")
147+
class InvalidAccount(id: Long, account: String) : MethodCallException(id, 3141, "Invalid account request: $account")
148+
}
149+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package org.walletconnect
2+
3+
import kotlin.experimental.and
4+
5+
//Map functions that throw exceptions into optional types
6+
fun <T> nullOnThrow(func: () -> T): T? = try {
7+
func.invoke()
8+
} catch (e: Exception) {
9+
null
10+
}
11+
12+
// TODO: Use khex
13+
14+
private val hexArray = "0123456789abcdef".toCharArray()
15+
16+
fun ByteArray.toHexString(): String {
17+
val hexChars = CharArray(this.size * 2)
18+
for (j in this.indices) {
19+
val v = ((this[j] and 0xFF.toByte()).toInt() + 256) % 256
20+
hexChars[j * 2] = hexArray[v ushr 4]
21+
hexChars[j * 2 + 1] = hexArray[v and 0x0F]
22+
}
23+
return String(hexChars)
24+
}
25+
26+
fun String.hexToByteArray(): ByteArray {
27+
val s = this.removePrefix("0x")
28+
val len = s.length
29+
val data = ByteArray(len / 2)
30+
var i = 0
31+
while (i < len) {
32+
data[i / 2] = ((Character.digit(s[i], 16) shl 4) + Character.digit(s[i + 1], 16)).toByte()
33+
i += 2
34+
}
35+
return data
36+
}

lib/src/main/kotlin/org/walletconnect/WalletConnectAPI.kt

Lines changed: 0 additions & 73 deletions
This file was deleted.

0 commit comments

Comments
 (0)