mirror of
https://github.com/greenart7c3/Amber.git
synced 2026-10-06 03:18:23 +00:00
add support for sending nips as permissions
This commit is contained in:
@@ -8,6 +8,7 @@ import android.net.Uri
|
||||
import com.greenart7c3.nostrsigner.database.HistoryEntity
|
||||
import com.greenart7c3.nostrsigner.models.SignerType
|
||||
import com.greenart7c3.nostrsigner.models.TimeUtils
|
||||
import com.greenart7c3.nostrsigner.models.kindToNip
|
||||
import com.greenart7c3.nostrsigner.service.AmberUtils
|
||||
import com.greenart7c3.nostrsigner.service.IntentUtils
|
||||
import com.vitorpamplona.quartz.crypto.CryptoUtils
|
||||
@@ -127,7 +128,7 @@ class SignerProvider : ContentProvider() {
|
||||
val event = Event.fromJson(json)
|
||||
val currentSelection = selection ?: "0"
|
||||
val database = NostrSigner.getInstance().getDatabase(account.keyPair.pubKey.toNpub())
|
||||
val permission =
|
||||
var permission =
|
||||
database
|
||||
.applicationDao()
|
||||
.getPermission(
|
||||
@@ -135,6 +136,18 @@ class SignerProvider : ContentProvider() {
|
||||
"SIGN_EVENT",
|
||||
event.kind,
|
||||
)
|
||||
if (permission == null) {
|
||||
event.kind.kindToNip()?.let {
|
||||
permission =
|
||||
database
|
||||
.applicationDao()
|
||||
.getPermission(
|
||||
sortOrder ?: packageName,
|
||||
"NIP",
|
||||
it.toInt(),
|
||||
)
|
||||
}
|
||||
}
|
||||
if (currentSelection == "1") {
|
||||
val isRemembered = permission?.acceptable ?: return null
|
||||
if (!isRemembered) {
|
||||
@@ -224,13 +237,33 @@ class SignerProvider : ContentProvider() {
|
||||
val account = LocalPreferences.loadFromEncryptedStorage(context!!, npub) ?: return null
|
||||
val currentSelection = selection ?: "0"
|
||||
val database = NostrSigner.getInstance().getDatabase(account.keyPair.pubKey.toNpub())
|
||||
val permission =
|
||||
var permission =
|
||||
database
|
||||
.applicationDao()
|
||||
.getPermission(
|
||||
sortOrder ?: packageName,
|
||||
uri.toString().replace("content://$appId.", ""),
|
||||
)
|
||||
if (permission == null) {
|
||||
val nip = when (stringType) {
|
||||
"NIP04_DECRYPT" -> 4
|
||||
"NIP44_DECRYPT" -> 44
|
||||
"NIP04_ENCRYPT" -> 4
|
||||
"NIP44_ENCRYPT" -> 44
|
||||
"DECRYPT_ZAP_EVENT" -> null
|
||||
else -> null
|
||||
}
|
||||
nip?.let {
|
||||
permission =
|
||||
database
|
||||
.applicationDao()
|
||||
.getPermission(
|
||||
sortOrder ?: packageName,
|
||||
"NIP",
|
||||
it,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (currentSelection == "1") {
|
||||
val isRemembered = permission?.acceptable ?: return null
|
||||
|
||||
@@ -131,7 +131,159 @@ data class Permission(
|
||||
}
|
||||
}
|
||||
"connect" -> context.getString(R.string.would_like_your_permission_to_read_your_public_key_and_sign_events_on_your_behalf)
|
||||
"nip" -> {
|
||||
when (kind) {
|
||||
1 -> context.getString(R.string.nip_01)
|
||||
2 -> context.getString(R.string.nip_02)
|
||||
3 -> context.getString(R.string.nip_03)
|
||||
4 -> context.getString(R.string.nip_04)
|
||||
5 -> context.getString(R.string.nip_05)
|
||||
6 -> context.getString(R.string.nip_06)
|
||||
7 -> context.getString(R.string.nip_07)
|
||||
8 -> context.getString(R.string.nip_08)
|
||||
9 -> context.getString(R.string.nip_09)
|
||||
10 -> context.getString(R.string.nip_10)
|
||||
11 -> context.getString(R.string.nip_11)
|
||||
13 -> context.getString(R.string.nip_13)
|
||||
14 -> context.getString(R.string.nip_14)
|
||||
15 -> context.getString(R.string.nip_15)
|
||||
17 -> context.getString(R.string.nip_17)
|
||||
18 -> context.getString(R.string.nip_18)
|
||||
19 -> context.getString(R.string.nip_19)
|
||||
21 -> context.getString(R.string.nip_21)
|
||||
23 -> context.getString(R.string.nip_23)
|
||||
24 -> context.getString(R.string.nip_24)
|
||||
25 -> context.getString(R.string.nip_25)
|
||||
26 -> context.getString(R.string.nip_26)
|
||||
27 -> context.getString(R.string.nip_27)
|
||||
28 -> context.getString(R.string.nip_28)
|
||||
29 -> context.getString(R.string.nip_29)
|
||||
30 -> context.getString(R.string.nip_30)
|
||||
31 -> context.getString(R.string.nip_31)
|
||||
32 -> context.getString(R.string.nip_32)
|
||||
34 -> context.getString(R.string.nip_34)
|
||||
35 -> context.getString(R.string.nip_35)
|
||||
36 -> context.getString(R.string.nip_36)
|
||||
38 -> context.getString(R.string.nip_38)
|
||||
39 -> context.getString(R.string.nip_39)
|
||||
40 -> context.getString(R.string.nip_40)
|
||||
42 -> context.getString(R.string.nip_42)
|
||||
44 -> context.getString(R.string.nip_44)
|
||||
45 -> context.getString(R.string.nip_45)
|
||||
46 -> context.getString(R.string.nip_46)
|
||||
47 -> context.getString(R.string.nip_47)
|
||||
48 -> context.getString(R.string.nip_48)
|
||||
49 -> context.getString(R.string.nip_49)
|
||||
50 -> context.getString(R.string.nip_50)
|
||||
51 -> context.getString(R.string.nip_51)
|
||||
52 -> context.getString(R.string.nip_52)
|
||||
53 -> context.getString(R.string.nip_53)
|
||||
54 -> context.getString(R.string.nip_54)
|
||||
55 -> context.getString(R.string.nip_55)
|
||||
56 -> context.getString(R.string.nip_56)
|
||||
57 -> context.getString(R.string.nip_57)
|
||||
58 -> context.getString(R.string.nip_58)
|
||||
59 -> context.getString(R.string.nip_59)
|
||||
65 -> context.getString(R.string.nip_65)
|
||||
70 -> context.getString(R.string.nip_70)
|
||||
71 -> context.getString(R.string.nip_71)
|
||||
72 -> context.getString(R.string.nip_72)
|
||||
75 -> context.getString(R.string.nip_75)
|
||||
78 -> context.getString(R.string.nip_78)
|
||||
84 -> context.getString(R.string.nip_84)
|
||||
89 -> context.getString(R.string.nip_89)
|
||||
90 -> context.getString(R.string.nip_90)
|
||||
92 -> context.getString(R.string.nip_92)
|
||||
94 -> context.getString(R.string.nip_94)
|
||||
96 -> context.getString(R.string.nip_96)
|
||||
98 -> context.getString(R.string.nip_98)
|
||||
99 -> context.getString(R.string.nip_99)
|
||||
else -> context.getString(R.string.nip_kind, kind.toString())
|
||||
}
|
||||
}
|
||||
else -> type
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class KindNip(val kind: IntRange, val nip: String)
|
||||
|
||||
fun Int.kindToNipUrl(): String? =
|
||||
kindsByNip.firstOrNull { it.kind.contains(this) }?.let {
|
||||
return if (it.nip.startsWith("http")) it.nip else "https://github.com/nostr-protocol/nips/blob/master/${it.nip}.md"
|
||||
}
|
||||
|
||||
fun Int.containsNip(): Boolean = kindsByNip.any {
|
||||
val nip = if (this < 10) {
|
||||
this.toString().padStart(2, '0')
|
||||
} else {
|
||||
this.toString()
|
||||
}
|
||||
it.nip.contains(nip)
|
||||
}
|
||||
|
||||
fun Int.kindToNip(): String? = kindsByNip.firstOrNull { it.kind.contains(this) }?.nip
|
||||
|
||||
fun Int.nipToUrl(): String? = kindsByNip.firstOrNull { it.nip.toIntOrNull() == this }
|
||||
?.nip?.let { nip -> if (nip.startsWith("http")) nip else "https://github.com/nostr-protocol/nips/blob/master/$nip.md" }
|
||||
|
||||
val kindsByNip = listOf(
|
||||
KindNip(0..2, "01"),
|
||||
KindNip(3..3, "02"),
|
||||
KindNip(4..4, "04"),
|
||||
KindNip(5..5, "09"),
|
||||
KindNip(6..6, "18"),
|
||||
KindNip(16..16, "18"),
|
||||
KindNip(7..7, "25"),
|
||||
KindNip(8..8, "58"),
|
||||
KindNip(9..12, "29"),
|
||||
KindNip(13..13, "59"),
|
||||
KindNip(14..14, "17"),
|
||||
KindNip(40..44, "28"),
|
||||
KindNip(818..818, "54"),
|
||||
KindNip(1021..1022, "15"),
|
||||
KindNip(1040..1040, "03"),
|
||||
KindNip(1059..1059, "59"),
|
||||
KindNip(1063..1063, "94"),
|
||||
KindNip(1311..1311, "53"),
|
||||
KindNip(1617..1633, "34"),
|
||||
KindNip(1971..1971, "https://github.com/nostrocket/NIPS/blob/main/Problems.md"),
|
||||
KindNip(1984..1985, "56"),
|
||||
KindNip(2003..2004, "35"),
|
||||
KindNip(2022..2022, "https://gitlab.com/1440000bytes/joinstr/-/blob/main/NIP.md"),
|
||||
KindNip(4550..4550, "72"),
|
||||
KindNip(5000..5999, "90"),
|
||||
KindNip(6000..6999, "90"),
|
||||
KindNip(7000..7000, "90"),
|
||||
KindNip(9000..9030, "29"),
|
||||
KindNip(9041..9041, "75"),
|
||||
KindNip(9734..9735, "57"),
|
||||
KindNip(9802..9802, "84"),
|
||||
KindNip(10009..10009, "29"),
|
||||
KindNip(10000..10030, "51"),
|
||||
KindNip(10050..10050, "17"),
|
||||
KindNip(10096..10096, "96"),
|
||||
KindNip(13194..13194, "47"),
|
||||
KindNip(23194..23195, "47"),
|
||||
KindNip(21000..21000, "https://github.com/shocknet/Lightning.Pub/blob/master/proto/autogenerated/client.md"),
|
||||
KindNip(22242..22242, "42"),
|
||||
KindNip(24133..24133, "46"),
|
||||
KindNip(27235..27235, "98"),
|
||||
KindNip(30000..30005, "51"),
|
||||
KindNip(30008..30009, "58"),
|
||||
KindNip(30017..30020, "15"),
|
||||
KindNip(30023..30024, "23"),
|
||||
KindNip(30078..30078, "78"),
|
||||
KindNip(30311..30311, "53"),
|
||||
KindNip(30315..30315, "38"),
|
||||
KindNip(30402..30403, "99"),
|
||||
KindNip(30617..30617, "34"),
|
||||
KindNip(30818..30819, "54"),
|
||||
KindNip(31890..31890, "https://wikifreedia.xyz/cip-01/97c70a44366a6535c1"),
|
||||
KindNip(31922..31925, "52"),
|
||||
KindNip(31989..31990, "89"),
|
||||
KindNip(34235..34237, "71"),
|
||||
KindNip(34550..34550, "72"),
|
||||
KindNip(39000..39009, "29"),
|
||||
KindNip(31234..31234, "https://github.com/nostr-protocol/nips/pull/1124"),
|
||||
)
|
||||
|
||||
@@ -11,6 +11,7 @@ import com.greenart7c3.nostrsigner.models.BunkerRequest
|
||||
import com.greenart7c3.nostrsigner.models.BunkerResponse
|
||||
import com.greenart7c3.nostrsigner.models.IntentData
|
||||
import com.greenart7c3.nostrsigner.models.SignerType
|
||||
import com.greenart7c3.nostrsigner.models.kindToNip
|
||||
import com.vitorpamplona.ammolite.relays.RelaySetupInfo
|
||||
import com.vitorpamplona.quartz.crypto.CryptoUtils
|
||||
import com.vitorpamplona.quartz.encoders.HexKey
|
||||
@@ -169,7 +170,11 @@ object AmberUtils {
|
||||
permissions = mutableListOf(),
|
||||
)
|
||||
|
||||
if (application.permissions.none { it.type == intentData.type.toString() && it.kind == kind }) {
|
||||
val noPermission = application.permissions.none {
|
||||
val nip = it.kind?.kindToNip()?.toIntOrNull()
|
||||
(it.type == intentData.type.toString() && it.kind == kind) || (nip != null && it.type == "NIP" && it.kind == nip)
|
||||
}
|
||||
if (noPermission) {
|
||||
application.permissions.add(
|
||||
ApplicationPermissionsEntity(
|
||||
null,
|
||||
|
||||
@@ -30,6 +30,7 @@ import com.greenart7c3.nostrsigner.models.Permission
|
||||
import com.greenart7c3.nostrsigner.models.ReturnType
|
||||
import com.greenart7c3.nostrsigner.models.SignerType
|
||||
import com.greenart7c3.nostrsigner.models.TimeUtils
|
||||
import com.greenart7c3.nostrsigner.models.containsNip
|
||||
import com.greenart7c3.nostrsigner.relays.AmberListenerSingleton
|
||||
import com.greenart7c3.nostrsigner.service.model.AmberEvent
|
||||
import com.greenart7c3.nostrsigner.ui.NotificationType
|
||||
@@ -433,6 +434,9 @@ object IntentUtils {
|
||||
}
|
||||
}
|
||||
|
||||
permissions.removeIf { it.kind == null && (it.type == "sign_event" || it.type == "nip") }
|
||||
permissions.removeIf { it.type == "nip" && (it.kind == null || !it.kind.containsNip()) }
|
||||
|
||||
when (type) {
|
||||
SignerType.CONNECT -> {
|
||||
onReady(
|
||||
@@ -611,7 +615,8 @@ object IntentUtils {
|
||||
permissions?.forEach {
|
||||
it.checked = true
|
||||
}
|
||||
permissions?.removeIf { it.kind == null && it.type == "sign_event" }
|
||||
permissions?.removeIf { it.kind == null && (it.type == "sign_event" || it.type == "nip") }
|
||||
permissions?.removeIf { it.type == "nip" && (it.kind == null || !it.kind.containsNip()) }
|
||||
|
||||
when (type) {
|
||||
SignerType.SIGN_EVENT -> {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.greenart7c3.nostrsigner.ui
|
||||
|
||||
import android.widget.Toast
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
@@ -13,6 +14,7 @@ import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.ContentPaste
|
||||
import androidx.compose.material.icons.filled.Delete
|
||||
import androidx.compose.material.icons.filled.Info
|
||||
import androidx.compose.material.icons.filled.QrCode
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Icon
|
||||
@@ -33,6 +35,7 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalClipboardManager
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalUriHandler
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
@@ -42,6 +45,7 @@ import androidx.compose.ui.text.intl.Locale
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.text.toLowerCase
|
||||
import androidx.compose.ui.text.toUpperCase
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.navigation.NavController
|
||||
@@ -54,6 +58,8 @@ import com.greenart7c3.nostrsigner.database.ApplicationPermissionsEntity
|
||||
import com.greenart7c3.nostrsigner.database.ApplicationWithPermissions
|
||||
import com.greenart7c3.nostrsigner.models.Account
|
||||
import com.greenart7c3.nostrsigner.models.Permission
|
||||
import com.greenart7c3.nostrsigner.models.kindToNipUrl
|
||||
import com.greenart7c3.nostrsigner.models.nipToUrl
|
||||
import com.greenart7c3.nostrsigner.ui.actions.ActivityDialog
|
||||
import com.greenart7c3.nostrsigner.ui.actions.DeleteDialog
|
||||
import com.greenart7c3.nostrsigner.ui.actions.EditRelaysDialog
|
||||
@@ -73,6 +79,7 @@ fun EditPermission(
|
||||
navController: NavController,
|
||||
database: AppDatabase,
|
||||
) {
|
||||
val uriHandler = LocalUriHandler.current
|
||||
val clipboardManager = LocalClipboardManager.current
|
||||
val context = LocalContext.current
|
||||
val localAccount = LocalPreferences.loadFromEncryptedStorage(context, account.keyPair.pubKey.toNpub())!!
|
||||
@@ -309,7 +316,7 @@ fun EditPermission(
|
||||
)
|
||||
|
||||
val message =
|
||||
if (permission.type == "SIGN_EVENT") {
|
||||
if (permission.type == "SIGN_EVENT" || permission.type == "NIP") {
|
||||
stringResource(R.string.sign, localPermission.toLocalizedString(context))
|
||||
} else {
|
||||
localPermission.toLocalizedString(context)
|
||||
@@ -374,6 +381,53 @@ fun EditPermission(
|
||||
permissions.remove(permission)
|
||||
},
|
||||
)
|
||||
IconButton(
|
||||
content = {
|
||||
Icon(
|
||||
Icons.Default.Info,
|
||||
stringResource(R.string.more_info),
|
||||
modifier = Modifier
|
||||
.fillMaxHeight(),
|
||||
)
|
||||
},
|
||||
onClick = {
|
||||
if (permission.type.toLowerCase(Locale.current) == "sign_event") {
|
||||
val nip = permission.kind?.kindToNipUrl()
|
||||
if (nip == null) {
|
||||
Toast.makeText(
|
||||
context,
|
||||
context.getString(R.string.nip_not_found_for_the_event_kind, permission.kind.toString()),
|
||||
Toast.LENGTH_SHORT,
|
||||
).show()
|
||||
return@IconButton
|
||||
}
|
||||
uriHandler.openUri(nip)
|
||||
} else if (permission.type.toLowerCase(Locale.current) == "nip") {
|
||||
val nip = permission.kind?.nipToUrl()
|
||||
if (nip == null) {
|
||||
Toast.makeText(
|
||||
context,
|
||||
context.getString(R.string.nip_not_found, permission.kind.toString()),
|
||||
Toast.LENGTH_SHORT,
|
||||
).show()
|
||||
return@IconButton
|
||||
}
|
||||
uriHandler.openUri(nip)
|
||||
} else if ((permission.type.toUpperCase(Locale.current) == "NIP04_ENCRYPT") || (permission.type.toUpperCase(Locale.current) == "NIP04_DECRYPT")) {
|
||||
uriHandler.openUri("https://github.com/nostr-protocol/nips/blob/master/04.md")
|
||||
} else if ((permission.type.toUpperCase(Locale.current) == "NIP44_ENCRYPT") || (permission.type.toUpperCase(Locale.current) == "NIP44_DECRYPT")) {
|
||||
uriHandler.openUri("https://github.com/nostr-protocol/nips/blob/master/44.md")
|
||||
} else if (permission.type.toLowerCase(Locale.current) == "decrypt_zap_event") {
|
||||
uriHandler.openUri("https://github.com/nostr-protocol/nips/blob/master/57.md")
|
||||
} else {
|
||||
Toast.makeText(
|
||||
context,
|
||||
context.getString(R.string.no_information_available_for, localPermission.toLocalizedString(context)),
|
||||
Toast.LENGTH_SHORT,
|
||||
).show()
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+16
-2
@@ -31,6 +31,7 @@ import com.greenart7c3.nostrsigner.models.Account
|
||||
import com.greenart7c3.nostrsigner.models.IntentData
|
||||
import com.greenart7c3.nostrsigner.models.SignerType
|
||||
import com.greenart7c3.nostrsigner.models.TimeUtils
|
||||
import com.greenart7c3.nostrsigner.models.kindToNip
|
||||
import com.greenart7c3.nostrsigner.service.AmberUtils
|
||||
import com.greenart7c3.nostrsigner.service.getAppCompatActivity
|
||||
import com.greenart7c3.nostrsigner.service.toShortenHex
|
||||
@@ -253,10 +254,22 @@ fun SingleEventHomeScreen(
|
||||
}
|
||||
|
||||
SignerType.NIP04_DECRYPT, SignerType.NIP04_ENCRYPT, SignerType.NIP44_ENCRYPT, SignerType.NIP44_DECRYPT, SignerType.DECRYPT_ZAP_EVENT -> {
|
||||
val permission =
|
||||
val nip = when (intentData.type) {
|
||||
SignerType.NIP04_DECRYPT, SignerType.NIP04_ENCRYPT -> 4
|
||||
SignerType.NIP44_ENCRYPT, SignerType.NIP44_DECRYPT -> 44
|
||||
SignerType.DECRYPT_ZAP_EVENT -> null
|
||||
else -> null
|
||||
}
|
||||
var permission =
|
||||
applicationEntity?.permissions?.firstOrNull {
|
||||
it.pkKey == key && it.type == intentData.type.toString()
|
||||
}
|
||||
if (permission == null && nip != null) {
|
||||
permission =
|
||||
applicationEntity?.permissions?.firstOrNull {
|
||||
it.pkKey == key && it.type == "NIP" && it.kind == nip
|
||||
}
|
||||
}
|
||||
val remember =
|
||||
remember {
|
||||
mutableStateOf(permission?.acceptable != null)
|
||||
@@ -393,7 +406,8 @@ fun SingleEventHomeScreen(
|
||||
} else {
|
||||
val permission =
|
||||
applicationEntity?.permissions?.firstOrNull {
|
||||
it.pkKey == key && it.type == intentData.type.toString() && it.kind == event.kind
|
||||
val nip = event.kind.kindToNip()?.toIntOrNull()
|
||||
it.pkKey == key && ((it.type == intentData.type.toString() && it.kind == event.kind) || (nip != null && it.type == "NIP" && it.kind == nip))
|
||||
}
|
||||
val remember =
|
||||
remember {
|
||||
|
||||
@@ -265,4 +265,74 @@
|
||||
<string name="event_kind_39000">Group metadata</string>
|
||||
<string name="event_kind_39001">Group admins</string>
|
||||
<string name="event_kind_39002">Group members</string>
|
||||
<string name="more_info">More information about this permission</string>
|
||||
<string name="nip_kind">Nip %1$s</string>
|
||||
<string name="nip_01">Basic protocol flow description</string>
|
||||
<string name="nip_02">Follow List</string>
|
||||
<string name="nip_03">OpenTimestamps Attestations for Events</string>
|
||||
<string name="nip_04">Encrypted Direct Message</string>
|
||||
<string name="nip_05">Mapping Nostr keys to DNS-based internet identifiers</string>
|
||||
<string name="nip_06">Basic key derivation from mnemonic seed phrase</string>
|
||||
<string name="nip_07">window.nostr capability for web browsers</string>
|
||||
<string name="nip_08">Handling Mentions</string>
|
||||
<string name="nip_09">Event Deletion</string>
|
||||
<string name="nip_10">Conventions for clients</string>
|
||||
<string name="nip_11">Relay Information Document</string>
|
||||
<string name="nip_13">Proof of Work</string>
|
||||
<string name="nip_14">Subject tag in text events</string>
|
||||
<string name="nip_15">Nostr Marketplace (for resilient marketplaces)</string>
|
||||
<string name="nip_17">Private Direct Messages</string>
|
||||
<string name="nip_18">Reposts</string>
|
||||
<string name="nip_19">bech32-encoded entities</string>
|
||||
<string name="nip_21">nostr: URI scheme</string>
|
||||
<string name="nip_23">Long-form Content</string>
|
||||
<string name="nip_24">Extra metadata fields and tags</string>
|
||||
<string name="nip_25">Reactions</string>
|
||||
<string name="nip_26">Delegated Event Signing</string>
|
||||
<string name="nip_27">Text Note References</string>
|
||||
<string name="nip_28">Public Chat</string>
|
||||
<string name="nip_29">Relay-based Groups</string>
|
||||
<string name="nip_30">Custom Emoji</string>
|
||||
<string name="nip_31">Dealing with Unknown Events</string>
|
||||
<string name="nip_32">Labeling</string>
|
||||
<string name="nip_34">git stuff</string>
|
||||
<string name="nip_35">Torrents</string>
|
||||
<string name="nip_36">Sensitive Content</string>
|
||||
<string name="nip_38">User Statuses</string>
|
||||
<string name="nip_39">External Identities in Profiles</string>
|
||||
<string name="nip_40">Expiration Timestamp</string>
|
||||
<string name="nip_42">Authentication of clients to relays</string>
|
||||
<string name="nip_44">Versioned Encryption</string>
|
||||
<string name="nip_45">Counting results</string>
|
||||
<string name="nip_46">Nostr Connect</string>
|
||||
<string name="nip_47">Wallet Connect</string>
|
||||
<string name="nip_48">Proxy Tags</string>
|
||||
<string name="nip_49">Private Key Encryption</string>
|
||||
<string name="nip_50">Search Capability</string>
|
||||
<string name="nip_51">Lists</string>
|
||||
<string name="nip_52">Calendar Events</string>
|
||||
<string name="nip_53">Live Activities</string>
|
||||
<string name="nip_54">Wiki</string>
|
||||
<string name="nip_55">Android Signer Application</string>
|
||||
<string name="nip_56">Reporting</string>
|
||||
<string name="nip_57">Lightning Zaps</string>
|
||||
<string name="nip_58">Badges</string>
|
||||
<string name="nip_59">Gift Wrap</string>
|
||||
<string name="nip_65">Relay List Metadata</string>
|
||||
<string name="nip_70">Protected Events</string>
|
||||
<string name="nip_71">Video Events</string>
|
||||
<string name="nip_72">Moderated Communities</string>
|
||||
<string name="nip_75">Zap Goals</string>
|
||||
<string name="nip_78">Application-specific data</string>
|
||||
<string name="nip_84">Highlights</string>
|
||||
<string name="nip_89">Recommended Application Handlers</string>
|
||||
<string name="nip_90">Data Vending Machines</string>
|
||||
<string name="nip_92">Media Attachments</string>
|
||||
<string name="nip_94">File Metadata</string>
|
||||
<string name="nip_96">HTTP File Storage Integration</string>
|
||||
<string name="nip_98">HTTP Auth</string>
|
||||
<string name="nip_99">Classified Listings</string>
|
||||
<string name="no_information_available_for">No information available for %1$s</string>
|
||||
<string name="nip_not_found">Nip %1$s not found</string>
|
||||
<string name="nip_not_found_for_the_event_kind">Nip not found for the event kind %1$s</string>
|
||||
</resources>
|
||||
|
||||
@@ -15,9 +15,9 @@ junit = "4.13.2"
|
||||
junitVersion = "1.2.1"
|
||||
lifecycle_version = "2.8.3"
|
||||
material3 = "1.2.1"
|
||||
mockk = "1.13.11"
|
||||
mockk = "1.13.12"
|
||||
nav_version = "2.7.7"
|
||||
quartz = "e764ebbcb2" # TODO: change back to amethyst before releasing a new version
|
||||
quartz = "0.89.7"
|
||||
compose_ui = "1.6.8"
|
||||
richtextUi = "077a2cde64"
|
||||
roomKtx = "2.6.1"
|
||||
@@ -53,8 +53,8 @@ material-icons-extended = { module = "androidx.compose.material:material-icons-e
|
||||
material3 = { module = "androidx.compose.material3:material3", version.ref = "material3" }
|
||||
mockk = { module = "io.mockk:mockk", version.ref = "mockk" }
|
||||
navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "nav_version" }
|
||||
quartz = { module = "com.github.greenart7c3.amethyst:quartz", version.ref = "quartz" }
|
||||
ammolite = { module = "com.github.greenart7c3.amethyst:ammolite", version.ref = "quartz" }
|
||||
quartz = { module = "com.github.vitorpamplona.amethyst:quartz", version.ref = "quartz" }
|
||||
ammolite = { module = "com.github.vitorpamplona.amethyst:ammolite", version.ref = "quartz" }
|
||||
richtext-commonmark = { module = "com.github.vitorpamplona.compose-richtext:richtext-commonmark", version.ref = "richtextUi" }
|
||||
richtext-ui = { module = "com.github.vitorpamplona.compose-richtext:richtext-ui", version.ref = "richtextUi" }
|
||||
richtext-ui-material3 = { module = "com.github.vitorpamplona.compose-richtext:richtext-ui-material3", version.ref = "richtextUi" }
|
||||
|
||||
Reference in New Issue
Block a user