-
Notifications
You must be signed in to change notification settings - Fork 1
/
ExternalSignerHandler.kt
71 lines (65 loc) · 2.57 KB
/
ExternalSignerHandler.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package com.dluvian.voyage.core
import android.content.Intent
import android.net.Uri
import androidx.activity.result.ActivityResult
import androidx.core.app.ActivityOptionsCompat
import kotlinx.coroutines.channels.Channel
import rust.nostr.protocol.Event
import rust.nostr.protocol.UnsignedEvent
private const val PERMISSIONS = """
[
{"type":"get_public_key"},
{"type":"sign_event","kind":0},
{"type":"sign_event","kind":1},
{"type":"sign_event","kind":3},
{"type":"sign_event","kind":5},
{"type":"sign_event","kind":6},
{"type":"sign_event","kind":7},
{"type":"sign_event","kind":16},
{"type":"sign_event","kind":10000},
{"type":"sign_event","kind":10002},
{"type":"sign_event","kind":10003},
{"type":"sign_event","kind":10004},
{"type":"sign_event","kind":10006},
{"type":"sign_event","kind":10015},
{"type":"sign_event","kind":22242}
]
"""
class ExternalSignerHandler {
private val signatureChannel = Channel<String?>()
fun requestExternalAccount(reqAccountLauncher: SignerLauncher): Throwable? {
return runCatching {
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("nostrsigner:"))
intent.putExtra("permissions", PERMISSIONS)
intent.putExtra("type", "get_public_key")
reqAccountLauncher.launch(intent)
}.exceptionOrNull()
}
suspend fun sign(
signerLauncher: SignerLauncher,
unsignedEvent: UnsignedEvent,
packageName: String
): Result<Event> {
val err = runCatching {
val intent = Intent(
Intent.ACTION_VIEW, Uri.parse("nostrsigner:${unsignedEvent.asJson()}")
)
intent.`package` = packageName
intent.putExtra("type", "sign_event")
intent.putExtra("id", unsignedEvent.id()?.toHex())
intent.putExtra("current_user", unsignedEvent.author().toBech32())
signerLauncher.launch(
input = intent,
options = ActivityOptionsCompat.makeBasic()
)
}.exceptionOrNull()
if (err != null) return Result.failure(err)
val signature = signatureChannel.receive()
return if (signature == null) Result.failure(IllegalStateException("Failed to retrieve signature"))
else Result.success(unsignedEvent.addSignature(sig = signature))
}
suspend fun processExternalSignature(result: ActivityResult) {
val signature = result.data?.getStringExtra("signature")
signatureChannel.send(signature)
}
}