Skip to content

Commit

Permalink
improve handling concurrent threaded communication
Browse files Browse the repository at this point in the history
  • Loading branch information
elefantel committed Sep 11, 2024
1 parent 79949ff commit d153d45
Show file tree
Hide file tree
Showing 7 changed files with 20 additions and 19 deletions.
1 change: 0 additions & 1 deletion metamask-android-sdk/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.9.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.test.ext:junit-ktx:1.1.5'
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.6.1"

testImplementation 'junit:junit:4.13.2'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ class EthereumTests {
private fun findRequestIdForAccountRequest(method: EthereumMethod): String {
return communicationClient.submittedRequests.entries.find {
it.value.request.method == method.value
}?.key ?: throw IllegalStateException("No account request found")
}?.key ?: ""
}

private fun prepareCommunicationClient() {
Expand Down
13 changes: 13 additions & 0 deletions nativesdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,19 @@ The MetaMask Android SDK Native Module is a Kotlin [Android Native Module](https

This module handles encrypted communication between the dapp and MetaMask and then relays the messages over to the Android SDK communication layer implemented in React Native in the wallet. The wallet calls the Native Module via NativeModules - an API that enables react-native code to call native Kotlin primitives.

## Compiling
To compile the nativesdk as a `.aar` file, you need to modify the project's `settings.gradle` file to have the nativesdk as a standalone module to include to the project:
```
include ':app'
include ':nativesdk'
include ':metamask-android-sdk'
```
Then run
```
./gradlew assembleDebug
```
The output file will be located in `nativesdk/build/outputs/aar`. This nativesdk library is then embedded in the MetaMask mobile in the path `android/libs/nativesdk.aar`. It becomes the server-side component of the AIDL communication mechanism described below in the Architecture section.

## Architecture
The client SDK communicates with the server SDK (Android Native Module) via IPC implemented using AIDL.

Expand Down
3 changes: 1 addition & 2 deletions nativesdk/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,12 @@ android {
dependencies {

compileOnly(files("libs/ecies.aar"))
implementation("com.facebook.react:react-native:+")
implementation("com.facebook.react:react-android:0.73.3")
implementation("androidx.core:core-ktx:1.7.0")
implementation ("com.squareup.okhttp3:okhttp:4.9.2")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.0")
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("com.google.android.material:material:1.9.0")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
}
Original file line number Diff line number Diff line change
Expand Up @@ -97,15 +97,6 @@ class CommunicationClient(reactContext: ReactApplicationContext) : ReactContextB
connectionStatusManager.onMetaMaskBroadcastUnregistered()
}

override fun invalidate() {
super.invalidate()
Logger.log("CommunicationClient:: invalidate - app terminated")

if (!didPerformTearDown) {
destroyActiveConnections()
}
}

override fun onCatalystInstanceDestroy() {
super.onCatalystInstanceDestroy()
Logger.log("CommunicationClient:: onCatalystInstanceDestroy - app terminating")
Expand Down Expand Up @@ -142,13 +133,14 @@ class CommunicationClient(reactContext: ReactApplicationContext) : ReactContextB

Logger.log("CommunicationClient:: Binding native module")
val intent = Intent(reactAppContext, MessageService::class.java)
return reactAppContext.bindService(
val success = reactAppContext.bindService(
intent,
serviceConnection,
Context.BIND_IMPORTANT)

// Metamask ready, start sending messages
connectionStatusManager.onMetaMaskReady()
return success
}

@ReactMethod
Expand Down Expand Up @@ -184,7 +176,7 @@ class CommunicationClient(reactContext: ReactApplicationContext) : ReactContextB

if (type == "ready") {
val dataJson = json.optJSONObject("data")
val id = dataJson.optString("id")
val id = dataJson?.optString("id")
val sessionId = SessionManager.getInstance().sessionId

if (id != sessionId) {
Expand Down
4 changes: 1 addition & 3 deletions nativesdk/src/main/java/io/metamask/nativesdk/KeyExchange.kt
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,7 @@ class KeyExchange {

fun resetKeys() {
privateKey = crypto.generatePrivateKey()
privateKey?.let {
publicKey = crypto.publicKey(it)
}
publicKey = crypto.publicKey(privateKey)
setIsKeysExchanged(false)
theirPublicKey = null
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ class MessageService : Service(), MetaMaskConnectionStatusCallback {

Logger.log("MessageService:: $keysExchangedMessage")
val payload = keyExchange.encrypt(keysExchangedMessage)
sendMessage(payload)
sendMessage(message=payload)
}
}

Expand Down

0 comments on commit d153d45

Please sign in to comment.