Skip to content

Commit

Permalink
Merge pull request #264 from WalletConnect/develop
Browse files Browse the repository at this point in the history
  • Loading branch information
Elyniss authored Jul 18, 2022
2 parents 2cc314a + df23052 commit 2e6a566
Show file tree
Hide file tree
Showing 160 changed files with 2,734 additions and 736 deletions.
11 changes: 10 additions & 1 deletion .github/workflows/android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@ on:
- develop
- master

concurrency:
# Support push/pr as event types with different behaviors each:
# 1. push: queue up builds by branch
# 2. pr: only allow one run per PR
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.event.pull_request.number || github.ref_name }}
# If there is already a workflow running for the same pull request, cancel it
# For non-PR triggers queue up builds
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

jobs:
unit_tests:
runs-on: ubuntu-latest
Expand All @@ -28,4 +37,4 @@ jobs:
# uses: reactivecircus/android-emulator-runner@v2
# with:
# api-level: 29
# script: ./gradlew walletconnectv2:connectedAndroidTest
# script: ./gradlew walletconnectv2:connectedAndroidTest
2 changes: 1 addition & 1 deletion buildSrc/src/main/kotlin/Dependencies.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ fun DependencyHandlerScope.scanner() {
}

fun DependencyHandlerScope.ktxCore() {
val ktxCoreVersion = "1.6.0"
val ktxCoreVersion = "1.8.0"
"implementation"("androidx.core:core-ktx:$ktxCoreVersion")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,11 @@ object Chat {
val message: String,
val authorAccount: AccountId,
val timestamp: Long,
val media: Media,
) : Model()

data class AccountIdWithPublicKey(
val account: AccountId,
val publicKey: String,
val media: Media?,
) : Model()

sealed class Events : Model() {
data class OnInvite(val id: Int, val invite: Invite) : Events()
data class OnInvite(val id: Long, val invite: Invite) : Events()

data class OnJoined(val topic: String) : Events()

Expand All @@ -74,11 +69,11 @@ object Chat {

data class Invite(val account: Model.AccountId, val invite: Model.Invite) : Params()

data class Accept(val inviteId: String) : Params()
data class Accept(val inviteId: Long) : Params()

data class Reject(val inviteId: String) : Params()

data class Message(val topic: String, val message: String, val media: Model.Media) : Params()
data class Message(val topic: String, val message: String, val media: Model.Media? = null) : Params()

data class Ping(val topic: String) : Params()

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
package com.walletconnect.chat.client

import com.walletconnect.chat.client.mapper.toInviteEngineDO
import com.walletconnect.chat.client.mapper.toMessageEngineDO
import com.walletconnect.chat.client.mapper.toClient
import com.walletconnect.chat.client.mapper.toEngineDO
import com.walletconnect.chat.client.mapper.toVO
import com.walletconnect.chat.copiedFromSign.core.model.vo.PublicKey
import com.walletconnect.chat.copiedFromSign.core.scope.scope
import com.walletconnect.chat.copiedFromSign.di.*
import com.walletconnect.chat.copiedFromSign.util.Logger
import com.walletconnect.chat.core.model.vo.AccountIdVO
import com.walletconnect.chat.core.model.vo.AccountIdWithPublicKeyVO
import com.walletconnect.chat.core.model.vo.EventsVO
import com.walletconnect.chat.di.engineModule
import com.walletconnect.chat.di.keyServerModule
import com.walletconnect.chat.engine.domain.ChatEngine
import com.walletconnect.chat.engine.model.EngineDO
import kotlinx.coroutines.launch
import org.koin.android.ext.koin.androidContext
import org.koin.core.KoinApplication
Expand Down Expand Up @@ -39,13 +44,13 @@ internal class ChatProtocol : ChatInterface {
networkModule(serverUrl),
relayerModule(),
storageModule(),

com.walletconnect.chat.di.storageModule(), // TODO: Refactor storage module into one
engineModule()
)

chatEngine = koin.get()
}
}

chatEngine = wcKoinApp.koin.get()
}

override fun setChatDelegate(delegate: ChatInterface.ChatDelegate) {
Expand All @@ -54,10 +59,10 @@ internal class ChatProtocol : ChatInterface {
scope.launch {
chatEngine.events.collect { event ->
when (event) {
is EventsVO.OnInvite -> TODO()
is EventsVO.OnJoined -> TODO()
is EventsVO.OnLeft -> TODO()
is EventsVO.OnMessage -> TODO()
is EngineDO.Events.OnInvite -> delegate.onInvite(event.toClient())
is EngineDO.Events.OnJoined -> delegate.onJoined(event.toClient())
is EngineDO.Events.OnLeft -> Unit
is EngineDO.Events.OnMessage -> delegate.onMessage(event.toClient())
}
}
}
Expand Down Expand Up @@ -90,7 +95,7 @@ internal class ChatProtocol : ChatInterface {
override fun invite(invite: Chat.Params.Invite, onError: (Chat.Model.Error) -> Unit) {
checkEngineInitialization()

chatEngine.invite(invite.toInviteEngineDO()) { error -> onError(Chat.Model.Error(error)) }
chatEngine.invite(invite.account.toVO(), invite.toEngineDO()) { error -> onError(Chat.Model.Error(error)) }
}

@Throws(IllegalStateException::class)
Expand All @@ -111,7 +116,7 @@ internal class ChatProtocol : ChatInterface {
override fun message(message: Chat.Params.Message, onError: (Chat.Model.Error) -> Unit) {
checkEngineInitialization()

chatEngine.message(message.topic, message.toMessageEngineDO()) { error -> onError(Chat.Model.Error(error)) }
chatEngine.message(message.topic, message.toEngineDO()) { error -> onError(Chat.Model.Error(error)) }
}

@Throws(IllegalStateException::class)
Expand All @@ -131,7 +136,9 @@ internal class ChatProtocol : ChatInterface {
@Throws(IllegalStateException::class)
override fun addContact(addContact: Chat.Params.AddContact, onError: (Chat.Model.Error) -> Unit) {
checkEngineInitialization()
TODO("Not yet implemented")
chatEngine.addContact(AccountIdWithPublicKeyVO(addContact.account.toVO(), PublicKey(addContact.publicKey))) { error ->
onError(Chat.Model.Error(error))
}
}

@Throws(IllegalStateException::class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,63 @@
package com.walletconnect.chat.client.mapper

import com.walletconnect.chat.client.Chat
import com.walletconnect.chat.core.model.vo.AccountIdVO
import com.walletconnect.chat.core.model.vo.MediaVO
import com.walletconnect.chat.engine.model.EngineDO

//TODO: Figure out what to do with models separation
@JvmSynthetic
internal fun Chat.Params.Invite.toInviteEngineDO(): EngineDO.Invite {
return EngineDO.Invite(invite.account.value, invite.message, invite.signature)
internal fun Chat.Params.Invite.toEngineDO(): EngineDO.Invite {
return EngineDO.Invite(invite.account.toVO(), invite.message, invite.signature)
}

@JvmSynthetic
internal fun Chat.Params.Message.toMessageEngineDO() : EngineDO.SendMessage {
return EngineDO.SendMessage(message, media.toMediaEngineDO())
internal fun Chat.Params.Message.toEngineDO() : EngineDO.SendMessage {
return EngineDO.SendMessage(message, media?.toVO())
}

@JvmSynthetic
private fun Chat.Model.Media.toMediaEngineDO() : EngineDO.Media {
return EngineDO.Media(type, data)
}
private fun Chat.Model.Media.toVO() : MediaVO {
return MediaVO(type, data)
}

@JvmSynthetic
internal fun Chat.Model.AccountId.toVO(): AccountIdVO {
return AccountIdVO(value)
}

@JvmSynthetic
internal fun EngineDO.Events.OnInvite.toClient(): Chat.Model.Events.OnInvite {
return Chat.Model.Events.OnInvite(id, invite.toClient())
}

@JvmSynthetic
internal fun EngineDO.Invite.toClient(): Chat.Model.Invite {
return Chat.Model.Invite(accountId.toClient(), message, signature)
}

@JvmSynthetic
internal fun AccountIdVO.toClient(): Chat.Model.AccountId {
return Chat.Model.AccountId(value)
}

@JvmSynthetic
internal fun MediaVO.toClient(): Chat.Model.Media {
return Chat.Model.Media(type, data)
}

@JvmSynthetic
internal fun EngineDO.Events.OnJoined.toClient(): Chat.Model.Events.OnJoined {
return Chat.Model.Events.OnJoined(topic)
}

@JvmSynthetic
internal fun EngineDO.Events.OnMessage.toClient(): Chat.Model.Events.OnMessage {
return Chat.Model.Events.OnMessage(topic, message.toClient())
}

@JvmSynthetic
internal fun EngineDO.Message.toClient(): Chat.Model.Message {
return Chat.Model.Message(message, authorAccountId.toClient(), timestamp, media?.toClient())
}

Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ internal class RelayDOJsonRpcResultJsonAdapter(moshi: Moshi) : JsonAdapter<Relay
private val stringAdapter: JsonAdapter<String> = moshi.adapter(String::class.java, emptySet(), "jsonrpc")
private val booleanAdapter: JsonAdapter<Long> = moshi.adapter(Boolean::class.java, emptySet(), "result")
private val anyAdapter: JsonAdapter<Any> = moshi.adapter(Any::class.java, emptySet(), "result")
private val approvalParamsAdapter: JsonAdapter<ChatParamsVO.ApprovalParams> =
moshi.adapter(ChatParamsVO.ApprovalParams::class.java)
private val acceptanceParamsAdapter: JsonAdapter<ChatParamsVO.AcceptanceParams> =
moshi.adapter(ChatParamsVO.AcceptanceParams::class.java)

@Volatile
private var constructorRef: Constructor<RelayerDO.JsonRpcResponse.JsonRpcResult>? = null
Expand All @@ -48,7 +48,7 @@ internal class RelayDOJsonRpcResultJsonAdapter(moshi: Moshi) : JsonAdapter<Relay
}
2 -> {
result = try {
approvalParamsAdapter.fromJson(reader)
acceptanceParamsAdapter.fromJson(reader)
} catch (e: Exception) {
anyAdapter.fromJson(reader)
}
Expand Down Expand Up @@ -97,8 +97,8 @@ internal class RelayDOJsonRpcResultJsonAdapter(moshi: Moshi) : JsonAdapter<Relay
stringAdapter.toJson(writer, value_.jsonrpc)
writer.name("result")

if ((value_.result as? ChatParamsVO.ApprovalParams) != null) {
val approvalParamsString = approvalParamsAdapter.toJson(value_.result)
if ((value_.result as? ChatParamsVO.AcceptanceParams) != null) {
val approvalParamsString = acceptanceParamsAdapter.toJson(value_.result)
writer.valueSink().use {
it.writeUtf8(approvalParamsString)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ object Relay {
val topic: String,
val message: String,
val ttl: Long,
val tag: Int,
val prompt: Boolean?,
)
}
Expand Down Expand Up @@ -153,5 +154,6 @@ object Relay {
}

data class ShutdownReason(val code: Int, val reason: String) : Relay.Model()
data class IridiumParams(val tag: Int, val ttl: Long, val prompt: Boolean = false) : Relay.Model()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.walletconnect.chat.copiedFromSign.core.model.vo

import com.walletconnect.chat.core.model.vo.Tags

internal data class IridiumParamsVO(val tag: Tags, val ttl: TtlVO, val prompt: Boolean = false)
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
package com.walletconnect.sign.util
package com.walletconnect.sign.core.model.utils

import java.util.concurrent.TimeUnit

object Time {
val currentTimeInSeconds: Long = System.currentTimeMillis() / 1000
val thirtySeconds: Long = TimeUnit.SECONDS.convert(30, TimeUnit.SECONDS)
val fiveMinutesInSeconds: Long = TimeUnit.SECONDS.convert(5, TimeUnit.MINUTES)
val dayInSeconds: Long = TimeUnit.SECONDS.convert(1, TimeUnit.DAYS)
val weekInSeconds: Long = TimeUnit.SECONDS.convert(7, TimeUnit.DAYS)
val monthInSeconds: Long = TimeUnit.SECONDS.convert(30, TimeUnit.DAYS)
}

object Expiration {
val inactivePairing: Long = Time.currentTimeInSeconds + Time.fiveMinutesInSeconds
val activePairing: Long = Time.currentTimeInSeconds + Time.monthInSeconds
val activeSession: Long = Time.currentTimeInSeconds + Time.weekInSeconds
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ import com.walletconnect.chat.copiedFromSign.core.model.vo.sync.ParticipantsVO

internal interface Codec {
fun encrypt(topic: TopicVO, payload: String, envelopeType: EnvelopeType, participants: ParticipantsVO? = null): String
fun decrypt(topic: TopicVO, cipherText: String, receiverPublicKey: PublicKey? = null): String
fun decrypt(topic: TopicVO, cipherText: String): String
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,10 @@ internal interface KeyManagementRepository {
fun removeKeys(tag: String)

//Added with Chat SDK
fun getOrGenerateInviteSelfKeyPair(): Pair<PublicKey, PrivateKey>
fun generateInviteSelfKeyPair(): Pair<PublicKey, PrivateKey>
fun getInviteSelfPublicKey(): PublicKey
fun setInviteSelfPublicKey(topic: TopicVO, publicKey: PublicKey)
fun getHash(string: String): String
fun getInvitePublicKey(topic: TopicVO): PublicKey
fun setKeyAgreement(topic: TopicVO, self: PublicKey, peer: PublicKey)
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
package com.walletconnect.chat.copiedFromSign.crypto

import com.walletconnect.chat.copiedFromSign.core.model.vo.Key
import com.walletconnect.chat.copiedFromSign.core.model.vo.PublicKey

internal interface KeyStore {
fun setSymmetricKey(tag: String, key: Key)
Expand All @@ -15,4 +16,7 @@ internal interface KeyStore {

// Added With Chat SDK
fun getInviteSelfPublicKey(tag: String): String?
fun setInviteSelfPublicKey(tag: String, key: Key)
fun getPublicKey(tag: String): String
fun setPublicKey(tag: String, publicKey: PublicKey)
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,12 @@ internal class ChaChaPolyCodec(private val keyManagementRepository: KeyManagemen
WalletConnectException.UnknownEnvelopeTypeException::class,
WalletConnectException.MissingReceiverPublicKeyException::class
)
override fun decrypt(topic: TopicVO, encryptedPayload: String, receiverPublicKey: PublicKey?): String {
override fun decrypt(topic: TopicVO, encryptedPayload: String): String {
val encryptedPayloadBytes = Base64.decode(encryptedPayload)

return when (val envelopeType = encryptedPayloadBytes.envelopeType) {
EnvelopeType.ZERO.id -> decryptType0(topic, encryptedPayloadBytes)
EnvelopeType.ONE.id -> decryptType1(encryptedPayloadBytes, receiverPublicKey)
EnvelopeType.ONE.id -> decryptType1(encryptedPayloadBytes, keyManagementRepository.getInvitePublicKey(topic))
else -> throw WalletConnectException.UnknownEnvelopeTypeException("Unknown envelope type: $envelopeType")
}
}
Expand Down Expand Up @@ -90,8 +90,9 @@ internal class ChaChaPolyCodec(private val keyManagementRepository: KeyManagemen
byteBuffer.get(nonce)
byteBuffer.get(encryptedMessageBytes)

val peer = PublicKey(publicKey.bytesToHex())
val peer = PublicKey(publicKey.bytesToHex()) // PubKey Y
val symmetricKey = keyManagementRepository.generateSymmetricKeyFromKeyAgreement(receiverPublicKey, peer)
keyManagementRepository.setSymmetricKey(TopicVO(keyManagementRepository.getHash(receiverPublicKey.keyAsHex)), symmetricKey)
val decryptedTextBytes = decryptPayload(symmetricKey, nonce, encryptedMessageBytes)

return String(decryptedTextBytes, Charsets.UTF_8)
Expand Down Expand Up @@ -123,7 +124,6 @@ internal class ChaChaPolyCodec(private val keyManagementRepository: KeyManagemen
val symmetricKey = keyManagementRepository.generateSymmetricKeyFromKeyAgreement(self, peer)
val cipherBytes = encryptPayload(symmetricKey, nonceBytes, input)
val payloadSize = cipherBytes.size + NONCE_SIZE + ENVELOPE_TYPE_SIZE + selfBytes.size

//tp + pk + iv + sb
val encryptedPayloadBytes = ByteBuffer.allocate(payloadSize)
.put(envelopeType.id).put(selfBytes).put(nonceBytes).put(cipherBytes)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ package com.walletconnect.chat.copiedFromSign.crypto.data.keystore

import android.content.SharedPreferences
import com.walletconnect.chat.copiedFromSign.core.model.vo.Key
import com.walletconnect.chat.copiedFromSign.core.model.vo.PublicKey
import com.walletconnect.chat.copiedFromSign.crypto.KeyStore
import com.walletconnect.chat.copiedFromSign.util.Empty
import com.walletconnect.chat.copiedFromSign.util.Logger
import com.walletconnect.chat.copiedFromSign.util.bytesToHex
import com.walletconnect.chat.copiedFromSign.util.hexToBytes

Expand Down Expand Up @@ -47,4 +49,20 @@ internal class KeyChain(private val sharedPreferences: SharedPreferences) : KeyS
override fun getInviteSelfPublicKey(tag: String): String? {
return sharedPreferences.getString(tag, null)
}

// Added With Chat SDK
override fun setInviteSelfPublicKey(tag: String, key: Key) {
sharedPreferences.edit().putString(tag, key.keyAsHex).apply()

}

// Added With Chat SDK
override fun getPublicKey(tag: String): String {
return sharedPreferences.getString(tag, String.Empty) ?: String.Empty
}

// Added With Chat SDK
override fun setPublicKey(tag: String, publicKey: PublicKey) {
sharedPreferences.edit().putString(tag, publicKey.keyAsHex).apply()
}
}
Loading

0 comments on commit 2e6a566

Please sign in to comment.