Skip to content

Commit

Permalink
Merge pull request #7 from KoalaSat/integrate-amber
Browse files Browse the repository at this point in the history
Integrate Amber
  • Loading branch information
KoalaSat authored Oct 24, 2024
2 parents 839d021 + 2230807 commit 1e38ce6
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 34 deletions.
1 change: 1 addition & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ dependencies {
implementation(libs.androidx.lifecycle.livedata.ktx)
implementation(libs.androidx.lifecycle.viewmodel.ktx)
implementation(libs.androidx.navigation.fragment.ktx)
implementation(libs.androidx.activity.ktx)
implementation(libs.lifecycle.runtime.compose)
implementation(libs.lifecycle.viewmodel.compose)
implementation(libs.lifecycle.runtime.ktx)
Expand Down
47 changes: 46 additions & 1 deletion app/src/main/java/com/koalasat/pokey/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package com.koalasat.pokey

import android.Manifest
import android.app.Activity
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
Expand All @@ -14,6 +17,11 @@ import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController
import com.google.android.material.bottomnavigation.BottomNavigationView
import com.koalasat.pokey.databinding.ActivityMainBinding
import com.koalasat.pokey.models.EncryptedStorage
import com.vitorpamplona.quartz.signers.ExternalSignerLauncher
import com.vitorpamplona.quartz.signers.SignerType
import java.util.UUID
import kotlin.coroutines.cancellation.CancellationException

class MainActivity : AppCompatActivity() {
private val requestCodePostNotifications: Int = 1
Expand All @@ -22,6 +30,8 @@ class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

EncryptedStorage.init(this)

binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)

Expand Down Expand Up @@ -52,6 +62,8 @@ class MainActivity : AppCompatActivity() {
requestCodePostNotifications,
)
}

if (EncryptedStorage.pubKey.value.isNullOrEmpty()) connectExternalSigner()
}

override fun onRequestPermissionsResult(
Expand All @@ -64,9 +76,42 @@ class MainActivity : AppCompatActivity() {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission granted
} else {
// Permission denied, handle accordingly
Toast.makeText(applicationContext, getString(R.string.permissions_required), Toast.LENGTH_SHORT).show()
}
}
}

private fun connectExternalSigner() {
val id = UUID.randomUUID().toString()
val externalSignerLauncher = ExternalSignerLauncher("", signerPackageName = "")

val nostrSignerLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode != Activity.RESULT_OK) {
Log.e("Pokey", "ExternalSigner result error: ${result.resultCode}")
} else {
result.data?.let { externalSignerLauncher.newResult(it) }
}
}
externalSignerLauncher.registerLauncher(
launcher = {
try {
nostrSignerLauncher.launch(it) // This can remain if you still need to launch it
} catch (e: Exception) {
if (e is CancellationException) throw e
Log.e("Pokey", "Error opening Signer app", e)
}
},
contentResolver = { Pokey.getInstance().contentResolverFn() },
)
externalSignerLauncher.openSignerApp(
"",
SignerType.GET_PUBLIC_KEY,
"",
id,
) { result ->
val split = result.split("-")
val pubkey = split.first()
if (split.first().isNotEmpty()) EncryptedStorage.updatePubKey(pubkey)
}
}
}
3 changes: 3 additions & 0 deletions app/src/main/java/com/koalasat/pokey/Pokey.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.koalasat.pokey

import android.app.Application
import android.content.ContentResolver
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
Expand Down Expand Up @@ -47,6 +48,8 @@ class Pokey : Application() {
saveForegroundServicePreference(this, false)
}

fun contentResolverFn(): ContentResolver = contentResolver

companion object {
private val _isEnabled = MutableLiveData(false)
val isEnabled: LiveData<Boolean> get() = _isEnabled
Expand Down
21 changes: 16 additions & 5 deletions app/src/main/java/com/koalasat/pokey/models/EncryptedStorage.kt
Original file line number Diff line number Diff line change
@@ -1,30 +1,41 @@
package com.koalasat.pokey.models

import android.content.Context
import android.content.SharedPreferences
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKey
import com.koalasat.pokey.Pokey

object PrefKeys {
const val NOSTR_PUBKEY = "nostr_pubkey"
const val NOSTR_RELAYS = "nostr_relays"
}

object EncryptedStorage {
private const val PREFERENCES_NAME = "secret_keeper"

fun preferences(): EncryptedSharedPreferences {
val context = Pokey.getInstance()
private lateinit var sharedPreferences: SharedPreferences

private val _pubKey = MutableLiveData<String>()
val pubKey: LiveData<String> get() = _pubKey

fun init(context: Context) {
val masterKey: MasterKey =
MasterKey.Builder(context, MasterKey.DEFAULT_MASTER_KEY_ALIAS)
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
.build()

return EncryptedSharedPreferences.create(
sharedPreferences = EncryptedSharedPreferences.create(
context,
PREFERENCES_NAME,
masterKey,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM,
) as EncryptedSharedPreferences
}

fun updatePubKey(newValue: String) {
sharedPreferences.edit().putString(PrefKeys.NOSTR_PUBKEY, newValue).apply()
_pubKey.value = newValue
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ import com.koalasat.pokey.R
import com.koalasat.pokey.database.AppDatabase
import com.koalasat.pokey.database.NotificationEntity
import com.koalasat.pokey.database.RelayEntity
import com.koalasat.pokey.models.EncryptedStorage.preferences
import com.koalasat.pokey.models.PrefKeys
import com.koalasat.pokey.models.EncryptedStorage
import com.vitorpamplona.ammolite.relays.COMMON_FEED_TYPES
import com.vitorpamplona.ammolite.relays.Client
import com.vitorpamplona.ammolite.relays.EVENT_FINDER_TYPES
Expand Down Expand Up @@ -332,7 +331,7 @@ class NotificationsService : Service() {

var title = ""
var text = ""
val pubKey = preferences().getString(PrefKeys.NOSTR_PUBKEY, "")
val pubKey = EncryptedStorage.pubKey

if (event.kind == 1) {
title = if (event.content().contains("nostr:$pubKey")) {
Expand Down Expand Up @@ -366,16 +365,16 @@ class NotificationsService : Service() {

private fun displayNoteNotification(title: String, text: String, event: Event) {
val deepLinkIntent = Intent(Intent.ACTION_VIEW).apply {
val nPub = Nip19Bech32.parseComponents(
"npub",
event.pubKey,
null,
)

if (nPub != null) {
Log.d("Pokey", "nostr:${nPub.nip19raw}")
data = Uri.parse("nostr:${nPub.nip19raw}")
}
// val nPub = Nip19Bech32.parseComponents(
// "npub",
// event.pubKey,
// null,
// )

// if (nPub != null) {
// data = Uri.parse("nostr:${nPub.nip19raw}")
// }
data = Uri.parse("nostr:")
}
val pendingIntent = PendingIntent.getActivity(
this@NotificationsService,
Expand All @@ -402,7 +401,7 @@ class NotificationsService : Service() {
}

private fun getHexKey(): String {
val pubKey = preferences().getString(PrefKeys.NOSTR_PUBKEY, "").toString()
val pubKey = EncryptedStorage.pubKey.value
var hexKey = ""
val parseReturn = uriToRoute(pubKey)
when (val parsed = parseReturn?.entity) {
Expand Down
28 changes: 14 additions & 14 deletions app/src/main/java/com/koalasat/pokey/ui/home/HomeViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,29 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.koalasat.pokey.Pokey
import com.koalasat.pokey.models.EncryptedStorage.preferences
import com.koalasat.pokey.models.PrefKeys
import com.koalasat.pokey.models.EncryptedStorage
import com.vitorpamplona.quartz.encoders.Nip19Bech32
import com.vitorpamplona.quartz.encoders.Nip19Bech32.uriToRoute

class HomeViewModel : ViewModel() {
private val _npubInput = MutableLiveData<String>().apply {
value = preferences().getString(PrefKeys.NOSTR_PUBKEY, "").toString()
}
private val _npubInput = MutableLiveData<String>()
val npubInput: LiveData<String> get() = _npubInput

private val _serviceStart = MutableLiveData<Boolean>().apply {
value = Pokey.isEnabled.value
}
private val _serviceStart = MutableLiveData<Boolean>()
val serviceStart: LiveData<Boolean> get() = _serviceStart

private val _validationResult = MutableLiveData<Boolean>().apply {
value = preferences().getString(PrefKeys.NOSTR_PUBKEY, "")?.isNotEmpty()
}
private val _validationResult = MutableLiveData<Boolean>()
val validationResult: LiveData<Boolean> get() = _validationResult

init {
_npubInput.value = EncryptedStorage.pubKey.value
_serviceStart.value = Pokey.isEnabled.value
_validationResult.value = EncryptedStorage.pubKey.value?.isNotEmpty()
EncryptedStorage.pubKey.observeForever { text ->
_npubInput.value = text
}
}

fun updateServiceStart(value: Boolean) {
if (value) {
Pokey.getInstance().startService()
Expand All @@ -38,9 +40,7 @@ class HomeViewModel : ViewModel() {
_npubInput.value = text
validateNpubInput()
if (_validationResult.value == true) {
preferences().edit().apply {
putString(PrefKeys.NOSTR_PUBKEY, text)
}.apply()
EncryptedStorage.updatePubKey(text)
}
}

Expand Down
1 change: 1 addition & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ ksp = "2.0.20-1.0.24"
ktlint = "12.1.1"

[libraries]
androidx-activity-ktx = { module = "androidx.activity:activity-ktx" }
androidx-compiler = { module = "androidx.compose.compiler:compiler", version.ref = "compiler" }
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
junit = { group = "junit", name = "junit", version.ref = "junit" }
Expand Down

0 comments on commit 1e38ce6

Please sign in to comment.