mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2025-04-02 08:58:23 +02:00
add support for private zaps
This commit is contained in:
parent
a773be12c4
commit
ff4d704bde
@ -461,6 +461,21 @@ class Account(
|
||||
AmberUtils.content
|
||||
)
|
||||
}
|
||||
|
||||
LnZapEvent.ZapType.PRIVATE -> {
|
||||
val unsignedEvent = LnZapRequestEvent.createPrivateZap(
|
||||
event,
|
||||
userProfile().latestContactList?.relays()?.keys?.ifEmpty { null }
|
||||
?: localRelays.map { it.url }.toSet(),
|
||||
keyPair.pubKey.toHexKey(),
|
||||
pollOption,
|
||||
message
|
||||
)
|
||||
AmberUtils.content = ""
|
||||
AmberUtils.openAmber(unsignedEvent)
|
||||
if (AmberUtils.content.isBlank()) return null
|
||||
return Event.fromJson(AmberUtils.content) as LnZapRequestEvent
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
} else {
|
||||
@ -485,10 +500,14 @@ class Account(
|
||||
fun isNIP47Author(pubkeyHex: String?): Boolean {
|
||||
val privKey = zapPaymentRequest?.secret?.hexToByteArray() ?: keyPair.privKey
|
||||
|
||||
if (privKey == null) return false
|
||||
if (privKey == null && !loginWithAmber) return false
|
||||
|
||||
val pubKey = CryptoUtils.pubkeyCreate(privKey).toHexKey()
|
||||
return (pubKey == pubkeyHex)
|
||||
if (privKey != null) {
|
||||
val pubKey = CryptoUtils.pubkeyCreate(privKey).toHexKey()
|
||||
return (pubKey == pubkeyHex)
|
||||
}
|
||||
|
||||
return (keyPair.pubKey.toHexKey() == pubkeyHex)
|
||||
}
|
||||
|
||||
fun decryptZapPaymentResponseEvent(zapResponseEvent: LnZapPaymentResponseEvent): Response? {
|
||||
@ -497,9 +516,14 @@ class Account(
|
||||
val privKey = myNip47.secret?.hexToByteArray() ?: keyPair.privKey
|
||||
val pubKey = myNip47.pubKeyHex.hexToByteArray()
|
||||
|
||||
if (privKey == null) return null
|
||||
if (privKey == null && !loginWithAmber) return null
|
||||
|
||||
return zapResponseEvent.response(privKey, pubKey)
|
||||
if (privKey != null) return zapResponseEvent.response(privKey, pubKey)
|
||||
|
||||
Log.d("zaps", "decrypt with amber")
|
||||
AmberUtils.decrypt(zapResponseEvent.content, pubKey.toHexKey(), zapResponseEvent.id)
|
||||
if (AmberUtils.content.isBlank()) return null
|
||||
return zapResponseEvent.response(AmberUtils.content)
|
||||
}
|
||||
|
||||
fun calculateIfNoteWasZappedByAccount(zappedNote: Note?): Boolean {
|
||||
@ -2546,12 +2570,21 @@ class Account(
|
||||
if (loginWithAmber && event is LnZapRequestEvent && event.isPrivateZap()) {
|
||||
val decryptedContent = AmberUtils.cachedDecryptedContent[event.id]
|
||||
if (decryptedContent != null) {
|
||||
return Event.fromJson(decryptedContent)
|
||||
return try {
|
||||
Event.fromJson(decryptedContent)
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
}
|
||||
AmberUtils.decryptZapEvent(event)
|
||||
if (AmberUtils.content.isBlank()) return null
|
||||
if (AmberUtils.content == "Could not decrypt the message") return null
|
||||
AmberUtils.cachedDecryptedContent[event.id] = AmberUtils.content
|
||||
return Event.fromJson(AmberUtils.content)
|
||||
return try {
|
||||
Event.fromJson(AmberUtils.content)
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
return if (event is LnZapRequestEvent && loggedInPrivateKey != null && event.isPrivateZap()) {
|
||||
|
@ -105,18 +105,16 @@ object AmberUtils {
|
||||
}
|
||||
|
||||
fun decryptZapEvent(event: LnZapRequestEvent) {
|
||||
if (content.isBlank()) {
|
||||
isActivityRunning = true
|
||||
openAmber(
|
||||
event.toJson(),
|
||||
SignerType.DECRYPT_ZAP_EVENT,
|
||||
IntentUtils.activityResultLauncher,
|
||||
event.pubKey,
|
||||
event.id
|
||||
)
|
||||
while (isActivityRunning) {
|
||||
// do nothing
|
||||
}
|
||||
isActivityRunning = true
|
||||
openAmber(
|
||||
event.toJson(),
|
||||
SignerType.DECRYPT_ZAP_EVENT,
|
||||
IntentUtils.activityResultLauncher,
|
||||
event.pubKey,
|
||||
event.id
|
||||
)
|
||||
while (isActivityRunning) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,27 +34,57 @@ class EventNotificationConsumer(private val applicationContext: Context) {
|
||||
// Test with all logged in accounts
|
||||
LocalPreferences.allSavedAccounts().forEach {
|
||||
val acc = LocalPreferences.loadFromEncryptedStorage(it.npub)
|
||||
if (acc != null && acc.keyPair.privKey != null) {
|
||||
if (acc != null && (acc.keyPair.privKey != null || acc.loginWithAmber)) {
|
||||
consumeIfMatchesAccount(event, acc)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun consumeIfMatchesAccount(pushWrappedEvent: GiftWrapEvent, account: Account) {
|
||||
val key = account.keyPair.privKey ?: return
|
||||
pushWrappedEvent.unwrap(key)?.let { notificationEvent ->
|
||||
if (!LocalCache.justVerify(notificationEvent)) return // invalid event
|
||||
if (LocalCache.notes[notificationEvent.id] != null) return // already processed
|
||||
val key = account.keyPair.privKey
|
||||
if (account.loginWithAmber) {
|
||||
var cached = AmberUtils.cachedDecryptedContent[pushWrappedEvent.id]
|
||||
if (cached == null) {
|
||||
AmberUtils.content = ""
|
||||
AmberUtils.decrypt(
|
||||
pushWrappedEvent.content,
|
||||
pushWrappedEvent.pubKey,
|
||||
pushWrappedEvent.id,
|
||||
SignerType.NIP44_DECRYPT
|
||||
)
|
||||
cached = AmberUtils.cachedDecryptedContent[pushWrappedEvent.id] ?: ""
|
||||
}
|
||||
pushWrappedEvent.unwrap(cached)?.let { notificationEvent ->
|
||||
if (!LocalCache.justVerify(notificationEvent)) return // invalid event
|
||||
if (LocalCache.notes[notificationEvent.id] != null) return // already processed
|
||||
|
||||
LocalCache.justConsume(notificationEvent, null)
|
||||
LocalCache.justConsume(notificationEvent, null)
|
||||
|
||||
unwrapAndConsume(notificationEvent, account)?.let { innerEvent ->
|
||||
if (innerEvent is PrivateDmEvent) {
|
||||
notify(innerEvent, account)
|
||||
} else if (innerEvent is LnZapEvent) {
|
||||
notify(innerEvent, account)
|
||||
} else if (innerEvent is ChatMessageEvent) {
|
||||
notify(innerEvent, account)
|
||||
unwrapAndConsume(notificationEvent, account)?.let { innerEvent ->
|
||||
if (innerEvent is PrivateDmEvent) {
|
||||
notify(innerEvent, account)
|
||||
} else if (innerEvent is LnZapEvent) {
|
||||
notify(innerEvent, account)
|
||||
} else if (innerEvent is ChatMessageEvent) {
|
||||
notify(innerEvent, account)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (key != null) {
|
||||
pushWrappedEvent.unwrap(key)?.let { notificationEvent ->
|
||||
if (!LocalCache.justVerify(notificationEvent)) return // invalid event
|
||||
if (LocalCache.notes[notificationEvent.id] != null) return // already processed
|
||||
|
||||
LocalCache.justConsume(notificationEvent, null)
|
||||
|
||||
unwrapAndConsume(notificationEvent, account)?.let { innerEvent ->
|
||||
if (innerEvent is PrivateDmEvent) {
|
||||
notify(innerEvent, account)
|
||||
} else if (innerEvent is LnZapEvent) {
|
||||
notify(innerEvent, account)
|
||||
} else if (innerEvent is ChatMessageEvent) {
|
||||
notify(innerEvent, account)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -71,16 +101,20 @@ class EventNotificationConsumer(private val applicationContext: Context) {
|
||||
unwrapAndConsume(it, account)
|
||||
}
|
||||
} else if (account.loginWithAmber) {
|
||||
AmberUtils.content = ""
|
||||
AmberUtils.decrypt(
|
||||
event.content,
|
||||
event.pubKey,
|
||||
event.id,
|
||||
SignerType.NIP44_DECRYPT
|
||||
)
|
||||
val decryptedContent = AmberUtils.cachedDecryptedContent[event.id] ?: ""
|
||||
if (decryptedContent.isNotBlank()) {
|
||||
event.cachedGift(account.keyPair.pubKey, decryptedContent)?.let {
|
||||
var cached = AmberUtils.cachedDecryptedContent[event.id]
|
||||
if (cached == null) {
|
||||
AmberUtils.content = ""
|
||||
AmberUtils.decrypt(
|
||||
event.content,
|
||||
event.pubKey,
|
||||
event.id,
|
||||
SignerType.NIP44_DECRYPT
|
||||
)
|
||||
cached = AmberUtils.cachedDecryptedContent[event.id] ?: ""
|
||||
}
|
||||
|
||||
if (cached.isNotBlank()) {
|
||||
event.cachedGift(account.keyPair.pubKey, cached)?.let {
|
||||
LocalCache.justConsume(it, null)
|
||||
it
|
||||
}
|
||||
@ -100,16 +134,19 @@ class EventNotificationConsumer(private val applicationContext: Context) {
|
||||
it
|
||||
}
|
||||
} else if (account.loginWithAmber) {
|
||||
AmberUtils.content = ""
|
||||
AmberUtils.decrypt(
|
||||
event.content,
|
||||
event.pubKey,
|
||||
event.id,
|
||||
SignerType.NIP44_DECRYPT
|
||||
)
|
||||
val decryptedContent = AmberUtils.cachedDecryptedContent[event.id] ?: ""
|
||||
if (decryptedContent.isNotBlank()) {
|
||||
event.cachedGossip(account.keyPair.pubKey, decryptedContent)?.let {
|
||||
var cached = AmberUtils.cachedDecryptedContent[event.id]
|
||||
if (cached == null) {
|
||||
AmberUtils.content = ""
|
||||
AmberUtils.decrypt(
|
||||
event.content,
|
||||
event.pubKey,
|
||||
event.id,
|
||||
SignerType.NIP44_DECRYPT
|
||||
)
|
||||
cached = AmberUtils.cachedDecryptedContent[event.id] ?: ""
|
||||
}
|
||||
if (cached.isNotBlank()) {
|
||||
event.cachedGossip(account.keyPair.pubKey, cached)?.let {
|
||||
LocalCache.justConsume(it, null)
|
||||
it
|
||||
}
|
||||
|
@ -61,6 +61,22 @@ class LnZapPaymentResponseEvent(
|
||||
}
|
||||
}
|
||||
|
||||
fun response(decryptedContent: String): Response? {
|
||||
if (response != null) response
|
||||
|
||||
return try {
|
||||
if (content.isNotEmpty()) {
|
||||
response = mapper.readValue(decryptedContent, Response::class.java)
|
||||
response
|
||||
} else {
|
||||
null
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.w("LnZapPaymentResponseEvent", "Can't parse content as a payment response: $content", e)
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val kind = 23195
|
||||
}
|
||||
|
@ -123,6 +123,32 @@ class LnZapRequestEvent(
|
||||
return LnZapRequestEvent(id.toHexKey(), pubKey, createdAt, tags, message, "")
|
||||
}
|
||||
|
||||
fun createPrivateZap(
|
||||
originalNote: EventInterface,
|
||||
relays: Set<String>,
|
||||
pubKey: HexKey,
|
||||
pollOption: Int?,
|
||||
message: String,
|
||||
createdAt: Long = TimeUtils.now()
|
||||
): LnZapRequestEvent {
|
||||
val content = message
|
||||
var tags = listOf(
|
||||
listOf("e", originalNote.id()),
|
||||
listOf("p", originalNote.pubKey()),
|
||||
listOf("relays") + relays
|
||||
)
|
||||
if (originalNote is AddressableEvent) {
|
||||
tags = tags + listOf(listOf("a", originalNote.address().toTag()))
|
||||
}
|
||||
if (pollOption != null && pollOption >= 0) {
|
||||
tags = tags + listOf(listOf(POLL_OPTION, pollOption.toString()))
|
||||
}
|
||||
|
||||
tags = tags + listOf(listOf("anon", ""))
|
||||
|
||||
return LnZapRequestEvent("", pubKey, createdAt, tags, content, "")
|
||||
}
|
||||
|
||||
fun createAnonymous(
|
||||
originalNote: EventInterface,
|
||||
relays: Set<String>,
|
||||
|
Loading…
x
Reference in New Issue
Block a user