Skip to content

Commit

Permalink
Merge pull request #30 from reown-com/develop
Browse files Browse the repository at this point in the history
BOM_1.0.3
  • Loading branch information
jakubuid authored Dec 9, 2024
2 parents 07e7313 + a599c27 commit 92bc597
Show file tree
Hide file tree
Showing 14 changed files with 137 additions and 28 deletions.
1 change: 1 addition & 0 deletions .github/workflows/ci_relay.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ jobs:
env:
TEST_RELAY_URL: wss://relay.walletconnect.org
TEST_PROJECT_ID: ${{ secrets.WC_CLOUD_PROJECT_ID }}
TEST_PROJECT_ID2: ${{ secrets.TEST_PROJECT_ID2 }}
NOTIFY_INTEGRATION_TESTS_PROJECT_ID: ${{ secrets.NOTIFY_INTEGRATION_TESTS_PROJECT_ID }}
NOTIFY_INTEGRATION_TESTS_SECRET: ${{ secrets.NOTIFY_INTEGRATION_TESTS_SECRET }}
with:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/ci_scheduled.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ jobs:
env:
TEST_RELAY_URL: wss://relay.walletconnect.org
TEST_PROJECT_ID: ${{ secrets.WC_CLOUD_PROJECT_ID }}
TEST_PROJECT_ID2: ${{ secrets.TEST_PROJECT_ID2 }}
with:
SECRETS_PROPERTIES: ${{ secrets.SECRETS_PROPERTIES }}
uses: ./.github/actions/ci_relay
Expand Down
12 changes: 12 additions & 0 deletions buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,16 @@ dependencies {
implementation("com.google.firebase:firebase-appdistribution-gradle:${libs.versions.firebaseAppDistribution.get()}")

testImplementation("junit:junit:${libs.versions.jUnit.get()}")
}

java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(11))
}
}

tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().configureEach {
kotlinOptions {
jvmTarget = "11"
}
}
16 changes: 8 additions & 8 deletions buildSrc/src/main/kotlin/Versions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ const val KEY_PUBLISH_ARTIFACT_ID = "PUBLISH_ARTIFACT_ID"
const val KEY_SDK_NAME = "SDK_NAME"

//Latest versions
const val BOM_VERSION = "1.0.2"
const val FOUNDATION_VERSION = "1.0.2"
const val CORE_VERSION = "1.0.2"
const val SIGN_VERSION = "1.0.2"
const val NOTIFY_VERSION = "1.0.2"
const val WALLETKIT_VERSION = "1.0.2"
const val APPKIT_VERSION = "1.0.2"
const val MODAL_CORE_VERSION = "1.0.2"
const val BOM_VERSION = "1.0.3"
const val FOUNDATION_VERSION = "1.0.3"
const val CORE_VERSION = "1.0.3"
const val SIGN_VERSION = "1.0.3"
const val NOTIFY_VERSION = "1.0.3"
const val WALLETKIT_VERSION = "1.0.3"
const val APPKIT_VERSION = "1.0.3"
const val MODAL_CORE_VERSION = "1.0.3"

//Artifact ids
const val ANDROID_BOM = "android-bom"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ import org.koin.android.ext.koin.androidContext
import org.koin.core.qualifier.named
import org.koin.dsl.module

fun coreStorageModule(storagePrefix: String = String.Empty, bundleId: String) = module {
fun coreStorageModule(storagePrefix: String = String.Empty, packageName: String) = module {

includes(baseStorageModule(storagePrefix, bundleId))
includes(baseStorageModule(storagePrefix, packageName))

single<SqlDriver>(named(AndroidBuildVariantDITags.ANDROID_CORE_DATABASE_DRIVER)) {
AndroidSqliteDriver(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,15 +138,15 @@ class CoreProtocol(private val koinApp: KoinApplication = wcKoinApp) : CoreInter
metaData: Core.Model.AppMetaData,
keyServerUrl: String?
) {
val bundleId: String = application.packageName
val packageName: String = application.packageName
val relayServerUrl = if (serverUrl.isNullOrEmpty()) "wss://relay.walletconnect.org?projectId=$projectId" else serverUrl

with(koinApp) {
androidContext(application)
modules(
module { single { ProjectId(projectId) } },
module { single(named(AndroidCommonDITags.TELEMETRY_ENABLED)) { TelemetryEnabled(telemetryEnabled) } },
coreAndroidNetworkModule(relayServerUrl, connectionType, BuildConfig.SDK_VERSION, networkClientTimeout, bundleId),
coreAndroidNetworkModule(relayServerUrl, connectionType, BuildConfig.SDK_VERSION, networkClientTimeout, packageName),
coreCommonModule(),
coreCryptoModule(),
)
Expand All @@ -156,7 +156,7 @@ class CoreProtocol(private val koinApp: KoinApplication = wcKoinApp) : CoreInter
}

modules(
coreStorageModule(bundleId = bundleId),
coreStorageModule(packageName = packageName),
module { single(named(AndroidCommonDITags.CLIENT_ID)) { requireNotNull(get<SharedPreferences>().getString(KEY_CLIENT_ID, null)) } },
pushModule(),
module { single { relay ?: Relay } },
Expand All @@ -181,7 +181,7 @@ class CoreProtocol(private val koinApp: KoinApplication = wcKoinApp) : CoreInter
keyServerModule(keyServerUrl),
explorerModule(),
appKitModule(),
pulseModule(bundleId)
pulseModule(packageName)
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import org.koin.core.scope.Scope
import org.koin.dsl.module
import com.reown.android.internal.common.scope as wcScope

fun baseStorageModule(storagePrefix: String = String.Empty, bundleId: String) = module {
fun baseStorageModule(storagePrefix: String = String.Empty, packageName: String) = module {
single<ColumnAdapter<List<String>, String>>(named(AndroidCommonDITags.COLUMN_ADAPTER_LIST)) {
object : ColumnAdapter<List<String>, String> {
override fun decode(databaseValue: String): List<String> =
Expand Down Expand Up @@ -128,7 +128,7 @@ fun baseStorageModule(storagePrefix: String = String.Empty, bundleId: String) =

single { PushMessagesRepository(pushMessageQueries = get()) }

single { EventsRepository(eventQueries = get(), bundleId = bundleId, telemetryEnabled = get(named(AndroidCommonDITags.TELEMETRY_ENABLED))) }
single { EventsRepository(eventQueries = get(), bundleId = packageName, telemetryEnabled = get(named(AndroidCommonDITags.TELEMETRY_ENABLED))) }

single { DatabaseConfig(storagePrefix = storagePrefix) }
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,15 @@ internal const val KEY_CLIENT_ID = "clientId"

@Suppress("LocalVariableName")
@JvmSynthetic
fun coreAndroidNetworkModule(serverUrl: String, connectionType: ConnectionType, sdkVersion: String, timeout: NetworkClientTimeout? = null, bundleId: String) = module {
fun coreAndroidNetworkModule(serverUrl: String, connectionType: ConnectionType, sdkVersion: String, timeout: NetworkClientTimeout? = null, packageName: String) = module {
val networkClientTimeout = timeout ?: NetworkClientTimeout.getDefaultTimeout()
factory(named(AndroidCommonDITags.RELAY_URL)) {
val jwt = get<GenerateJwtStoreClientIdUseCase>().invoke(serverUrl)
Uri.parse(serverUrl)
.buildUpon()
.appendQueryParameter("auth", jwt)
.appendQueryParameter("ua", get(named(AndroidCommonDITags.USER_AGENT)))
.appendQueryParameter("packageName", packageName)
.build()
.toString()
}
Expand All @@ -58,7 +59,6 @@ fun coreAndroidNetworkModule(serverUrl: String, connectionType: ConnectionType,
Interceptor { chain ->
val updatedRequest = chain.request().newBuilder()
.addHeader("User-Agent", get(named(AndroidCommonDITags.USER_AGENT)))
.addHeader("Origin", bundleId)
.build()

chain.proceed(updatedRequest)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,9 +178,9 @@ private fun loadSqlCipherLibrary(context: Context) {
}
}

fun coreStorageModule(storagePrefix: String = String.Empty, bundleId: String) = module {
fun coreStorageModule(storagePrefix: String = String.Empty, packageName: String) = module {

includes(baseStorageModule(storagePrefix, bundleId), signingModule())
includes(baseStorageModule(storagePrefix, packageName), signingModule())

single<SqlDriver>(named(AndroidBuildVariantDITags.ANDROID_CORE_DATABASE_DRIVER)) {
AndroidSqliteDriver(
Expand Down
1 change: 1 addition & 0 deletions foundation/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ tasks.withType<Test> {
systemProperty("SDK_VERSION", requireNotNull(project.extra.get(KEY_PUBLISH_VERSION)))
systemProperty("TEST_RELAY_URL", System.getenv("TEST_RELAY_URL"))
systemProperty("TEST_PROJECT_ID", System.getenv("TEST_PROJECT_ID"))
systemProperty("TEST_PROJECT_ID2", System.getenv("TEST_PROJECT_ID2"))
}

dependencies {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import org.koin.core.qualifier.named
import org.koin.dsl.module
import java.util.concurrent.TimeUnit

fun networkModule(serverUrl: String, sdkVersion: String, jwt: String): Module = module {
fun networkModule(serverUrl: String, sdkVersion: String, jwt: String, packageName: String): Module = module {
val DEFAULT_BACKOFF_SECONDS = 5L
val TIMEOUT_TIME = 40000L

Expand Down Expand Up @@ -50,7 +50,7 @@ fun networkModule(serverUrl: String, sdkVersion: String, jwt: String): Module =
single(named(FoundationDITags.SCARLET)) {
Scarlet.Builder()
.backoffStrategy(get<LinearBackoffStrategy>())
.webSocketFactory(get<OkHttpClient>(named(FoundationDITags.OK_HTTP)).newWebSocketFactory("$serverUrl&auth=$jwt"))
.webSocketFactory(get<OkHttpClient>(named(FoundationDITags.OK_HTTP)).newWebSocketFactory("$serverUrl&auth=$jwt&packageName=$packageName"))
.addMessageAdapterFactory(get<MoshiMessageAdapter.Factory>(named(FoundationDITags.MSG_ADAPTER)))
.addStreamAdapterFactory(get<FlowStreamAdapter.Factory>())
.build()
Expand Down
102 changes: 98 additions & 4 deletions foundation/src/test/kotlin/com/reown/foundation/RelayTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,106 @@ sealed class TestState {
@ExperimentalCoroutinesApi
class RelayTest {
private val testProjectId: String = requireNotNull(System.getProperty("TEST_PROJECT_ID"))
private val testProjectId2: String = requireNotNull(System.getProperty("TEST_PROJECT_ID2"))
private val testRelayUrl: String = requireNotNull(System.getProperty("TEST_RELAY_URL"))
private val serverUrl = "$testRelayUrl?projectId=$testProjectId"
private var serverUrl = "$testRelayUrl?projectId=$testProjectId"
private val sdkVersion: String = System.getProperty("SDK_VERSION") + "-relayTest"
private val testJob: CompletableJob = SupervisorJob()
private val testScope: CoroutineScope = CoroutineScope(testJob + Dispatchers.IO)


@ExperimentalTime
@Test
fun `Connect with empty packageName when some packageName is already configured in Cloud - successful connection`() {
val testState = MutableStateFlow<TestState>(TestState.Idle)
val (clientA: RelayInterface, clientB: RelayInterface) = initTwoClients(packageName = "")

//Await connection
val connectionTime = measureTime { awaitConnection(clientA, clientB) }.inWholeMilliseconds
println("Connection time: $connectionTime ms")
testState.compareAndSet(expect = TestState.Idle, update = TestState.Success)

//Lock until is finished or timed out
runBlocking {
val start = System.currentTimeMillis()
// Await test finish or check if timeout occurred
while (testState.value is TestState.Idle && !didTimeout(start, 60000L)) {
delay(10)
}

// Success or fail or idle
when (testState.value) {
is TestState.Success -> return@runBlocking
is TestState.Error -> fail((testState.value as TestState.Error).message)
is TestState.Idle -> fail("Test timeout")
}
}
}

@ExperimentalTime
@Test
fun `Connect with not whitelisted packageName when some packageName is already configured in Cloud - return an error`() {
val testState = MutableStateFlow<TestState>(TestState.Idle)
val (clientA: RelayInterface, clientB: RelayInterface) = initTwoClients(packageName = "com.test.failure")

clientA.eventsFlow.onEach { event ->
when (event) {
is Relay.Model.Event.OnConnectionFailed -> {
if (event.throwable.message?.contains("403") == true) {
testState.compareAndSet(expect = TestState.Idle, update = TestState.Success)
}
}

else -> {}
}
}.launchIn(testScope)

//Lock until is finished or timed out
runBlocking {
val start = System.currentTimeMillis()
// Await test finish or check if timeout occurred
while (testState.value is TestState.Idle && !didTimeout(start, 60000L)) {
delay(10)
}

// Success or fail or idle
when (testState.value) {
is TestState.Success -> return@runBlocking
is TestState.Error -> fail((testState.value as TestState.Error).message)
is TestState.Idle -> fail("Test timeout")
}
}
}

@ExperimentalTime
@Test
fun `Connect with some packageName when no packageName is configured in Cloud - successful connection`() {
serverUrl = "$testRelayUrl?projectId=$testProjectId2"
val testState = MutableStateFlow<TestState>(TestState.Idle)
val (clientA: RelayInterface, clientB: RelayInterface) = initTwoClients(packageName = "com.test")

//Await connection
val connectionTime = measureTime { awaitConnection(clientA, clientB) }.inWholeMilliseconds
println("Connection time: $connectionTime ms")
testState.compareAndSet(expect = TestState.Idle, update = TestState.Success)

//Lock until is finished or timed out
runBlocking {
val start = System.currentTimeMillis()
// Await test finish or check if timeout occurred
while (testState.value is TestState.Idle && !didTimeout(start, 60000L)) {
delay(10)
}

// Success or fail or idle
when (testState.value) {
is TestState.Success -> return@runBlocking
is TestState.Error -> fail((testState.value as TestState.Error).message)
is TestState.Idle -> fail("Test timeout")
}
}
}

@ExperimentalTime
@Test
fun `One client sends unencrypted message, second one receives it`() {
Expand Down Expand Up @@ -152,21 +246,21 @@ class RelayTest {
private fun startLoggingClientEventsFlow(client: RelayInterface, tag: String) =
client.eventsFlow.onEach { println("$tag eventsFlow: $it") }.launchIn(testScope)

private fun initTwoClients(): Pair<RelayInterface, RelayInterface> {
private fun initTwoClients(packageName: String = "com.reown.sample.wallet"): Pair<RelayInterface, RelayInterface> {
val koinAppA: KoinApplication = KoinApplication.init()
.apply { modules(foundationCommonModule(), cryptoModule()) }.also { koinApp ->
val jwt = koinApp.koin.get<ClientIdJwtRepository>().generateJWT(testRelayUrl) { clientId ->
println("ClientA id: $clientId")
}
koinApp.modules(networkModule(serverUrl.addUserAgent(sdkVersion), sdkVersion, jwt))
koinApp.modules(networkModule(serverUrl.addUserAgent(sdkVersion), sdkVersion, jwt, packageName))
}

val koinAppB: KoinApplication = KoinApplication.init()
.apply { modules(foundationCommonModule(), cryptoModule()) }.also { koinApp ->
val jwt = koinApp.koin.get<ClientIdJwtRepository>().generateJWT(testRelayUrl) { clientId ->
println("ClientB id: $clientId")
}
koinApp.modules(networkModule(serverUrl.addUserAgent(sdkVersion), sdkVersion, jwt))
koinApp.modules(networkModule(serverUrl.addUserAgent(sdkVersion), sdkVersion, jwt, packageName))
}

val clientA: BaseRelayClient = koinAppA.koin.get()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,6 @@ internal fun overrideModule(
corePairingModule(pairing, pairingController),
coreCryptoModule(sharedPrefsFile, keyStoreAlias),
coreJsonRpcModule(),
coreAndroidNetworkModule(relayUrl, connectionType, "test_version", bundleId = bundleId)
coreAndroidNetworkModule(relayUrl, connectionType, "test_version", packageName = bundleId)
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ internal fun overrideModule(
coreStorageModule(storagePrefix, bundleId),
corePairingModule(pairing, pairingController),
coreCryptoModule(sharedPrefsFile, keyStoreAlias),
coreAndroidNetworkModule(relayUrl, connectionType, "test_version", bundleId = bundleId),
coreAndroidNetworkModule(relayUrl, connectionType, "test_version", packageName = bundleId),
coreJsonRpcModule()
)
}

0 comments on commit 92bc597

Please sign in to comment.