First idea without changing NIP-44
This commit is contained in:
+112
@@ -0,0 +1,112 @@
|
||||
/**
|
||||
* Copyright (c) 2024 Vitor Pamplona
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.experimental.decoupling
|
||||
|
||||
import com.vitorpamplona.quartz.experimental.decoupling.setup.EncryptionKeyListEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.hexToByteArray
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||
import com.vitorpamplona.quartz.nip44Encryption.Nip44
|
||||
|
||||
class DecoupledCipher {
|
||||
fun innerEncrypt(
|
||||
content: String,
|
||||
privKey: ByteArray,
|
||||
toPublicKey: HexKey,
|
||||
) = Nip44
|
||||
.encrypt(content, privKey, toPublicKey.hexToByteArray())
|
||||
.encodePayload()
|
||||
|
||||
fun innerDecrypt(
|
||||
ciphertext: String,
|
||||
privKey: ByteArray,
|
||||
fromPublicKey: HexKey,
|
||||
) = Nip44.decrypt(
|
||||
payload = ciphertext,
|
||||
privateKey = privKey,
|
||||
pubKey = fromPublicKey.hexToByteArray(),
|
||||
)
|
||||
|
||||
fun encrypt(
|
||||
decryptedContent: String,
|
||||
toPublicKey: HexKey,
|
||||
fromKeyList: EncryptionKeyListEvent,
|
||||
toKeyList: EncryptionKeyListEvent,
|
||||
signer: NostrSigner,
|
||||
onReady: (String) -> Unit,
|
||||
) {
|
||||
val toKeys = toKeyList.keys()
|
||||
val sendToKey = if (toKeys.isEmpty()) toKeyList.pubKey else toKeys.random().pubkey
|
||||
|
||||
val fromKeys = fromKeyList.keys()
|
||||
|
||||
// uses the main key
|
||||
if (fromKeys.isEmpty()) {
|
||||
signer.nip44Encrypt(decryptedContent, sendToKey, onReady)
|
||||
} else {
|
||||
val keyToUse = fromKeys.random()
|
||||
|
||||
EncryptionKeyCache.getOrLoad(
|
||||
deriveFromPubKey = signer.pubKey,
|
||||
nonce = keyToUse.nonce,
|
||||
load = { onLoaded ->
|
||||
signer.deriveKey(keyToUse.nonce) { newPrivKey ->
|
||||
onLoaded(newPrivKey.hexToByteArray())
|
||||
}
|
||||
},
|
||||
) { derivedPrivKey ->
|
||||
onReady(innerEncrypt(decryptedContent, derivedPrivKey, sendToKey))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun decrypt(
|
||||
encryptedContent: String,
|
||||
fromPublicKey: HexKey,
|
||||
toPublicKey: HexKey,
|
||||
fromKeyList: EncryptionKeyListEvent,
|
||||
toEncryptedKeyList: EncryptionKeyListEvent,
|
||||
signer: NostrSigner,
|
||||
onReady: (String) -> Unit,
|
||||
) {
|
||||
val fromKeys = fromKeyList.keys()
|
||||
val sentFromKey = if (fromKeys.isEmpty()) fromKeyList.pubKey else fromKeys.random().pubkey
|
||||
|
||||
val keyToUse = toEncryptedKeyList.keys().firstOrNull { it.pubkey == toPublicKey }
|
||||
|
||||
// uses the main key
|
||||
if (signer.pubKey == toPublicKey) {
|
||||
signer.nip44Decrypt(encryptedContent, sentFromKey, onReady)
|
||||
} else if (keyToUse != null) {
|
||||
EncryptionKeyCache.getOrLoad(
|
||||
deriveFromPubKey = signer.pubKey,
|
||||
nonce = keyToUse.nonce,
|
||||
load = { onLoaded ->
|
||||
signer.deriveKey(keyToUse.nonce) { newPrivKey ->
|
||||
onLoaded(newPrivKey.hexToByteArray())
|
||||
}
|
||||
},
|
||||
) { derivedPrivKey ->
|
||||
innerDecrypt(encryptedContent, derivedPrivKey, sentFromKey)?.let { onReady(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* Copyright (c) 2024 Vitor Pamplona
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.experimental.decoupling
|
||||
|
||||
import android.util.LruCache
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
|
||||
object EncryptionKeyCache {
|
||||
private val sharedNonceKeyCache = LruCache<EncryptionKeyCacheKey, ByteArray>(50)
|
||||
|
||||
private fun idx(
|
||||
key: HexKey,
|
||||
nonce: HexKey,
|
||||
) = EncryptionKeyCacheKey(key, nonce)
|
||||
|
||||
fun put(
|
||||
deriveFromPubKey: HexKey,
|
||||
nonce: HexKey,
|
||||
privKey: ByteArray,
|
||||
) = sharedNonceKeyCache.put(idx(deriveFromPubKey, nonce), privKey)
|
||||
|
||||
fun get(
|
||||
deriveFromPubKey: HexKey,
|
||||
nonce: HexKey,
|
||||
) = sharedNonceKeyCache.get(idx(deriveFromPubKey, nonce))
|
||||
|
||||
inline fun getOrLoad(
|
||||
deriveFromPubKey: HexKey,
|
||||
nonce: HexKey,
|
||||
load: (onLoaded: (privKey: ByteArray) -> Unit) -> Unit,
|
||||
crossinline whenReady: (privKey: ByteArray) -> Unit,
|
||||
) {
|
||||
val cachedPrivKey = get(deriveFromPubKey, nonce)
|
||||
if (cachedPrivKey != null) {
|
||||
whenReady(cachedPrivKey)
|
||||
return
|
||||
}
|
||||
|
||||
load { newPrivKey ->
|
||||
put(deriveFromPubKey, nonce, newPrivKey)
|
||||
whenReady(newPrivKey)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// keeps a cache per signed-in user
|
||||
private data class EncryptionKeyCacheKey(
|
||||
val pubkey: HexKey,
|
||||
val nonce: HexKey,
|
||||
)
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* Copyright (c) 2024 Vitor Pamplona
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.experimental.decoupling
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair
|
||||
import com.vitorpamplona.quartz.nip44Encryption.crypto.Hkdf
|
||||
import com.vitorpamplona.quartz.utils.sha256.sha256
|
||||
|
||||
class EncryptionKeyDerivation {
|
||||
companion object {
|
||||
private val saltPrefix = "nip44kd".toByteArray(Charsets.UTF_8)
|
||||
|
||||
fun derivePrivateKey(
|
||||
privKey: ByteArray,
|
||||
nonce: ByteArray?,
|
||||
): ByteArray {
|
||||
if (nonce == null) {
|
||||
return privKey
|
||||
}
|
||||
return sha256(Hkdf().extract(privKey, saltPrefix + nonce))
|
||||
}
|
||||
|
||||
fun deriveKeyPair(
|
||||
privKey: ByteArray,
|
||||
nonce: ByteArray?,
|
||||
): KeyPair = KeyPair(privKey = derivePrivateKey(privKey, nonce))
|
||||
}
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* Copyright (c) 2024 Vitor Pamplona
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.experimental.decoupling.setup
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.experimental.decoupling.setup.tags.KeyTag
|
||||
import com.vitorpamplona.quartz.nip01Core.core.BaseAddressableEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.eventUpdate
|
||||
import com.vitorpamplona.quartz.nip31Alts.alt
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
|
||||
@Immutable
|
||||
class EncryptionKeyListEvent(
|
||||
id: HexKey,
|
||||
pubKey: HexKey,
|
||||
createdAt: Long,
|
||||
tags: Array<Array<String>>,
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : BaseAddressableEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
fun keys() = tags.mapNotNull(KeyTag::parse)
|
||||
|
||||
companion object {
|
||||
const val KIND = 10044
|
||||
const val ALT = "Encryption keys"
|
||||
|
||||
fun add(
|
||||
key: KeyTag,
|
||||
currentEvent: EncryptionKeyListEvent,
|
||||
createdAt: Long = TimeUtils.now(),
|
||||
initializer: TagArrayBuilder<EncryptionKeyListEvent>.() -> Unit = {},
|
||||
) = eventUpdate(currentEvent, createdAt) {
|
||||
alt(ALT)
|
||||
key(key)
|
||||
initializer()
|
||||
}
|
||||
|
||||
fun remove(
|
||||
key: KeyTag,
|
||||
currentEvent: EncryptionKeyListEvent,
|
||||
createdAt: Long = TimeUtils.now(),
|
||||
initializer: TagArrayBuilder<EncryptionKeyListEvent>.() -> Unit = {},
|
||||
) = eventUpdate(currentEvent, createdAt) {
|
||||
alt(ALT)
|
||||
removeIf(KeyTag::isSameKey, key.toTagArray())
|
||||
initializer()
|
||||
}
|
||||
|
||||
fun build(
|
||||
keys: List<KeyTag>,
|
||||
createdAt: Long = TimeUtils.now(),
|
||||
initializer: TagArrayBuilder<EncryptionKeyListEvent>.() -> Unit = {},
|
||||
) = eventTemplate(KIND, "", createdAt) {
|
||||
alt(ALT)
|
||||
keys(keys)
|
||||
initializer()
|
||||
}
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* Copyright (c) 2024 Vitor Pamplona
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.experimental.decoupling.setup
|
||||
|
||||
import com.vitorpamplona.quartz.experimental.decoupling.setup.tags.KeyTag
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||
|
||||
fun TagArrayBuilder<EncryptionKeyListEvent>.key(
|
||||
key: HexKey,
|
||||
nonce: HexKey,
|
||||
) = add(KeyTag.assemble(key, nonce))
|
||||
|
||||
fun TagArrayBuilder<EncryptionKeyListEvent>.key(key: KeyTag) = add(key.toTagArray())
|
||||
|
||||
fun TagArrayBuilder<EncryptionKeyListEvent>.keys(keys: List<KeyTag>) = addAll(keys.map { it.toTagArray() })
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* Copyright (c) 2024 Vitor Pamplona
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.experimental.decoupling.setup.tags
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.has
|
||||
import com.vitorpamplona.quartz.utils.ensure
|
||||
|
||||
class KeyTag(
|
||||
val pubkey: HexKey,
|
||||
val nonce: HexKey,
|
||||
) {
|
||||
fun toTagArray() = assemble(pubkey, nonce)
|
||||
|
||||
companion object {
|
||||
const val TAG_NAME = "n"
|
||||
|
||||
fun isSameKey(
|
||||
tag1: Array<String>,
|
||||
tag2: Array<String>,
|
||||
): Boolean {
|
||||
ensure(tag1.has(1)) { return false }
|
||||
ensure(tag2.has(1)) { return false }
|
||||
ensure(tag1[0] == tag2[0]) { return false }
|
||||
ensure(tag1[1] == tag2[1]) { return false }
|
||||
return true
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun parse(tag: Array<String>): KeyTag? {
|
||||
ensure(tag.has(2)) { return null }
|
||||
ensure(tag[0] == TAG_NAME) { return null }
|
||||
ensure(tag[1].isNotEmpty()) { return null }
|
||||
ensure(tag[2].isNotEmpty()) { return null }
|
||||
return KeyTag(tag[1], tag[2])
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun assemble(
|
||||
key: HexKey,
|
||||
nonce: HexKey,
|
||||
) = arrayOf(TAG_NAME, key, nonce)
|
||||
}
|
||||
}
|
||||
@@ -73,6 +73,11 @@ abstract class NostrSigner(
|
||||
onReady: (LnZapPrivateEvent) -> Unit,
|
||||
)
|
||||
|
||||
abstract fun deriveKey(
|
||||
nonce: HexKey,
|
||||
onReady: (HexKey) -> Unit,
|
||||
)
|
||||
|
||||
fun decrypt(
|
||||
encryptedContent: String,
|
||||
fromPublicKey: HexKey,
|
||||
|
||||
@@ -80,4 +80,11 @@ class NostrSignerInternal(
|
||||
) {
|
||||
signerSync.decryptZapEvent(event)?.let { onReady(it) }
|
||||
}
|
||||
|
||||
override fun deriveKey(
|
||||
nonce: HexKey,
|
||||
onReady: (HexKey) -> Unit,
|
||||
) {
|
||||
signerSync.deriveKey(nonce)?.let { onReady(it) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
package com.vitorpamplona.quartz.nip01Core.signers
|
||||
|
||||
import android.util.Log
|
||||
import com.vitorpamplona.quartz.experimental.decoupling.EncryptionKeyDerivation
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.hexToByteArray
|
||||
@@ -128,4 +129,10 @@ class NostrSignerSync(
|
||||
}
|
||||
|
||||
fun decryptZapEvent(event: LnZapRequestEvent): LnZapPrivateEvent? = PrivateZapRequestBuilder().decryptZapEvent(event, this)
|
||||
|
||||
fun deriveKey(nonce: HexKey): HexKey? {
|
||||
if (keyPair.privKey == null) return null
|
||||
|
||||
return EncryptionKeyDerivation.derivePrivateKey(keyPair.privKey, nonce.hexToByteArray()).toHexKey()
|
||||
}
|
||||
}
|
||||
|
||||
+34
@@ -46,6 +46,7 @@ enum class SignerType {
|
||||
NIP44_DECRYPT,
|
||||
GET_PUBLIC_KEY,
|
||||
DECRYPT_ZAP_EVENT,
|
||||
DERIVE_KEY,
|
||||
}
|
||||
|
||||
class Permission(
|
||||
@@ -219,6 +220,7 @@ class ExternalSignerLauncher(
|
||||
SignerType.NIP44_DECRYPT -> "nip44_decrypt"
|
||||
SignerType.GET_PUBLIC_KEY -> "get_public_key"
|
||||
SignerType.DECRYPT_ZAP_EVENT -> "decrypt_zap_event"
|
||||
SignerType.DERIVE_KEY -> "derive_key"
|
||||
}
|
||||
intent.putExtra("type", signerType)
|
||||
intent.putExtra("pubKey", pubKey)
|
||||
@@ -318,6 +320,15 @@ class ExternalSignerLauncher(
|
||||
return kotlin.Result.success(null)
|
||||
}
|
||||
|
||||
fun hashCodeFields(
|
||||
str1: String,
|
||||
onReady: (String) -> Unit,
|
||||
): Int {
|
||||
var result = str1.hashCode()
|
||||
result = 31 * result + onReady.hashCode()
|
||||
return result
|
||||
}
|
||||
|
||||
fun hashCodeFields(
|
||||
str1: String,
|
||||
str2: String,
|
||||
@@ -398,4 +409,27 @@ class ExternalSignerLauncher(
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fun deriveKey(
|
||||
nonce: HexKey,
|
||||
signerType: SignerType = SignerType.DERIVE_KEY,
|
||||
onReady: (String) -> Unit,
|
||||
) {
|
||||
getDataFromResolver(signerType, arrayOf(nonce)).fold(
|
||||
onFailure = { },
|
||||
onSuccess = {
|
||||
if (it == null) {
|
||||
openSignerApp(
|
||||
nonce,
|
||||
signerType,
|
||||
"",
|
||||
hashCodeFields(nonce, onReady).toString(),
|
||||
onReady,
|
||||
)
|
||||
} else {
|
||||
onReady(it)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+11
@@ -133,6 +133,17 @@ class NostrSignerExternal(
|
||||
)
|
||||
}
|
||||
|
||||
override fun deriveKey(
|
||||
nonce: HexKey,
|
||||
onReady: (HexKey) -> Unit,
|
||||
) {
|
||||
launcher.deriveKey(
|
||||
nonce,
|
||||
SignerType.DERIVE_KEY,
|
||||
onReady,
|
||||
)
|
||||
}
|
||||
|
||||
override fun decryptZapEvent(
|
||||
event: LnZapRequestEvent,
|
||||
onReady: (LnZapPrivateEvent) -> Unit,
|
||||
|
||||
Reference in New Issue
Block a user