diff --git a/app/build.gradle b/app/build.gradle index e711d3577..6b57d88ab 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -87,6 +87,7 @@ android { } dependencies { + implementation project(path: ':quartz') implementation 'androidx.core:core-ktx:1.10.1' implementation 'androidx.activity:activity-compose:1.7.2' implementation "androidx.compose.ui:ui:$compose_ui_version" @@ -115,16 +116,9 @@ dependencies { // Biometrics implementation "androidx.biometric:biometric-ktx:1.2.0-alpha05" - // Bitcoin secp256k1 bindings to Android - implementation 'fr.acinq.secp256k1:secp256k1-kmp-jni-android:0.10.1' - // Websockets API implementation 'com.squareup.okhttp3:okhttp:5.0.0-alpha.11' - // Json Serialization TODO: We might need to converge between gson and Jackson (we are usin both) - implementation 'com.fasterxml.jackson.module:jackson-module-kotlin:2.15.2' - implementation 'com.squareup.retrofit2:converter-gson:2.9.0' - // link preview implementation 'org.jsoup:jsoup:1.16.1' @@ -149,9 +143,6 @@ dependencies { // Permission to upload pictures: implementation "com.google.accompanist:accompanist-permissions:$accompanist_version" - // Parses URLs from Text: - implementation "io.github.url-detector:url-detector:0.1.23" - // For QR generation implementation 'com.google.zxing:core:3.5.2' implementation 'com.journeyapps:zxing-android-embedded:4.3.0' @@ -188,16 +179,9 @@ dependencies { implementation "com.patrykandpatrick.vico:views:${vico_version}" implementation "com.patrykandpatrick.vico:compose-m2:${vico_version}" - // immutable collections to avoid recomposition - implementation("org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.5") - // GeoHash implementation 'com.github.drfonfon:android-kotlin-geohash:1.0' - // LibSodium for XChaCha encryption - implementation "com.goterl:lazysodium-android:5.1.0@aar" - implementation 'net.java.dev.jna:jna:5.13.0@aar' - // Video compression lib implementation 'com.github.AbedElazizShe:LightCompressor:1.3.1' // Image compression lib diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 32effad2f..97496bbf1 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -52,23 +52,9 @@ private static java.lang.Object fromNative(com.sun.jna.FromNativeConverter, java.lang.Object, java.lang.reflect.Method); } -# GSON parsing --keep class com.vitorpamplona.amethyst.service.model.** { *; } +# JSON parsing +-keep class com.vitorpamplona.quartz.crypto.** { *; } +-keep class com.vitorpamplona.quartz.encoders.** { *; } +-keep class com.vitorpamplona.quartz.events.** { *; } -keep class com.vitorpamplona.amethyst.model.** { *; } -keep class com.vitorpamplona.amethyst.service.** { *; } - -# Prevent proguard from stripping interface information from TypeAdapter, TypeAdapterFactory, -# JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter) --keep class * extends com.google.gson.TypeAdapter --keep class * implements com.google.gson.TypeAdapterFactory --keep class * implements com.google.gson.JsonSerializer --keep class * implements com.google.gson.JsonDeserializer - -# Prevent R8 from leaving Data object members always null --keepclassmembers,allowobfuscation class * { - @com.google.gson.annotations.SerializedName ; -} - -# Retain generic signatures of TypeToken and its subclasses with R8 version 3.0 and higher. --keep,allowobfuscation,allowshrinking class com.google.gson.reflect.TypeToken --keep,allowobfuscation,allowshrinking class * extends com.google.gson.reflect.TypeToken diff --git a/app/src/androidTest/java/com/vitorpamplona/amethyst/ImageUploadTesting.kt b/app/src/androidTest/java/com/vitorpamplona/amethyst/ImageUploadTesting.kt index 48ea82a2b..6b1b58f5e 100644 --- a/app/src/androidTest/java/com/vitorpamplona/amethyst/ImageUploadTesting.kt +++ b/app/src/androidTest/java/com/vitorpamplona/amethyst/ImageUploadTesting.kt @@ -2,13 +2,13 @@ package com.vitorpamplona.amethyst import androidx.test.ext.junit.runners.AndroidJUnit4 import com.vitorpamplona.amethyst.model.Account -import com.vitorpamplona.amethyst.service.KeyPair import com.vitorpamplona.amethyst.ui.actions.FileServer import com.vitorpamplona.amethyst.ui.actions.ImageUploader import com.vitorpamplona.amethyst.ui.actions.ImgurServer import com.vitorpamplona.amethyst.ui.actions.NostrBuildServer import com.vitorpamplona.amethyst.ui.actions.NostrFilesDevServer import com.vitorpamplona.amethyst.ui.actions.NostrImgServer +import com.vitorpamplona.quartz.crypto.KeyPair import kotlinx.coroutines.runBlocking import org.junit.Assert import org.junit.Test diff --git a/app/src/androidTest/java/com/vitorpamplona/amethyst/RichTextParserTest.kt b/app/src/androidTest/java/com/vitorpamplona/amethyst/RichTextParserTest.kt index 278b05ce3..c21fc4ec1 100644 --- a/app/src/androidTest/java/com/vitorpamplona/amethyst/RichTextParserTest.kt +++ b/app/src/androidTest/java/com/vitorpamplona/amethyst/RichTextParserTest.kt @@ -3,7 +3,7 @@ package com.vitorpamplona.amethyst import androidx.test.ext.junit.runners.AndroidJUnit4 import com.vitorpamplona.amethyst.service.RichTextParser import com.vitorpamplona.amethyst.service.RichTextViewerState -import com.vitorpamplona.amethyst.ui.actions.ImmutableListOfLists +import com.vitorpamplona.quartz.events.ImmutableListOfLists import org.junit.Assert import org.junit.Test import org.junit.runner.RunWith diff --git a/app/src/androidTest/java/com/vitorpamplona/amethyst/ThreadAssemblerTest.kt b/app/src/androidTest/java/com/vitorpamplona/amethyst/ThreadAssemblerTest.kt new file mode 100644 index 000000000..1bbf7caeb --- /dev/null +++ b/app/src/androidTest/java/com/vitorpamplona/amethyst/ThreadAssemblerTest.kt @@ -0,0 +1,146 @@ +package com.vitorpamplona.amethyst + +import com.fasterxml.jackson.module.kotlin.readValue +import com.vitorpamplona.amethyst.model.LocalCache +import com.vitorpamplona.amethyst.ui.dal.ThreadFeedFilter +import com.vitorpamplona.quartz.encoders.ATag +import com.vitorpamplona.quartz.events.Event +import junit.framework.TestCase +import junit.framework.TestCase.assertEquals +import org.junit.Test + +class ThreadAssemblerTest { + val db = """ + [ + {"id":"741f5367a9415f4d6f19c0f57a1e4647c8ed8309b53b0da2d82fc4ebfba03b2c","pubkey":"d85c99afd244911e0aaf800cbea4221df557f06f8a4ff2cbe84b24e0b9e728fc","created_at":1684674845,"kind":1,"tags":[["p","fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52"],["e","532808e4d60f5f82b95aeaa3ed2e930a0c5973dccb0ede68b28b1931db91440f"],["p","6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"Getting my head around this","sig":"069874040bac26a219777fc0f90b8f4df71e38c30e3e6a953d53222499d8e0c5a8f32c6b4204d14eb335bb654f01c5610372d9dc00062284b8e0f2bb98c7ed85"}, + {"id":"22323fc72b4c37f93ea21f6069684339ce5f63111161c81f2aa3de4a21bfe83b","pubkey":"73c7f6d5bb599bb7d7cee84c72e89dbd549df53da522ed6c7611055cc0db64bc","created_at":1683571810,"kind":1,"tags":[["p","fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52"],["e","532808e4d60f5f82b95aeaa3ed2e930a0c5973dccb0ede68b28b1931db91440f"],["p","6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"test","sig":"f6d3bcf0f8e07d06720a2527f95910ee5a66aa889dd9261514921a155bbc3e9a3c7d721f5a2ec948cd795183f85dbe80f2ee2e36663f9d1de33fc03274ccb9d9"}, + {"id":"14525fcaae530a029f782fd361dd0cd66634c3e23020bd19e66fe11c1e254e32","pubkey":"afd563434a737334d69db899e4a32fe38d73a182bb6d1e91d83a2c4c4e04737c","created_at":1682968749,"kind":1,"tags":[["p","fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52"],["e","532808e4d60f5f82b95aeaa3ed2e930a0c5973dccb0ede68b28b1931db91440f"],["p","6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"This is most amazing thing yet for nostr!","sig":"3dcbb058b8fa6e6f388f5b1a26d21b888dbc91bb831b0ed80ee30d9d2494fbbbb40dac9daf637b948c3afe1f32c2c662eca8d7acc0ba31f23b89edc8ade99631"}, + {"id":"98ae0d6d10e494ed0bf70feb577e8225c6a6732c7af3d29f88bfe1b87d4439e6","pubkey":"83fd07de9b763334cc9d46f2785c2558e6c2eabfe7d0c6ec214667cbaec50d47","created_at":1681995243,"kind":1,"tags":[["p","fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52"],["e","532808e4d60f5f82b95aeaa3ed2e930a0c5973dccb0ede68b28b1931db91440f"],["p","6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"true if big","sig":"bb7d97e81207096d8615ebb0458c3023fa1b8f3aac463f3f0293ae94e2b90d043ad371067ce984a2ab2ba49cd7432a553f128b8d2d678238551538ad657bd75c"}, + {"id":"36e262e71b7e8bcae946f69885b8c3614e318e82864437342cf50e8b9ab7229d","pubkey":"b111d517452f9ef015e16d60ae623a6b66af63024eec941b0653bfee0dd667d4","created_at":1681979196,"kind":1,"tags":[["p","fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52"],["e","532808e4d60f5f82b95aeaa3ed2e930a0c5973dccb0ede68b28b1931db91440f"],["p","6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"this is wonderful. great work.","sig":"205a46d867c22cbb09c7dcc4351330a95304c0d80540c85b9ea39f7f464ea60df1ef5006c1f93b862536f04d8a7855e4cc2a915d7a01437cd30f7f12c716b239"}, + {"id":"37725c2924ca267d66c2c27c2dae65550c07e7b883034cf1ea69671883430642","pubkey":"90b9bec74789688e515125596ab6350bfe646176ac75742275063922c5fea010","created_at":1681944950,"kind":1,"tags":[["p","fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52"],["e","532808e4d60f5f82b95aeaa3ed2e930a0c5973dccb0ede68b28b1931db91440f"],["p","6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"Epic!","sig":"c461b97a3cdc5cf967e6f32c59c94b1b912c296feb1cbb7943c81731e558b10a3674982d6990567260d9fb033f5a3d3db8984b1eb362715d68ba46034a8b1b86"}, + {"id":"8ba54cfb6375270e8ae97a7e0992c1a0dbaa4cd46af8309d67a839e86789fde6","pubkey":"c48e29f04b482cc01ca1f9ef8c86ef8318c059e0e9353235162f080f26e14c11","created_at":1681944377,"kind":1,"tags":[["p","fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52"],["e","532808e4d60f5f82b95aeaa3ed2e930a0c5973dccb0ede68b28b1931db91440f"],["p","6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"This is incredible... Bravo, Pablo, and shoutout to Gigi.","sig":"fb1a84d4859742b001b810c98a5e9301bc861fa2d65a711cb21c57f6e62c98f27e5b0c0c6432ef1111bc6cc52aa8cb0ae909d28af50c497d125950bfaeade475"}, + {"id":"53410bc6d47e87f3f18ecbc93c716b5a6ef8ee3805516b2ff4d155154a685b7c","pubkey":"fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52","created_at":1681945005,"kind":1,"tags":[["e","532808e4d60f5f82b95aeaa3ed2e930a0c5973dccb0ede68b28b1931db91440f"],["e","8ba54cfb6375270e8ae97a7e0992c1a0dbaa4cd46af8309d67a839e86789fde6"],["p","6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93"],["p","c48e29f04b482cc01ca1f9ef8c86ef8318c059e0e9353235162f080f26e14c11"]],"content":"Thank you, my friend 🤙 ","sig":"3d2fbcefdfac2183601076c8f9e518e05620cefe74cba233684cce931a69b51befa329c94734e434805bd9382ff3dad36e42d1955d4e47c822e973ba69b7377f"}, + {"id":"e383476cb1ce5accde11d4b1338424fa32c3724cf96e6214af8e5e852981728a","pubkey":"50de492cfe5472450df1a0176fdf6d915e97cb5d9f8d3eccef7d25ff0a8871de","created_at":1681932060,"kind":1,"tags":[["p","fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52"],["e","532808e4d60f5f82b95aeaa3ed2e930a0c5973dccb0ede68b28b1931db91440f"],["p","6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"https://nostr.build/p/nb5753.png","sig":"9df6e3872f420ed5225aaa242f1c806b4739f17e265f02ca593a3c31c5fb5cb48705ee6bc0510f81f123527aa96ec4d07adf829362e2196bd7b833deded4c2b8"}, + {"id":"e2d8aaed336d3c0f73a9ca46a89fdb2da62a6d172936a91b0067a68797b3bcb8","pubkey":"50de492cfe5472450df1a0176fdf6d915e97cb5d9f8d3eccef7d25ff0a8871de","created_at":1681931869,"kind":1,"tags":[["p","fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52"],["e","532808e4d60f5f82b95aeaa3ed2e930a0c5973dccb0ede68b28b1931db91440f"],["p","6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"Very Cool, I started playing around!","sig":"5980b2d0ef114d50c5f45b5d0c55bfc56b16a0a1807774ec2a86c4e352e17e3ec78877c73f2fedfbfd097a018df8e965107d6efd4ad9c0a0e1ecc89332d51cec"}, + {"id":"b92e4d6a5d0e8d1d2d2421044b84a4d11f2188261c55145d782b1b6bf0995009","pubkey":"fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52","created_at":1681932193,"kind":1,"tags":[["e","532808e4d60f5f82b95aeaa3ed2e930a0c5973dccb0ede68b28b1931db91440f","","root"],["e","e2d8aaed336d3c0f73a9ca46a89fdb2da62a6d172936a91b0067a68797b3bcb8","","reply"],["p","6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93"]],"content":"love seeing it!!!","sig":"47850c205f1fa6d8836cda347c7d12c4307d35a110629eac48b4fff26600a14a5c5c8a7877b851db062a89e0157be112eae60ba0594525c1cc4d355906368dbb"}, + {"id":"da13e14cc8bcc243e0373dde14533d3829b8b621e214ca3c99c90f3dd9e11b8a","pubkey":"b488b594d84bb3e7c8421a4b91b19a006dc13d0c00da304a0263355d02195f04","created_at":1681931637,"kind":1,"tags":[["p","fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52"],["e","532808e4d60f5f82b95aeaa3ed2e930a0c5973dccb0ede68b28b1931db91440f"],["p","6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"Great thoughts ","sig":"34c81430952508746fd5d5a4c4f7df0f5762aeb17d075a74f7b0daf387a7b8772edf4152731cff6650219e1aa9f8f63924410baa03091a698af0513cbf57e0af"}, + {"id":"b5234d90a1543ba60765c57ac3fc7140129a4ac28bbd013531ec9b85e256ea55","pubkey":"b488b594d84bb3e7c8421a4b91b19a006dc13d0c00da304a0263355d02195f04","created_at":1681931560,"kind":1,"tags":[["p","fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52"],["e","532808e4d60f5f82b95aeaa3ed2e930a0c5973dccb0ede68b28b1931db91440f"],["p","6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"I like comments ","sig":"6915f4c2a08622339957495931eabc37f8d0c50ab1f3ec42327b67d15e50f50ff4bc302848b606e6d7c170696f8d744e6f896223f30ecb39a3adffe58020ff6f"}, + {"id":"fc4e4a1230b002e4ae08251a0b26107de7f518800188b7a504f5de62d8b07996","pubkey":"fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52","created_at":1681834615,"kind":1,"tags":[["p","fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52"],["e","532808e4d60f5f82b95aeaa3ed2e930a0c5973dccb0ede68b28b1931db91440f"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"This is exactly why I built this. I am enamored by this idea.","sig":"bdd1b3532efa3badeb3807fe74d31c25f17c84bbe39fe3c692d3d73efa39408089843ebb3c049840f2d525e6849f8254179a888bedc776ee7ad5e6997dc10c44"}, + {"id":"d4a0b4f08d98d82a04292654ec132723cc2cf3fa24ffb6c0833426cb9372f4d5","pubkey":"39a8b17475be0db44e313f9fd032ffde183c8abd6498e4932a873330d2cd4868","created_at":1680618462,"kind":1,"tags":[["e","44d3ecbb5752e96becc330d9b56352ea595d37b4c55edd8701fd24f18df5eee2"],["p","6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93"],["p","39a8b17475be0db44e313f9fd032ffde183c8abd6498e4932a873330d2cd4868"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"Unfortunately when boosting this it gets broken 🥹\n#[1]","sig":"c4a4197df4fec008f2f565170d09c46f0b9a7217ed90432cb53d1dddf70ad8520722b6e4f04ec9e52dd219ee01387c6191f449cd10a6c2488b1d2866424b7a8a"}, + {"id":"8cdc4676aca93bbafcfbe6784f9b2df54e8ca20fbe69ba55fda487736bfdb7f6","pubkey":"6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93","created_at":1680636068,"kind":1,"tags":[["e","44d3ecbb5752e96becc330d9b56352ea595d37b4c55edd8701fd24f18df5eee2"],["e","d4a0b4f08d98d82a04292654ec132723cc2cf3fa24ffb6c0833426cb9372f4d5"],["p","6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93"],["p","39a8b17475be0db44e313f9fd032ffde183c8abd6498e4932a873330d2cd4868"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"we early ","sig":"b8026e43c61b491014915caf79289968b87e52aa87a487ebecbf6cb2b3c07d460f2ab1a86da99b1c5410a0f5d14e77cf27f78c56bf1ab709f0d616ad2711de78"}, + {"id":"e15b386824fbfdcbf1b50b8860f03062cef534a3ea5339cc837536fb2a58465e","pubkey":"d3d2b986796c9e2067c58fc9017cace5adc1876e9b674719078d5c13d82e54a9","created_at":1690025613,"kind":1,"tags":[["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599","","root"]],"content":"test 3","sig":"1a34f9bb9eca624f4e0c3de2ad4ad7d9c915cd16e3f1e41066a69d3799a5bb19689a8e0d894e00649cae7f7d27beadbab2b04d4083f7f2ce68e5ee65af229f55"}, + {"id":"ba9a8a1a8afb0b53fb5d4fa3f5130fe557a8d8d56fac7af9ad3443531d2a2933","pubkey":"95181f816dc80a141e9158a2a398bec37f580f4309633321a1ca53757bf08794","created_at":1690373626,"kind":1,"tags":[["e","e15b386824fbfdcbf1b50b8860f03062cef534a3ea5339cc837536fb2a58465e"],["p","d3d2b986796c9e2067c58fc9017cace5adc1876e9b674719078d5c13d82e54a9"]],"content":"I see your tests. 1-3 🫡","sig":"cc8d3af65578cc2436878fb5dbf3ac27751b50f91b02dd944094e9f9f2965193e32fb20ce68cfe5555ecfb4b13fd06b9cdb673dc71e5db47199b8e6cde2d2e60"}, + {"id":"b0425132a3dd4142a0f78986166aaa28021cc8fb440c95c321a95afce3d5e056","pubkey":"d3d2b986796c9e2067c58fc9017cace5adc1876e9b674719078d5c13d82e54a9","created_at":1690025593,"kind":1,"tags":[["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599","","root"]],"content":"test 2","sig":"0226d5836991836ba105cd483def0baa4255bad19a8213ae483c0168efb4de6e493233ed1fdc83e038d5227e0254dc0b461e7a7fa8032a7eada56b9840e8762f"}, + {"id":"e9bb4e2d56bd2be2952570bd52b102c23444a62ada5b78ba086f086d9147651a","pubkey":"d3d2b986796c9e2067c58fc9017cace5adc1876e9b674719078d5c13d82e54a9","created_at":1690025573,"kind":1,"tags":[["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599","","root"]],"content":"test","sig":"ba66f1123e93a70645f3f01814378d23609cc2fda38f083410e0e06b037dc9fc45d139b690e2e892278f768c97a03e02e0a9cd0a8b385271db180e1e8838784d"}, + {"id":"4d7b21c462f3fbf27a1882dbaaec4e99e5a5d18a2c18d1f2d1f0736684ad157c","pubkey":"84142dede040f7e0852ba867cfa921986b7b7e92c4b7bc5c72fbd2a4577545e4","created_at":1688308094,"kind":1,"tags":[["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599","","root"]],"content":"testing","sig":"9f991643229822577c967d6d71831a6d98993dbbd3613b04abda0907a944b8eb20f6f8477bc8e922308e2e2135243ab78a31a93f285ee6215ac5536141a7d95d"}, + {"id":"9cdbced750e6b1e1274b7df47cb433f565414dd08c897167eba761eadee841cc","pubkey":"726a1e261cc6474674e8285e3951b3bb139be9a773d1acf49dc868db861a1c11","created_at":1687990252,"kind":1,"tags":[["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599","","root"]],"content":"Running zapthreads","sig":"1cd2209548f5a791807e4a8aeafbf3a2fb28cee013ad5f444f86dffd448668c05480d7714b892314f5fa50b7c65a23708362c1d5b0cb669c64cfb06ca8486ba9"}, + {"id":"5799aac7a9b06f3cae3d3791b79df29d14173515cfdbf34398aab73ed4a44121","pubkey":"726a1e261cc6474674e8285e3951b3bb139be9a773d1acf49dc868db861a1c11","created_at":1687996513,"kind":1,"tags":[["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599","","root"],["e","9cdbced750e6b1e1274b7df47cb433f565414dd08c897167eba761eadee841cc","","reply"]],"content":"Testing nested comments","sig":"335f9969d23e28fef45adfda63da236f1d4d72dfb5873fc78961d47ee948e9333632ce8a45df3c09fc431cf8d29d2fb99bea9c9a4b3502465b05a0328d563231"}, + {"id":"7a18dda355525d468b31bba4fa947cba98cc19048d4a3099d5e9ba045d878c26","pubkey":"45c41f21e1cf715fa6d9ca20b8e002a574db7bb49e96ee89834c66dac5446b7a","created_at":1680618145,"kind":1,"tags":[["e","1a1fe6c838400f3347f97a9adce08c10068f3bc35a279520c911b025c387b061",""],["p","6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93",""],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599",""],["title","Purple Text, Orange Highlights"],["summary","Using nostr as a base layer to create, consume, and monetize long-form content."],["image","https://dergigi.com/assets/images/reader.jpg"],["published_at","1680613802"]],"content":"good read. the highlighted part to be a shareable event 1 idea seems interesting, might explore it on flycat","sig":"ee913e997b907a03300616c36cffa12d2362932bd5e249cde39a44ec1250c7622703dddac167b093c3e3a28d41ebfeb9aed9d663d82bea9f8deaed4e342248dc"}, + {"id":"a3b3825af621727f9af3bd77392fe38c04d71658024916af7fe4c5867ef73eaa","pubkey":"619af6a60b3fe4c733aaca061c522cc9c7cf1d87ef4c908facc5ed936d3bdf23","created_at":1681941926,"kind":1,"tags":[["p","330fb1431ff9d8c250706bbcdc016d5495a3f744e047a408173e92ae7ee42dac"],["e","d7ef8220e3521779e2e0c3ff0afb9738f241e44ace8ed1d5237cab36330a69d0"],["p","6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"Good or bad time?","sig":"5629e21769b018c7f050ad35e20c3926e5f9c415ebcd54656e874cff7948a9117de6fb32d18f993b7c96f480f3e4baffb079a3db7c126c74b0188006bba41768"}, + {"id":"c5ad64b1b72776a068c39f4549d089032432814a146849eba0650d1b329fb285","pubkey":"126df36019a793922eae86bfcfedc5240b68d67953892237e3eb500ab92140bf","created_at":1681911407,"kind":1,"tags":[["p","fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52"],["e","f2610be11393f884c020119316d3304bc06c48ab01f9cbcf5a5a8290031bf20e"],["p","6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"Cool","sig":"62240add277f55e896ae24276fdae60f1580be9de4889e546fd2141b73e07b3e48f225a57914a5e0e5a2fd87570a1dfe1af4f869b355a7c455aa77f395c10bdb"}, + {"id":"6a58f8315af5badb1bdaeb5489417b94621a4d8e192ae2fedcca0c5dcf0c9cd4","pubkey":"73c7f6d5bb599bb7d7cee84c72e89dbd549df53da522ed6c7611055cc0db64bc","created_at":1681821926,"kind":1,"tags":[["p","73c7f6d5bb599bb7d7cee84c72e89dbd549df53da522ed6c7611055cc0db64bc"],["e","81a6379301d7b517f96cc7d070b5b30fb43db97c5c814be3bc9f58d8fcbaf190"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"test 5","sig":"eeba84f251d8d79e0f16213b766aee8079a3a5018407c3f7d1e8161c762e6a735bb695ac54898e04d7abe245ec12f24d680927351d37a6f31557344adeebd3c2"}, + {"id":"6e9bb03c7c40d67fec0d0bb872548ec207ba0ac4533efa137d7bcaca9fb4b191","pubkey":"fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52","created_at":1681755803,"kind":1,"tags":[["p","fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52"],["e","9defafc0783f16b2ef9ac02d2e808a103d5d38f12905b7840420634af67d0821"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"test1","sig":"17c2489ee28dc32df68ebf87ced6f5f9af0e3f091b31298fece408acba43236bc6c9f50d756f61bcf46a204e043141535e0cd281d541146cbfac259814cd2cbe"}, + {"id":"e2ae784b239cac4bad38136e4bd758b87dd261b659ef460450064bf9073edcb3","pubkey":"73c7f6d5bb599bb7d7cee84c72e89dbd549df53da522ed6c7611055cc0db64bc","created_at":1681648013,"kind":1,"tags":[["p","73c7f6d5bb599bb7d7cee84c72e89dbd549df53da522ed6c7611055cc0db64bc"],["e","81a6379301d7b517f96cc7d070b5b30fb43db97c5c814be3bc9f58d8fcbaf190"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"powerful quote 👀","sig":"eda9e5565000892dacab78469936d96aad7fb0dc0828630563b8ccb731f08e704eacfefff246b6bb668332e046f5650f2a9e4186c108f07cba07eefc775c6c58"}, + {"id":"45d4fc726f2cc5b524be862c14fdadc1a24b25b8c6c011eedf2d2909589263e7","pubkey":"73c7f6d5bb599bb7d7cee84c72e89dbd549df53da522ed6c7611055cc0db64bc","created_at":1681821952,"kind":1,"tags":[["p","73c7f6d5bb599bb7d7cee84c72e89dbd549df53da522ed6c7611055cc0db64bc"],["e","e2ae784b239cac4bad38136e4bd758b87dd261b659ef460450064bf9073edcb3"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"test 7","sig":"e2c35766479d549700f4dbaeae385cfdacee1275ddf24777643ca7d7335c6d1baf7f89ac25d1dc90688bc49f8d2f5e4857d2234035291628a0c0ac760485bab0"}, + {"id":"7a4a2419824669f07081abe2132f8cc0027efbce066ccdf187c897bb7ffa5dc3","pubkey":"73c7f6d5bb599bb7d7cee84c72e89dbd549df53da522ed6c7611055cc0db64bc","created_at":1681821936,"kind":1,"tags":[["p","73c7f6d5bb599bb7d7cee84c72e89dbd549df53da522ed6c7611055cc0db64bc"],["e","e2ae784b239cac4bad38136e4bd758b87dd261b659ef460450064bf9073edcb3"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"test 5","sig":"875339b3e666fb1013d6563552997dcdd02e87b1f290ad25b0d7dd085d2f87dd10a4e6c20dfe3fc109d1809733b93675505341fe149e4399c42371c743fafc73"}, + {"id":"674c62f84afdc045bc3623ea132d90afdfe4b64249807f65302231115af5406d","pubkey":"73c7f6d5bb599bb7d7cee84c72e89dbd549df53da522ed6c7611055cc0db64bc","created_at":1681648340,"kind":1,"tags":[["p","73c7f6d5bb599bb7d7cee84c72e89dbd549df53da522ed6c7611055cc0db64bc"],["e","e2ae784b239cac4bad38136e4bd758b87dd261b659ef460450064bf9073edcb3"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"nested reply","sig":"f0f4fdd2d34e59255137c457b9d42fa9b5357e824f3154340de964616f6daf21e3b03491363b0060f97c5061445d7b2854eed328c5cced751b2b480e5ce8ce9a"}, + {"id":"d54761f672669ea4f4b7592f3b0a30ee28de340b0a7e46b91af94e66905171c9","pubkey":"73c7f6d5bb599bb7d7cee84c72e89dbd549df53da522ed6c7611055cc0db64bc","created_at":1681648345,"kind":1,"tags":[["p","73c7f6d5bb599bb7d7cee84c72e89dbd549df53da522ed6c7611055cc0db64bc"],["e","674c62f84afdc045bc3623ea132d90afdfe4b64249807f65302231115af5406d"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"another one","sig":"dd732eb380542dd8068449d5617bb8b6c1dfe1495c9facbd46aad3ca9b084122479df30861b8e85e13e7b0c9bf9bce589b7fc062daa086c1ff8a0b1d1ffc7aa7"}, + {"id":"00813a18ac9084cd0948c27027a980e34039a3011f30279a8b52ad87da5a3031","pubkey":"73c7f6d5bb599bb7d7cee84c72e89dbd549df53da522ed6c7611055cc0db64bc","created_at":1681648351,"kind":1,"tags":[["p","73c7f6d5bb599bb7d7cee84c72e89dbd549df53da522ed6c7611055cc0db64bc"],["e","d54761f672669ea4f4b7592f3b0a30ee28de340b0a7e46b91af94e66905171c9"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"yet another one","sig":"6332c8a441439487898fd5b423e42dde7d1d7aadfcf9b36defd78d76d1685ba099ac86ae00a1dac6ed5e8a166422d59bbb93bfccb2596dc1c5461efcfcf345b4"}, + {"id":"87a5bd25aa084cefb3357fc9c2a5b327254fab35fdd7b2d4bd0acddc63d0abe8","pubkey":"726a1e261cc6474674e8285e3951b3bb139be9a773d1acf49dc868db861a1c11","created_at":1687990701,"kind":1,"tags":[["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599","","root"],["e","00813a18ac9084cd0948c27027a980e34039a3011f30279a8b52ad87da5a3031","","reply"]],"content":"and another one more","sig":"6a385fb259ff40d9b6bd8bb1d5a2e20057ec1c5b5ed2c307fbc40e4a96d4c191b80b6ea3f3f5748c907d4b0e6e64a92210a0be2889af856ad084ec6806f3cbd8"}, + {"id":"512962dbada5fd5015fc727a107d5c3f569662de67eab8e5da5a8065012cf11e","pubkey":"7fa56f5d6962ab1e3cd424e758c3002b8665f7b0d8dcee9fe9e288d7751ac194","created_at":1688194800,"kind":1,"tags":[["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599","","root"],["e","87a5bd25aa084cefb3357fc9c2a5b327254fab35fdd7b2d4bd0acddc63d0abe8","","reply"]],"content":"another one","sig":"b4bc4d8206a08de0a918043129b27c8863d17f60e4f58b4d2b535326625870d32640b04f247eb9eb5df1d62fe98c8e1b0341bdd119655553488300ec9d5b4036"}, + {"id":"ce6e32e3e17b6901d2cc70b60f3743e24f885bb6e9da6d88cff516079eac1883","pubkey":"726a1e261cc6474674e8285e3951b3bb139be9a773d1acf49dc868db861a1c11","created_at":1688234921,"kind":1,"tags":[["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599","","root"],["e","512962dbada5fd5015fc727a107d5c3f569662de67eab8e5da5a8065012cf11e","","reply"]],"content":"yet another one, testing 0.0.3","sig":"13bd41c4029c6a7ee41cb03d12e831e9e9b6e14d43a61c78a72657070b45385ba2ce98e8121049fbcbdb7b2dd777c36c7867ba70b5e6a4798a9b866910ae5b62"} + ] + """.trimIndent() + + val header = """ + { + "content": "Not too long ago, I tried to paint a picture of what\na [vision for a value-enabled web][vew]\ncould look like. Now, only a couple of months later,\nall this stuff is being built. On nostr, and on lightning. Orange and\npurple, a match made in heaven.\n\nIt goes without saying that I'm beyond delighted. What a time to be alive!\n\n## nostr\n\nHere's the thing that nostr got right, and it's the same thing that\nBitcoin got right: information is easy to spread and hard to stifle.[^fn-stifle]\nInformation can be copied quickly and perfectly, which is, I believe,\nthe underlying reason for its desire to be free.\n\n[^fn-stifle]: That's a [Satoshi quote][stifle], of course: \"Bitcoin's solution is to use a peer-to-peer network to check for double-spending. In a nutshell, the network works like a distributed timestamp server, stamping the first transaction to spend a coin. It takes advantage of the nature of information being easy to spread but hard to stifle.\"\n\n[stifle]: https://satoshi.nakamotoinstitute.org/posts/p2pfoundation/1/\n\nEasy to spread, hard to stifle. That's the base reality of the nature\nof information. As always, the smart thing is to work with nature, not\nagainst it.[^1] That's what's beautiful about the orange coin and\nthe purple ostrich: both manage to work with the peculiarities of\ninformation, not against them. Both realize that information can and should be\ncopied, as it can be perfectly read and easily spread, always. Both understand\nthat resistance to censorship comes from writing to many places, making the cost\nof deletion prohibitive.\n\n> Information does not just want to be free,\n> it longs to be free. Information expands to fill the available\n> storage space. Information is Rumor's younger, stronger cousin;\n> Information is fleeter of foot, has more eyes, knows more, and\n> understands less than Rumor.\n>\n> Eric Hughes, [A Cypherpunk's Manifesto][manifesto]\n\n[manifesto]: https://nakamotoinstitute.org/static/docs/cypherpunk-manifesto.txt\n\nNostr is quickly establishing itself as a base layer for information exchange,\none that is identity-native and value-enabled. It is distinctly different from\nsystems that came before it, just like Bitcoin is distinctly different from\nmonies that came before it.\n\nAs of today, the focus of nostr is mostly on short text notes, the so-called\n\"type 1\" events more commonly known as *tweets*.[^fn-kinds] However, as you should be aware\nby now, nostr is way more than just an alternative to twitter. It is a new\nparadigm. Change the note kind from `1` to `30023` and you don't have an\nalternative to Twitter, but a replacement for Medium, Substack, and all the\nother long-form platforms. I believe that special-purpose clients that focus on\ncertain content types will emerge over time, just like we have seen the\nemergence of special-purpose platforms in the Web 2.0 era. This time, however,\nthe network effects are cumulative, not separate. A new paradigm.\n\nLet me now turn to one such special-purpose client, a nostr-based reading app.\n\n[^fn-kinds]: Refer to the various NIPs to discover the multitude of [event kinds][kinds] defined by the protocol.\n\n[kinds]: https://github.com/nostr-protocol/nips#event-kinds\n[nip23]: https://github.com/nostr-protocol/nips/blob/master/23.md\n\n## Reading\n\nI'm constantly surprised that, even though most people do read a lot\nonline, very few people seem to have a reading workflow or reading\ntools.\n\nWhy that is is anyone's guess, but maybe the added value of such tools\nis not readily apparent. You can just read the stuff right there, on the\nad-ridden, dead-ugly site, right? Why should you sign up for another\nsite, use another app, or bind yourself to another closed platform?\n\nThat's a fair point, but the success of Medium and Substack shows that\nthere is an appetite for clean reading and writing, as well as providing\navenues for authors to get paid for their writing (and a willingness of\nreaders to support said authors, just because).\n\nThe problem is, of course, that all of these platforms are *platforms*,\nwhich is to say, walled gardens that imprison readers and writers alike.\nWorse than that: they are fiat platforms, which means that\npermissionless value-flows are not only absent from their DNA, they are\noutright impossible.[^2]\n\nNostr fixes this.\n\n![Nostriches like to read, or so I've heard](https://dergigi.com/assets/images/bitcoin/2023-04-04-purple-text-orange-highlights/nostrich-reading-a-newspaper.jpg)\n\nThe beauty of nostr is that it is not a platform. It's a protocol,\nwhich means that you don't have to sign up for it---you can create an\nidentity yourself. You don't have to ask for permission; you just *do*,\nwithout having to rely on the benevolence of whatever dictator is in\ncharge of the platform right now.\n\nNostr is *not* a platform, and yet, powerful tools and services can be\nbuilt and monetized on top of it. This is good for users, good for\nservice providers, and good for the network(s) at large. Win-win-win.\n\nSo what am I talking about, exactly? How can nostr improve everyone's\nreading (and writing) experience?\n\nAllow me to paint a (rough) picture of what I have in mind. Nostr\nalready supports private and public bookmarks, so let's start from\nthere.\n\nImagine a special-purpose client that scans all your bookmarks for long-form\ncontent.[^fn-urls] Everything that you marked to be read later is shown in an orderly\nfashion, which is to say searchable, sortable, filterable, and displayed without\ndistractions. Voilà, you have yourself a reading app. That's, in essence, how\nPocket, Readwise, and other reading apps work. But all these apps are walled\ngardens without much interoperability and without direct monetization.\n\n[^fn-urls]: In the nostr world long-form content is simply markdown as defined in [NIP-23][nip23], but it could also be a link to an article or PDF, which in turn could get [converted into markdown][readability] and posted as an event to a special relay.\n\n[readability]: https://github.com/mozilla/readability\n\nBitcoin fixes the direct monetization part.[^fn-v4v] Nostr fixes the interoperability part.\n\n[^fn-v4v]: ...because Bitcoin makes [V4V][busking] practical. (Paywalls are not the way.)\n\nAlright, we got ourselves a boring reading app. Great. Now, imagine that\nusers are able to highlight passages. These highlights, just like\nbookmarks now, could be private or public. When shared publicly,\nsomething interesting emerges: an overlay on existing content, a lens on\nthe written Web. In other words: *swarm highlights*.\n\nImagine a visual overlay of all public highlights, automatically shining\na light on what the swarm of readers found most useful, insightful,\nfunny, etc.\n\n![Swarm Highlights](https://dergigi.com/assets/images/bitcoin/2023-04-04-purple-text-orange-highlights/highlights.png)\n\nFurther, imagine the possibility of sharing these highlights as a \"type 1\" event\nwith one click, automatically tagging the highlighter(s)---as well as the\nauthor, of course---so that eventual sat-flows can be split and forwarded\nautomatically.\n\n![Automated value splits](https://dergigi.com/assets/images/bitcoin/2023-04-04-purple-text-orange-highlights/sat-flows.png)\n\nVoilà, you have a system that allows for value to flow back to those who\nprovide it, be it authors, editors, curators, or readers that willingly\nslog through the information jungle to share and highlight the best\nstuff (which is a form of curation, of course).\n\nZaps make nostr a defacto address book[^fn-pp] of payment information, which is\nto say lightning addresses, as of now. Thanks to [nostr wallet connect][nwc] (among\nother developments), sending sats ~~will soon be~~ is already as\nfrictionless as leaving a like.\n\n[^fn-pp]: The Yellow Pages are dead, long live [The Purple Pages](http://purplepag.es/)!\n\nValue-for-value and participatory payment flows are something that\ntraditional reading apps desperately lack, be it Pocket, Instapaper,\nReadwise, or the simple reading mode that is part of every browser.\n\nA neat side-effect of a more structured way to share passages of text is\nthat it enables semi-structured discussions around said\npassages---which could be another useful overlay inside\nspecial-purpose clients, providing context and further insights.[^5]\n\nFurther, imagine the option of seamlessly switching from text-on-screen\nto text-to-speech, allowing the user to stream sats if desired, as\nPodcasting 2.0 clients already do.[^3]\n\nImagine user-built curations of the best articles of the week, bundled\nneatly for your reading pleasure, incentivized by a small value split\nthat allows the curator to participate in the flow of sats.\n\nYou get the idea.\n\nI'm sure that the various implementation details will be hashed out,\nbut as I see it, 90% of the stuff is already there. Maybe we'll need\nanother NIP or two, but I don't see a reason why this can't be\nbuilt---and, more importantly: I don't see a reason why it wouldn't\nbe sustainable for everyone involved.\n\nMost puzzle pieces are already there, and the rest of them can probably\nbe implemented by custom event types. From the point of view of nostr,\nmost everything is an event: bookmarks are events, highlights are\nevents, marking something as read is an event, and sharing an excerpt or\na highlight is an event. Public actions are out in the open, private\nactions are encrypted, the data is not in a silo, and everyone wins.\nEspecially the users, those who are at the edge of the network and\nusually lose out on the value generated.\n\nIn this case, the reading case, the users are mostly \"consumers\" of\ncontent. What changes from the producing perspective, the perspective of\nthe writer?\n\n## Writing\n\nBack to the one thing that nostr got right: information is easy to\nspread but hard to stifle. In addition to that, digital information can\nbe copied perfectly, which is why it shouldn't matter where stuff is\npublished in the first place.\n\nAllow me to repeat this point in all caps, for emphasis: **IT SHOULD NOT\nMATTER WHERE INFORMATION IS PUBLISHED**, and, maybe even more\nimportantly, it shouldn't matter if it is published in a hundred\ndifferent places at once.[^fn-torrents]\n\nWhat matters is trust and accuracy, which is to say, digital signatures\nand reputation. To translate this to nostr speak: because every event is\nsigned by default, as long as you trust the person behind the signature,\nit doesn't matter from which relay the information is fetched.\n\nThis is already true (or mostly true) on the regular web. Whether you\nread the internet archive version of an article or the version that is\npublished by an online magazine, the version on the author's website,\nor the version read by some guy that has read more about Bitcoin than\nanyone else you know[^fn-guy]---it's all the same, essentially. What matters\nis the information itself.\n\n[^fn-guy]: There is only one such guy, as we all know, and it's this Guy: nostr:npub1h8nk2346qezka5cpm8jjh3yl5j88pf4ly2ptu7s6uu55wcfqy0wq36rpev\n\nPractically speaking, the source of truth in a hypernostrized world is---you\nguessed it---an event. An event signed by the author, which allows for\nthe information to be wrapped in a tamper-proof manner, which in turn\nallows the information to spread far and wide---without it being\nhosted in one place.\n\nThe first clients that focus on long-form content already exist, and I expect\nmore clients to pop up over time.[^4] As mentioned before, one could easily\nimagine [prism-like value splits][prism] seamlessly integrated into these\nclients, splitting zaps automatically to compensate writers, editors,\nproofreaders, and illustrators in a V4V fashion. Further, one could imagine\nvarious compute-intensive services built into these special-purpose clients,\nsuch as GPT Ghostwriters, or writing aids such as Grammarly and the like. All\nthese services could be seamlessly paid for in sats, without the requirement of\nany sign-ups or the gathering of any user data. That's the beauty of [money\nproper][rediscovery].\n\n![A clean and simple reading and writing interface](https://dergigi.com/assets/images/bitcoin/2023-04-04-purple-text-orange-highlights/nostr-reader-and-writer.png)\n\nPlagiarism is one issue that needs to be dealt with, of course. Humans\nare greedy, and some humans are assholes. Neither bitcoin nor nostr\nfixes this. However, while plagiarism detection is not necessarily\ntrivial, it is also not impossible, especially if most texts are\npublished on nostr first. Nostr-based publishing tools allow for\nOpenTimestamp attestations thanks\nto [NIP-03](https://github.com/nostr-protocol/nips/blob/master/03.md),\nwhich in turn allows for plagiarism detection based on \"first seen\"\nlookups.\n\nThat's just one way to deal with the problem, of course. In any case,\nI'm confident that we'll figure it out.\n\n## Value\n\nI believe that in the open ~~attention~~ information economy we find\nourselves in, value will mostly derive from effective curation,\ndissemination, and transmission of information, *not* the exclusive\nownership of it.\n\nAlthough it is still early days,\nthe [statistics](https://stats.podcastindex.org/v4v) around Podcasting\n2.0 and [nostr zaps](https://zaplife.lol/) clearly show that (a) people\nare willing to monetarily reward content they care about, and (b) the\nwillingness to send sats *increases* as friction *decreases*.\n\nThe ingenious thing about boostagrams and zaps is that they are direct\nand visible, which is to say, public and interactive. They are neither\nregular transactions nor simple donations---they are something else\nentirely. An unforgable value signal, a special form of gratitude and\nappreciation.\n\nContrast that with a link to Paypal or Patreon: impersonal, slow,\nindirect, and friction-laden. It's the opposite of a super-charged\ninteraction.\n\nWhile today's information jungle increasingly presents itself in the\nform of (short) videos and (long-form) audio, I believe that we will see\na renaissance of the written word, especially if we manage to move away\nfrom an economy built around attention, towards an economy built upon\nvalue and insight.\n\nThe orange future now has a purple hue, and I believe that it will be as\nbright as ever. We just have a lot of building to do.\n\n---\n\n## Further Reading\n\n- [A Vision for a Value-Enabled Web][vew]\n- [The Freedom of Value][busking]\n- [The Rediscovery of Money][prism]\n- [Lightning Prisms][rediscovery]\n\n[vew]: https://dergigi.com/vew\n[prism]: https://dergigi.com/prism\n[rediscovery]: https://dergigi.com/rediscovery\n[busking]: https://dergigi.com/busking\n\n## NIPs and Resources\n\n- [Nostr Resources][nr]\n- [value4value.info](https://value4value.info/)\n- [nips.be](https://nips.be/)\n- [NIP-23: Long-form content](https://github.com/nostr-protocol/nips/blob/master/23.md)\n- [NIP-57: Event-specific zap markers](https://github.com/nostr-protocol/nips/blob/master/57.md)\n- [NIP-47: Nostr Wallet Connect](https://github.com/getAlby/nips/blob/master/47.md)\n- [NIP-03: OpenTimestamps attestations for events](https://github.com/nostr-protocol/nips/blob/master/03.md)\n\nOriginally published on [dergigi.com](https://dergigi.com/reader)\n\n---\n\n[^1]: Paywalls work against this nature, which is why I consider them misguided at best and incredibly retarded at worst.\n\n[^2]: Fiat doesn't work for the [value-enabled web][vew], as fiat rails can never be open and permissionless. Digital fiat is never money. It is---and always will be---[credit][rediscovery].\n\n[^3]: Whether the recipient is a text-to-speech service provider or a human narrator doesn't even matter too much, sats will flow just the same.\n\n[^4]: [BlogStack](https://blogstack.io/) and [Habla](https://habla.news/) being two of them.\n\n[^5]: Use a URI as the discussion base (instead of a highlight), and you got yourself a [Disqus](https://disqus.com/) in purple feathers!\n\n[^fn-torrents]: That's what torrents got right, and [ipfs] for that matter.\n\n[nr]: https://nostr-resources.com\n[nwc]: https://nwc.getalby.com/\n[ipfs]: https://fiatjaf.com/d5031e5b.html\n", + "created_at": 1680614039, + "id": "9517aa60334990596fdea4493c1bde429c55e9cefb84d8d88a6758c4e3ebcabc", + "kind": 30023, + "pubkey": "6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93", + "sig": "c8c8c7ac8c288f6a6e1090e0e5f7eed85daaaba03eeab0a4936535f95ce066c08723bedcfb80a6af4941a9fafb9fe351950b9376d13ff0e81030cd4391840f04", + "tags": [ + ["d","1680612926599"], + ["title","Purple Text, Orange Highlights"], + ["summary","Using nostr as a base layer to create, consume, and monetize long-form content."], + ["published_at","1680613802"], + ["t","nostr"], + ["t","reading"], + ["t","writing"], + ["t","readability"], + ["t","highlights"], + ["t","pocket"], + ["t","instapaper"], + ["t","readwise"], + ["t","disqus"], + ["t","v4v"], + ["t","value4value"], + ["image","https://dergigi.com/assets/images/reader.jpg"], + ["p","b9e76546ba06456ed301d9e52bc49fa48e70a6bf2282be7a1ae72947612023dc"] + ] + } + """.trimIndent() + + @Test + fun threadOrderTest() { + val eventArray = Event.mapper.readValue>(db) as List + Event.fromJson(header) + + var counter = 0 + eventArray.forEach { + TestCase.assertTrue("${it.id} failed signature check", it.hasValidSignature()) + LocalCache.verifyAndConsume(it, null) + counter++ + } + + val naddr = ATag(30023, "6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93", "1680612926599", null) + + val filter = ThreadFeedFilter(naddr.toTag()) + val calculatedFeed = filter.feed() + + val expecteedOrder = listOf( + "30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599", + "e15b386824fbfdcbf1b50b8860f03062cef534a3ea5339cc837536fb2a58465e", + "ba9a8a1a8afb0b53fb5d4fa3f5130fe557a8d8d56fac7af9ad3443531d2a2933", + "b0425132a3dd4142a0f78986166aaa28021cc8fb440c95c321a95afce3d5e056", + "e9bb4e2d56bd2be2952570bd52b102c23444a62ada5b78ba086f086d9147651a", + "4d7b21c462f3fbf27a1882dbaaec4e99e5a5d18a2c18d1f2d1f0736684ad157c", + "9cdbced750e6b1e1274b7df47cb433f565414dd08c897167eba761eadee841cc", + "5799aac7a9b06f3cae3d3791b79df29d14173515cfdbf34398aab73ed4a44121", + "741f5367a9415f4d6f19c0f57a1e4647c8ed8309b53b0da2d82fc4ebfba03b2c", + "22323fc72b4c37f93ea21f6069684339ce5f63111161c81f2aa3de4a21bfe83b", + "14525fcaae530a029f782fd361dd0cd66634c3e23020bd19e66fe11c1e254e32", + "98ae0d6d10e494ed0bf70feb577e8225c6a6732c7af3d29f88bfe1b87d4439e6", + "36e262e71b7e8bcae946f69885b8c3614e318e82864437342cf50e8b9ab7229d", + "37725c2924ca267d66c2c27c2dae65550c07e7b883034cf1ea69671883430642", + "8ba54cfb6375270e8ae97a7e0992c1a0dbaa4cd46af8309d67a839e86789fde6", + "53410bc6d47e87f3f18ecbc93c716b5a6ef8ee3805516b2ff4d155154a685b7c", + "a3b3825af621727f9af3bd77392fe38c04d71658024916af7fe4c5867ef73eaa", + "e383476cb1ce5accde11d4b1338424fa32c3724cf96e6214af8e5e852981728a", + "e2d8aaed336d3c0f73a9ca46a89fdb2da62a6d172936a91b0067a68797b3bcb8", + "b92e4d6a5d0e8d1d2d2421044b84a4d11f2188261c55145d782b1b6bf0995009", + "da13e14cc8bcc243e0373dde14533d3829b8b621e214ca3c99c90f3dd9e11b8a", + "b5234d90a1543ba60765c57ac3fc7140129a4ac28bbd013531ec9b85e256ea55", + "c5ad64b1b72776a068c39f4549d089032432814a146849eba0650d1b329fb285", + "fc4e4a1230b002e4ae08251a0b26107de7f518800188b7a504f5de62d8b07996", + "6a58f8315af5badb1bdaeb5489417b94621a4d8e192ae2fedcca0c5dcf0c9cd4", + "6e9bb03c7c40d67fec0d0bb872548ec207ba0ac4533efa137d7bcaca9fb4b191", + "e2ae784b239cac4bad38136e4bd758b87dd261b659ef460450064bf9073edcb3", + "45d4fc726f2cc5b524be862c14fdadc1a24b25b8c6c011eedf2d2909589263e7", + "7a4a2419824669f07081abe2132f8cc0027efbce066ccdf187c897bb7ffa5dc3", + "674c62f84afdc045bc3623ea132d90afdfe4b64249807f65302231115af5406d", + "d54761f672669ea4f4b7592f3b0a30ee28de340b0a7e46b91af94e66905171c9", + "00813a18ac9084cd0948c27027a980e34039a3011f30279a8b52ad87da5a3031", + "87a5bd25aa084cefb3357fc9c2a5b327254fab35fdd7b2d4bd0acddc63d0abe8", + "512962dbada5fd5015fc727a107d5c3f569662de67eab8e5da5a8065012cf11e", + "ce6e32e3e17b6901d2cc70b60f3743e24f885bb6e9da6d88cff516079eac1883", + "d4a0b4f08d98d82a04292654ec132723cc2cf3fa24ffb6c0833426cb9372f4d5", + "8cdc4676aca93bbafcfbe6784f9b2df54e8ca20fbe69ba55fda487736bfdb7f6", + "7a18dda355525d468b31bba4fa947cba98cc19048d4a3099d5e9ba045d878c26" + ) + + for (i in expecteedOrder.indices) { + assertEquals(expecteedOrder[i], calculatedFeed[i].idHex) + } + } +} diff --git a/app/src/androidTest/java/com/vitorpamplona/amethyst/UrlUserTagTransformationTest.kt b/app/src/androidTest/java/com/vitorpamplona/amethyst/UrlUserTagTransformationTest.kt index 4f98b023e..68eae0777 100644 --- a/app/src/androidTest/java/com/vitorpamplona/amethyst/UrlUserTagTransformationTest.kt +++ b/app/src/androidTest/java/com/vitorpamplona/amethyst/UrlUserTagTransformationTest.kt @@ -5,10 +5,10 @@ import androidx.compose.ui.text.AnnotatedString import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.platform.app.InstrumentationRegistry import com.vitorpamplona.amethyst.model.LocalCache -import com.vitorpamplona.amethyst.model.UserMetadata -import com.vitorpamplona.amethyst.model.decodePublicKey -import com.vitorpamplona.amethyst.model.toHexKey import com.vitorpamplona.amethyst.ui.actions.buildAnnotatedStringWithUrlHighlighting +import com.vitorpamplona.quartz.encoders.decodePublicKey +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.events.UserMetadata import org.junit.Assert.assertEquals import org.junit.Test import org.junit.runner.RunWith @@ -29,7 +29,10 @@ class UrlUserTagTransformationTest { @Test fun transformationText() { - val user = LocalCache.getOrCreateUser(decodePublicKey("npub1gcxzte5zlkncx26j68ez60fzkvtkm9e0vrwdcvsjakxf9mu9qewqlfnj5z").toHexKey()) + val user = LocalCache.getOrCreateUser( + decodePublicKey("npub1gcxzte5zlkncx26j68ez60fzkvtkm9e0vrwdcvsjakxf9mu9qewqlfnj5z") + .toHexKey() + ) user.info = UserMetadata() user.info?.displayName = "Vitor Pamplona" @@ -63,7 +66,10 @@ class UrlUserTagTransformationTest { @Test fun transformationTextTwoKeys() { - val user = LocalCache.getOrCreateUser(decodePublicKey("npub1gcxzte5zlkncx26j68ez60fzkvtkm9e0vrwdcvsjakxf9mu9qewqlfnj5z").toHexKey()) + val user = LocalCache.getOrCreateUser( + decodePublicKey("npub1gcxzte5zlkncx26j68ez60fzkvtkm9e0vrwdcvsjakxf9mu9qewqlfnj5z") + .toHexKey() + ) user.info = UserMetadata() user.info?.displayName = "Vitor Pamplona" diff --git a/app/src/fdroid/java/com/vitorpamplona/amethyst/ui/components/TranslatableRichTextViewer.kt b/app/src/fdroid/java/com/vitorpamplona/amethyst/ui/components/TranslatableRichTextViewer.kt index 93b0ea1b5..5c7855ed1 100644 --- a/app/src/fdroid/java/com/vitorpamplona/amethyst/ui/components/TranslatableRichTextViewer.kt +++ b/app/src/fdroid/java/com/vitorpamplona/amethyst/ui/components/TranslatableRichTextViewer.kt @@ -4,8 +4,8 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import com.vitorpamplona.amethyst.ui.actions.ImmutableListOfLists import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel +import com.vitorpamplona.quartz.events.ImmutableListOfLists @Composable fun TranslatableRichTextViewer( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt b/app/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt index 717b8243c..cce79d5b6 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt @@ -4,8 +4,7 @@ import android.annotation.SuppressLint import android.content.Context import android.content.SharedPreferences import androidx.compose.runtime.Immutable -import com.google.gson.GsonBuilder -import com.google.gson.reflect.TypeToken +import com.fasterxml.jackson.module.kotlin.readValue import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.ConnectivityType import com.vitorpamplona.amethyst.model.GLOBAL_FOLLOWS @@ -14,17 +13,16 @@ import com.vitorpamplona.amethyst.model.Nip47URI import com.vitorpamplona.amethyst.model.RelaySetupInfo import com.vitorpamplona.amethyst.model.ServersAvailable import com.vitorpamplona.amethyst.model.Settings -import com.vitorpamplona.amethyst.model.hexToByteArray import com.vitorpamplona.amethyst.model.parseConnectivityType -import com.vitorpamplona.amethyst.model.toHexKey import com.vitorpamplona.amethyst.service.HttpClient -import com.vitorpamplona.amethyst.service.KeyPair -import com.vitorpamplona.amethyst.service.model.ContactListEvent -import com.vitorpamplona.amethyst.service.model.Event -import com.vitorpamplona.amethyst.service.model.Event.Companion.getRefinedEvent -import com.vitorpamplona.amethyst.service.model.LnZapEvent -import com.vitorpamplona.amethyst.service.toNpub -import fr.acinq.secp256k1.Hex +import com.vitorpamplona.quartz.crypto.KeyPair +import com.vitorpamplona.quartz.encoders.Hex +import com.vitorpamplona.quartz.encoders.hexToByteArray +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.encoders.toNpub +import com.vitorpamplona.quartz.events.ContactListEvent +import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.events.LnZapEvent import java.io.File import java.util.Locale @@ -79,8 +77,6 @@ private object PrefKeys { val LAST_READ: (String) -> String = { route -> "last_read_route_$route" } } -private val gson = GsonBuilder().create() - object LocalPreferences { private const val comma = "," @@ -217,20 +213,20 @@ object LocalPreferences { putStringSet(PrefKeys.FOLLOWING_CHANNELS, account.followingChannels) putStringSet(PrefKeys.FOLLOWING_COMMUNITIES, account.followingCommunities) putStringSet(PrefKeys.HIDDEN_USERS, account.hiddenUsers) - putString(PrefKeys.RELAYS, gson.toJson(account.localRelays)) + putString(PrefKeys.RELAYS, Event.mapper.writeValueAsString(account.localRelays)) putStringSet(PrefKeys.DONT_TRANSLATE_FROM, account.dontTranslateFrom) - putString(PrefKeys.LANGUAGE_PREFS, gson.toJson(account.languagePreferences)) + putString(PrefKeys.LANGUAGE_PREFS, Event.mapper.writeValueAsString(account.languagePreferences)) putString(PrefKeys.TRANSLATE_TO, account.translateTo) - putString(PrefKeys.ZAP_AMOUNTS, gson.toJson(account.zapAmountChoices)) - putString(PrefKeys.REACTION_CHOICES, gson.toJson(account.reactionChoices)) - putString(PrefKeys.DEFAULT_ZAPTYPE, gson.toJson(account.defaultZapType)) - putString(PrefKeys.DEFAULT_FILE_SERVER, gson.toJson(account.defaultFileServer)) + putString(PrefKeys.ZAP_AMOUNTS, Event.mapper.writeValueAsString(account.zapAmountChoices)) + putString(PrefKeys.REACTION_CHOICES, Event.mapper.writeValueAsString(account.reactionChoices)) + putString(PrefKeys.DEFAULT_ZAPTYPE, account.defaultZapType.name) + putString(PrefKeys.DEFAULT_FILE_SERVER, account.defaultFileServer.name) putString(PrefKeys.DEFAULT_HOME_FOLLOW_LIST, account.defaultHomeFollowList) putString(PrefKeys.DEFAULT_STORIES_FOLLOW_LIST, account.defaultStoriesFollowList) putString(PrefKeys.DEFAULT_NOTIFICATION_FOLLOW_LIST, account.defaultNotificationFollowList) putString(PrefKeys.DEFAULT_DISCOVERY_FOLLOW_LIST, account.defaultDiscoveryFollowList) - putString(PrefKeys.ZAP_PAYMENT_REQUEST_SERVER, gson.toJson(account.zapPaymentRequest)) - putString(PrefKeys.LATEST_CONTACT_LIST, Event.gson.toJson(account.backupContactList)) + putString(PrefKeys.ZAP_PAYMENT_REQUEST_SERVER, Event.mapper.writeValueAsString(account.zapPaymentRequest)) + putString(PrefKeys.LATEST_CONTACT_LIST, Event.mapper.writeValueAsString(account.backupContactList)) putBoolean(PrefKeys.HIDE_DELETE_REQUEST_DIALOG, account.hideDeleteRequestDialog) putBoolean(PrefKeys.HIDE_NIP_24_WARNING_DIALOG, account.hideNIP24WarningDialog) putBoolean(PrefKeys.HIDE_BLOCK_ALERT_DIALOG, account.hideBlockAlertDialog) @@ -238,7 +234,7 @@ object LocalPreferences { putInt(PrefKeys.PROXY_PORT, account.proxyPort) putBoolean(PrefKeys.WARN_ABOUT_REPORTS, account.warnAboutPostsWithReports) putBoolean(PrefKeys.FILTER_SPAM_FROM_STRANGERS, account.filterSpamFromStrangers) - putString(PrefKeys.LAST_READ_PER_ROUTE, gson.toJson(account.lastReadPerRoute)) + putString(PrefKeys.LAST_READ_PER_ROUTE, Event.mapper.writeValueAsString(account.lastReadPerRoute)) if (account.showSensitiveContent == null) { remove(PrefKeys.SHOW_SENSITIVE_CONTENT) @@ -302,10 +298,9 @@ object LocalPreferences { val followingChannels = getStringSet(PrefKeys.FOLLOWING_CHANNELS, null) ?: setOf() val followingCommunities = getStringSet(PrefKeys.FOLLOWING_COMMUNITIES, null) ?: setOf() val hiddenUsers = getStringSet(PrefKeys.HIDDEN_USERS, emptySet()) ?: setOf() - val localRelays = gson.fromJson( - getString(PrefKeys.RELAYS, "[]"), - object : TypeToken>() {}.type - ) ?: setOf() + val localRelays = getString(PrefKeys.RELAYS, "[]")?.let { + Event.mapper.readValue>(it) + } ?: setOf() val dontTranslateFrom = getStringSet(PrefKeys.DONT_TRANSLATE_FROM, null) ?: setOf() val translateTo = getString(PrefKeys.TRANSLATE_TO, null) ?: Locale.getDefault().language @@ -314,29 +309,25 @@ object LocalPreferences { val defaultNotificationFollowList = getString(PrefKeys.DEFAULT_NOTIFICATION_FOLLOW_LIST, null) ?: GLOBAL_FOLLOWS val defaultDiscoveryFollowList = getString(PrefKeys.DEFAULT_DISCOVERY_FOLLOW_LIST, null) ?: GLOBAL_FOLLOWS - val zapAmountChoices = gson.fromJson( - getString(PrefKeys.ZAP_AMOUNTS, "[]"), - object : TypeToken>() {}.type - ) ?: listOf(500L, 1000L, 5000L) + val zapAmountChoices = getString(PrefKeys.ZAP_AMOUNTS, "[]")?.let { + Event.mapper.readValue>(it) + }?.ifEmpty { listOf(500L, 1000L, 5000L) } ?: listOf(500L, 1000L, 5000L) - val reactionChoices = gson.fromJson>( - getString(PrefKeys.REACTION_CHOICES, "[]"), - object : TypeToken>() {}.type - ).ifEmpty { listOf("+") } ?: listOf("+") + val reactionChoices = getString(PrefKeys.REACTION_CHOICES, "[]")?.let { + Event.mapper.readValue>(it) + }?.ifEmpty { listOf("+") } ?: listOf("+") - val defaultZapType = gson.fromJson( - getString(PrefKeys.DEFAULT_ZAPTYPE, "PUBLIC"), - object : TypeToken() {}.type - ) ?: LnZapEvent.ZapType.PUBLIC + val defaultZapType = getString(PrefKeys.DEFAULT_ZAPTYPE, "")?.let { serverName -> + LnZapEvent.ZapType.values().first { it.name == serverName } + } ?: LnZapEvent.ZapType.PUBLIC - val defaultFileServer = gson.fromJson( - getString(PrefKeys.DEFAULT_FILE_SERVER, "NOSTR_BUILD"), - object : TypeToken() {}.type - ) ?: ServersAvailable.NOSTR_BUILD + val defaultFileServer = getString(PrefKeys.DEFAULT_FILE_SERVER, "")?.let { serverName -> + ServersAvailable.values().first { it.name == serverName } + } ?: ServersAvailable.NOSTR_BUILD val zapPaymentRequestServer = try { getString(PrefKeys.ZAP_PAYMENT_REQUEST_SERVER, null)?.let { - gson.fromJson(it, Nip47URI::class.java) + Event.mapper.readValue(it) } } catch (e: Throwable) { e.printStackTrace() @@ -345,8 +336,7 @@ object LocalPreferences { val latestContactList = try { getString(PrefKeys.LATEST_CONTACT_LIST, null)?.let { - Event.gson.fromJson(it, Event::class.java) - .getRefinedEvent(true) as ContactListEvent + Event.fromJson(it) as ContactListEvent? } } catch (e: Throwable) { e.printStackTrace() @@ -355,10 +345,7 @@ object LocalPreferences { val languagePreferences = try { getString(PrefKeys.LANGUAGE_PREFS, null)?.let { - gson.fromJson( - it, - object : TypeToken>() {}.type - ) as Map + Event.mapper.readValue>(it) } ?: mapOf() } catch (e: Throwable) { e.printStackTrace() @@ -382,10 +369,7 @@ object LocalPreferences { val lastReadPerRoute = try { getString(PrefKeys.LAST_READ_PER_ROUTE, null)?.let { - gson.fromJson( - it, - object : TypeToken>() {}.type - ) as Map + Event.mapper.readValue>(it) } ?: mapOf() } catch (e: Throwable) { e.printStackTrace() diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt index 67c2d0226..fd034067a 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt @@ -8,11 +8,8 @@ import androidx.core.os.ConfigurationCompat import androidx.lifecycle.LiveData import androidx.lifecycle.distinctUntilChanged import com.vitorpamplona.amethyst.OptOutFromFilters -import com.vitorpamplona.amethyst.service.CryptoUtils import com.vitorpamplona.amethyst.service.FileHeader -import com.vitorpamplona.amethyst.service.KeyPair import com.vitorpamplona.amethyst.service.NostrLnZapPaymentResponseDataSource -import com.vitorpamplona.amethyst.service.model.* import com.vitorpamplona.amethyst.service.relays.Client import com.vitorpamplona.amethyst.service.relays.Constants import com.vitorpamplona.amethyst.service.relays.FeedType @@ -20,6 +17,13 @@ import com.vitorpamplona.amethyst.service.relays.Relay import com.vitorpamplona.amethyst.service.relays.RelayPool import com.vitorpamplona.amethyst.ui.components.BundledUpdate import com.vitorpamplona.amethyst.ui.note.combineWith +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.crypto.KeyPair +import com.vitorpamplona.quartz.encoders.ATag +import com.vitorpamplona.quartz.encoders.HexKey +import com.vitorpamplona.quartz.encoders.hexToByteArray +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.events.* import kotlinx.collections.immutable.ImmutableSet import kotlinx.collections.immutable.persistentSetOf import kotlinx.collections.immutable.toImmutableSet @@ -1381,7 +1385,12 @@ class Account( } fun getBlockListNote(): AddressableNote { - val aTag = ATag(PeopleListEvent.kind, userProfile().pubkeyHex, PeopleListEvent.blockList, null) + val aTag = ATag( + PeopleListEvent.kind, + userProfile().pubkeyHex, + PeopleListEvent.blockList, + null + ) return LocalCache.getOrCreateAddressableNote(aTag) } @@ -1509,7 +1518,12 @@ class Account( val privKey = keyPair.privKey return if (listName != null) { - val aTag = ATag(PeopleListEvent.kind, userProfile().pubkeyHex, listName, null).toTag() + val aTag = ATag( + PeopleListEvent.kind, + userProfile().pubkeyHex, + listName, + null + ).toTag() val list = LocalCache.addressables[aTag] if (list != null) { val publicHexList = (list.event as? PeopleListEvent)?.bookmarkedPeople() ?: emptySet() @@ -1533,7 +1547,12 @@ class Account( val privKey = keyPair.privKey return if (listName != null) { - val aTag = ATag(PeopleListEvent.kind, userProfile().pubkeyHex, listName, null).toTag() + val aTag = ATag( + PeopleListEvent.kind, + userProfile().pubkeyHex, + listName, + null + ).toTag() val list = LocalCache.addressables[aTag] if (list != null) { val publicAddresses = list.event?.hashtags() ?: emptySet() @@ -1557,7 +1576,12 @@ class Account( val privKey = keyPair.privKey return if (listName != null) { - val aTag = ATag(PeopleListEvent.kind, userProfile().pubkeyHex, listName, null).toTag() + val aTag = ATag( + PeopleListEvent.kind, + userProfile().pubkeyHex, + listName, + null + ).toTag() val list = LocalCache.addressables[aTag] if (list != null) { val publicAddresses = list.event?.geohashes() ?: emptySet() @@ -1581,7 +1605,12 @@ class Account( val privKey = keyPair.privKey return if (listName != null) { - val aTag = ATag(PeopleListEvent.kind, userProfile().pubkeyHex, listName, null).toTag() + val aTag = ATag( + PeopleListEvent.kind, + userProfile().pubkeyHex, + listName, + null + ).toTag() val list = LocalCache.addressables[aTag] if (list != null) { val publicAddresses = list.event?.taggedAddresses()?.map { it.toTag() } ?: emptySet() diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/AntiSpamFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/AntiSpamFilter.kt index 0bd42bd4e..dab9a1473 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/AntiSpamFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/AntiSpamFilter.kt @@ -6,10 +6,11 @@ import androidx.compose.runtime.Stable import androidx.lifecycle.LiveData import com.vitorpamplona.amethyst.OptOutFromFilters import com.vitorpamplona.amethyst.service.checkNotInMainThread -import com.vitorpamplona.amethyst.service.model.Event -import com.vitorpamplona.amethyst.service.nip19.Nip19 import com.vitorpamplona.amethyst.service.relays.Relay import com.vitorpamplona.amethyst.ui.components.BundledUpdate +import com.vitorpamplona.quartz.encoders.HexKey +import com.vitorpamplona.quartz.encoders.Nip19 +import com.vitorpamplona.quartz.events.Event import kotlinx.coroutines.Dispatchers data class Spammer(val pubkeyHex: HexKey, var duplicatedMessages: Set) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/Channel.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/Channel.kt index 217020561..70bc4a706 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/Channel.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/Channel.kt @@ -4,13 +4,14 @@ import androidx.compose.runtime.Stable import androidx.lifecycle.LiveData import com.vitorpamplona.amethyst.service.NostrSingleChannelDataSource import com.vitorpamplona.amethyst.service.checkNotInMainThread -import com.vitorpamplona.amethyst.service.model.ATag -import com.vitorpamplona.amethyst.service.model.ChannelCreateEvent -import com.vitorpamplona.amethyst.service.model.LiveActivitiesEvent -import com.vitorpamplona.amethyst.service.toNote import com.vitorpamplona.amethyst.ui.components.BundledUpdate import com.vitorpamplona.amethyst.ui.note.toShortenHex -import fr.acinq.secp256k1.Hex +import com.vitorpamplona.quartz.encoders.ATag +import com.vitorpamplona.quartz.encoders.Hex +import com.vitorpamplona.quartz.encoders.HexKey +import com.vitorpamplona.quartz.encoders.toNote +import com.vitorpamplona.quartz.events.ChannelCreateEvent +import com.vitorpamplona.quartz.events.LiveActivitiesEvent import kotlinx.coroutines.Dispatchers import java.util.concurrent.ConcurrentHashMap diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/HexUtils.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/HexUtils.kt deleted file mode 100644 index 0f5a13027..000000000 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/HexUtils.kt +++ /dev/null @@ -1,52 +0,0 @@ -package com.vitorpamplona.amethyst.model - -import com.vitorpamplona.amethyst.service.KeyPair -import com.vitorpamplona.amethyst.service.bechToBytes -import com.vitorpamplona.amethyst.service.nip19.Nip19 -import com.vitorpamplona.amethyst.ui.note.toShortenHex -import fr.acinq.secp256k1.Hex - -/** Makes the distinction between String and Hex **/ -typealias HexKey = String - -fun ByteArray.toHexKey(): HexKey { - return Hex.encode(this) -} - -fun HexKey.hexToByteArray(): ByteArray { - return Hex.decode(this) -} - -fun HexKey.toDisplayHexKey(): String { - return this.toShortenHex() -} - -fun decodePublicKey(key: String): ByteArray { - val parsed = Nip19.uriToRoute(key) - val pubKeyParsed = parsed?.hex?.hexToByteArray() - - return if (key.startsWith("nsec")) { - KeyPair(privKey = key.bechToBytes()).pubKey - } else if (pubKeyParsed != null) { - pubKeyParsed - } else { - Hex.decode(key) - } -} - -fun decodePublicKeyAsHexOrNull(key: String): HexKey? { - return try { - val parsed = Nip19.uriToRoute(key) - val pubKeyParsed = parsed?.hex - - if (key.startsWith("nsec")) { - KeyPair(privKey = key.bechToBytes()).pubKey.toHexKey() - } else if (pubKeyParsed != null) { - pubKeyParsed - } else { - Hex.decode(key).toHexKey() - } - } catch (e: Exception) { - null - } -} diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt index 0664e2bb5..e7a774ba2 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt @@ -3,13 +3,17 @@ package com.vitorpamplona.amethyst.model import android.util.Log import androidx.compose.runtime.Stable import com.vitorpamplona.amethyst.Amethyst -import com.vitorpamplona.amethyst.service.HexValidator import com.vitorpamplona.amethyst.service.checkNotInMainThread -import com.vitorpamplona.amethyst.service.model.* -import com.vitorpamplona.amethyst.service.nip19.Nip19 import com.vitorpamplona.amethyst.service.relays.Relay import com.vitorpamplona.amethyst.ui.components.BundledInsert -import fr.acinq.secp256k1.Hex +import com.vitorpamplona.quartz.encoders.ATag +import com.vitorpamplona.quartz.encoders.Hex +import com.vitorpamplona.quartz.encoders.HexKey +import com.vitorpamplona.quartz.encoders.HexValidator +import com.vitorpamplona.quartz.encoders.Nip19 +import com.vitorpamplona.quartz.encoders.decodePublicKeyAsHexOrNull +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.events.* import kotlinx.collections.immutable.persistentSetOf import kotlinx.collections.immutable.toImmutableSet import kotlinx.coroutines.* diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/Nip47URI.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/Nip47URI.kt index 3401a255d..887e4df00 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/Nip47URI.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/Nip47URI.kt @@ -1,3 +1,5 @@ package com.vitorpamplona.amethyst.model +import com.vitorpamplona.quartz.encoders.HexKey + data class Nip47URI(val pubKeyHex: HexKey, val relayUri: String?, val secret: HexKey?) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/Note.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/Note.kt index 3d9705b1c..5045abc16 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/Note.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/Note.kt @@ -6,25 +6,24 @@ import androidx.lifecycle.LiveData import com.vitorpamplona.amethyst.service.NostrSingleEventDataSource import com.vitorpamplona.amethyst.service.checkNotInMainThread import com.vitorpamplona.amethyst.service.firstFullCharOrEmoji -import com.vitorpamplona.amethyst.service.lnurl.LnInvoiceUtil -import com.vitorpamplona.amethyst.service.model.* -import com.vitorpamplona.amethyst.service.nip19.Nip19 import com.vitorpamplona.amethyst.service.relays.EOSETime import com.vitorpamplona.amethyst.service.relays.Relay -import com.vitorpamplona.amethyst.service.toNote -import com.vitorpamplona.amethyst.ui.actions.ImmutableListOfLists import com.vitorpamplona.amethyst.ui.actions.updated import com.vitorpamplona.amethyst.ui.components.BundledUpdate import com.vitorpamplona.amethyst.ui.note.toShortenHex -import fr.acinq.secp256k1.Hex +import com.vitorpamplona.quartz.encoders.ATag +import com.vitorpamplona.quartz.encoders.Hex +import com.vitorpamplona.quartz.encoders.HexKey +import com.vitorpamplona.quartz.encoders.LnInvoiceUtil +import com.vitorpamplona.quartz.encoders.Nip19 +import com.vitorpamplona.quartz.encoders.toNote +import com.vitorpamplona.quartz.events.* +import com.vitorpamplona.quartz.utils.TimeUtils import kotlinx.coroutines.Dispatchers import java.math.BigDecimal import java.time.Instant import java.time.ZoneId import java.time.format.DateTimeFormatter -import java.util.regex.Pattern - -val tagSearch = Pattern.compile("(?:\\s|\\A)\\#\\[([0-9]+)\\]") @Stable class AddressableNote(val address: ATag) : Note(address.toTag()) { @@ -121,17 +120,24 @@ open class Note(val idHex: String) { /** * This method caches signatures during each execution to avoid recalculation in longer threads */ - fun replyLevelSignature(cachedSignatures: MutableMap = mutableMapOf()): String { + fun replyLevelSignature( + eventsToConsider: Set, + cachedSignatures: MutableMap + ): String { val replyTo = replyTo if (event is RepostEvent || event is GenericRepostEvent || replyTo == null || replyTo.isEmpty()) { return "/" + formattedDateTime(createdAt() ?: 0) + ";" } - return replyTo + val mySignature = replyTo + .filter { it in eventsToConsider } // This forces the signature to be based on a branch, avoiding two roots .map { - cachedSignatures[it] ?: it.replyLevelSignature(cachedSignatures).apply { cachedSignatures.put(it, this) } + cachedSignatures[it] ?: it.replyLevelSignature(eventsToConsider, cachedSignatures).apply { cachedSignatures.put(it, this) } } .maxBy { it.length }.removeSuffix(";") + "/" + formattedDateTime(createdAt() ?: 0) + ";" + + cachedSignatures[this] = mySignature + return mySignature } fun replyLevel(cachedLevels: MutableMap = mutableMapOf()): Int { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/ParticipantListBuilder.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/ParticipantListBuilder.kt index 0ff26b895..544dc9cfe 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/ParticipantListBuilder.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/ParticipantListBuilder.kt @@ -1,5 +1,7 @@ package com.vitorpamplona.amethyst.model +import com.vitorpamplona.quartz.encoders.HexKey + class ParticipantListBuilder { private fun addFollowsThatDirectlyParticipateOnToSet(baseNote: Note, followingSet: Set?, set: MutableSet) { baseNote.author?.let { author -> diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/RelayInformation.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/RelayInformation.kt index 73d3942d2..81e38a037 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/RelayInformation.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/RelayInformation.kt @@ -1,17 +1,12 @@ package com.vitorpamplona.amethyst.model import androidx.compose.runtime.Stable -import com.google.gson.Gson -import com.google.gson.GsonBuilder -import com.google.gson.JsonArray -import com.google.gson.JsonElement -import com.google.gson.JsonObject -import com.google.gson.JsonSerializationContext -import com.google.gson.JsonSerializer -import java.lang.reflect.Type +import com.fasterxml.jackson.databind.DeserializationFeature +import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper @Stable class RelayInformation( + val id: String?, val name: String?, val description: String?, val pubkey: String?, @@ -29,15 +24,9 @@ class RelayInformation( val fees: RelayInformationFees? ) { companion object { - val gson: Gson = GsonBuilder() - .disableHtmlEscaping() - .registerTypeAdapter(RelayInformation::class.java, RelayInformationSerializer()) - .registerTypeAdapter(RelayInformationLimitation::class.java, RelayInformationLimitationSerializer()) - .registerTypeAdapter(RelayInformationFees::class.java, RelayInformationFeesSerializer()) - .registerTypeAdapter(RelayInformationFee::class.java, RelayInformationFeeSerializer()) - .create() + val mapper = jacksonObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) - fun fromJson(json: String): RelayInformation = gson.fromJson(json, RelayInformation::class.java) + fun fromJson(json: String): RelayInformation = mapper.readValue(json, RelayInformation::class.java) } } @@ -47,96 +36,14 @@ class RelayInformationFee( val unit: String?, val period: Int?, val kinds: List? -) { - companion object { - val gson: Gson = GsonBuilder() - .disableHtmlEscaping() - .registerTypeAdapter(RelayInformationFee::class.java, RelayInformationFeeSerializer()) - .create() - - fun fromJson(json: String): RelayInformationFee = gson.fromJson(json, RelayInformationFee::class.java) - } -} - -private class RelayInformationFeeSerializer : JsonSerializer { - override fun serialize( - src: RelayInformationFee, - typeOfSrc: Type?, - context: JsonSerializationContext? - ): JsonElement { - return JsonObject().apply { - addProperty("amount", src.amount) - addProperty("unit", src.unit) - addProperty("period", src.period) - add( - "kinds", - JsonArray().also { kinds -> - src.kinds?.forEach { kind -> - kinds.add( - kind - ) - } - } - ) - } - } -} +) class RelayInformationFees( val admission: List?, val subscription: List?, - val publication: List? -) { - companion object { - val gson: Gson = GsonBuilder() - .disableHtmlEscaping() - .registerTypeAdapter(RelayInformationFees::class.java, RelayInformationFeesSerializer()) - .create() - - fun fromJson(json: String): RelayInformationFees = gson.fromJson(json, RelayInformationFees::class.java) - } -} - -private class RelayInformationFeesSerializer : JsonSerializer { - override fun serialize( - src: RelayInformationFees, - typeOfSrc: Type?, - context: JsonSerializationContext? - ): JsonElement { - return JsonObject().apply { - add( - "admission", - JsonArray().also { admissions -> - src.admission?.forEach { admission -> - admissions.add( - admission.toString() - ) - } - } - ) - add( - "publication", - JsonArray().also { publications -> - src.publication?.forEach { publication -> - publications.add( - publication.toString() - ) - } - } - ) - add( - "subscription", - JsonArray().also { subscriptions -> - src.subscription?.forEach { subscription -> - subscriptions.add( - subscription.toString() - ) - } - } - ) - } - } -} + val publication: List?, + val retention: List? +) class RelayInformationLimitation( val max_message_length: Int?, @@ -150,104 +57,4 @@ class RelayInformationLimitation( val min_pow_difficulty: Int?, val auth_required: Boolean?, val payment_required: Boolean? -) { - companion object { - val gson: Gson = GsonBuilder() - .disableHtmlEscaping() - .registerTypeAdapter(RelayInformationLimitation::class.java, RelayInformationLimitationSerializer()) - .create() - - fun fromJson(json: String): RelayInformationLimitation = gson.fromJson(json, RelayInformationLimitation::class.java) - } -} - -private class RelayInformationLimitationSerializer : JsonSerializer { - override fun serialize( - src: RelayInformationLimitation, - typeOfSrc: Type?, - context: JsonSerializationContext? - ): JsonElement { - return JsonObject().apply { - addProperty("max_message_length", src.max_message_length) - addProperty("max_subscriptions", src.max_subscriptions) - addProperty("max_filters", src.max_filters) - addProperty("max_limit", src.max_limit) - addProperty("max_subid_length", src.max_subid_length) - addProperty("min_prefix", src.min_prefix) - addProperty("max_event_tags", src.max_event_tags) - addProperty("max_content_length", src.max_content_length) - addProperty("min_pow_difficulty", src.min_pow_difficulty) - addProperty("auth_required", src.auth_required) - addProperty("payment_required", src.payment_required) - } - } -} - -private class RelayInformationSerializer : JsonSerializer { - override fun serialize( - src: RelayInformation, - typeOfSrc: Type?, - context: JsonSerializationContext? - ): JsonElement { - return JsonObject().apply { - addProperty("name", src.name) - addProperty("description", src.description) - addProperty("pubkey", src.pubkey) - addProperty("contact", src.contact) - add( - "supported_nip_extensions", - JsonArray().also { supported_nip_extensions -> - src.supported_nip_extensions?.forEach { nip -> - supported_nip_extensions.add( - nip - ) - } - } - ) - add( - "supported_nips", - JsonArray().also { supported_nips -> - src.supported_nips?.forEach { nip -> - supported_nips.add( - nip - ) - } - } - ) - addProperty("software", src.software) - addProperty("version", src.version) - add( - "relay_countries", - JsonArray().also { relay_countries -> - src.relay_countries?.forEach { country -> - relay_countries.add( - country - ) - } - } - ) - add( - "language_tags", - JsonArray().also { language_tags -> - src.language_tags?.forEach { language_tag -> - language_tags.add( - language_tag - ) - } - } - ) - add( - "tags", - JsonArray().also { tags -> - src.tags?.forEach { tag -> - tags.add( - tag - ) - } - } - ) - addProperty("posting_policy", src.posting_policy) - addProperty("payments_url", src.payments_url) - } - } -} +) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/ThreadAssembler.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/ThreadAssembler.kt index 8a83f194b..c636884db 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/ThreadAssembler.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/ThreadAssembler.kt @@ -1,9 +1,8 @@ package com.vitorpamplona.amethyst.model import com.vitorpamplona.amethyst.service.checkNotInMainThread -import com.vitorpamplona.amethyst.service.model.GenericRepostEvent -import com.vitorpamplona.amethyst.service.model.RepostEvent -import kotlin.time.ExperimentalTime +import com.vitorpamplona.quartz.events.GenericRepostEvent +import com.vitorpamplona.quartz.events.RepostEvent import kotlin.time.measureTimedValue class ThreadAssembler { @@ -37,7 +36,6 @@ class ThreadAssembler { return null } - @OptIn(ExperimentalTime::class) fun findThreadFor(noteId: String): Set { checkNotInMainThread() diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/User.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/User.kt index 69e300cbb..ff33dccb1 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/User.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/User.kt @@ -3,23 +3,25 @@ package com.vitorpamplona.amethyst.model import androidx.compose.runtime.Immutable import androidx.compose.runtime.Stable import androidx.lifecycle.LiveData -import com.vitorpamplona.amethyst.service.Bech32 import com.vitorpamplona.amethyst.service.NostrSingleUserDataSource import com.vitorpamplona.amethyst.service.checkNotInMainThread -import com.vitorpamplona.amethyst.service.model.BookmarkListEvent -import com.vitorpamplona.amethyst.service.model.ContactListEvent -import com.vitorpamplona.amethyst.service.model.LnZapEvent -import com.vitorpamplona.amethyst.service.model.MetadataEvent -import com.vitorpamplona.amethyst.service.model.ReportEvent import com.vitorpamplona.amethyst.service.relays.EOSETime import com.vitorpamplona.amethyst.service.relays.Relay -import com.vitorpamplona.amethyst.service.toNpub -import com.vitorpamplona.amethyst.ui.actions.ImmutableListOfLists -import com.vitorpamplona.amethyst.ui.actions.toImmutableListOfLists import com.vitorpamplona.amethyst.ui.components.BundledUpdate import com.vitorpamplona.amethyst.ui.note.toShortenHex -import fr.acinq.secp256k1.Hex -import kotlinx.collections.immutable.ImmutableSet +import com.vitorpamplona.quartz.encoders.Bech32 +import com.vitorpamplona.quartz.encoders.Hex +import com.vitorpamplona.quartz.encoders.HexKey +import com.vitorpamplona.quartz.encoders.toNpub +import com.vitorpamplona.quartz.events.BookmarkListEvent +import com.vitorpamplona.quartz.events.ChatroomKey +import com.vitorpamplona.quartz.events.ContactListEvent +import com.vitorpamplona.quartz.events.LnZapEvent +import com.vitorpamplona.quartz.events.MetadataEvent +import com.vitorpamplona.quartz.events.ReportEvent +import com.vitorpamplona.quartz.events.UserMetadata +import com.vitorpamplona.quartz.events.toImmutableListOfLists +import com.vitorpamplona.quartz.utils.TimeUtils import kotlinx.collections.immutable.persistentSetOf import kotlinx.coroutines.Dispatchers import java.math.BigDecimal @@ -27,11 +29,6 @@ import java.util.regex.Pattern val lnurlpPattern = Pattern.compile("(?i:http|https):\\/\\/((.+)\\/)*\\.well-known\\/lnurlp\\/(.*)") -@Stable -data class ChatroomKey( - val users: ImmutableSet -) - @Stable class User(val pubkeyHex: String) { var info: UserMetadata? = null @@ -469,65 +466,6 @@ class Chatroom() { } } -@Stable -class UserMetadata { - var name: String? = null - var username: String? = null - var display_name: String? = null - var displayName: String? = null - var picture: String? = null - var banner: String? = null - var website: String? = null - var about: String? = null - - var nip05: String? = null - var nip05Verified: Boolean = false - var nip05LastVerificationTime: Long? = 0 - - var domain: String? = null - var lud06: String? = null - var lud16: String? = null - - var publish: String? = null - var iris: String? = null - var main_relay: String? = null - var twitter: String? = null - - var updatedMetadataAt: Long = 0 - var latestMetadata: MetadataEvent? = null - var tags: ImmutableListOfLists? = null - - fun anyName(): String? { - return display_name ?: displayName ?: name ?: username - } - - fun anyNameStartsWith(prefix: String): Boolean { - return listOfNotNull(name, username, display_name, displayName, nip05, lud06, lud16) - .any { it.contains(prefix, true) } - } - - fun lnAddress(): String? { - return (lud16?.trim() ?: lud06?.trim())?.ifBlank { null } - } - - fun bestUsername(): String? { - return name?.ifBlank { null } ?: username?.ifBlank { null } - } - - fun bestDisplayName(): String? { - return displayName?.ifBlank { null } ?: display_name?.ifBlank { null } - } - - fun nip05(): String? { - return nip05?.ifBlank { null } - } - - fun profilePicture(): String? { - if (picture.isNullOrBlank()) picture = null - return picture - } -} - class UserLiveData(val user: User) : LiveData(UserState(user)) { // Refreshes observers in batches. private val bundler = BundledUpdate(500, Dispatchers.IO) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/CachedRichTextParser.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/CachedRichTextParser.kt index 7c3ec2c59..4eb357334 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/CachedRichTextParser.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/CachedRichTextParser.kt @@ -6,7 +6,6 @@ import android.util.Patterns import androidx.compose.runtime.Immutable import com.linkedin.urls.detection.UrlDetector import com.linkedin.urls.detection.UrlDetectorOptions -import com.vitorpamplona.amethyst.ui.actions.ImmutableListOfLists import com.vitorpamplona.amethyst.ui.components.ZoomableUrlContent import com.vitorpamplona.amethyst.ui.components.ZoomableUrlImage import com.vitorpamplona.amethyst.ui.components.ZoomableUrlVideo @@ -15,6 +14,7 @@ import com.vitorpamplona.amethyst.ui.components.imageExtensions import com.vitorpamplona.amethyst.ui.components.startsWithNIP19Scheme import com.vitorpamplona.amethyst.ui.components.tagIndex import com.vitorpamplona.amethyst.ui.components.videoExtensions +import com.vitorpamplona.quartz.events.ImmutableListOfLists import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableMap import kotlinx.collections.immutable.ImmutableSet diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/CashuProcessor.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/CashuProcessor.kt index d3f25c7fd..39fc58ca4 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/CashuProcessor.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/CashuProcessor.kt @@ -1,12 +1,11 @@ package com.vitorpamplona.amethyst.service import androidx.compose.runtime.Immutable +import com.fasterxml.jackson.databind.JsonNode import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper -import com.google.gson.JsonArray -import com.google.gson.JsonObject -import com.google.gson.JsonParser import com.vitorpamplona.amethyst.service.lnurl.LightningAddressResolver import com.vitorpamplona.amethyst.ui.components.GenericLoadable +import com.vitorpamplona.quartz.events.Event import okhttp3.MediaType.Companion.toMediaType import okhttp3.Request import okhttp3.RequestBody.Companion.toRequestBody @@ -19,7 +18,7 @@ data class CashuToken( val totalAmount: Long, val fees: Int, val redeemInvoiceAmount: Long, - val proofs: JsonArray + val proofs: JsonNode ) class CashuProcessor { @@ -28,14 +27,14 @@ class CashuProcessor { try { val base64token = cashuToken.replace("cashuA", "") - val cashu = JsonParser.parseString(String(Base64.getDecoder().decode(base64token))) - val token = cashu.asJsonObject.get("token").asJsonArray[0].asJsonObject - val proofs = token["proofs"].asJsonArray - val mint = token["mint"].asString + val cashu = jacksonObjectMapper().readTree(String(Base64.getDecoder().decode(base64token))) + val token = cashu.get("token").get(0) + val proofs = token.get("proofs") + val mint = token.get("mint").asText() var totalAmount = 0L for (proof in proofs) { - totalAmount += proof.asJsonObject["amount"].asLong + totalAmount += proof.get("amount").asLong() } val fees = Math.max(((totalAmount * 0.02).toInt()), 2) val redeemInvoiceAmount = totalAmount - fees @@ -69,9 +68,11 @@ class CashuProcessor { val client = HttpClient.getHttpClient() val url = token.mint + "/melt" // Melt cashu tokens at Mint - val jsonObject = JsonObject() - jsonObject.add("proofs", token.proofs) - jsonObject.addProperty("pr", invoice) + val factory = Event.mapper.nodeFactory + + val jsonObject = factory.objectNode() + jsonObject.put("proofs", token.proofs) + jsonObject.put("pr", invoice) val mediaType = "application/json; charset=utf-8".toMediaType() val requestBody = jsonObject.toString().toRequestBody(mediaType) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/StringUtils.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/EmojiUtils.kt similarity index 97% rename from app/src/main/java/com/vitorpamplona/amethyst/service/StringUtils.kt rename to app/src/main/java/com/vitorpamplona/amethyst/service/EmojiUtils.kt index 404712a15..85f2e059b 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/StringUtils.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/EmojiUtils.kt @@ -1,6 +1,6 @@ package com.vitorpamplona.amethyst.service -import com.vitorpamplona.amethyst.ui.actions.ImmutableListOfLists +import com.vitorpamplona.quartz.events.ImmutableListOfLists fun String.isUTF16Char(pos: Int): Boolean { return Character.charCount(this.codePointAt(pos)) == 2 diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/FileHeader.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/FileHeader.kt index 4b4ca0bb6..d03cd7da1 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/FileHeader.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/FileHeader.kt @@ -3,8 +3,9 @@ package com.vitorpamplona.amethyst.service import android.graphics.Bitmap import android.graphics.BitmapFactory import android.util.Log -import com.vitorpamplona.amethyst.model.toHexKey import com.vitorpamplona.amethyst.ui.actions.ImageDownloader +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.toHexKey import io.trbl.blurhash.BlurHash import kotlin.math.roundToInt diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/HexValidator.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/HexValidator.kt deleted file mode 100644 index 10f2686b9..000000000 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/HexValidator.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.vitorpamplona.amethyst.service - -object HexValidator { - - private fun isHex2(c: Char): Boolean { - return when (c) { - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'A', 'B', 'C', 'D', 'E', 'F', ' ' -> true - else -> false - } - } - - fun isHex(hex: String?): Boolean { - if (hex == null) return false - var isHex = true - for (c in hex.toCharArray()) { - if (!isHex2(c)) { - isHex = false - break - } - } - return isHex - } -} diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/Nip47.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/Nip47.kt index 55160aeda..071f7a57f 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/Nip47.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/Nip47.kt @@ -2,8 +2,8 @@ package com.vitorpamplona.amethyst.ui.note import android.net.Uri import com.vitorpamplona.amethyst.model.Nip47URI -import com.vitorpamplona.amethyst.model.decodePublicKey -import com.vitorpamplona.amethyst.model.toHexKey +import com.vitorpamplona.quartz.encoders.decodePublicKey +import com.vitorpamplona.quartz.encoders.toHexKey // Rename to the corect nip number when ready. object Nip47 { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrAccountDataSource.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrAccountDataSource.kt index 4ed3941bc..2f4c8311b 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrAccountDataSource.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrAccountDataSource.kt @@ -2,24 +2,24 @@ package com.vitorpamplona.amethyst.service import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.LocalCache -import com.vitorpamplona.amethyst.service.model.* -import com.vitorpamplona.amethyst.service.model.BadgeAwardEvent -import com.vitorpamplona.amethyst.service.model.BadgeProfilesEvent -import com.vitorpamplona.amethyst.service.model.BookmarkListEvent -import com.vitorpamplona.amethyst.service.model.ChannelMessageEvent -import com.vitorpamplona.amethyst.service.model.ContactListEvent -import com.vitorpamplona.amethyst.service.model.LnZapEvent -import com.vitorpamplona.amethyst.service.model.MetadataEvent -import com.vitorpamplona.amethyst.service.model.ReactionEvent -import com.vitorpamplona.amethyst.service.model.ReportEvent -import com.vitorpamplona.amethyst.service.model.RepostEvent -import com.vitorpamplona.amethyst.service.model.TextNoteEvent import com.vitorpamplona.amethyst.service.relays.COMMON_FEED_TYPES import com.vitorpamplona.amethyst.service.relays.Client import com.vitorpamplona.amethyst.service.relays.EOSEAccount import com.vitorpamplona.amethyst.service.relays.JsonFilter import com.vitorpamplona.amethyst.service.relays.Relay import com.vitorpamplona.amethyst.service.relays.TypedFilter +import com.vitorpamplona.quartz.events.* +import com.vitorpamplona.quartz.events.BadgeAwardEvent +import com.vitorpamplona.quartz.events.BadgeProfilesEvent +import com.vitorpamplona.quartz.events.BookmarkListEvent +import com.vitorpamplona.quartz.events.ChannelMessageEvent +import com.vitorpamplona.quartz.events.ContactListEvent +import com.vitorpamplona.quartz.events.LnZapEvent +import com.vitorpamplona.quartz.events.MetadataEvent +import com.vitorpamplona.quartz.events.ReactionEvent +import com.vitorpamplona.quartz.events.ReportEvent +import com.vitorpamplona.quartz.events.RepostEvent +import com.vitorpamplona.quartz.events.TextNoteEvent object NostrAccountDataSource : NostrDataSource("AccountData") { lateinit var account: Account diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrChannelDataSource.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrChannelDataSource.kt index 5994c23a1..84e79dd3e 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrChannelDataSource.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrChannelDataSource.kt @@ -4,11 +4,11 @@ import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.Channel import com.vitorpamplona.amethyst.model.LiveActivitiesChannel import com.vitorpamplona.amethyst.model.PublicChatChannel -import com.vitorpamplona.amethyst.service.model.ChannelMessageEvent -import com.vitorpamplona.amethyst.service.model.LiveActivitiesChatMessageEvent import com.vitorpamplona.amethyst.service.relays.FeedType import com.vitorpamplona.amethyst.service.relays.JsonFilter import com.vitorpamplona.amethyst.service.relays.TypedFilter +import com.vitorpamplona.quartz.events.ChannelMessageEvent +import com.vitorpamplona.quartz.events.LiveActivitiesChatMessageEvent object NostrChannelDataSource : NostrDataSource("ChatroomFeed") { var account: Account? = null diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrChatroomDataSource.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrChatroomDataSource.kt index c6b926bb8..5a30c1a6b 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrChatroomDataSource.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrChatroomDataSource.kt @@ -1,12 +1,12 @@ package com.vitorpamplona.amethyst.service import com.vitorpamplona.amethyst.model.Account -import com.vitorpamplona.amethyst.model.ChatroomKey -import com.vitorpamplona.amethyst.service.model.PrivateDmEvent import com.vitorpamplona.amethyst.service.relays.EOSEAccount import com.vitorpamplona.amethyst.service.relays.FeedType import com.vitorpamplona.amethyst.service.relays.JsonFilter import com.vitorpamplona.amethyst.service.relays.TypedFilter +import com.vitorpamplona.quartz.events.ChatroomKey +import com.vitorpamplona.quartz.events.PrivateDmEvent object NostrChatroomDataSource : NostrDataSource("ChatroomFeed") { lateinit var account: Account diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrChatroomListDataSource.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrChatroomListDataSource.kt index 5e0f92f44..09826ca1e 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrChatroomListDataSource.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrChatroomListDataSource.kt @@ -1,15 +1,15 @@ package com.vitorpamplona.amethyst.service import com.vitorpamplona.amethyst.model.Account -import com.vitorpamplona.amethyst.service.model.ChannelCreateEvent -import com.vitorpamplona.amethyst.service.model.ChannelMessageEvent -import com.vitorpamplona.amethyst.service.model.ChannelMetadataEvent -import com.vitorpamplona.amethyst.service.model.PrivateDmEvent import com.vitorpamplona.amethyst.service.relays.COMMON_FEED_TYPES import com.vitorpamplona.amethyst.service.relays.EOSEAccount import com.vitorpamplona.amethyst.service.relays.FeedType import com.vitorpamplona.amethyst.service.relays.JsonFilter import com.vitorpamplona.amethyst.service.relays.TypedFilter +import com.vitorpamplona.quartz.events.ChannelCreateEvent +import com.vitorpamplona.quartz.events.ChannelMessageEvent +import com.vitorpamplona.quartz.events.ChannelMetadataEvent +import com.vitorpamplona.quartz.events.PrivateDmEvent object NostrChatroomListDataSource : NostrDataSource("MailBoxFeed") { lateinit var account: Account diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrCommunityDataSource.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrCommunityDataSource.kt index 77fbfcb90..6e8384a29 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrCommunityDataSource.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrCommunityDataSource.kt @@ -1,11 +1,11 @@ package com.vitorpamplona.amethyst.service import com.vitorpamplona.amethyst.model.AddressableNote -import com.vitorpamplona.amethyst.service.model.CommunityDefinitionEvent -import com.vitorpamplona.amethyst.service.model.CommunityPostApprovalEvent import com.vitorpamplona.amethyst.service.relays.COMMON_FEED_TYPES import com.vitorpamplona.amethyst.service.relays.JsonFilter import com.vitorpamplona.amethyst.service.relays.TypedFilter +import com.vitorpamplona.quartz.events.CommunityDefinitionEvent +import com.vitorpamplona.quartz.events.CommunityPostApprovalEvent object NostrCommunityDataSource : NostrDataSource("SingleCommunityFeed") { private var communityToWatch: AddressableNote? = null diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrDataSource.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrDataSource.kt index 6d6427e58..f403aaab3 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrDataSource.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrDataSource.kt @@ -2,13 +2,12 @@ package com.vitorpamplona.amethyst.service import android.util.Log import com.vitorpamplona.amethyst.model.LocalCache -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.service.model.* -import com.vitorpamplona.amethyst.service.model.Event import com.vitorpamplona.amethyst.service.relays.Client import com.vitorpamplona.amethyst.service.relays.Relay import com.vitorpamplona.amethyst.service.relays.Subscription import com.vitorpamplona.amethyst.ui.components.BundledUpdate +import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.utils.TimeUtils import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrDiscoveryDataSource.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrDiscoveryDataSource.kt index 3bd03f69a..d58f40853 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrDiscoveryDataSource.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrDiscoveryDataSource.kt @@ -1,17 +1,17 @@ package com.vitorpamplona.amethyst.service import com.vitorpamplona.amethyst.model.Account -import com.vitorpamplona.amethyst.service.model.ChannelCreateEvent -import com.vitorpamplona.amethyst.service.model.ChannelMessageEvent -import com.vitorpamplona.amethyst.service.model.ChannelMetadataEvent -import com.vitorpamplona.amethyst.service.model.CommunityDefinitionEvent -import com.vitorpamplona.amethyst.service.model.CommunityPostApprovalEvent -import com.vitorpamplona.amethyst.service.model.LiveActivitiesChatMessageEvent -import com.vitorpamplona.amethyst.service.model.LiveActivitiesEvent import com.vitorpamplona.amethyst.service.relays.EOSEAccount import com.vitorpamplona.amethyst.service.relays.FeedType import com.vitorpamplona.amethyst.service.relays.JsonFilter import com.vitorpamplona.amethyst.service.relays.TypedFilter +import com.vitorpamplona.quartz.events.ChannelCreateEvent +import com.vitorpamplona.quartz.events.ChannelMessageEvent +import com.vitorpamplona.quartz.events.ChannelMetadataEvent +import com.vitorpamplona.quartz.events.CommunityDefinitionEvent +import com.vitorpamplona.quartz.events.CommunityPostApprovalEvent +import com.vitorpamplona.quartz.events.LiveActivitiesChatMessageEvent +import com.vitorpamplona.quartz.events.LiveActivitiesEvent object NostrDiscoveryDataSource : NostrDataSource("DiscoveryFeed") { lateinit var account: Account diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrGeohashDataSource.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrGeohashDataSource.kt index 3e04dee9e..783988400 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrGeohashDataSource.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrGeohashDataSource.kt @@ -1,16 +1,16 @@ package com.vitorpamplona.amethyst.service -import com.vitorpamplona.amethyst.service.model.AudioTrackEvent -import com.vitorpamplona.amethyst.service.model.ChannelMessageEvent -import com.vitorpamplona.amethyst.service.model.ClassifiedsEvent -import com.vitorpamplona.amethyst.service.model.HighlightEvent -import com.vitorpamplona.amethyst.service.model.LiveActivitiesChatMessageEvent -import com.vitorpamplona.amethyst.service.model.LongTextNoteEvent -import com.vitorpamplona.amethyst.service.model.PollNoteEvent -import com.vitorpamplona.amethyst.service.model.TextNoteEvent import com.vitorpamplona.amethyst.service.relays.COMMON_FEED_TYPES import com.vitorpamplona.amethyst.service.relays.JsonFilter import com.vitorpamplona.amethyst.service.relays.TypedFilter +import com.vitorpamplona.quartz.events.AudioTrackEvent +import com.vitorpamplona.quartz.events.ChannelMessageEvent +import com.vitorpamplona.quartz.events.ClassifiedsEvent +import com.vitorpamplona.quartz.events.HighlightEvent +import com.vitorpamplona.quartz.events.LiveActivitiesChatMessageEvent +import com.vitorpamplona.quartz.events.LongTextNoteEvent +import com.vitorpamplona.quartz.events.PollNoteEvent +import com.vitorpamplona.quartz.events.TextNoteEvent object NostrGeohashDataSource : NostrDataSource("SingleGeoHashFeed") { private var geohashToWatch: String? = null diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrHashtagDataSource.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrHashtagDataSource.kt index 94784f29a..02ef50fba 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrHashtagDataSource.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrHashtagDataSource.kt @@ -1,17 +1,16 @@ package com.vitorpamplona.amethyst.service -import androidx.compose.ui.text.capitalize -import com.vitorpamplona.amethyst.service.model.AudioTrackEvent -import com.vitorpamplona.amethyst.service.model.ChannelMessageEvent -import com.vitorpamplona.amethyst.service.model.ClassifiedsEvent -import com.vitorpamplona.amethyst.service.model.HighlightEvent -import com.vitorpamplona.amethyst.service.model.LiveActivitiesChatMessageEvent -import com.vitorpamplona.amethyst.service.model.LongTextNoteEvent -import com.vitorpamplona.amethyst.service.model.PollNoteEvent -import com.vitorpamplona.amethyst.service.model.TextNoteEvent import com.vitorpamplona.amethyst.service.relays.COMMON_FEED_TYPES import com.vitorpamplona.amethyst.service.relays.JsonFilter import com.vitorpamplona.amethyst.service.relays.TypedFilter +import com.vitorpamplona.quartz.events.AudioTrackEvent +import com.vitorpamplona.quartz.events.ChannelMessageEvent +import com.vitorpamplona.quartz.events.ClassifiedsEvent +import com.vitorpamplona.quartz.events.HighlightEvent +import com.vitorpamplona.quartz.events.LiveActivitiesChatMessageEvent +import com.vitorpamplona.quartz.events.LongTextNoteEvent +import com.vitorpamplona.quartz.events.PollNoteEvent +import com.vitorpamplona.quartz.events.TextNoteEvent object NostrHashtagDataSource : NostrDataSource("SingleHashtagFeed") { private var hashtagToWatch: String? = null diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrHomeDataSource.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrHomeDataSource.kt index 88eafe939..f666d3075 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrHomeDataSource.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrHomeDataSource.kt @@ -2,22 +2,22 @@ package com.vitorpamplona.amethyst.service import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.UserState -import com.vitorpamplona.amethyst.service.model.AudioTrackEvent -import com.vitorpamplona.amethyst.service.model.ClassifiedsEvent -import com.vitorpamplona.amethyst.service.model.CommunityPostApprovalEvent -import com.vitorpamplona.amethyst.service.model.GenericRepostEvent -import com.vitorpamplona.amethyst.service.model.HighlightEvent -import com.vitorpamplona.amethyst.service.model.LiveActivitiesChatMessageEvent -import com.vitorpamplona.amethyst.service.model.LiveActivitiesEvent -import com.vitorpamplona.amethyst.service.model.LongTextNoteEvent -import com.vitorpamplona.amethyst.service.model.PinListEvent -import com.vitorpamplona.amethyst.service.model.PollNoteEvent -import com.vitorpamplona.amethyst.service.model.RepostEvent -import com.vitorpamplona.amethyst.service.model.TextNoteEvent import com.vitorpamplona.amethyst.service.relays.EOSEAccount import com.vitorpamplona.amethyst.service.relays.FeedType import com.vitorpamplona.amethyst.service.relays.JsonFilter import com.vitorpamplona.amethyst.service.relays.TypedFilter +import com.vitorpamplona.quartz.events.AudioTrackEvent +import com.vitorpamplona.quartz.events.ClassifiedsEvent +import com.vitorpamplona.quartz.events.CommunityPostApprovalEvent +import com.vitorpamplona.quartz.events.GenericRepostEvent +import com.vitorpamplona.quartz.events.HighlightEvent +import com.vitorpamplona.quartz.events.LiveActivitiesChatMessageEvent +import com.vitorpamplona.quartz.events.LiveActivitiesEvent +import com.vitorpamplona.quartz.events.LongTextNoteEvent +import com.vitorpamplona.quartz.events.PinListEvent +import com.vitorpamplona.quartz.events.PollNoteEvent +import com.vitorpamplona.quartz.events.RepostEvent +import com.vitorpamplona.quartz.events.TextNoteEvent import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrLnZapPaymentResponseDataSource.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrLnZapPaymentResponseDataSource.kt index 7993306f5..6b179794c 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrLnZapPaymentResponseDataSource.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrLnZapPaymentResponseDataSource.kt @@ -1,12 +1,12 @@ package com.vitorpamplona.amethyst.service -import com.vitorpamplona.amethyst.service.model.LnZapPaymentResponseEvent -import com.vitorpamplona.amethyst.service.model.RelayAuthEvent import com.vitorpamplona.amethyst.service.relays.Client import com.vitorpamplona.amethyst.service.relays.FeedType import com.vitorpamplona.amethyst.service.relays.JsonFilter import com.vitorpamplona.amethyst.service.relays.Relay import com.vitorpamplona.amethyst.service.relays.TypedFilter +import com.vitorpamplona.quartz.events.LnZapPaymentResponseEvent +import com.vitorpamplona.quartz.events.RelayAuthEvent class NostrLnZapPaymentResponseDataSource( private val fromServiceHex: String, diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrSearchEventOrUserDataSource.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrSearchEventOrUserDataSource.kt index 51ae523f1..315f91de3 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrSearchEventOrUserDataSource.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrSearchEventOrUserDataSource.kt @@ -1,13 +1,13 @@ package com.vitorpamplona.amethyst.service -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.model.* -import com.vitorpamplona.amethyst.service.nip19.Nip19 import com.vitorpamplona.amethyst.service.relays.COMMON_FEED_TYPES import com.vitorpamplona.amethyst.service.relays.FeedType import com.vitorpamplona.amethyst.service.relays.JsonFilter import com.vitorpamplona.amethyst.service.relays.TypedFilter -import fr.acinq.secp256k1.Hex +import com.vitorpamplona.quartz.encoders.Hex +import com.vitorpamplona.quartz.encoders.Nip19 +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.events.* object NostrSearchEventOrUserDataSource : NostrDataSource("SearchEventFeed") { private var searchString: String? = null diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleChannelDataSource.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleChannelDataSource.kt index 63c9d1f89..1315a614f 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleChannelDataSource.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleChannelDataSource.kt @@ -3,12 +3,12 @@ package com.vitorpamplona.amethyst.service import com.vitorpamplona.amethyst.model.LiveActivitiesChannel import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.PublicChatChannel -import com.vitorpamplona.amethyst.service.model.ChannelCreateEvent -import com.vitorpamplona.amethyst.service.model.ChannelMetadataEvent import com.vitorpamplona.amethyst.service.relays.COMMON_FEED_TYPES import com.vitorpamplona.amethyst.service.relays.FeedType import com.vitorpamplona.amethyst.service.relays.JsonFilter import com.vitorpamplona.amethyst.service.relays.TypedFilter +import com.vitorpamplona.quartz.events.ChannelCreateEvent +import com.vitorpamplona.quartz.events.ChannelMetadataEvent object NostrSingleChannelDataSource : NostrDataSource("SingleChannelFeed") { private var channelsToWatch = setOf() diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleEventDataSource.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleEventDataSource.kt index c5274166c..deb51116f 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleEventDataSource.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleEventDataSource.kt @@ -2,11 +2,11 @@ package com.vitorpamplona.amethyst.service import com.vitorpamplona.amethyst.model.AddressableNote import com.vitorpamplona.amethyst.model.Note -import com.vitorpamplona.amethyst.service.model.* import com.vitorpamplona.amethyst.service.relays.COMMON_FEED_TYPES import com.vitorpamplona.amethyst.service.relays.EOSETime import com.vitorpamplona.amethyst.service.relays.JsonFilter import com.vitorpamplona.amethyst.service.relays.TypedFilter +import com.vitorpamplona.quartz.events.* object NostrSingleEventDataSource : NostrDataSource("SingleEventFeed") { private var eventsToWatch = setOf() diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleUserDataSource.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleUserDataSource.kt index d6991c53f..47de281e7 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleUserDataSource.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleUserDataSource.kt @@ -1,12 +1,12 @@ package com.vitorpamplona.amethyst.service import com.vitorpamplona.amethyst.model.User -import com.vitorpamplona.amethyst.service.model.MetadataEvent -import com.vitorpamplona.amethyst.service.model.ReportEvent import com.vitorpamplona.amethyst.service.relays.COMMON_FEED_TYPES import com.vitorpamplona.amethyst.service.relays.EOSETime import com.vitorpamplona.amethyst.service.relays.JsonFilter import com.vitorpamplona.amethyst.service.relays.TypedFilter +import com.vitorpamplona.quartz.events.MetadataEvent +import com.vitorpamplona.quartz.events.ReportEvent object NostrSingleUserDataSource : NostrDataSource("SingleUserFeed") { var usersToWatch = setOf() diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrUserProfileDataSource.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrUserProfileDataSource.kt index 6ccc6f1ee..7ecd639f7 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrUserProfileDataSource.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrUserProfileDataSource.kt @@ -1,10 +1,10 @@ package com.vitorpamplona.amethyst.service import com.vitorpamplona.amethyst.model.User -import com.vitorpamplona.amethyst.service.model.* import com.vitorpamplona.amethyst.service.relays.COMMON_FEED_TYPES import com.vitorpamplona.amethyst.service.relays.JsonFilter import com.vitorpamplona.amethyst.service.relays.TypedFilter +import com.vitorpamplona.quartz.events.* object NostrUserProfileDataSource : NostrDataSource("UserProfileFeed") { var user: User? = null diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrVideoDataSource.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrVideoDataSource.kt index b91f1b2c3..1ca8bd199 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrVideoDataSource.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrVideoDataSource.kt @@ -1,12 +1,12 @@ package com.vitorpamplona.amethyst.service import com.vitorpamplona.amethyst.model.Account -import com.vitorpamplona.amethyst.service.model.FileHeaderEvent -import com.vitorpamplona.amethyst.service.model.FileStorageHeaderEvent import com.vitorpamplona.amethyst.service.relays.EOSEAccount import com.vitorpamplona.amethyst.service.relays.FeedType import com.vitorpamplona.amethyst.service.relays.JsonFilter import com.vitorpamplona.amethyst.service.relays.TypedFilter +import com.vitorpamplona.quartz.events.FileHeaderEvent +import com.vitorpamplona.quartz.events.FileStorageHeaderEvent object NostrVideoDataSource : NostrDataSource("VideoFeed") { lateinit var account: Account diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/lnurl/LightningAddressResolver.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/lnurl/LightningAddressResolver.kt index 26272766b..01e372fa3 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/lnurl/LightningAddressResolver.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/lnurl/LightningAddressResolver.kt @@ -2,10 +2,11 @@ package com.vitorpamplona.amethyst.service.lnurl import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import com.vitorpamplona.amethyst.BuildConfig -import com.vitorpamplona.amethyst.service.Bech32 import com.vitorpamplona.amethyst.service.HttpClient import com.vitorpamplona.amethyst.service.checkNotInMainThread -import com.vitorpamplona.amethyst.service.toLnUrl +import com.vitorpamplona.quartz.encoders.Bech32 +import com.vitorpamplona.quartz.encoders.LnInvoiceUtil +import com.vitorpamplona.quartz.encoders.toLnUrl import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/zaps/UserZaps.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/model/zaps/UserZaps.kt index a943797ac..23b2740f3 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/zaps/UserZaps.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/model/zaps/UserZaps.kt @@ -1,8 +1,8 @@ -package com.vitorpamplona.amethyst.service.model.zaps +package com.vitorpamplona.quartz.events.zaps import com.vitorpamplona.amethyst.model.Note -import com.vitorpamplona.amethyst.service.model.LnZapEventInterface import com.vitorpamplona.amethyst.ui.screen.ZapReqResponse +import com.vitorpamplona.quartz.events.LnZapEventInterface object UserZaps { fun forProfileFeed(zaps: Map?): List { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/notifications/EventNotificationConsumer.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/notifications/EventNotificationConsumer.kt index f18f1ef3a..c154778a4 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/notifications/EventNotificationConsumer.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/notifications/EventNotificationConsumer.kt @@ -6,19 +6,19 @@ import androidx.core.content.ContextCompat import com.vitorpamplona.amethyst.LocalPreferences import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.Account -import com.vitorpamplona.amethyst.model.ChatroomKey import com.vitorpamplona.amethyst.model.LocalCache -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.model.ChatMessageEvent -import com.vitorpamplona.amethyst.service.model.Event -import com.vitorpamplona.amethyst.service.model.GiftWrapEvent -import com.vitorpamplona.amethyst.service.model.LnZapEvent -import com.vitorpamplona.amethyst.service.model.LnZapRequestEvent -import com.vitorpamplona.amethyst.service.model.PrivateDmEvent -import com.vitorpamplona.amethyst.service.model.SealedGossipEvent import com.vitorpamplona.amethyst.service.notifications.NotificationUtils.sendDMNotification import com.vitorpamplona.amethyst.service.notifications.NotificationUtils.sendZapNotification import com.vitorpamplona.amethyst.ui.note.showAmount +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.events.ChatMessageEvent +import com.vitorpamplona.quartz.events.ChatroomKey +import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.events.GiftWrapEvent +import com.vitorpamplona.quartz.events.LnZapEvent +import com.vitorpamplona.quartz.events.LnZapRequestEvent +import com.vitorpamplona.quartz.events.PrivateDmEvent +import com.vitorpamplona.quartz.events.SealedGossipEvent import kotlinx.collections.immutable.persistentSetOf import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -47,17 +47,18 @@ class EventNotificationConsumer(private val applicationContext: Context) { } fun unwrapAndConsume(event: Event, account: Account): Event? { - if (account.keyPair.privKey == null) return null if (!LocalCache.justVerify(event)) return null return when (event) { is GiftWrapEvent -> { - event.cachedGift(account.keyPair.privKey)?.let { + val key = account.keyPair.privKey ?: return null + event.cachedGift(key)?.let { unwrapAndConsume(it, account) } } is SealedGossipEvent -> { - event.cachedGossip(account.keyPair.privKey)?.let { + val key = account.keyPair.privKey ?: return null + event.cachedGossip(key)?.let { // this is not verifiable LocalCache.justConsume(it, null) it diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/notifications/RegisterAccounts.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/notifications/RegisterAccounts.kt index 7407651d3..3fb7f7c3f 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/notifications/RegisterAccounts.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/notifications/RegisterAccounts.kt @@ -5,7 +5,7 @@ import com.vitorpamplona.amethyst.AccountInfo import com.vitorpamplona.amethyst.BuildConfig import com.vitorpamplona.amethyst.LocalPreferences import com.vitorpamplona.amethyst.service.HttpClient -import com.vitorpamplona.amethyst.service.model.RelayAuthEvent +import com.vitorpamplona.quartz.events.RelayAuthEvent import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/relays/Client.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/relays/Client.kt index e922670dd..f012b0f21 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/relays/Client.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/relays/Client.kt @@ -2,8 +2,8 @@ package com.vitorpamplona.amethyst.service.relays import com.vitorpamplona.amethyst.service.HttpClient import com.vitorpamplona.amethyst.service.checkNotInMainThread -import com.vitorpamplona.amethyst.service.model.Event -import com.vitorpamplona.amethyst.service.model.EventInterface +import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.events.EventInterface import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope @@ -17,16 +17,6 @@ import java.util.UUID * Events are stored with their respective persona. */ object Client : RelayPool.Listener { - /** - * Lenient mode: - * - * true: For maximum compatibility. If you want to play ball with sloppy counterparts, use - * this. - * false: For developers who want to make protocol compliant counterparts. If your software - * produces events that fail to deserialize in strict mode, you should probably fix - * something. - **/ - var lenient: Boolean = false private var listeners = setOf() private var relays = Constants.convertDefaultRelays() private var subscriptions = mapOf>() diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/relays/JsonFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/relays/JsonFilter.kt index 74bc52613..0fe851b6f 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/relays/JsonFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/relays/JsonFilter.kt @@ -1,9 +1,6 @@ package com.vitorpamplona.amethyst.service.relays -import com.google.gson.Gson -import com.google.gson.GsonBuilder -import com.google.gson.JsonArray -import com.google.gson.JsonObject +import com.vitorpamplona.quartz.events.Event class JsonFilter( val ids: List? = null, @@ -15,51 +12,64 @@ class JsonFilter( val limit: Int? = null, val search: String? = null ) { + fun toJson(forRelay: String? = null): String { - val jsonObject = JsonObject() - ids?.run { - jsonObject.add("ids", JsonArray().apply { ids.forEach { add(it) } }) - } - authors?.run { - jsonObject.add("authors", JsonArray().apply { authors.forEach { add(it) } }) - } - kinds?.run { - jsonObject.add("kinds", JsonArray().apply { kinds.forEach { add(it) } }) - } - tags?.run { - entries.forEach { kv -> - jsonObject.add("#${kv.key}", JsonArray().apply { kv.value.forEach { add(it) } }) + val factory = Event.mapper.nodeFactory + val filter = factory.objectNode().apply { + ids?.run { + put( + "ids", + factory.arrayNode(ids.size).apply { + ids.forEach { add(it) } + } + ) } - } - since?.run { - if (!isEmpty()) { - if (forRelay != null) { - val relaySince = get(forRelay) - if (relaySince != null) { - jsonObject.addProperty("since", relaySince.time) + authors?.run { + put( + "authors", + factory.arrayNode(authors.size).apply { + authors.forEach { add(it) } } - } else { - val jsonObjectSince = JsonObject() - entries.forEach { sincePairs -> - jsonObjectSince.addProperty(sincePairs.key, "${sincePairs.value}") + ) + } + kinds?.run { + put( + "kinds", + factory.arrayNode(kinds.size).apply { + kinds.forEach { add(it) } } - jsonObject.add("since", jsonObjectSince) + ) + } + tags?.run { + entries.forEach { kv -> + put( + "#${kv.key}", + factory.arrayNode(kv.value.size).apply { + kv.value.forEach { add(it) } + } + ) } } + since?.run { + if (!isEmpty()) { + if (forRelay != null) { + val relaySince = get(forRelay) + if (relaySince != null) { + put("since", relaySince.time) + } + } else { + val jsonObjectSince = factory.objectNode() + entries.forEach { sincePairs -> + put(sincePairs.key, "${sincePairs.value}") + } + put("since", jsonObjectSince) + } + } + } + until?.run { put("until", until) } + limit?.run { put("limit", limit) } + search?.run { put("search", search) } } - until?.run { - jsonObject.addProperty("until", until) - } - limit?.run { - jsonObject.addProperty("limit", limit) - } - search?.run { - jsonObject.addProperty("search", search) - } - return gson.toJson(jsonObject) - } - - companion object { - val gson: Gson = GsonBuilder().create() + return Event.mapper.writeValueAsString(filter) } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/relays/Relay.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/relays/Relay.kt index 74bdc5cba..dc7909179 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/relays/Relay.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/relays/Relay.kt @@ -1,13 +1,13 @@ package com.vitorpamplona.amethyst.service.relays import android.util.Log -import com.google.gson.JsonElement import com.vitorpamplona.amethyst.BuildConfig -import com.vitorpamplona.amethyst.model.TimeUtils import com.vitorpamplona.amethyst.service.checkNotInMainThread -import com.vitorpamplona.amethyst.service.model.Event -import com.vitorpamplona.amethyst.service.model.EventInterface -import com.vitorpamplona.amethyst.service.model.RelayAuthEvent +import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.events.EventInterface +import com.vitorpamplona.quartz.events.RelayAuthEvent +import com.vitorpamplona.quartz.events.bytesUsedInMemory +import com.vitorpamplona.quartz.utils.TimeUtils import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.Response @@ -189,13 +189,13 @@ class Relay( } fun processNewRelayMessage(newMessage: String) { - val msgArray = Event.gson.fromJson(newMessage, JsonElement::class.java).asJsonArray - val type = msgArray[0].asString - val channel = msgArray[1].asString + val msgArray = Event.mapper.readTree(newMessage) + val type = msgArray.get(0).asText() + val channel = msgArray.get(1).asText() when (type) { "EVENT" -> { - val event = Event.fromJson(msgArray[2], Client.lenient) + val event = Event.fromJson(msgArray.get(2)) // Log.w("Relay", "Relay onEVENT $url, $channel") listeners.forEach { @@ -215,12 +215,12 @@ class Relay( it.onError(this@Relay, channel, Error("Relay sent notice: " + channel)) } "OK" -> listeners.forEach { - Log.w("Relay", "Relay on OK $url, ${msgArray[1].asString}, ${msgArray[2].asBoolean}, ${msgArray[3].asString}") - it.onSendResponse(this@Relay, msgArray[1].asString, msgArray[2].asBoolean, msgArray[3].asString) + Log.w("Relay", "Relay on OK $url, ${msgArray[1].asText()}, ${msgArray[2].asBoolean()}, ${msgArray[3].asText()}") + it.onSendResponse(this@Relay, msgArray[1].asText(), msgArray[2].asBoolean(), msgArray[3].asText()) } "AUTH" -> listeners.forEach { // Log.w("Relay", "Relay$url, ${msg[1].asString}") - it.onAuth(this@Relay, msgArray[1].asString) + it.onAuth(this@Relay, msgArray[1].asText()) } else -> listeners.forEach { // Log.w("Relay", "Relay something else $url, $channel") @@ -343,7 +343,3 @@ class Relay( fun onRelayStateChange(relay: Relay, type: Type, channel: String?) } } - -fun String.bytesUsedInMemory(): Int { - return (8 * ((((this.length) * 2) + 45) / 8)) -} diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/relays/RelayPool.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/relays/RelayPool.kt index a5fe3a219..38d2c5868 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/relays/RelayPool.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/relays/RelayPool.kt @@ -2,8 +2,8 @@ package com.vitorpamplona.amethyst.service.relays import androidx.lifecycle.LiveData import com.vitorpamplona.amethyst.service.checkNotInMainThread -import com.vitorpamplona.amethyst.service.model.Event -import com.vitorpamplona.amethyst.service.model.EventInterface +import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.events.EventInterface import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/relays/Subscription.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/relays/Subscription.kt index 86870f3ef..50549afb4 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/relays/Subscription.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/relays/Subscription.kt @@ -1,8 +1,7 @@ package com.vitorpamplona.amethyst.service.relays -import com.google.gson.GsonBuilder -import com.google.gson.JsonArray -import com.google.gson.JsonObject +import com.fasterxml.jackson.databind.JsonNode +import com.vitorpamplona.quartz.events.Event import java.util.UUID data class Subscription( @@ -16,15 +15,24 @@ data class Subscription( } fun toJson(): String { - return GsonBuilder().create().toJson(toJsonObject()) + return Event.mapper.writeValueAsString(toJsonObject()) } - fun toJsonObject(): JsonObject { - val jsonObject = JsonObject() - jsonObject.addProperty("id", id) - typedFilters?.run { - jsonObject.add("typedFilters", JsonArray().apply { typedFilters?.forEach { add(it.toJsonObject()) } }) + fun toJsonObject(): JsonNode { + val factory = Event.mapper.nodeFactory + + return factory.objectNode().apply { + put("id", id) + typedFilters?.also { filters -> + put( + "typedFilters", + factory.arrayNode(filters.size).apply { + filters.forEach { filter -> + add(filter.toJsonObject()) + } + } + ) + } } - return jsonObject } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/relays/TypedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/relays/TypedFilter.kt index 96e6c0b90..75b11ad44 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/relays/TypedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/relays/TypedFilter.kt @@ -1,8 +1,8 @@ package com.vitorpamplona.amethyst.service.relays -import com.google.gson.GsonBuilder -import com.google.gson.JsonArray -import com.google.gson.JsonObject +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.node.ArrayNode +import com.vitorpamplona.quartz.events.Event class TypedFilter( val types: Set, @@ -10,54 +10,74 @@ class TypedFilter( ) { fun toJson(): String { - return GsonBuilder().create().toJson(toJsonObject()) + return Event.mapper.writeValueAsString(toJsonObject()) } - fun toJsonObject(): JsonObject { - val jsonObject = JsonObject() - jsonObject.add("types", typesToJson(types)) - jsonObject.add("filter", filterToJson(filter)) - return jsonObject + fun toJsonObject(): JsonNode { + val factory = Event.mapper.nodeFactory + + return factory.objectNode().apply { + put("types", typesToJson(types)) + put("filter", filterToJson(filter)) + } } - fun typesToJson(types: Set): JsonArray { - return JsonArray().apply { types.forEach { add(it.name.lowercase()) } } + fun typesToJson(types: Set): ArrayNode { + val factory = Event.mapper.nodeFactory + return factory.arrayNode(types.size).apply { + types.forEach { add(it.name.lowercase()) } + } } - fun filterToJson(filter: JsonFilter): JsonObject { - val jsonObject = JsonObject() - filter.ids?.run { - jsonObject.add("ids", JsonArray().apply { filter.ids.forEach { add(it) } }) - } - filter.authors?.run { - jsonObject.add("authors", JsonArray().apply { filter.authors.forEach { add(it) } }) - } - filter.kinds?.run { - jsonObject.add("kinds", JsonArray().apply { filter.kinds.forEach { add(it) } }) - } - filter.tags?.run { - entries.forEach { kv -> - jsonObject.add("#${kv.key}", JsonArray().apply { kv.value.forEach { add(it) } }) + fun filterToJson(filter: JsonFilter): JsonNode { + val factory = Event.mapper.nodeFactory + return factory.objectNode().apply { + filter.ids?.run { + put( + "ids", + factory.arrayNode(filter.ids.size).apply { + filter.ids.forEach { add(it) } + } + ) } - } - /* - Does not include since in the json comparison - filter.since?.run { - val jsonObjectSince = JsonObject() - entries.forEach { sincePairs -> - jsonObjectSince.addProperty(sincePairs.key, "${sincePairs.value}") + filter.authors?.run { + put( + "authors", + factory.arrayNode(filter.authors.size).apply { + filter.authors.forEach { add(it) } + } + ) } - jsonObject.add("since", jsonObjectSince) - }*/ - filter.until?.run { - jsonObject.addProperty("until", filter.until) + filter.kinds?.run { + put( + "kinds", + factory.arrayNode(filter.kinds.size).apply { + filter.kinds.forEach { add(it) } + } + ) + } + filter.tags?.run { + entries.forEach { kv -> + put( + "#${kv.key}", + factory.arrayNode(kv.value.size).apply { + kv.value.forEach { add(it) } + } + ) + } + } + /* + Does not include since in the json comparison + filter.since?.run { + val jsonObjectSince = JsonObject() + entries.forEach { sincePairs -> + jsonObjectSince.addProperty(sincePairs.key, "${sincePairs.value}") + } + jsonObject.add("since", jsonObjectSince) + }*/ + filter.until?.run { put("until", filter.until) } + filter.limit?.run { put("limit", filter.limit) } + filter.search?.run { put("search", filter.search) } } - filter.limit?.run { - jsonObject.addProperty("limit", filter.limit) - } - filter.search?.run { - jsonObject.addProperty("search", filter.search) - } - return jsonObject } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/MainActivity.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/MainActivity.kt index 7ba47d70c..b7732e6b3 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/MainActivity.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/MainActivity.kt @@ -17,8 +17,6 @@ import androidx.appcompat.app.AppCompatDelegate import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material.MaterialTheme import androidx.compose.material.Surface -import androidx.compose.runtime.getValue -import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.core.os.LocaleListCompat import androidx.lifecycle.viewmodel.compose.viewModel @@ -26,15 +24,7 @@ import com.vitorpamplona.amethyst.BuildConfig import com.vitorpamplona.amethyst.LocalPreferences import com.vitorpamplona.amethyst.ServiceManager import com.vitorpamplona.amethyst.service.connectivitystatus.ConnectivityStatus -import com.vitorpamplona.amethyst.service.model.ChannelCreateEvent -import com.vitorpamplona.amethyst.service.model.ChannelMessageEvent -import com.vitorpamplona.amethyst.service.model.ChannelMetadataEvent -import com.vitorpamplona.amethyst.service.model.CommunityDefinitionEvent -import com.vitorpamplona.amethyst.service.model.LiveActivitiesEvent -import com.vitorpamplona.amethyst.service.model.PrivateDmEvent -import com.vitorpamplona.amethyst.service.nip19.Nip19 import com.vitorpamplona.amethyst.service.notifications.PushNotificationUtils -import com.vitorpamplona.amethyst.service.relays.Client import com.vitorpamplona.amethyst.ui.components.DefaultMutedSetting import com.vitorpamplona.amethyst.ui.components.keepPlayingMutex import com.vitorpamplona.amethyst.ui.navigation.Route @@ -44,6 +34,13 @@ import com.vitorpamplona.amethyst.ui.screen.AccountScreen import com.vitorpamplona.amethyst.ui.screen.AccountStateViewModel import com.vitorpamplona.amethyst.ui.screen.ThemeViewModel import com.vitorpamplona.amethyst.ui.theme.AmethystTheme +import com.vitorpamplona.quartz.encoders.Nip19 +import com.vitorpamplona.quartz.events.ChannelCreateEvent +import com.vitorpamplona.quartz.events.ChannelMessageEvent +import com.vitorpamplona.quartz.events.ChannelMetadataEvent +import com.vitorpamplona.quartz.events.CommunityDefinitionEvent +import com.vitorpamplona.quartz.events.LiveActivitiesEvent +import com.vitorpamplona.quartz.events.PrivateDmEvent import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope @@ -87,8 +84,6 @@ class MainActivity : AppCompatActivity() { val connectivityManager = getSystemService(ConnectivityManager::class.java) as ConnectivityManager connectivityManager.requestNetwork(networkRequest, networkCallback) - - Client.lenient = true } @OptIn(DelicateCoroutinesApi::class) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/JoinUserOrChannelView.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/JoinUserOrChannelView.kt index 352ed7e52..9acfc0485 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/JoinUserOrChannelView.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/JoinUserOrChannelView.kt @@ -54,7 +54,6 @@ import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleEventObserver import androidx.lifecycle.viewmodel.compose.viewModel import com.vitorpamplona.amethyst.R -import com.vitorpamplona.amethyst.model.ChatroomKey import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.service.NostrSearchEventOrUserDataSource @@ -68,6 +67,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.SearchBarViewModel import com.vitorpamplona.amethyst.ui.theme.Size20Modifier import com.vitorpamplona.amethyst.ui.theme.Size55dp import com.vitorpamplona.amethyst.ui.theme.placeholderText +import com.vitorpamplona.quartz.events.ChatroomKey import kotlinx.collections.immutable.persistentSetOf import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.channels.Channel diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewMessageTagger.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewMessageTagger.kt index 2d4831c87..83b4c1393 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewMessageTagger.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewMessageTagger.kt @@ -1,13 +1,13 @@ package com.vitorpamplona.amethyst.ui.actions -import com.vitorpamplona.amethyst.model.HexKey import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User -import com.vitorpamplona.amethyst.service.KeyPair -import com.vitorpamplona.amethyst.service.bechToBytes -import com.vitorpamplona.amethyst.service.nip19.Nip19 -import com.vitorpamplona.amethyst.service.toNpub +import com.vitorpamplona.quartz.crypto.KeyPair +import com.vitorpamplona.quartz.encoders.HexKey +import com.vitorpamplona.quartz.encoders.Nip19 +import com.vitorpamplona.quartz.encoders.bechToBytes +import com.vitorpamplona.quartz.encoders.toNpub class NewMessageTagger( var message: String, diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostView.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostView.kt index 91c0b16bc..9f8259922 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostView.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostView.kt @@ -34,7 +34,6 @@ import androidx.compose.material.icons.rounded.Warning import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.Stable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.livedata.observeAsState @@ -81,7 +80,6 @@ import com.vitorpamplona.amethyst.model.ServersAvailable import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.service.NostrSearchEventOrUserDataSource import com.vitorpamplona.amethyst.service.ReverseGeoLocationUtil -import com.vitorpamplona.amethyst.service.model.Event import com.vitorpamplona.amethyst.service.noProtocolUrlValidator import com.vitorpamplona.amethyst.service.relays.Client import com.vitorpamplona.amethyst.ui.components.* @@ -105,6 +103,8 @@ import com.vitorpamplona.amethyst.ui.theme.mediumImportanceLink import com.vitorpamplona.amethyst.ui.theme.placeholderText import com.vitorpamplona.amethyst.ui.theme.replyModifier import com.vitorpamplona.amethyst.ui.theme.subtleBorder +import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.events.toImmutableListOfLists import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.Dispatchers @@ -1469,13 +1469,6 @@ fun ImageVideoDescription( } } -@Stable -data class ImmutableListOfLists(val lists: List> = emptyList()) - -fun List>.toImmutableListOfLists(): ImmutableListOfLists { - return ImmutableListOfLists(this) -} - @Composable fun SettingSwitchItem( modifier: Modifier = Modifier, diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostViewModel.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostViewModel.kt index 420d5c47f..6ef132dd3 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostViewModel.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostViewModel.kt @@ -18,17 +18,18 @@ import com.vitorpamplona.amethyst.model.* import com.vitorpamplona.amethyst.service.FileHeader import com.vitorpamplona.amethyst.service.LocationUtil import com.vitorpamplona.amethyst.service.NostrSearchEventOrUserDataSource -import com.vitorpamplona.amethyst.service.model.AddressableEvent -import com.vitorpamplona.amethyst.service.model.BaseTextNoteEvent -import com.vitorpamplona.amethyst.service.model.ChatMessageEvent -import com.vitorpamplona.amethyst.service.model.CommunityDefinitionEvent -import com.vitorpamplona.amethyst.service.model.Event -import com.vitorpamplona.amethyst.service.model.PrivateDmEvent -import com.vitorpamplona.amethyst.service.model.TextNoteEvent import com.vitorpamplona.amethyst.service.noProtocolUrlValidator import com.vitorpamplona.amethyst.service.relays.Relay import com.vitorpamplona.amethyst.ui.components.MediaCompressor import com.vitorpamplona.amethyst.ui.components.isValidURL +import com.vitorpamplona.quartz.encoders.HexKey +import com.vitorpamplona.quartz.events.AddressableEvent +import com.vitorpamplona.quartz.events.BaseTextNoteEvent +import com.vitorpamplona.quartz.events.ChatMessageEvent +import com.vitorpamplona.quartz.events.CommunityDefinitionEvent +import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.events.PrivateDmEvent +import com.vitorpamplona.quartz.events.TextNoteEvent import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableSharedFlow diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewRelayListView.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewRelayListView.kt index 0d9ade1c7..692a602ec 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewRelayListView.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewRelayListView.kt @@ -60,7 +60,6 @@ import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.RelayInformation import com.vitorpamplona.amethyst.model.RelaySetupInfo import com.vitorpamplona.amethyst.service.PackageUtils -import com.vitorpamplona.amethyst.service.model.Event import com.vitorpamplona.amethyst.service.relays.Client import com.vitorpamplona.amethyst.service.relays.Constants.defaultRelays import com.vitorpamplona.amethyst.service.relays.FeedType @@ -71,6 +70,7 @@ import com.vitorpamplona.amethyst.ui.theme.Size35dp import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer import com.vitorpamplona.amethyst.ui.theme.placeholderText +import com.vitorpamplona.quartz.events.Event import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewRelayListViewModel.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewRelayListViewModel.kt index 8296e3cb1..539844545 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewRelayListViewModel.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewRelayListViewModel.kt @@ -4,10 +4,10 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.RelaySetupInfo -import com.vitorpamplona.amethyst.service.model.ContactListEvent import com.vitorpamplona.amethyst.service.relays.Constants import com.vitorpamplona.amethyst.service.relays.FeedType import com.vitorpamplona.amethyst.service.relays.RelayPool +import com.vitorpamplona.quartz.events.ContactListEvent import kotlinx.collections.immutable.toImmutableSet import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewUserMetadataView.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewUserMetadataView.kt index f70c6a451..87029d6d2 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewUserMetadataView.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewUserMetadataView.kt @@ -35,9 +35,9 @@ import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.service.PackageUtils -import com.vitorpamplona.amethyst.service.model.Event import com.vitorpamplona.amethyst.service.relays.Client import com.vitorpamplona.amethyst.ui.theme.placeholderText +import com.vitorpamplona.quartz.events.Event import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewUserMetadataViewModel.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewUserMetadataViewModel.kt index b4740fd70..47363e008 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewUserMetadataViewModel.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewUserMetadataViewModel.kt @@ -10,12 +10,11 @@ import androidx.lifecycle.viewModelScope import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.databind.node.ObjectNode import com.vitorpamplona.amethyst.model.Account -import com.vitorpamplona.amethyst.service.model.GitHubIdentity -import com.vitorpamplona.amethyst.service.model.MastodonIdentity -import com.vitorpamplona.amethyst.service.model.MetadataEvent -import com.vitorpamplona.amethyst.service.model.TwitterIdentity import com.vitorpamplona.amethyst.ui.components.MediaCompressor -import id.zelory.compressor.Compressor.compress +import com.vitorpamplona.quartz.events.GitHubIdentity +import com.vitorpamplona.quartz.events.MastodonIdentity +import com.vitorpamplona.quartz.events.MetadataEvent +import com.vitorpamplona.quartz.events.TwitterIdentity import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.launch diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/RelayInformationDialog.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/RelayInformationDialog.kt index 0fbd4db7f..790a7ea33 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/RelayInformationDialog.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/RelayInformationDialog.kt @@ -343,7 +343,7 @@ fun loadRelayInfo( } override fun onFailure(call: Call, e: IOException) { - Log.e("RelayInfoFail", "Resulting Message from Relay in not parseable $dirtyUrl", e) + Log.e("RelayInfoFail", "$dirtyUrl unavailable", e) scope.launch { Toast .makeText( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/SignerDialog.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/SignerDialog.kt index 0a4c878b2..e9c1acb2b 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/SignerDialog.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/SignerDialog.kt @@ -39,13 +39,13 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.DialogProperties import com.vitorpamplona.amethyst.R -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.service.model.Event -import com.vitorpamplona.amethyst.service.model.EventInterface -import com.vitorpamplona.amethyst.service.model.PrivateDmEvent -import com.vitorpamplona.amethyst.service.model.TextNoteEvent import com.vitorpamplona.amethyst.ui.theme.ButtonBorder import com.vitorpamplona.amethyst.ui.theme.DoubleVertSpacer +import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.events.EventInterface +import com.vitorpamplona.quartz.events.PrivateDmEvent +import com.vitorpamplona.quartz.events.TextNoteEvent +import com.vitorpamplona.quartz.utils.TimeUtils import kotlinx.coroutines.launch fun openAmber( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/UrlUserTagTransformation.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/UrlUserTagTransformation.kt index 317162932..21d323444 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/UrlUserTagTransformation.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/UrlUserTagTransformation.kt @@ -11,8 +11,8 @@ import androidx.compose.ui.text.input.TransformedText import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.text.style.TextDecoration import com.vitorpamplona.amethyst.model.LocalCache -import com.vitorpamplona.amethyst.model.decodePublicKey -import com.vitorpamplona.amethyst.model.toHexKey +import com.vitorpamplona.quartz.encoders.decodePublicKey +import com.vitorpamplona.quartz.encoders.toHexKey import kotlin.math.roundToInt data class RangesChanges(val original: TextRange, val modified: TextRange) @@ -43,7 +43,8 @@ fun buildAnnotatedStringWithUrlHighlighting(text: AnnotatedString, color: Color) val endIndex = startIndex + keyB32.length - val key = decodePublicKey(keyB32.removePrefix("@")) + val key = + decodePublicKey(keyB32.removePrefix("@")) val user = LocalCache.getOrCreateUser(key.toHexKey()) val newWord = "@${user.toBestDisplayName()}" diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableRoute.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableRoute.kt index 1c911a3ed..0e5370aec 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableRoute.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableRoute.kt @@ -44,13 +44,13 @@ import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.service.NIP30Parser -import com.vitorpamplona.amethyst.service.model.ChannelCreateEvent -import com.vitorpamplona.amethyst.service.model.PrivateDmEvent -import com.vitorpamplona.amethyst.service.nip19.Nip19 -import com.vitorpamplona.amethyst.ui.actions.ImmutableListOfLists -import com.vitorpamplona.amethyst.ui.actions.toImmutableListOfLists import com.vitorpamplona.amethyst.ui.note.LoadChannel import com.vitorpamplona.amethyst.ui.note.toShortenHex +import com.vitorpamplona.quartz.encoders.Nip19 +import com.vitorpamplona.quartz.events.ChannelCreateEvent +import com.vitorpamplona.quartz.events.ImmutableListOfLists +import com.vitorpamplona.quartz.events.PrivateDmEvent +import com.vitorpamplona.quartz.events.toImmutableListOfLists import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableMap import kotlinx.collections.immutable.persistentListOf diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableWithdrawal.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableWithdrawal.kt index d6670d2ba..3a10db49e 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableWithdrawal.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableWithdrawal.kt @@ -12,7 +12,7 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.style.TextDirection import androidx.core.content.ContextCompat -import com.vitorpamplona.amethyst.service.lnurl.LnWithdrawalUtil +import com.vitorpamplona.quartz.encoders.LnWithdrawalUtil import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/ExpandableRichTextViewer.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/ExpandableRichTextViewer.kt index 1b715234a..e3551cb1f 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/ExpandableRichTextViewer.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/ExpandableRichTextViewer.kt @@ -24,11 +24,11 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.vitorpamplona.amethyst.R -import com.vitorpamplona.amethyst.ui.actions.ImmutableListOfLists import com.vitorpamplona.amethyst.ui.note.getGradient import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.theme.ButtonBorder import com.vitorpamplona.amethyst.ui.theme.secondaryButtonBackground +import com.vitorpamplona.quartz.events.ImmutableListOfLists const val SHORT_TEXT_LENGTH = 350 diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/InvoicePreview.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/InvoicePreview.kt index 04ccefaa1..87d6179df 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/InvoicePreview.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/InvoicePreview.kt @@ -24,9 +24,9 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.core.content.ContextCompat.startActivity import com.vitorpamplona.amethyst.R -import com.vitorpamplona.amethyst.service.lnurl.LnInvoiceUtil import com.vitorpamplona.amethyst.ui.theme.QuoteBorder import com.vitorpamplona.amethyst.ui.theme.subtleBorder +import com.vitorpamplona.quartz.encoders.LnInvoiceUtil import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import java.text.NumberFormat diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/RichTextViewer.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/RichTextViewer.kt index d5a56ff21..70c5944e9 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/RichTextViewer.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/RichTextViewer.kt @@ -57,8 +57,6 @@ import com.vitorpamplona.amethyst.service.RichTextViewerState import com.vitorpamplona.amethyst.service.SchemelessUrlSegment import com.vitorpamplona.amethyst.service.Segment import com.vitorpamplona.amethyst.service.WithdrawSegment -import com.vitorpamplona.amethyst.service.nip19.Nip19 -import com.vitorpamplona.amethyst.ui.actions.ImmutableListOfLists import com.vitorpamplona.amethyst.ui.note.LoadUser import com.vitorpamplona.amethyst.ui.note.NoteCompose import com.vitorpamplona.amethyst.ui.note.toShortenHex @@ -70,6 +68,8 @@ import com.vitorpamplona.amethyst.ui.theme.innerPostModifier import com.vitorpamplona.amethyst.ui.theme.markdownStyle import com.vitorpamplona.amethyst.ui.theme.replyModifier import com.vitorpamplona.amethyst.ui.uriToRoute +import com.vitorpamplona.quartz.encoders.Nip19 +import com.vitorpamplona.quartz.events.ImmutableListOfLists import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import java.net.MalformedURLException diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/Robohash.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/Robohash.kt index 7cca9de0e..ce22d7c3f 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/Robohash.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/Robohash.kt @@ -13,9 +13,9 @@ import coil.fetch.Fetcher import coil.fetch.SourceResult import coil.request.ImageRequest import coil.request.Options -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils import com.vitorpamplona.amethyst.service.checkNotInMainThread +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.toHexKey import okio.Buffer private fun toHex(color: Color): String { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/SensitivityWarning.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/SensitivityWarning.kt index 653aa61f2..11d152c36 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/SensitivityWarning.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/SensitivityWarning.kt @@ -35,9 +35,9 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.Note -import com.vitorpamplona.amethyst.service.model.EventInterface import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.theme.ButtonBorder +import com.vitorpamplona.quartz.events.EventInterface @Composable fun SensitivityWarning( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/ZoomableContentView.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/ZoomableContentView.kt index eb958abdc..1e0616cde 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/ZoomableContentView.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/ZoomableContentView.kt @@ -67,9 +67,7 @@ import coil.compose.AsyncImagePainter import coil.imageLoader import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.ConnectivityType -import com.vitorpamplona.amethyst.model.toHexKey import com.vitorpamplona.amethyst.service.BlurHashRequester -import com.vitorpamplona.amethyst.service.CryptoUtils import com.vitorpamplona.amethyst.service.connectivitystatus.ConnectivityStatus import com.vitorpamplona.amethyst.ui.actions.CloseButton import com.vitorpamplona.amethyst.ui.actions.LoadingAnimation @@ -84,6 +82,8 @@ import com.vitorpamplona.amethyst.ui.theme.Size20dp import com.vitorpamplona.amethyst.ui.theme.Size24dp import com.vitorpamplona.amethyst.ui.theme.Size30dp import com.vitorpamplona.amethyst.ui.theme.imageModifier +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.toHexKey import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.Dispatchers diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChatroomFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChatroomFeedFilter.kt index 8acc68570..4c73e162b 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChatroomFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChatroomFeedFilter.kt @@ -1,8 +1,8 @@ package com.vitorpamplona.amethyst.ui.dal import com.vitorpamplona.amethyst.model.Account -import com.vitorpamplona.amethyst.model.ChatroomKey import com.vitorpamplona.amethyst.model.Note +import com.vitorpamplona.quartz.events.ChatroomKey class ChatroomFeedFilter(val withUser: ChatroomKey, val account: Account) : AdditiveFeedFilter() { // returns the last Note of each user. diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChatroomListKnownFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChatroomListKnownFeedFilter.kt index 0a74ac6c6..2f7a22ddd 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChatroomListKnownFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChatroomListKnownFeedFilter.kt @@ -1,12 +1,12 @@ package com.vitorpamplona.amethyst.ui.dal import com.vitorpamplona.amethyst.model.Account -import com.vitorpamplona.amethyst.model.ChatroomKey import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note -import com.vitorpamplona.amethyst.service.model.ChannelMessageEvent -import com.vitorpamplona.amethyst.service.model.ChatroomKeyable import com.vitorpamplona.amethyst.ui.actions.updated +import com.vitorpamplona.quartz.events.ChannelMessageEvent +import com.vitorpamplona.quartz.events.ChatroomKey +import com.vitorpamplona.quartz.events.ChatroomKeyable import kotlin.time.ExperimentalTime import kotlin.time.measureTimedValue diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChatroomListNewFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChatroomListNewFeedFilter.kt index 41eff82e0..7b5b8b9b4 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChatroomListNewFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChatroomListNewFeedFilter.kt @@ -1,11 +1,11 @@ package com.vitorpamplona.amethyst.ui.dal import com.vitorpamplona.amethyst.model.Account -import com.vitorpamplona.amethyst.model.ChatroomKey import com.vitorpamplona.amethyst.model.Note -import com.vitorpamplona.amethyst.service.model.ChatroomKeyable -import com.vitorpamplona.amethyst.service.model.PrivateDmEvent import com.vitorpamplona.amethyst.ui.actions.updated +import com.vitorpamplona.quartz.events.ChatroomKey +import com.vitorpamplona.quartz.events.ChatroomKeyable +import com.vitorpamplona.quartz.events.PrivateDmEvent import kotlin.time.ExperimentalTime import kotlin.time.measureTimedValue diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/CommunityFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/CommunityFeedFilter.kt index 2e2bfcffb..4cb185b1b 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/CommunityFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/CommunityFeedFilter.kt @@ -4,7 +4,7 @@ import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.AddressableNote import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note -import com.vitorpamplona.amethyst.service.model.CommunityPostApprovalEvent +import com.vitorpamplona.quartz.events.CommunityPostApprovalEvent class CommunityFeedFilter(val note: AddressableNote, val account: Account) : AdditiveFeedFilter() { override fun feedKey(): String { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverChatFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverChatFeedFilter.kt index dbb1ba1c8..15ed119cf 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverChatFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverChatFeedFilter.kt @@ -5,8 +5,8 @@ import com.vitorpamplona.amethyst.model.GLOBAL_FOLLOWS import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.ParticipantListBuilder -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.service.model.* +import com.vitorpamplona.quartz.events.* +import com.vitorpamplona.quartz.utils.TimeUtils open class DiscoverChatFeedFilter(val account: Account) : AdditiveFeedFilter() { override fun feedKey(): String { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverCommunityFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverCommunityFeedFilter.kt index ff8d5d6d4..216cd0f49 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverCommunityFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverCommunityFeedFilter.kt @@ -5,8 +5,8 @@ import com.vitorpamplona.amethyst.model.GLOBAL_FOLLOWS import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.ParticipantListBuilder -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.service.model.* +import com.vitorpamplona.quartz.events.* +import com.vitorpamplona.quartz.utils.TimeUtils open class DiscoverCommunityFeedFilter(val account: Account) : AdditiveFeedFilter() { override fun feedKey(): String { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverLiveFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverLiveFeedFilter.kt index 1a83273ce..7ff5230c2 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverLiveFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverLiveFeedFilter.kt @@ -5,11 +5,11 @@ import com.vitorpamplona.amethyst.model.GLOBAL_FOLLOWS import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.ParticipantListBuilder -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.service.model.* -import com.vitorpamplona.amethyst.service.model.LiveActivitiesEvent.Companion.STATUS_ENDED -import com.vitorpamplona.amethyst.service.model.LiveActivitiesEvent.Companion.STATUS_LIVE -import com.vitorpamplona.amethyst.service.model.LiveActivitiesEvent.Companion.STATUS_PLANNED +import com.vitorpamplona.quartz.events.* +import com.vitorpamplona.quartz.events.LiveActivitiesEvent.Companion.STATUS_ENDED +import com.vitorpamplona.quartz.events.LiveActivitiesEvent.Companion.STATUS_LIVE +import com.vitorpamplona.quartz.events.LiveActivitiesEvent.Companion.STATUS_PLANNED +import com.vitorpamplona.quartz.utils.TimeUtils open class DiscoverLiveFeedFilter(val account: Account) : AdditiveFeedFilter() { override fun feedKey(): String { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverLiveNowFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverLiveNowFeedFilter.kt index e506cf983..a55fb8dfb 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverLiveNowFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverLiveNowFeedFilter.kt @@ -3,8 +3,8 @@ package com.vitorpamplona.amethyst.ui.dal import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.service.OnlineChecker -import com.vitorpamplona.amethyst.service.model.* -import com.vitorpamplona.amethyst.service.model.LiveActivitiesEvent.Companion.STATUS_LIVE +import com.vitorpamplona.quartz.events.* +import com.vitorpamplona.quartz.events.LiveActivitiesEvent.Companion.STATUS_LIVE class DiscoverLiveNowFeedFilter(account: Account) : DiscoverLiveFeedFilter(account) { override fun innerApplyFilter(collection: Collection): Set { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/GeoHashFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/GeoHashFeedFilter.kt index bda44c6bd..d87af75b9 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/GeoHashFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/GeoHashFeedFilter.kt @@ -3,10 +3,10 @@ package com.vitorpamplona.amethyst.ui.dal import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note -import com.vitorpamplona.amethyst.service.model.ChannelMessageEvent -import com.vitorpamplona.amethyst.service.model.LongTextNoteEvent -import com.vitorpamplona.amethyst.service.model.PrivateDmEvent -import com.vitorpamplona.amethyst.service.model.TextNoteEvent +import com.vitorpamplona.quartz.events.ChannelMessageEvent +import com.vitorpamplona.quartz.events.LongTextNoteEvent +import com.vitorpamplona.quartz.events.PrivateDmEvent +import com.vitorpamplona.quartz.events.TextNoteEvent class GeoHashFeedFilter(val tag: String, val account: Account) : AdditiveFeedFilter() { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/HashtagFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/HashtagFeedFilter.kt index 06d787aff..b9fe23c35 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/HashtagFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/HashtagFeedFilter.kt @@ -3,10 +3,10 @@ package com.vitorpamplona.amethyst.ui.dal import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note -import com.vitorpamplona.amethyst.service.model.ChannelMessageEvent -import com.vitorpamplona.amethyst.service.model.LongTextNoteEvent -import com.vitorpamplona.amethyst.service.model.PrivateDmEvent -import com.vitorpamplona.amethyst.service.model.TextNoteEvent +import com.vitorpamplona.quartz.events.ChannelMessageEvent +import com.vitorpamplona.quartz.events.LongTextNoteEvent +import com.vitorpamplona.quartz.events.PrivateDmEvent +import com.vitorpamplona.quartz.events.TextNoteEvent class HashtagFeedFilter(val tag: String, val account: Account) : AdditiveFeedFilter() { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/HomeConversationsFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/HomeConversationsFeedFilter.kt index f4f9f4120..b9f400176 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/HomeConversationsFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/HomeConversationsFeedFilter.kt @@ -4,12 +4,12 @@ import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.GLOBAL_FOLLOWS import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.service.model.ChannelMessageEvent -import com.vitorpamplona.amethyst.service.model.LiveActivitiesChatMessageEvent -import com.vitorpamplona.amethyst.service.model.PeopleListEvent -import com.vitorpamplona.amethyst.service.model.PollNoteEvent -import com.vitorpamplona.amethyst.service.model.TextNoteEvent +import com.vitorpamplona.quartz.events.ChannelMessageEvent +import com.vitorpamplona.quartz.events.LiveActivitiesChatMessageEvent +import com.vitorpamplona.quartz.events.PeopleListEvent +import com.vitorpamplona.quartz.events.PollNoteEvent +import com.vitorpamplona.quartz.events.TextNoteEvent +import com.vitorpamplona.quartz.utils.TimeUtils class HomeConversationsFeedFilter(val account: Account) : AdditiveFeedFilter() { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/HomeNewThreadFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/HomeNewThreadFeedFilter.kt index a5e625117..60466abb4 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/HomeNewThreadFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/HomeNewThreadFeedFilter.kt @@ -4,16 +4,16 @@ import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.GLOBAL_FOLLOWS import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.service.model.AudioTrackEvent -import com.vitorpamplona.amethyst.service.model.ClassifiedsEvent -import com.vitorpamplona.amethyst.service.model.GenericRepostEvent -import com.vitorpamplona.amethyst.service.model.HighlightEvent -import com.vitorpamplona.amethyst.service.model.LongTextNoteEvent -import com.vitorpamplona.amethyst.service.model.PeopleListEvent -import com.vitorpamplona.amethyst.service.model.PollNoteEvent -import com.vitorpamplona.amethyst.service.model.RepostEvent -import com.vitorpamplona.amethyst.service.model.TextNoteEvent +import com.vitorpamplona.quartz.events.AudioTrackEvent +import com.vitorpamplona.quartz.events.ClassifiedsEvent +import com.vitorpamplona.quartz.events.GenericRepostEvent +import com.vitorpamplona.quartz.events.HighlightEvent +import com.vitorpamplona.quartz.events.LongTextNoteEvent +import com.vitorpamplona.quartz.events.PeopleListEvent +import com.vitorpamplona.quartz.events.PollNoteEvent +import com.vitorpamplona.quartz.events.RepostEvent +import com.vitorpamplona.quartz.events.TextNoteEvent +import com.vitorpamplona.quartz.utils.TimeUtils class HomeNewThreadFeedFilter(val account: Account) : AdditiveFeedFilter() { override fun feedKey(): String { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/NotificationFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/NotificationFeedFilter.kt index af8481449..1e5369065 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/NotificationFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/NotificationFeedFilter.kt @@ -2,10 +2,10 @@ package com.vitorpamplona.amethyst.ui.dal import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.GLOBAL_FOLLOWS -import com.vitorpamplona.amethyst.model.HexKey import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note -import com.vitorpamplona.amethyst.service.model.* +import com.vitorpamplona.quartz.encoders.HexKey +import com.vitorpamplona.quartz.events.* class NotificationFeedFilter(val account: Account) : AdditiveFeedFilter() { override fun feedKey(): String { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ThreadFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ThreadFeedFilter.kt index 1612d85cb..411d37104 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ThreadFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ThreadFeedFilter.kt @@ -14,8 +14,9 @@ class ThreadFeedFilter(val noteId: String) : FeedFilter() { override fun feed(): List { val cachedSignatures: MutableMap = mutableMapOf() val eventsToWatch = ThreadAssembler().findThreadFor(noteId) ?: emptySet() + // Currently orders by date of each event, descending, at each level of the reply stack - val order = compareByDescending { it.replyLevelSignature(cachedSignatures) } + val order = compareByDescending { it.replyLevelSignature(eventsToWatch, cachedSignatures) } return eventsToWatch.sortedWith(order) } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileAppRecommendationsFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileAppRecommendationsFeedFilter.kt index 7765aa94a..5fda9017e 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileAppRecommendationsFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileAppRecommendationsFeedFilter.kt @@ -3,7 +3,7 @@ package com.vitorpamplona.amethyst.ui.dal import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User -import com.vitorpamplona.amethyst.service.model.AppRecommendationEvent +import com.vitorpamplona.quartz.events.AppRecommendationEvent class UserProfileAppRecommendationsFeedFilter(val user: User) : AdditiveFeedFilter() { override fun feedKey(): String { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileConversationsFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileConversationsFeedFilter.kt index 846727ca8..b2a61a82a 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileConversationsFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileConversationsFeedFilter.kt @@ -4,10 +4,10 @@ import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User -import com.vitorpamplona.amethyst.service.model.ChannelMessageEvent -import com.vitorpamplona.amethyst.service.model.LiveActivitiesChatMessageEvent -import com.vitorpamplona.amethyst.service.model.PollNoteEvent -import com.vitorpamplona.amethyst.service.model.TextNoteEvent +import com.vitorpamplona.quartz.events.ChannelMessageEvent +import com.vitorpamplona.quartz.events.LiveActivitiesChatMessageEvent +import com.vitorpamplona.quartz.events.PollNoteEvent +import com.vitorpamplona.quartz.events.TextNoteEvent class UserProfileConversationsFeedFilter(val user: User, val account: Account) : AdditiveFeedFilter() { override fun feedKey(): String { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileFollowsFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileFollowsFeedFilter.kt index 69eb82888..d4b45f048 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileFollowsFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileFollowsFeedFilter.kt @@ -3,7 +3,7 @@ package com.vitorpamplona.amethyst.ui.dal import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.User -import com.vitorpamplona.amethyst.service.model.ContactListEvent +import com.vitorpamplona.quartz.events.ContactListEvent class UserProfileFollowsFeedFilter(val user: User, val account: Account) : FeedFilter() { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileNewThreadFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileNewThreadFeedFilter.kt index 8b3613b4d..3abfbeb8d 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileNewThreadFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileNewThreadFeedFilter.kt @@ -4,14 +4,14 @@ import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User -import com.vitorpamplona.amethyst.service.model.AudioTrackEvent -import com.vitorpamplona.amethyst.service.model.ClassifiedsEvent -import com.vitorpamplona.amethyst.service.model.GenericRepostEvent -import com.vitorpamplona.amethyst.service.model.HighlightEvent -import com.vitorpamplona.amethyst.service.model.LongTextNoteEvent -import com.vitorpamplona.amethyst.service.model.PollNoteEvent -import com.vitorpamplona.amethyst.service.model.RepostEvent -import com.vitorpamplona.amethyst.service.model.TextNoteEvent +import com.vitorpamplona.quartz.events.AudioTrackEvent +import com.vitorpamplona.quartz.events.ClassifiedsEvent +import com.vitorpamplona.quartz.events.GenericRepostEvent +import com.vitorpamplona.quartz.events.HighlightEvent +import com.vitorpamplona.quartz.events.LongTextNoteEvent +import com.vitorpamplona.quartz.events.PollNoteEvent +import com.vitorpamplona.quartz.events.RepostEvent +import com.vitorpamplona.quartz.events.TextNoteEvent class UserProfileNewThreadFeedFilter(val user: User, val account: Account) : AdditiveFeedFilter() { override fun feedKey(): String { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileReportsFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileReportsFeedFilter.kt index 1db5438b1..353d59ff6 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileReportsFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileReportsFeedFilter.kt @@ -2,7 +2,7 @@ package com.vitorpamplona.amethyst.ui.dal import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User -import com.vitorpamplona.amethyst.service.model.ReportEvent +import com.vitorpamplona.quartz.events.ReportEvent class UserProfileReportsFeedFilter(val user: User) : AdditiveFeedFilter() { override fun feedKey(): String { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileZapsFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileZapsFeedFilter.kt index 15f598436..6a34b51c7 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileZapsFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileZapsFeedFilter.kt @@ -1,8 +1,8 @@ package com.vitorpamplona.amethyst.ui.dal import com.vitorpamplona.amethyst.model.User -import com.vitorpamplona.amethyst.service.model.zaps.UserZaps import com.vitorpamplona.amethyst.ui.screen.ZapReqResponse +import com.vitorpamplona.quartz.events.zaps.UserZaps class UserProfileZapsFeedFilter(val user: User) : FeedFilter() { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/VideoFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/VideoFeedFilter.kt index fc88acdb4..547da6e45 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/VideoFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/VideoFeedFilter.kt @@ -4,8 +4,8 @@ import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.GLOBAL_FOLLOWS import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.service.model.* +import com.vitorpamplona.quartz.events.* +import com.vitorpamplona.quartz.utils.TimeUtils class VideoFeedFilter(val account: Account) : AdditiveFeedFilter() { override fun feedKey(): String { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AccountSwitchBottomSheet.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AccountSwitchBottomSheet.kt index b56582716..61274b30e 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AccountSwitchBottomSheet.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AccountSwitchBottomSheet.kt @@ -46,9 +46,6 @@ import com.vitorpamplona.amethyst.LocalPreferences import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.User -import com.vitorpamplona.amethyst.model.decodePublicKey -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.ui.actions.toImmutableListOfLists import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImageProxy import com.vitorpamplona.amethyst.ui.note.ArrowBackIcon @@ -57,6 +54,9 @@ import com.vitorpamplona.amethyst.ui.screen.AccountStateViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedOff.LoginPage import com.vitorpamplona.amethyst.ui.theme.AccountPictureModifier +import com.vitorpamplona.quartz.encoders.decodePublicKey +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.events.toImmutableListOfLists import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -126,13 +126,23 @@ fun DisplayAccount( accountViewModel: AccountViewModel, accountStateViewModel: AccountStateViewModel ) { - var baseUser by remember { mutableStateOf(LocalCache.getUserIfExists(decodePublicKey(acc.npub).toHexKey())) } + var baseUser by remember { + mutableStateOf( + LocalCache.getUserIfExists( + decodePublicKey( + acc.npub + ).toHexKey() + ) + ) + } if (baseUser == null) { LaunchedEffect(key1 = acc.npub) { launch(Dispatchers.IO) { baseUser = try { - LocalCache.getOrCreateUser(decodePublicKey(acc.npub).toHexKey()) + LocalCache.getOrCreateUser( + decodePublicKey(acc.npub).toHexKey() + ) } catch (e: Exception) { null } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppTopBar.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppTopBar.kt index af92d985a..23c3224da 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppTopBar.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppTopBar.kt @@ -57,7 +57,6 @@ import androidx.navigation.NavBackStackEntry import coil.Coil import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.Account -import com.vitorpamplona.amethyst.model.ChatroomKey import com.vitorpamplona.amethyst.model.GLOBAL_FOLLOWS import com.vitorpamplona.amethyst.model.KIND3_FOLLOWS import com.vitorpamplona.amethyst.model.LiveActivitiesChannel @@ -79,7 +78,6 @@ import com.vitorpamplona.amethyst.service.NostrThreadDataSource import com.vitorpamplona.amethyst.service.NostrUserProfileDataSource import com.vitorpamplona.amethyst.service.NostrVideoDataSource import com.vitorpamplona.amethyst.service.checkNotInMainThread -import com.vitorpamplona.amethyst.service.model.PeopleListEvent import com.vitorpamplona.amethyst.service.relays.Client import com.vitorpamplona.amethyst.service.relays.RelayPool import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImageProxy @@ -115,6 +113,8 @@ import com.vitorpamplona.amethyst.ui.theme.Size22Modifier import com.vitorpamplona.amethyst.ui.theme.Size34dp import com.vitorpamplona.amethyst.ui.theme.Size40dp import com.vitorpamplona.amethyst.ui.theme.placeholderText +import com.vitorpamplona.quartz.events.ChatroomKey +import com.vitorpamplona.quartz.events.PeopleListEvent import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toPersistentList diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/DrawerContent.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/DrawerContent.kt index 5995d5ec4..184092bab 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/DrawerContent.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/DrawerContent.kt @@ -63,7 +63,6 @@ import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.service.HttpClient import com.vitorpamplona.amethyst.ui.actions.NewRelayListView -import com.vitorpamplona.amethyst.ui.actions.toImmutableListOfLists import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImageProxy import com.vitorpamplona.amethyst.ui.screen.RelayPoolViewModel @@ -73,6 +72,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.ConnectOrbotDialog import com.vitorpamplona.amethyst.ui.theme.DoubleHorzSpacer import com.vitorpamplona.amethyst.ui.theme.Size16dp import com.vitorpamplona.amethyst.ui.theme.placeholderText +import com.vitorpamplona.quartz.events.toImmutableListOfLists import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/Routes.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/Routes.kt index 7400306ae..9e4ff9981 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/Routes.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/Routes.kt @@ -16,13 +16,13 @@ import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.service.checkNotInMainThread -import com.vitorpamplona.amethyst.service.model.ChatroomKeyable -import com.vitorpamplona.amethyst.service.model.LiveActivitiesEvent import com.vitorpamplona.amethyst.ui.dal.AdditiveFeedFilter import com.vitorpamplona.amethyst.ui.dal.ChatroomListKnownFeedFilter import com.vitorpamplona.amethyst.ui.dal.DiscoverLiveNowFeedFilter import com.vitorpamplona.amethyst.ui.dal.HomeNewThreadFeedFilter import com.vitorpamplona.amethyst.ui.dal.NotificationFeedFilter +import com.vitorpamplona.quartz.events.ChatroomKeyable +import com.vitorpamplona.quartz.events.LiveActivitiesEvent import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChannelCardCompose.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChannelCardCompose.kt index c76b48ab4..c9c9b82e4 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChannelCardCompose.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChannelCardCompose.kt @@ -50,12 +50,6 @@ import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.ParticipantListBuilder import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.service.OnlineChecker -import com.vitorpamplona.amethyst.service.model.ChannelCreateEvent -import com.vitorpamplona.amethyst.service.model.CommunityDefinitionEvent -import com.vitorpamplona.amethyst.service.model.LiveActivitiesEvent -import com.vitorpamplona.amethyst.service.model.LiveActivitiesEvent.Companion.STATUS_ENDED -import com.vitorpamplona.amethyst.service.model.LiveActivitiesEvent.Companion.STATUS_LIVE -import com.vitorpamplona.amethyst.service.model.LiveActivitiesEvent.Companion.STATUS_PLANNED import com.vitorpamplona.amethyst.ui.components.SensitivityWarning import com.vitorpamplona.amethyst.ui.screen.equalImmutableLists import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel @@ -72,6 +66,12 @@ import com.vitorpamplona.amethyst.ui.theme.StdPadding import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer import com.vitorpamplona.amethyst.ui.theme.newItemBackgroundColor import com.vitorpamplona.amethyst.ui.theme.placeholderText +import com.vitorpamplona.quartz.events.ChannelCreateEvent +import com.vitorpamplona.quartz.events.CommunityDefinitionEvent +import com.vitorpamplona.quartz.events.LiveActivitiesEvent +import com.vitorpamplona.quartz.events.LiveActivitiesEvent.Companion.STATUS_ENDED +import com.vitorpamplona.quartz.events.LiveActivitiesEvent.Companion.STATUS_LIVE +import com.vitorpamplona.quartz.events.LiveActivitiesEvent.Companion.STATUS_PLANNED import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentSetOf diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChatroomHeaderCompose.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChatroomHeaderCompose.kt index 15751756e..2979f033b 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChatroomHeaderCompose.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChatroomHeaderCompose.kt @@ -47,14 +47,9 @@ import androidx.lifecycle.map import com.patrykandpatrick.vico.core.extension.forEachIndexedExtended import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.Channel -import com.vitorpamplona.amethyst.model.ChatroomKey -import com.vitorpamplona.amethyst.model.HexKey import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User -import com.vitorpamplona.amethyst.service.model.ChannelCreateEvent -import com.vitorpamplona.amethyst.service.model.ChannelMetadataEvent -import com.vitorpamplona.amethyst.service.model.ChatroomKeyable import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImageProxy import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel @@ -68,6 +63,11 @@ import com.vitorpamplona.amethyst.ui.theme.Size75dp import com.vitorpamplona.amethyst.ui.theme.StdTopPadding import com.vitorpamplona.amethyst.ui.theme.grayText import com.vitorpamplona.amethyst.ui.theme.placeholderText +import com.vitorpamplona.quartz.encoders.HexKey +import com.vitorpamplona.quartz.events.ChannelCreateEvent +import com.vitorpamplona.quartz.events.ChannelMetadataEvent +import com.vitorpamplona.quartz.events.ChatroomKey +import com.vitorpamplona.quartz.events.ChatroomKeyable import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChatroomMessageCompose.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChatroomMessageCompose.kt index d78f0286d..687b544c2 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChatroomMessageCompose.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChatroomMessageCompose.kt @@ -46,13 +46,7 @@ import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.service.PackageUtils -import com.vitorpamplona.amethyst.service.model.ChannelCreateEvent -import com.vitorpamplona.amethyst.service.model.ChannelMetadataEvent -import com.vitorpamplona.amethyst.service.model.ChatMessageEvent -import com.vitorpamplona.amethyst.service.model.PrivateDmEvent -import com.vitorpamplona.amethyst.ui.actions.ImmutableListOfLists import com.vitorpamplona.amethyst.ui.actions.SignerDialog -import com.vitorpamplona.amethyst.ui.actions.toImmutableListOfLists import com.vitorpamplona.amethyst.ui.components.CreateClickableTextWithEmoji import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImageProxy @@ -72,6 +66,12 @@ import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer import com.vitorpamplona.amethyst.ui.theme.mediumImportanceLink import com.vitorpamplona.amethyst.ui.theme.placeholderText import com.vitorpamplona.amethyst.ui.theme.subtleBorder +import com.vitorpamplona.quartz.events.ChannelCreateEvent +import com.vitorpamplona.quartz.events.ChannelMetadataEvent +import com.vitorpamplona.quartz.events.ChatMessageEvent +import com.vitorpamplona.quartz.events.ImmutableListOfLists +import com.vitorpamplona.quartz.events.PrivateDmEvent +import com.vitorpamplona.quartz.events.toImmutableListOfLists import kotlinx.collections.immutable.persistentSetOf import kotlinx.collections.immutable.toImmutableSet import kotlinx.coroutines.Dispatchers diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/Icons.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/Icons.kt index 1e72fd759..48bbe5e01 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/Icons.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/Icons.kt @@ -32,6 +32,7 @@ import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange import com.vitorpamplona.amethyst.ui.theme.Size18Modifier import com.vitorpamplona.amethyst.ui.theme.Size20Modifier import com.vitorpamplona.amethyst.ui.theme.Size30Modifier +import com.vitorpamplona.amethyst.ui.theme.grayText import com.vitorpamplona.amethyst.ui.theme.placeholderText import com.vitorpamplona.amethyst.ui.theme.subtleButton @@ -60,7 +61,7 @@ fun ArrowBackIcon() { Icon( imageVector = Icons.Default.ArrowBack, contentDescription = stringResource(R.string.back), - tint = MaterialTheme.colors.onSurface + tint = MaterialTheme.colors.grayText ) } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/MultiSetCompose.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/MultiSetCompose.kt index fa003d5e5..d4d555e1e 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/MultiSetCompose.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/MultiSetCompose.kt @@ -46,9 +46,6 @@ import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User -import com.vitorpamplona.amethyst.service.model.LnZapEvent -import com.vitorpamplona.amethyst.service.model.LnZapRequestEvent -import com.vitorpamplona.amethyst.ui.actions.ImmutableListOfLists import com.vitorpamplona.amethyst.ui.components.ImageUrlType import com.vitorpamplona.amethyst.ui.components.InLineIconRenderer import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImageProxy @@ -72,6 +69,9 @@ import com.vitorpamplona.amethyst.ui.theme.bitcoinColor import com.vitorpamplona.amethyst.ui.theme.newItemBackgroundColor import com.vitorpamplona.amethyst.ui.theme.overPictureBackground import com.vitorpamplona.amethyst.ui.theme.profile35dpModifier +import com.vitorpamplona.quartz.events.ImmutableListOfLists +import com.vitorpamplona.quartz.events.LnZapEvent +import com.vitorpamplona.quartz.events.LnZapRequestEvent import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.Dispatchers diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NIP05VerificationDisplay.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NIP05VerificationDisplay.kt index 95efc9d3d..412241c8c 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NIP05VerificationDisplay.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NIP05VerificationDisplay.kt @@ -4,7 +4,6 @@ import androidx.compose.animation.Crossfade import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size import androidx.compose.foundation.text.ClickableText import androidx.compose.material.LocalTextStyle import androidx.compose.material.MaterialTheme @@ -25,9 +24,7 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.lifecycle.map import com.vitorpamplona.amethyst.model.Note -import com.vitorpamplona.amethyst.model.TimeUtils import com.vitorpamplona.amethyst.model.User -import com.vitorpamplona.amethyst.model.UserMetadata import com.vitorpamplona.amethyst.service.Nip05Verifier import com.vitorpamplona.amethyst.ui.note.NIP05CheckingIcon import com.vitorpamplona.amethyst.ui.note.NIP05FailedVerification @@ -36,6 +33,8 @@ import com.vitorpamplona.amethyst.ui.theme.NIP05IconSize import com.vitorpamplona.amethyst.ui.theme.Size16Modifier import com.vitorpamplona.amethyst.ui.theme.nip05 import com.vitorpamplona.amethyst.ui.theme.placeholderText +import com.vitorpamplona.quartz.events.UserMetadata +import com.vitorpamplona.quartz.utils.TimeUtils import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt index 209654eb0..ac0969f59 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt @@ -82,49 +82,10 @@ import com.vitorpamplona.amethyst.model.ConnectivityType import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User -import com.vitorpamplona.amethyst.model.UserMetadata import com.vitorpamplona.amethyst.service.OnlineChecker import com.vitorpamplona.amethyst.service.ReverseGeoLocationUtil import com.vitorpamplona.amethyst.service.connectivitystatus.ConnectivityStatus -import com.vitorpamplona.amethyst.service.model.ATag -import com.vitorpamplona.amethyst.service.model.AppDefinitionEvent -import com.vitorpamplona.amethyst.service.model.AudioTrackEvent -import com.vitorpamplona.amethyst.service.model.BadgeAwardEvent -import com.vitorpamplona.amethyst.service.model.BadgeDefinitionEvent -import com.vitorpamplona.amethyst.service.model.BaseTextNoteEvent -import com.vitorpamplona.amethyst.service.model.ChannelCreateEvent -import com.vitorpamplona.amethyst.service.model.ChannelMessageEvent -import com.vitorpamplona.amethyst.service.model.ChannelMetadataEvent -import com.vitorpamplona.amethyst.service.model.ChatroomKeyable -import com.vitorpamplona.amethyst.service.model.ClassifiedsEvent -import com.vitorpamplona.amethyst.service.model.CommunityDefinitionEvent -import com.vitorpamplona.amethyst.service.model.CommunityPostApprovalEvent -import com.vitorpamplona.amethyst.service.model.EmojiPackEvent -import com.vitorpamplona.amethyst.service.model.EmojiPackSelectionEvent -import com.vitorpamplona.amethyst.service.model.EmojiUrl -import com.vitorpamplona.amethyst.service.model.FileHeaderEvent -import com.vitorpamplona.amethyst.service.model.FileStorageHeaderEvent -import com.vitorpamplona.amethyst.service.model.GenericRepostEvent -import com.vitorpamplona.amethyst.service.model.HighlightEvent -import com.vitorpamplona.amethyst.service.model.LiveActivitiesChatMessageEvent -import com.vitorpamplona.amethyst.service.model.LiveActivitiesEvent -import com.vitorpamplona.amethyst.service.model.LiveActivitiesEvent.Companion.STATUS_LIVE -import com.vitorpamplona.amethyst.service.model.LiveActivitiesEvent.Companion.STATUS_PLANNED -import com.vitorpamplona.amethyst.service.model.LongTextNoteEvent -import com.vitorpamplona.amethyst.service.model.Participant -import com.vitorpamplona.amethyst.service.model.PeopleListEvent -import com.vitorpamplona.amethyst.service.model.PinListEvent -import com.vitorpamplona.amethyst.service.model.PollNoteEvent -import com.vitorpamplona.amethyst.service.model.PrivateDmEvent -import com.vitorpamplona.amethyst.service.model.ReactionEvent -import com.vitorpamplona.amethyst.service.model.RelaySetEvent -import com.vitorpamplona.amethyst.service.model.ReportEvent -import com.vitorpamplona.amethyst.service.model.RepostEvent -import com.vitorpamplona.amethyst.service.model.TextNoteEvent -import com.vitorpamplona.amethyst.service.toNpub -import com.vitorpamplona.amethyst.ui.actions.ImmutableListOfLists import com.vitorpamplona.amethyst.ui.actions.NewRelayListView -import com.vitorpamplona.amethyst.ui.actions.toImmutableListOfLists import com.vitorpamplona.amethyst.ui.components.ClickableUrl import com.vitorpamplona.amethyst.ui.components.CreateClickableTextWithEmoji import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji @@ -190,6 +151,45 @@ import com.vitorpamplona.amethyst.ui.theme.replyBackground import com.vitorpamplona.amethyst.ui.theme.replyModifier import com.vitorpamplona.amethyst.ui.theme.repostProfileBorder import com.vitorpamplona.amethyst.ui.theme.subtleBorder +import com.vitorpamplona.quartz.encoders.ATag +import com.vitorpamplona.quartz.encoders.toNpub +import com.vitorpamplona.quartz.events.AppDefinitionEvent +import com.vitorpamplona.quartz.events.AudioTrackEvent +import com.vitorpamplona.quartz.events.BadgeAwardEvent +import com.vitorpamplona.quartz.events.BadgeDefinitionEvent +import com.vitorpamplona.quartz.events.BaseTextNoteEvent +import com.vitorpamplona.quartz.events.ChannelCreateEvent +import com.vitorpamplona.quartz.events.ChannelMessageEvent +import com.vitorpamplona.quartz.events.ChannelMetadataEvent +import com.vitorpamplona.quartz.events.ChatroomKeyable +import com.vitorpamplona.quartz.events.ClassifiedsEvent +import com.vitorpamplona.quartz.events.CommunityDefinitionEvent +import com.vitorpamplona.quartz.events.CommunityPostApprovalEvent +import com.vitorpamplona.quartz.events.EmojiPackEvent +import com.vitorpamplona.quartz.events.EmojiPackSelectionEvent +import com.vitorpamplona.quartz.events.EmojiUrl +import com.vitorpamplona.quartz.events.FileHeaderEvent +import com.vitorpamplona.quartz.events.FileStorageHeaderEvent +import com.vitorpamplona.quartz.events.GenericRepostEvent +import com.vitorpamplona.quartz.events.HighlightEvent +import com.vitorpamplona.quartz.events.ImmutableListOfLists +import com.vitorpamplona.quartz.events.LiveActivitiesChatMessageEvent +import com.vitorpamplona.quartz.events.LiveActivitiesEvent +import com.vitorpamplona.quartz.events.LiveActivitiesEvent.Companion.STATUS_LIVE +import com.vitorpamplona.quartz.events.LiveActivitiesEvent.Companion.STATUS_PLANNED +import com.vitorpamplona.quartz.events.LongTextNoteEvent +import com.vitorpamplona.quartz.events.Participant +import com.vitorpamplona.quartz.events.PeopleListEvent +import com.vitorpamplona.quartz.events.PinListEvent +import com.vitorpamplona.quartz.events.PollNoteEvent +import com.vitorpamplona.quartz.events.PrivateDmEvent +import com.vitorpamplona.quartz.events.ReactionEvent +import com.vitorpamplona.quartz.events.RelaySetEvent +import com.vitorpamplona.quartz.events.ReportEvent +import com.vitorpamplona.quartz.events.RepostEvent +import com.vitorpamplona.quartz.events.TextNoteEvent +import com.vitorpamplona.quartz.events.UserMetadata +import com.vitorpamplona.quartz.events.toImmutableListOfLists import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableSet import kotlinx.collections.immutable.persistentListOf diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteQuickActionMenu.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteQuickActionMenu.kt index a6f0d96ed..4a8d53283 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteQuickActionMenu.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteQuickActionMenu.kt @@ -61,14 +61,14 @@ import androidx.core.graphics.ColorUtils import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.AddressableNote import com.vitorpamplona.amethyst.model.Note -import com.vitorpamplona.amethyst.service.model.AudioTrackEvent -import com.vitorpamplona.amethyst.service.model.FileHeaderEvent -import com.vitorpamplona.amethyst.service.model.PeopleListEvent import com.vitorpamplona.amethyst.ui.components.SelectTextDialog import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.ReportNoteDialog import com.vitorpamplona.amethyst.ui.theme.WarningColor import com.vitorpamplona.amethyst.ui.theme.secondaryButtonBackground +import com.vitorpamplona.quartz.events.AudioTrackEvent +import com.vitorpamplona.quartz.events.FileHeaderEvent +import com.vitorpamplona.quartz.events.PeopleListEvent import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/PollNote.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/PollNote.kt index decc55f5f..1ae831a26 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/PollNote.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/PollNote.kt @@ -24,9 +24,6 @@ import androidx.compose.ui.window.Popup import androidx.lifecycle.viewmodel.compose.viewModel import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.Note -import com.vitorpamplona.amethyst.service.model.LnZapEvent -import com.vitorpamplona.amethyst.ui.actions.ImmutableListOfLists -import com.vitorpamplona.amethyst.ui.actions.toImmutableListOfLists import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange @@ -35,6 +32,9 @@ import com.vitorpamplona.amethyst.ui.theme.Font14SP import com.vitorpamplona.amethyst.ui.theme.QuoteBorder import com.vitorpamplona.amethyst.ui.theme.mediumImportanceLink import com.vitorpamplona.amethyst.ui.theme.placeholderText +import com.vitorpamplona.quartz.events.ImmutableListOfLists +import com.vitorpamplona.quartz.events.LnZapEvent +import com.vitorpamplona.quartz.events.toImmutableListOfLists import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import java.util.* diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/PollNoteViewModel.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/PollNoteViewModel.kt index 828568ea8..e9675f200 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/PollNoteViewModel.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/PollNoteViewModel.kt @@ -2,19 +2,16 @@ package com.vitorpamplona.amethyst.ui.note import androidx.compose.runtime.Immutable import androidx.compose.runtime.Stable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.setValue import androidx.lifecycle.ViewModel import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.Note -import com.vitorpamplona.amethyst.model.TimeUtils import com.vitorpamplona.amethyst.model.User -import com.vitorpamplona.amethyst.service.model.* +import com.vitorpamplona.quartz.events.* +import com.vitorpamplona.quartz.utils.TimeUtils import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import java.math.BigDecimal import java.math.RoundingMode -import java.util.* @Immutable data class PollOption( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/PubKeyFormatter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/PubKeyFormatter.kt index 2ff0d3799..8fb415f84 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/PubKeyFormatter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/PubKeyFormatter.kt @@ -1,6 +1,7 @@ package com.vitorpamplona.amethyst.ui.note -import com.vitorpamplona.amethyst.model.toHexKey +import com.vitorpamplona.quartz.encoders.HexKey +import com.vitorpamplona.quartz.encoders.toHexKey fun ByteArray.toShortenHex(): String { return toHexKey().toShortenHex() @@ -10,3 +11,7 @@ fun String.toShortenHex(): String { if (length <= 16) return this return replaceRange(8, length - 8, ":") } + +fun HexKey.toDisplayHexKey(): String { + return this.toShortenHex() +} diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt index 3ed2a0b82..e654478d2 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt @@ -78,7 +78,6 @@ import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.service.PackageUtils -import com.vitorpamplona.amethyst.service.model.Event import com.vitorpamplona.amethyst.service.relays.Client import com.vitorpamplona.amethyst.ui.actions.NewPostView import com.vitorpamplona.amethyst.ui.actions.SignerDialog @@ -110,6 +109,7 @@ import com.vitorpamplona.amethyst.ui.theme.TinyBorders import com.vitorpamplona.amethyst.ui.theme.mediumImportanceLink import com.vitorpamplona.amethyst.ui.theme.placeholderText import com.vitorpamplona.amethyst.ui.theme.placeholderTextColorFilter +import com.vitorpamplona.quartz.events.Event import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableMap import kotlinx.coroutines.CoroutineScope diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ReplyInformation.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ReplyInformation.kt index d3cc33b89..9d299117b 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ReplyInformation.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ReplyInformation.kt @@ -19,12 +19,12 @@ import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.unit.sp import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.* -import com.vitorpamplona.amethyst.ui.actions.toImmutableListOfLists import com.vitorpamplona.amethyst.ui.components.CreateClickableTextWithEmoji import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer import com.vitorpamplona.amethyst.ui.theme.lessImportantLink import com.vitorpamplona.amethyst.ui.theme.placeholderText +import com.vitorpamplona.quartz.events.toImmutableListOfLists import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.Dispatchers diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UpdateReactionTypeDialog.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UpdateReactionTypeDialog.kt index 5ab6b825b..864313a2f 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UpdateReactionTypeDialog.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UpdateReactionTypeDialog.kt @@ -57,9 +57,6 @@ import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.AddressableNote import com.vitorpamplona.amethyst.service.firstFullChar -import com.vitorpamplona.amethyst.service.model.ATag -import com.vitorpamplona.amethyst.service.model.EmojiPackSelectionEvent -import com.vitorpamplona.amethyst.service.model.EmojiUrl import com.vitorpamplona.amethyst.ui.actions.CloseButton import com.vitorpamplona.amethyst.ui.actions.SaveButton import com.vitorpamplona.amethyst.ui.components.ImageUrlType @@ -68,6 +65,9 @@ import com.vitorpamplona.amethyst.ui.components.TextType import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.theme.ButtonBorder import com.vitorpamplona.amethyst.ui.theme.placeholderText +import com.vitorpamplona.quartz.encoders.ATag +import com.vitorpamplona.quartz.events.EmojiPackSelectionEvent +import com.vitorpamplona.quartz.events.EmojiUrl import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.launch diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UpdateZapAmountDialog.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UpdateZapAmountDialog.kt index 30bf505d7..284d69ee1 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UpdateZapAmountDialog.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UpdateZapAmountDialog.kt @@ -68,9 +68,6 @@ import androidx.lifecycle.viewmodel.compose.viewModel import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.Nip47URI -import com.vitorpamplona.amethyst.model.decodePublicKey -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.model.LnZapEvent import com.vitorpamplona.amethyst.ui.actions.CloseButton import com.vitorpamplona.amethyst.ui.actions.SaveButton import com.vitorpamplona.amethyst.ui.qrcode.SimpleQrCodeScanner @@ -80,6 +77,9 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.getFragmentActivity import com.vitorpamplona.amethyst.ui.theme.ButtonBorder import com.vitorpamplona.amethyst.ui.theme.Font14SP import com.vitorpamplona.amethyst.ui.theme.placeholderText +import com.vitorpamplona.quartz.encoders.decodePublicKey +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.events.LnZapEvent import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UserProfilePicture.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UserProfilePicture.kt index d37c8fa01..a7bb6a9fa 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UserProfilePicture.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UserProfilePicture.kt @@ -41,13 +41,13 @@ import androidx.core.content.ContextCompat import androidx.lifecycle.distinctUntilChanged import androidx.lifecycle.map import com.vitorpamplona.amethyst.R -import com.vitorpamplona.amethyst.model.HexKey import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImage import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImageProxy import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.ReportNoteDialog +import com.vitorpamplona.quartz.encoders.HexKey import kotlinx.collections.immutable.ImmutableSet import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UserReactionsRow.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UserReactionsRow.kt index 586d94261..1be65dba1 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UserReactionsRow.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UserReactionsRow.kt @@ -35,16 +35,10 @@ import com.patrykandpatrick.vico.core.entry.composed.plus import com.patrykandpatrick.vico.core.entry.entryOf import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.Account -import com.vitorpamplona.amethyst.model.HexKey import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.service.checkNotInMainThread -import com.vitorpamplona.amethyst.service.model.GenericRepostEvent -import com.vitorpamplona.amethyst.service.model.LnZapEvent -import com.vitorpamplona.amethyst.service.model.ReactionEvent -import com.vitorpamplona.amethyst.service.model.RepostEvent -import com.vitorpamplona.amethyst.service.model.TextNoteEvent import com.vitorpamplona.amethyst.ui.components.BundledInsert import com.vitorpamplona.amethyst.ui.screen.loggedIn.showAmountAxis import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange @@ -53,6 +47,12 @@ import com.vitorpamplona.amethyst.ui.theme.Size20Modifier import com.vitorpamplona.amethyst.ui.theme.Size24Modifier import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer import com.vitorpamplona.amethyst.ui.theme.placeholderText +import com.vitorpamplona.quartz.encoders.HexKey +import com.vitorpamplona.quartz.events.GenericRepostEvent +import com.vitorpamplona.quartz.events.LnZapEvent +import com.vitorpamplona.quartz.events.ReactionEvent +import com.vitorpamplona.quartz.events.RepostEvent +import com.vitorpamplona.quartz.events.TextNoteEvent import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlinx.coroutines.flow.MutableStateFlow diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UsernameDisplay.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UsernameDisplay.kt index 81e3b968f..0839774d5 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UsernameDisplay.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UsernameDisplay.kt @@ -24,11 +24,11 @@ import androidx.lifecycle.map import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.service.tts.TextToSpeechHelper -import com.vitorpamplona.amethyst.ui.actions.ImmutableListOfLists import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji import com.vitorpamplona.amethyst.ui.theme.StdButtonSizeModifier import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer import com.vitorpamplona.amethyst.ui.theme.placeholderText +import com.vitorpamplona.quartz.events.ImmutableListOfLists @Composable fun NoteUsernameDisplay(baseNote: Note, weight: Modifier = Modifier, showPlayButton: Boolean = true) { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapCustomDialog.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapCustomDialog.kt index 85a8109f4..309bc8d15 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapCustomDialog.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapCustomDialog.kt @@ -21,12 +21,12 @@ import androidx.lifecycle.viewmodel.compose.viewModel import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.Note -import com.vitorpamplona.amethyst.service.model.LnZapEvent import com.vitorpamplona.amethyst.ui.actions.CloseButton import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.TextSpinner import com.vitorpamplona.amethyst.ui.theme.ButtonBorder import com.vitorpamplona.amethyst.ui.theme.placeholderText +import com.vitorpamplona.quartz.events.LnZapEvent import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapNoteCompose.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapNoteCompose.kt index bfd801e4b..c4b297408 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapNoteCompose.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapNoteCompose.kt @@ -30,9 +30,6 @@ import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.service.PackageUtils -import com.vitorpamplona.amethyst.service.model.ContactListEvent -import com.vitorpamplona.amethyst.service.model.LnZapEvent -import com.vitorpamplona.amethyst.service.model.LnZapRequestEvent import com.vitorpamplona.amethyst.service.relays.Client import com.vitorpamplona.amethyst.ui.actions.SignerDialog import com.vitorpamplona.amethyst.ui.screen.ZapReqResponse @@ -45,6 +42,9 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.showAmountAxis import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange import com.vitorpamplona.amethyst.ui.theme.Size55dp import com.vitorpamplona.amethyst.ui.theme.placeholderText +import com.vitorpamplona.quartz.events.ContactListEvent +import com.vitorpamplona.quartz.events.LnZapEvent +import com.vitorpamplona.quartz.events.LnZapRequestEvent import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/qrcode/QrCodeScanner.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/qrcode/QrCodeScanner.kt index c1f31f99c..6e76f2f3f 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/qrcode/QrCodeScanner.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/qrcode/QrCodeScanner.kt @@ -10,7 +10,7 @@ import com.google.zxing.client.android.Intents import com.journeyapps.barcodescanner.ScanContract import com.journeyapps.barcodescanner.ScanOptions import com.vitorpamplona.amethyst.R -import com.vitorpamplona.amethyst.service.nip19.Nip19 +import com.vitorpamplona.quartz.encoders.Nip19 @Composable fun NIP19QrCodeScanner(onScan: (String?) -> Unit) { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/qrcode/ShowQRDialog.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/qrcode/ShowQRDialog.kt index 361711dba..b284489c8 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/qrcode/ShowQRDialog.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/qrcode/ShowQRDialog.kt @@ -34,11 +34,11 @@ import androidx.compose.ui.window.DialogProperties import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.ui.actions.CloseButton -import com.vitorpamplona.amethyst.ui.actions.toImmutableListOfLists import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImageProxy import com.vitorpamplona.amethyst.ui.qrcode.NIP19QrCodeScanner import com.vitorpamplona.amethyst.ui.theme.Size35dp +import com.vitorpamplona.quartz.events.toImmutableListOfLists @Composable fun ShowQRDialog(user: User, onScan: (String) -> Unit, onClose: () -> Unit) { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/AccountStateViewModel.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/AccountStateViewModel.kt index 7c439d05a..1b3d963df 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/AccountStateViewModel.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/AccountStateViewModel.kt @@ -7,12 +7,12 @@ import androidx.lifecycle.ViewModel import com.vitorpamplona.amethyst.LocalPreferences import com.vitorpamplona.amethyst.ServiceManager import com.vitorpamplona.amethyst.model.Account -import com.vitorpamplona.amethyst.model.hexToByteArray import com.vitorpamplona.amethyst.service.HttpClient -import com.vitorpamplona.amethyst.service.KeyPair -import com.vitorpamplona.amethyst.service.bechToBytes -import com.vitorpamplona.amethyst.service.nip19.Nip19 -import fr.acinq.secp256k1.Hex +import com.vitorpamplona.quartz.crypto.KeyPair +import com.vitorpamplona.quartz.encoders.Hex +import com.vitorpamplona.quartz.encoders.Nip19 +import com.vitorpamplona.quartz.encoders.bechToBytes +import com.vitorpamplona.quartz.encoders.hexToByteArray import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.Dispatchers diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/CardFeedState.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/CardFeedState.kt index 4e6da3890..ada8a6665 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/CardFeedState.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/CardFeedState.kt @@ -6,7 +6,7 @@ import androidx.compose.runtime.Stable import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.service.firstFullCharOrEmoji -import com.vitorpamplona.amethyst.ui.actions.ImmutableListOfLists +import com.vitorpamplona.quartz.events.ImmutableListOfLists import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableMap diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/CardFeedViewModel.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/CardFeedViewModel.kt index dfe38fb3c..0e5cdef3b 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/CardFeedViewModel.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/CardFeedViewModel.kt @@ -12,20 +12,20 @@ import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.service.checkNotInMainThread -import com.vitorpamplona.amethyst.service.model.BadgeAwardEvent -import com.vitorpamplona.amethyst.service.model.ChannelCreateEvent -import com.vitorpamplona.amethyst.service.model.ChannelMetadataEvent -import com.vitorpamplona.amethyst.service.model.ChatMessageEvent -import com.vitorpamplona.amethyst.service.model.GenericRepostEvent -import com.vitorpamplona.amethyst.service.model.LnZapEvent -import com.vitorpamplona.amethyst.service.model.PrivateDmEvent -import com.vitorpamplona.amethyst.service.model.ReactionEvent -import com.vitorpamplona.amethyst.service.model.RepostEvent import com.vitorpamplona.amethyst.ui.components.BundledInsert import com.vitorpamplona.amethyst.ui.components.BundledUpdate import com.vitorpamplona.amethyst.ui.dal.AdditiveFeedFilter import com.vitorpamplona.amethyst.ui.dal.FeedFilter import com.vitorpamplona.amethyst.ui.dal.NotificationFeedFilter +import com.vitorpamplona.quartz.events.BadgeAwardEvent +import com.vitorpamplona.quartz.events.ChannelCreateEvent +import com.vitorpamplona.quartz.events.ChannelMetadataEvent +import com.vitorpamplona.quartz.events.ChatMessageEvent +import com.vitorpamplona.quartz.events.GenericRepostEvent +import com.vitorpamplona.quartz.events.LnZapEvent +import com.vitorpamplona.quartz.events.PrivateDmEvent +import com.vitorpamplona.quartz.events.ReactionEvent +import com.vitorpamplona.quartz.events.RepostEvent import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.CoroutineScope diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ChatroomListFeedView.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ChatroomListFeedView.kt index 4c7cd1bb0..c0b42e5fe 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ChatroomListFeedView.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ChatroomListFeedView.kt @@ -16,9 +16,9 @@ import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import com.vitorpamplona.amethyst.service.model.ChatroomKeyable import com.vitorpamplona.amethyst.ui.note.ChatroomHeaderCompose import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel +import com.vitorpamplona.quartz.events.ChatroomKeyable import kotlin.time.ExperimentalTime import kotlin.time.measureTimedValue diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/FeedViewModel.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/FeedViewModel.kt index b6c70485d..b12369b6c 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/FeedViewModel.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/FeedViewModel.kt @@ -9,7 +9,6 @@ import androidx.lifecycle.viewModelScope import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.AddressableNote import com.vitorpamplona.amethyst.model.Channel -import com.vitorpamplona.amethyst.model.ChatroomKey import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User @@ -39,6 +38,7 @@ import com.vitorpamplona.amethyst.ui.dal.UserProfileConversationsFeedFilter import com.vitorpamplona.amethyst.ui.dal.UserProfileNewThreadFeedFilter import com.vitorpamplona.amethyst.ui.dal.UserProfileReportsFeedFilter import com.vitorpamplona.amethyst.ui.dal.VideoFeedFilter +import com.vitorpamplona.quartz.events.ChatroomKey import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.CoroutineScope diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ThreadFeedView.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ThreadFeedView.kt index d8fbb41f0..ef644c570 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ThreadFeedView.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ThreadFeedView.kt @@ -57,25 +57,6 @@ import androidx.compose.ui.unit.sp import coil.compose.AsyncImage import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.Note -import com.vitorpamplona.amethyst.service.model.AppDefinitionEvent -import com.vitorpamplona.amethyst.service.model.AudioTrackEvent -import com.vitorpamplona.amethyst.service.model.BadgeDefinitionEvent -import com.vitorpamplona.amethyst.service.model.ChannelCreateEvent -import com.vitorpamplona.amethyst.service.model.ChannelMetadataEvent -import com.vitorpamplona.amethyst.service.model.ClassifiedsEvent -import com.vitorpamplona.amethyst.service.model.CommunityDefinitionEvent -import com.vitorpamplona.amethyst.service.model.CommunityPostApprovalEvent -import com.vitorpamplona.amethyst.service.model.EmojiPackEvent -import com.vitorpamplona.amethyst.service.model.FileHeaderEvent -import com.vitorpamplona.amethyst.service.model.FileStorageHeaderEvent -import com.vitorpamplona.amethyst.service.model.GenericRepostEvent -import com.vitorpamplona.amethyst.service.model.HighlightEvent -import com.vitorpamplona.amethyst.service.model.LongTextNoteEvent -import com.vitorpamplona.amethyst.service.model.PeopleListEvent -import com.vitorpamplona.amethyst.service.model.PinListEvent -import com.vitorpamplona.amethyst.service.model.PollNoteEvent -import com.vitorpamplona.amethyst.service.model.RelaySetEvent -import com.vitorpamplona.amethyst.service.model.RepostEvent import com.vitorpamplona.amethyst.ui.components.ObserveDisplayNip05Status import com.vitorpamplona.amethyst.ui.note.* import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel @@ -84,6 +65,25 @@ import com.vitorpamplona.amethyst.ui.theme.SmallBorder import com.vitorpamplona.amethyst.ui.theme.lessImportantLink import com.vitorpamplona.amethyst.ui.theme.placeholderText import com.vitorpamplona.amethyst.ui.theme.selectedNote +import com.vitorpamplona.quartz.events.AppDefinitionEvent +import com.vitorpamplona.quartz.events.AudioTrackEvent +import com.vitorpamplona.quartz.events.BadgeDefinitionEvent +import com.vitorpamplona.quartz.events.ChannelCreateEvent +import com.vitorpamplona.quartz.events.ChannelMetadataEvent +import com.vitorpamplona.quartz.events.ClassifiedsEvent +import com.vitorpamplona.quartz.events.CommunityDefinitionEvent +import com.vitorpamplona.quartz.events.CommunityPostApprovalEvent +import com.vitorpamplona.quartz.events.EmojiPackEvent +import com.vitorpamplona.quartz.events.FileHeaderEvent +import com.vitorpamplona.quartz.events.FileStorageHeaderEvent +import com.vitorpamplona.quartz.events.GenericRepostEvent +import com.vitorpamplona.quartz.events.HighlightEvent +import com.vitorpamplona.quartz.events.LongTextNoteEvent +import com.vitorpamplona.quartz.events.PeopleListEvent +import com.vitorpamplona.quartz.events.PinListEvent +import com.vitorpamplona.quartz.events.PollNoteEvent +import com.vitorpamplona.quartz.events.RelaySetEvent +import com.vitorpamplona.quartz.events.RepostEvent import kotlinx.collections.immutable.toImmutableSet import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountBackupDialog.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountBackupDialog.kt index 6418db6a2..36d624f79 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountBackupDialog.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountBackupDialog.kt @@ -44,10 +44,10 @@ import com.halilibo.richtext.ui.material.MaterialRichText import com.halilibo.richtext.ui.resolveDefaults import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.Account -import com.vitorpamplona.amethyst.service.toNsec import com.vitorpamplona.amethyst.ui.actions.CloseButton import com.vitorpamplona.amethyst.ui.note.authenticate import com.vitorpamplona.amethyst.ui.theme.ButtonBorder +import com.vitorpamplona.quartz.encoders.toNsec import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt index a8c19a560..7646f4876 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt @@ -4,7 +4,6 @@ import android.content.Context import android.content.Intent import android.net.Uri import androidx.compose.runtime.Stable -import androidx.compose.runtime.getValue import androidx.core.content.ContextCompat import androidx.lifecycle.LiveData import androidx.lifecycle.ViewModel @@ -16,19 +15,19 @@ import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.AccountState import com.vitorpamplona.amethyst.model.ConnectivityType -import com.vitorpamplona.amethyst.model.HexKey import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.model.UserState import com.vitorpamplona.amethyst.service.lnurl.LightningAddressResolver -import com.vitorpamplona.amethyst.service.model.DeletionEvent -import com.vitorpamplona.amethyst.service.model.Event -import com.vitorpamplona.amethyst.service.model.GiftWrapEvent -import com.vitorpamplona.amethyst.service.model.LnZapEvent -import com.vitorpamplona.amethyst.service.model.PayInvoiceErrorResponse -import com.vitorpamplona.amethyst.service.model.ReactionEvent -import com.vitorpamplona.amethyst.service.model.ReportEvent -import com.vitorpamplona.amethyst.service.model.SealedGossipEvent +import com.vitorpamplona.quartz.encoders.HexKey +import com.vitorpamplona.quartz.events.DeletionEvent +import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.events.GiftWrapEvent +import com.vitorpamplona.quartz.events.LnZapEvent +import com.vitorpamplona.quartz.events.PayInvoiceErrorResponse +import com.vitorpamplona.quartz.events.ReactionEvent +import com.vitorpamplona.quartz.events.ReportEvent +import com.vitorpamplona.quartz.events.SealedGossipEvent import kotlinx.collections.immutable.ImmutableSet import kotlinx.collections.immutable.persistentSetOf import kotlinx.collections.immutable.toImmutableSet diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChannelScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChannelScreen.kt index c73b628ce..0dcffe16c 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChannelScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChannelScreen.kt @@ -87,18 +87,13 @@ import com.vitorpamplona.amethyst.model.ServersAvailable import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.service.NostrChannelDataSource import com.vitorpamplona.amethyst.service.PackageUtils -import com.vitorpamplona.amethyst.service.model.Event -import com.vitorpamplona.amethyst.service.model.LiveActivitiesEvent.Companion.STATUS_LIVE -import com.vitorpamplona.amethyst.service.model.Participant import com.vitorpamplona.amethyst.service.relays.Client -import com.vitorpamplona.amethyst.ui.actions.ImmutableListOfLists import com.vitorpamplona.amethyst.ui.actions.NewChannelView import com.vitorpamplona.amethyst.ui.actions.NewMessageTagger import com.vitorpamplona.amethyst.ui.actions.NewPostViewModel import com.vitorpamplona.amethyst.ui.actions.PostButton import com.vitorpamplona.amethyst.ui.actions.SignerDialog import com.vitorpamplona.amethyst.ui.actions.UploadFromGallery -import com.vitorpamplona.amethyst.ui.actions.toImmutableListOfLists import com.vitorpamplona.amethyst.ui.components.LoadNote import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImageProxy import com.vitorpamplona.amethyst.ui.components.SensitivityWarning @@ -137,6 +132,11 @@ import com.vitorpamplona.amethyst.ui.theme.SmallBorder import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer import com.vitorpamplona.amethyst.ui.theme.StdPadding import com.vitorpamplona.amethyst.ui.theme.placeholderText +import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.events.ImmutableListOfLists +import com.vitorpamplona.quartz.events.LiveActivitiesEvent.Companion.STATUS_LIVE +import com.vitorpamplona.quartz.events.Participant +import com.vitorpamplona.quartz.events.toImmutableListOfLists import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChatroomScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChatroomScreen.kt index f424a1a09..d25c3197e 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChatroomScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChatroomScreen.kt @@ -64,12 +64,10 @@ import androidx.lifecycle.distinctUntilChanged import androidx.lifecycle.map import androidx.lifecycle.viewmodel.compose.viewModel import com.vitorpamplona.amethyst.R -import com.vitorpamplona.amethyst.model.ChatroomKey import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.ServersAvailable import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.service.NostrChatroomDataSource -import com.vitorpamplona.amethyst.service.model.ChatMessageEvent import com.vitorpamplona.amethyst.ui.actions.CloseButton import com.vitorpamplona.amethyst.ui.actions.NewPostViewModel import com.vitorpamplona.amethyst.ui.actions.PostButton @@ -93,6 +91,8 @@ import com.vitorpamplona.amethyst.ui.theme.Size30Modifier import com.vitorpamplona.amethyst.ui.theme.Size34dp import com.vitorpamplona.amethyst.ui.theme.StdPadding import com.vitorpamplona.amethyst.ui.theme.placeholderText +import com.vitorpamplona.quartz.events.ChatMessageEvent +import com.vitorpamplona.quartz.events.ChatroomKey import kotlinx.collections.immutable.persistentSetOf import kotlinx.collections.immutable.toPersistentList import kotlinx.coroutines.Dispatchers @@ -183,6 +183,17 @@ fun PrepareChatroomViewModels(room: ChatroomKey, accountViewModel: AccountViewMo newPostModel.nip24 = true } + LaunchedEffect(key1 = newPostModel) { + launch(Dispatchers.IO) { + val hasNIP24 = accountViewModel.userProfile().privateChatrooms[room]?.roomMessages?.any { + it.event is ChatMessageEvent && (it.event as ChatMessageEvent).pubKey != accountViewModel.userProfile().pubkeyHex + } + if (hasNIP24 == true && newPostModel.nip24 == false) { + newPostModel.nip24 = true + } + } + } + ChatroomScreen( room = room, feedViewModel = feedViewModel, @@ -515,9 +526,11 @@ fun GroupChatroomHeader( val expanded = remember { mutableStateOf(false) } Column( - modifier = Modifier.fillMaxWidth().clickable { - expanded.value = !expanded.value - } + modifier = Modifier + .fillMaxWidth() + .clickable { + expanded.value = !expanded.value + } ) { Column( verticalArrangement = Arrangement.Center, @@ -680,7 +693,9 @@ fun LongRoomHeader(room: ChatroomKey, accountViewModel: AccountViewModel, nav: ( } Row( - modifier = Modifier.padding(top = 10.dp).fillMaxWidth(), + modifier = Modifier + .padding(top = 10.dp) + .fillMaxWidth(), horizontalArrangement = Arrangement.Center, verticalAlignment = Alignment.CenterVertically ) { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/DiscoverScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/DiscoverScreen.kt index dad00bd97..ed06371c8 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/DiscoverScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/DiscoverScreen.kt @@ -35,9 +35,6 @@ import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleEventObserver import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.service.NostrDiscoveryDataSource -import com.vitorpamplona.amethyst.service.model.ChannelCreateEvent -import com.vitorpamplona.amethyst.service.model.CommunityDefinitionEvent -import com.vitorpamplona.amethyst.service.model.LiveActivitiesEvent import com.vitorpamplona.amethyst.ui.navigation.Route import com.vitorpamplona.amethyst.ui.note.ChannelCardCompose import com.vitorpamplona.amethyst.ui.screen.FeedEmpty @@ -54,6 +51,9 @@ import com.vitorpamplona.amethyst.ui.screen.SaveableFeedState import com.vitorpamplona.amethyst.ui.screen.ScrollStateKeys import com.vitorpamplona.amethyst.ui.screen.rememberForeverPagerState import com.vitorpamplona.amethyst.ui.theme.TabRowHeight +import com.vitorpamplona.quartz.events.ChannelCreateEvent +import com.vitorpamplona.quartz.events.CommunityDefinitionEvent +import com.vitorpamplona.quartz.events.LiveActivitiesEvent import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.launch diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/HashtagScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/HashtagScreen.kt index f9fa24f19..35a1f5919 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/HashtagScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/HashtagScreen.kt @@ -33,12 +33,12 @@ import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.service.NostrHashtagDataSource import com.vitorpamplona.amethyst.service.PackageUtils -import com.vitorpamplona.amethyst.service.model.Event import com.vitorpamplona.amethyst.service.relays.Client import com.vitorpamplona.amethyst.ui.actions.SignerDialog import com.vitorpamplona.amethyst.ui.screen.NostrHashtagFeedViewModel import com.vitorpamplona.amethyst.ui.screen.RefresheableFeedView import com.vitorpamplona.amethyst.ui.theme.StdPadding +import com.vitorpamplona.quartz.events.Event import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/LoadRedirectScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/LoadRedirectScreen.kt index 112d8c640..40ef07cef 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/LoadRedirectScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/LoadRedirectScreen.kt @@ -22,9 +22,9 @@ import androidx.navigation.NavController import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note -import com.vitorpamplona.amethyst.service.model.ChannelCreateEvent -import com.vitorpamplona.amethyst.service.model.ChatroomKeyable import com.vitorpamplona.amethyst.ui.navigation.Route +import com.vitorpamplona.quartz.events.ChannelCreateEvent +import com.vitorpamplona.quartz.events.ChatroomKeyable import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/NotificationScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/NotificationScreen.kt index 666757574..645a61cc7 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/NotificationScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/NotificationScreen.kt @@ -8,6 +8,7 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.padding import androidx.compose.material.Divider +import androidx.compose.material.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect @@ -56,6 +57,7 @@ import com.vitorpamplona.amethyst.ui.screen.RefresheableCardView import com.vitorpamplona.amethyst.ui.screen.ScrollStateKeys import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange import com.vitorpamplona.amethyst.ui.theme.RoyalBlue +import com.vitorpamplona.amethyst.ui.theme.chartStyle import java.math.BigDecimal import java.math.RoundingMode import java.text.DecimalFormat @@ -192,26 +194,10 @@ fun SummaryBar(model: UserReactionsViewModel) { .padding(vertical = 10.dp, horizontal = 20.dp) .clickable(onClick = { showChart = !showChart }) ) { - ProvideChartStyle() { - val axisModel by model.axisLabels.collectAsState() - val chartModel by model.chartModel.collectAsState() - chartModel?.let { - Chart( - chart = remember(lineChartCount, lineChartZaps) { - lineChartCount.plus(lineChartZaps) - }, - model = it, - startAxis = startAxis( - valueFormatter = CountAxisValueFormatter() - ), - endAxis = endAxis( - valueFormatter = AmountAxisValueFormatter() - ), - bottomAxis = bottomAxis( - valueFormatter = LabelValueFormatter(axisModel) - ) - ) - } + ProvideChartStyle( + chartStyle = MaterialTheme.colors.chartStyle + ) { + ObserveAndShowChart(model, lineChartCount, lineChartZaps) } } } @@ -221,6 +207,33 @@ fun SummaryBar(model: UserReactionsViewModel) { ) } +@Composable +private fun ObserveAndShowChart( + model: UserReactionsViewModel, + lineChartCount: LineChart, + lineChartZaps: LineChart +) { + val axisModel by model.axisLabels.collectAsState() + val chartModel by model.chartModel.collectAsState() + chartModel?.let { + Chart( + chart = remember(lineChartCount, lineChartZaps) { + lineChartCount.plus(lineChartZaps) + }, + model = it, + startAxis = startAxis( + valueFormatter = CountAxisValueFormatter() + ), + endAxis = endAxis( + valueFormatter = AmountAxisValueFormatter() + ), + bottomAxis = bottomAxis( + valueFormatter = LabelValueFormatter(axisModel) + ) + ) + } +} + @Stable class LabelValueFormatter(val axisLabels: List) : AxisValueFormatter { override fun formatValue( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ProfileScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ProfileScreen.kt index c0da57897..f9dc4aa00 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ProfileScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ProfileScreen.kt @@ -54,27 +54,14 @@ import androidx.lifecycle.viewmodel.compose.viewModel import coil.compose.AsyncImage import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.Account -import com.vitorpamplona.amethyst.model.ChatroomKey import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.service.NostrUserProfileDataSource import com.vitorpamplona.amethyst.service.PackageUtils -import com.vitorpamplona.amethyst.service.model.ATag -import com.vitorpamplona.amethyst.service.model.AppDefinitionEvent -import com.vitorpamplona.amethyst.service.model.BadgeDefinitionEvent -import com.vitorpamplona.amethyst.service.model.BadgeProfilesEvent -import com.vitorpamplona.amethyst.service.model.ContactListEvent -import com.vitorpamplona.amethyst.service.model.Event -import com.vitorpamplona.amethyst.service.model.IdentityClaim -import com.vitorpamplona.amethyst.service.model.PayInvoiceErrorResponse -import com.vitorpamplona.amethyst.service.model.PayInvoiceSuccessResponse -import com.vitorpamplona.amethyst.service.model.ReportEvent import com.vitorpamplona.amethyst.service.relays.Client -import com.vitorpamplona.amethyst.ui.actions.ImmutableListOfLists import com.vitorpamplona.amethyst.ui.actions.NewUserMetadataView import com.vitorpamplona.amethyst.ui.actions.SignerDialog -import com.vitorpamplona.amethyst.ui.actions.toImmutableListOfLists import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji import com.vitorpamplona.amethyst.ui.components.DisplayNip05ProfileStatus import com.vitorpamplona.amethyst.ui.components.InvoiceRequestCard @@ -108,6 +95,22 @@ import com.vitorpamplona.amethyst.ui.theme.ButtonBorder import com.vitorpamplona.amethyst.ui.theme.Size16Modifier import com.vitorpamplona.amethyst.ui.theme.Size35dp import com.vitorpamplona.amethyst.ui.theme.placeholderText +import com.vitorpamplona.quartz.encoders.ATag +import com.vitorpamplona.quartz.events.AppDefinitionEvent +import com.vitorpamplona.quartz.events.BadgeDefinitionEvent +import com.vitorpamplona.quartz.events.BadgeProfilesEvent +import com.vitorpamplona.quartz.events.ChatroomKey +import com.vitorpamplona.quartz.events.ContactListEvent +import com.vitorpamplona.quartz.events.GitHubIdentity +import com.vitorpamplona.quartz.events.IdentityClaim +import com.vitorpamplona.quartz.events.ImmutableListOfLists +import com.vitorpamplona.quartz.events.MastodonIdentity +import com.vitorpamplona.quartz.events.PayInvoiceErrorResponse +import com.vitorpamplona.quartz.events.PayInvoiceSuccessResponse +import com.vitorpamplona.quartz.events.ReportEvent +import com.vitorpamplona.quartz.events.TelegramIdentity +import com.vitorpamplona.quartz.events.TwitterIdentity +import com.vitorpamplona.quartz.events.toImmutableListOfLists import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentSetOf import kotlinx.collections.immutable.toImmutableList @@ -845,6 +848,26 @@ fun WatchIsHiddenUser(baseUser: User, accountViewModel: AccountViewModel, conten content(isHidden) } +fun getIdentityClaimIcon(identity: IdentityClaim): Int { + return when (identity) { + is TwitterIdentity -> R.drawable.twitter + is TelegramIdentity -> R.drawable.telegram + is MastodonIdentity -> R.drawable.mastodon + is GitHubIdentity -> R.drawable.github + else -> R.drawable.github + } +} + +fun getIdentityClaimDescription(identity: IdentityClaim): Int { + return when (identity) { + is TwitterIdentity -> R.string.twitter + is TelegramIdentity -> R.string.telegram + is MastodonIdentity -> R.string.mastodon + is GitHubIdentity -> R.string.github + else -> R.drawable.github + } +} + @Composable private fun DrawAdditionalInfo( baseUser: User, @@ -967,8 +990,8 @@ private fun DrawAdditionalInfo( Row(verticalAlignment = Alignment.CenterVertically) { Icon( tint = Color.Unspecified, - painter = painterResource(id = identity.toIcon()), - contentDescription = stringResource(identity.toDescriptor()), + painter = painterResource(id = getIdentityClaimIcon(identity)), + contentDescription = stringResource(getIdentityClaimDescription(identity)), modifier = Modifier.size(16.dp) ) @@ -996,7 +1019,7 @@ private fun DrawAdditionalInfo( TranslatableRichTextViewer( content = it, canPreview = false, - tags = remember { ImmutableListOfLists(emptyList()) }, + tags = remember { ImmutableListOfLists(emptyList()) }, backgroundColor = background, accountViewModel = accountViewModel, nav = nav diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ReportNoteDialog.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ReportNoteDialog.kt index 072d77be5..e0b56ed9f 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ReportNoteDialog.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ReportNoteDialog.kt @@ -39,9 +39,9 @@ import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.DialogProperties import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.Note -import com.vitorpamplona.amethyst.service.model.ReportEvent import com.vitorpamplona.amethyst.ui.note.ArrowBackIcon import com.vitorpamplona.amethyst.ui.theme.WarningColor +import com.vitorpamplona.quartz.events.ReportEvent import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/SearchScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/SearchScreen.kt index efea1be20..acf734db7 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/SearchScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/SearchScreen.kt @@ -65,6 +65,7 @@ import com.vitorpamplona.amethyst.ui.note.UserCompose import com.vitorpamplona.amethyst.ui.note.UsernameDisplay import com.vitorpamplona.amethyst.ui.theme.Size20Modifier import com.vitorpamplona.amethyst.ui.theme.placeholderText +import com.vitorpamplona.quartz.events.findHashtags import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.flow.MutableStateFlow @@ -76,7 +77,6 @@ import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.receiveAsFlow import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import java.util.regex.Pattern import kotlinx.coroutines.channels.Channel as CoroutineChannel @Composable @@ -395,23 +395,6 @@ private fun DisplaySearchResults( } } -val hashtagSearch = Pattern.compile("(?:\\s|\\A)#([^\\s!@#\$%^&*()=+./,\\[{\\]};:'\"?><]+)") - -fun findHashtags(content: String): List { - val matcher = hashtagSearch.matcher(content) - val returningList = mutableSetOf() - while (matcher.find()) { - try { - val tag = matcher.group(1) - if (tag != null && tag.isNotBlank()) { - returningList.add(tag) - } - } catch (e: Exception) { - } - } - return returningList.toList() -} - @Composable fun HashtagLine(tag: String, onClick: () -> Unit) { Column( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/VideoScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/VideoScreen.kt index fd17b304a..1c075d859 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/VideoScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/VideoScreen.kt @@ -41,11 +41,8 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleEventObserver -import androidx.lifecycle.viewmodel.compose.viewModel import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.service.NostrVideoDataSource -import com.vitorpamplona.amethyst.service.model.FileHeaderEvent -import com.vitorpamplona.amethyst.service.model.FileStorageHeaderEvent import com.vitorpamplona.amethyst.ui.actions.NewPostView import com.vitorpamplona.amethyst.ui.components.ObserveDisplayNip05Status import com.vitorpamplona.amethyst.ui.note.FileHeaderDisplay @@ -57,7 +54,6 @@ import com.vitorpamplona.amethyst.ui.note.NoteComposeReportState import com.vitorpamplona.amethyst.ui.note.NoteDropDownMenu import com.vitorpamplona.amethyst.ui.note.NoteUsernameDisplay import com.vitorpamplona.amethyst.ui.note.RenderRelay -import com.vitorpamplona.amethyst.ui.note.RenderReportState import com.vitorpamplona.amethyst.ui.note.ViewCountReaction import com.vitorpamplona.amethyst.ui.note.WatchForReports import com.vitorpamplona.amethyst.ui.note.ZapReaction @@ -72,6 +68,8 @@ import com.vitorpamplona.amethyst.ui.screen.rememberForeverPagerState import com.vitorpamplona.amethyst.ui.theme.Size35dp import com.vitorpamplona.amethyst.ui.theme.onBackgroundColorFilter import com.vitorpamplona.amethyst.ui.theme.placeholderText +import com.vitorpamplona.quartz.events.FileHeaderEvent +import com.vitorpamplona.quartz.events.FileStorageHeaderEvent import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentSetOf import kotlinx.coroutines.Dispatchers diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/theme/Theme.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/theme/Theme.kt index 0f8e61333..42a6331c6 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/theme/Theme.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/theme/Theme.kt @@ -28,6 +28,8 @@ import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.unit.dp import com.halilibo.richtext.ui.RichTextStyle import com.halilibo.richtext.ui.resolveDefaults +import com.patrykandpatrick.vico.compose.style.ChartStyle +import com.patrykandpatrick.vico.core.DefaultColors import com.vitorpamplona.amethyst.ui.screen.ThemeViewModel private val DarkColorPalette = darkColors( @@ -302,6 +304,22 @@ val Colors.replyModifier: Modifier val Colors.innerPostModifier: Modifier get() = if (isLight) LightInnerPostBorderModifier else DarkInnerPostBorderModifier +val Colors.chartStyle: ChartStyle + get() { + val defaultColors = if (isLight) DefaultColors.Light else DefaultColors.Dark + return ChartStyle.fromColors( + axisLabelColor = Color(defaultColors.axisLabelColor), + axisGuidelineColor = Color(defaultColors.axisGuidelineColor), + axisLineColor = Color(defaultColors.axisLineColor), + entityColors = listOf( + defaultColors.entity1Color, + defaultColors.entity2Color, + defaultColors.entity3Color + ).map(::Color), + elevationOverlayColor = Color(defaultColors.elevationOverlayColor) + ) + } + @Composable fun AmethystTheme(themeViewModel: ThemeViewModel, content: @Composable () -> Unit) { val theme = themeViewModel.theme.observeAsState() diff --git a/app/src/play/java/com/vitorpamplona/amethyst/service/notifications/PushNotificationReceiverService.kt b/app/src/play/java/com/vitorpamplona/amethyst/service/notifications/PushNotificationReceiverService.kt index d1d1d2c9b..60cb97d47 100644 --- a/app/src/play/java/com/vitorpamplona/amethyst/service/notifications/PushNotificationReceiverService.kt +++ b/app/src/play/java/com/vitorpamplona/amethyst/service/notifications/PushNotificationReceiverService.kt @@ -5,9 +5,9 @@ import androidx.core.content.ContextCompat import com.google.firebase.messaging.FirebaseMessagingService import com.google.firebase.messaging.RemoteMessage import com.vitorpamplona.amethyst.LocalPreferences -import com.vitorpamplona.amethyst.service.model.Event import com.vitorpamplona.amethyst.service.notifications.NotificationUtils.getOrCreateDMChannel import com.vitorpamplona.amethyst.service.notifications.NotificationUtils.getOrCreateZapChannel +import com.vitorpamplona.quartz.events.Event class PushNotificationReceiverService : FirebaseMessagingService() { @@ -15,7 +15,7 @@ class PushNotificationReceiverService : FirebaseMessagingService() { override fun onMessageReceived(remoteMessage: RemoteMessage) { remoteMessage.data.let { val eventStr = remoteMessage.data["event"] ?: return - val event = Event.fromJson(eventStr, true) + val event = Event.fromJson(eventStr) EventNotificationConsumer(applicationContext).consume(event) } } diff --git a/app/src/play/java/com/vitorpamplona/amethyst/ui/components/TranslatableRichTextViewer.kt b/app/src/play/java/com/vitorpamplona/amethyst/ui/components/TranslatableRichTextViewer.kt index 0160bc960..47fac7211 100644 --- a/app/src/play/java/com/vitorpamplona/amethyst/ui/components/TranslatableRichTextViewer.kt +++ b/app/src/play/java/com/vitorpamplona/amethyst/ui/components/TranslatableRichTextViewer.kt @@ -35,9 +35,9 @@ import androidx.compose.ui.unit.dp import androidx.core.os.ConfigurationCompat import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.service.lang.LanguageTranslatorService -import com.vitorpamplona.amethyst.ui.actions.ImmutableListOfLists import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.theme.lessImportantLink +import com.vitorpamplona.quartz.events.ImmutableListOfLists import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import java.util.Locale diff --git a/app/src/test/java/com/vitorpamplona/amethyst/NewMessageTaggerKeyParseTest.kt b/app/src/test/java/com/vitorpamplona/amethyst/NewMessageTaggerKeyParseTest.kt index b1023d9df..f555f8684 100644 --- a/app/src/test/java/com/vitorpamplona/amethyst/NewMessageTaggerKeyParseTest.kt +++ b/app/src/test/java/com/vitorpamplona/amethyst/NewMessageTaggerKeyParseTest.kt @@ -1,7 +1,7 @@ package com.vitorpamplona.amethyst -import com.vitorpamplona.amethyst.service.nip19.Nip19 import com.vitorpamplona.amethyst.ui.actions.NewMessageTagger +import com.vitorpamplona.quartz.encoders.Nip19 import org.junit.Assert.assertEquals import org.junit.Test diff --git a/app/src/test/java/com/vitorpamplona/amethyst/service/zaps/UserZapsTest.kt b/app/src/test/java/com/vitorpamplona/amethyst/service/zaps/UserZapsTest.kt index db91f6b85..e65681862 100644 --- a/app/src/test/java/com/vitorpamplona/amethyst/service/zaps/UserZapsTest.kt +++ b/app/src/test/java/com/vitorpamplona/amethyst/service/zaps/UserZapsTest.kt @@ -1,9 +1,9 @@ package com.vitorpamplona.amethyst.service.zaps -import com.vitorpamplona.amethyst.model.HexKey import com.vitorpamplona.amethyst.model.Note -import com.vitorpamplona.amethyst.service.model.LnZapEventInterface -import com.vitorpamplona.amethyst.service.model.zaps.UserZaps +import com.vitorpamplona.quartz.encoders.HexKey +import com.vitorpamplona.quartz.events.LnZapEventInterface +import com.vitorpamplona.quartz.events.zaps.UserZaps import io.mockk.every import io.mockk.mockk import org.junit.Assert diff --git a/benchmark/.gitignore b/benchmark/.gitignore new file mode 100644 index 000000000..42afabfd2 --- /dev/null +++ b/benchmark/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/benchmark/benchmark-proguard-rules.pro b/benchmark/benchmark-proguard-rules.pro new file mode 100644 index 000000000..e4061d222 --- /dev/null +++ b/benchmark/benchmark-proguard-rules.pro @@ -0,0 +1,37 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile + +-dontobfuscate + +-ignorewarnings + +-keepattributes *Annotation* + +-dontnote junit.framework.** +-dontnote junit.runner.** + +-dontwarn androidx.test.** +-dontwarn org.junit.** +-dontwarn org.hamcrest.** +-dontwarn com.squareup.javawriter.JavaWriter + +-keepclasseswithmembers @org.junit.runner.RunWith public class * \ No newline at end of file diff --git a/benchmark/build.gradle b/benchmark/build.gradle new file mode 100644 index 000000000..63c6e2931 --- /dev/null +++ b/benchmark/build.gradle @@ -0,0 +1,52 @@ +plugins { + id 'com.android.library' + id 'androidx.benchmark' + id 'org.jetbrains.kotlin.android' +} + +android { + namespace 'com.vitorpamplona.amethyst.benchmark' + compileSdk 33 + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + + kotlinOptions { + jvmTarget = "1.8" + } + + defaultConfig { + minSdk 26 + targetSdk 33 + + testInstrumentationRunner 'androidx.benchmark.junit4.AndroidBenchmarkRunner' + } + + testBuildType = "release" + buildTypes { + debug { + // Since debuggable can"t be modified by gradle for library modules, + // it must be done in a manifest - see src/androidTest/AndroidManifest.xml + minifyEnabled true + proguardFiles getDefaultProguardFile("proguard-android-optimize.txt"), "benchmark-proguard-rules.pro" + } + release { + isDefault = true + } + } +} + +dependencies { + androidTestImplementation 'androidx.test:runner:1.5.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.5' + androidTestImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.benchmark:benchmark-junit4:1.1.1' + androidTestImplementation project(path: ':quartz') + + // Add your dependencies here. Note that you cannot benchmark code + // in an app module this way - you will need to move any code you + // want to benchmark to a library module: + // https://developer.android.com/studio/projects/android-library#Convert +} \ No newline at end of file diff --git a/benchmark/src/androidTest/AndroidManifest.xml b/benchmark/src/androidTest/AndroidManifest.xml new file mode 100644 index 000000000..405595ca6 --- /dev/null +++ b/benchmark/src/androidTest/AndroidManifest.xml @@ -0,0 +1,15 @@ + + + + + + \ No newline at end of file diff --git a/benchmark/src/androidTest/java/com/vitorpamplona/amethyst/benchmark/EventBenchmark.kt b/benchmark/src/androidTest/java/com/vitorpamplona/amethyst/benchmark/EventBenchmark.kt new file mode 100644 index 000000000..5583407d6 --- /dev/null +++ b/benchmark/src/androidTest/java/com/vitorpamplona/amethyst/benchmark/EventBenchmark.kt @@ -0,0 +1,122 @@ +package com.vitorpamplona.amethyst.benchmark + +import androidx.benchmark.junit4.BenchmarkRule +import androidx.benchmark.junit4.measureRepeated +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.events.Event +import junit.framework.TestCase.assertNotNull +import junit.framework.TestCase.assertTrue +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + +/** + * Benchmark, which will execute on an Android device. + * + * The body of [BenchmarkRule.measureRepeated] is measured in a loop, and Studio will + * output the result. Modify your code to see how it affects performance. + */ +@RunWith(AndroidJUnit4::class) +class EventBenchmark { + + val payload1 = "[\"EVENT\",\"40b9\",{\"id\":\"48a72b485d38338627ec9d427583551f9af4f016c739b8ec0d6313540a8b12cf\",\"kind\":1,\"pubkey\":\"3d842afecd5e293f28b6627933704a3fb8ce153aa91d790ab11f6a752d44a42d\",\"created_at\":1677940007,\"content\":\"I got asked about follower count again today. Why does my follower count go down when I delete public relays (in our list) and replace them with filter.nostr.wine? \\n\\nI’ll give you one final explanation to rule them all. First, let’s go over how clients calculate your follower count.\\n\\n1. Your client sends a request to all your connected relays asking for accounts who follow you\\n2. Relays answer back with the events requested\\n3. The client aggregates the event total and displays it\\n\\nEach relay has a set limit on how many stored events it will return per request. For some relays it’s 500, others 1000, some as high as 5000. Let’s say for simplicity that all your public relays use 500 as their limit. If you ask 10 relays for your followers the max possible answer you can get is 5000. That won’t change if you have 20,000 followers or 100,000. You may get back a “different” 5000 each time, but you’ll still cap out at 5000 because that is the most events your client will receive.\u2028\u2028Our limit on filter.nostr.wine is 2000 events. If you replace 10 public relays with only filter.nostr.wine, the MOST followers you will ever get back from our filter relay is 2000. That doesn’t mean you only have 2000 followers or that your reach is reduced in any way.\\n\\nAs long as you are writing to and reading from the same public relays, neither your reach nor any content was lost. That concludes my TED talk. I hope you all have a fantastic day and weekend.\",\"tags\":[],\"sig\":\"dcaf8ab98bb9179017b35bd814092850d1062b26c263dff89fb1ae8c019a324139d1729012d9d05ff0a517f76b1117d869b2cc7d36bea8aa5f4b94c5e2548aa8\"}]" + + val payload2 = """ + { + "content": "Astral:\n\nhttps://void.cat/d/A5Fba5B1bcxwEmeyoD9nBs.webp\n\nIris:\n\nhttps://void.cat/d/44hTcVvhRps6xYYs99QsqA.webp\n\nSnort:\n\nhttps://void.cat/d/4nJD5TRePuQChM5tzteYbU.webp\n\nAmethyst agrees with Astral which I suspect are both wrong. nostr:npub13sx6fp3pxq5rl70x0kyfmunyzaa9pzt5utltjm0p8xqyafndv95q3saapa nostr:npub1v0lxxxxutpvrelsksy8cdhgfux9l6a42hsj2qzquu2zk7vc9qnkszrqj49 nostr:npub1g53mukxnjkcmr94fhryzkqutdz2ukq4ks0gvy5af25rgmwsl4ngq43drvk nostr:npub1gcxzte5zlkncx26j68ez60fzkvtkm9e0vrwdcvsjakxf9mu9qewqlfnj5z ", + "created_at": 1683596206, + "id": "98b574c3527f0ffb30b7271084e3f07480733c7289f8de424d29eae82e36c758", + "kind": 1, + "pubkey": "46fcbe3065eaf1ae7811465924e48923363ff3f526bd6f73d7c184b16bd8ce4d", + "sig": "4aa5264965018fa12a326686ad3d3bd8beae3218dcc83689b19ca1e6baeb791531943c15363aa6707c7c0c8b2d601deca1f20c32078b2872d356cdca03b04cce", + "tags": [ + ["e","27ac621d7dc4a932e1a79f984308e7d20656dd6fddb2ce9cdfcb6a67b9a7bcc3","","root"], + ["e","be7245af96210a0dd048cab4ad38e52dbd6c09a53ea21a7edb6be8898e5727cc","","reply"], + ["p","22aa81510ee63fe2b16cae16e0921f78e9ba9882e2868e7e63ad6d08ae9b5954"], + ["p","22aa81510ee63fe2b16cae16e0921f78e9ba9882e2868e7e63ad6d08ae9b5954"], + ["p","3f770d65d3a764a9c5cb503ae123e62ec7598ad035d836e2a810f3877a745b24"], + ["p","ec4d241c334311b3a304433ee3442be29d0e88e7ec19b85edf2bba29b93565e2"], + ["p","0fe0b18b4dbf0e0aa40fcd47209b2a49b3431fc453b460efcf45ca0bd16bd6ac"], + ["p","8c0da4862130283ff9e67d889df264177a508974e2feb96de139804ea66d6168"], + ["p","63fe6318dc58583cfe16810f86dd09e18bfd76aabc24a0081ce2856f330504ed"], + ["p","4523be58d395b1b196a9b8c82b038b6895cb02b683d0c253a955068dba1facd0"], + ["p","460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"] + ], + "seenOn": [ + "wss://nostr.wine/" + ] +} +""" + + @get:Rule + val benchmarkRule = BenchmarkRule() + + @Test + fun parseREQString() { + benchmarkRule.measureRepeated { + Event.mapper.readTree(payload1) + } + } + + @Test + fun parseEvent() { + val msg = Event.mapper.readTree(payload1) + + benchmarkRule.measureRepeated { + Event.fromJson(msg[2]) + } + } + + @Test + fun checkSignature() { + val msg = Event.mapper.readTree(payload1) + val event = Event.fromJson(msg[2]) + benchmarkRule.measureRepeated { + // Should pass + assertTrue( event.hasVerifedSignature() ) + } + } + + @Test + fun checkIDHashPayload1() { + val msg = Event.mapper.readTree(payload1) + val event = Event.fromJson(msg[2]) + + benchmarkRule.measureRepeated { + // Should pass + assertTrue( event.hasCorrectIDHash() ) + } + } + + @Test + fun checkIDHashPayload2() { + val event = Event.fromJson(payload2) + + benchmarkRule.measureRepeated { + // Should pass + assertTrue( event.hasCorrectIDHash() ) + } + } + + @Test + fun toMakeJsonForID() { + val event = Event.fromJson(payload2) + + benchmarkRule.measureRepeated { + assertNotNull(event.makeJsonForId()) + } + } + + @Test + fun sha256() { + val event = Event.fromJson(payload2) + val byteArray = event.makeJsonForId().toByteArray() + + benchmarkRule.measureRepeated { + // Should pass + assertNotNull(CryptoUtils.sha256(byteArray)) + } + } + +} \ No newline at end of file diff --git a/benchmark/src/androidTest/java/com/vitorpamplona/amethyst/benchmark/GiftWrapBenchmark.kt b/benchmark/src/androidTest/java/com/vitorpamplona/amethyst/benchmark/GiftWrapBenchmark.kt new file mode 100644 index 000000000..c63d2c58e --- /dev/null +++ b/benchmark/src/androidTest/java/com/vitorpamplona/amethyst/benchmark/GiftWrapBenchmark.kt @@ -0,0 +1,227 @@ +package com.vitorpamplona.amethyst.benchmark + +import androidx.benchmark.junit4.BenchmarkRule +import androidx.benchmark.junit4.measureRepeated +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.KeyPair +import com.vitorpamplona.quartz.events.NIP24Factory +import com.vitorpamplona.quartz.events.SealedGossipEvent +import org.junit.Assert +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + +/** + * Benchmark, which will execute on an Android device. + * + * The body of [BenchmarkRule.measureRepeated] is measured in a loop, and Studio will + * output the result. Modify your code to see how it affects performance. + */ +@RunWith(AndroidJUnit4::class) +class GiftWrapBenchmark { + + @get:Rule + val benchmarkRule = BenchmarkRule() + + fun basePerformanceTest(message: String, expectedLength: Int) { + val sender = KeyPair() + val receiver = KeyPair() + + val events = NIP24Factory().createMsgNIP24( + message, + listOf(receiver.pubKey.toHexKey()), + sender.privKey!! + ) + + Assert.assertEquals(expectedLength, events.map { it.toJson() }.joinToString("").length) + + // Simulate Receiver + events.forEach { + it.checkSignature() + + val keyToUse = if (it.recipientPubKey() == sender.pubKey.toHexKey()) sender.privKey!! else receiver.privKey!! + val event = it.unwrap(keyToUse) + event?.checkSignature() + + if (event is SealedGossipEvent) { + val innerData = event.unseal(keyToUse) + Assert.assertEquals(message, innerData?.content) + } else { + Assert.fail("Wrong Event") + } + } + } + + + @Test + fun tinyMessageHardCoded() { + benchmarkRule.measureRepeated { + basePerformanceTest("Hola, que tal?", 2946) + } + } + + @Test + fun regularMessageHardCoded() { + benchmarkRule.measureRepeated { + basePerformanceTest("Hi, honey, can you drop by the market and get some bread?", 3098) + } + } + + @Test + fun longMessageHardCoded() { + benchmarkRule.measureRepeated { + basePerformanceTest( + "My queen, you are nothing short of royalty to me. You possess more beauty in the nail of your pinkie toe than everything else in this world combined. I am astounded by your grace, generosity, and graciousness. I am so lucky to know you. ", + 3738 + ) + } + } +/* + @Test + fun tinyMessageHardCodedCompressed() { + benchmarkRule.measureRepeated { + basePerformanceTest("Hola, que tal?", 2318) + } + } + + @Test + fun regularMessageHardCodedCompressed() { + benchmarkRule.measureRepeated { + basePerformanceTest("Hi, honey, can you drop by the market and get some bread?", 2406) + } + } + + @Test + fun longMessageHardCodedCompressed() { + benchmarkRule.measureRepeated { + basePerformanceTest( + "My queen, you are nothing short of royalty to me. You possess more beauty in the nail of your pinkie toe than everything else in this world combined. I am astounded by your grace, generosity, and graciousness. I am so lucky to know you. ", + 2722 + ) + } + }*/ + +/* + @Test + fun tinyMessageJSONCompressed() { + benchmarkRule.measureRepeated { + basePerformanceTest("Hola, que tal?", 2318) + } + } + + @Test + fun regularMessageJSONCompressed() { + benchmarkRule.measureRepeated { + basePerformanceTest("Hi, honey, can you drop by the market and get some bread?", 2394) + } + } + + @Test + fun longMessageJSONCompressed() { + benchmarkRule.measureRepeated { + basePerformanceTest( + "My queen, you are nothing short of royalty to me. You possess more beauty in the nail of your pinkie toe than everything else in this world combined. I am astounded by your grace, generosity, and graciousness. I am so lucky to know you. ", + 2714 + ) + } + }*/ + +/* + @Test + fun tinyMessageJSON() { + benchmarkRule.measureRepeated { + basePerformanceTest("Hola, que tal?", 3154) + } + } + + @Test + fun regularMessageJSON() { + benchmarkRule.measureRepeated { + basePerformanceTest("Hi, honey, can you drop by the market and get some bread?", 3298) + } + } + + @Test + fun longMessageJSON() { + benchmarkRule.measureRepeated { + basePerformanceTest( + "My queen, you are nothing short of royalty to me. You possess more beauty in the nail of your pinkie toe than everything else in this world combined. I am astounded by your grace, generosity, and graciousness. I am so lucky to know you. ", + 3938 + ) + } + }*/ + +/* + @Test + fun tinyMessageJackson() { + benchmarkRule.measureRepeated { + basePerformanceTest("Hola, que tal?", 3154) + } + } + + @Test + fun regularMessageJackson() { + benchmarkRule.measureRepeated { + basePerformanceTest("Hi, honey, can you drop by the market and get some bread?", 3298) + } + } + + @Test + fun longMessageJackson() { + benchmarkRule.measureRepeated { + basePerformanceTest( + "My queen, you are nothing short of royalty to me. You possess more beauty in the nail of your pinkie toe than everything else in this world combined. I am astounded by your grace, generosity, and graciousness. I am so lucky to know you. ", + 3938 + ) + } + } */ +/* + @Test + fun tinyMessageKotlin() { + benchmarkRule.measureRepeated { + basePerformanceTest("Hola, que tal?", 3154) + } + } + + @Test + fun regularMessageKotlin() { + benchmarkRule.measureRepeated { + basePerformanceTest("Hi, honey, can you drop by the market and get some bread?", 3298) + } + } + + @Test + fun longMessageKotlin() { + benchmarkRule.measureRepeated { + basePerformanceTest( + "My queen, you are nothing short of royalty to me. You possess more beauty in the nail of your pinkie toe than everything else in this world combined. I am astounded by your grace, generosity, and graciousness. I am so lucky to know you. ", + 3938 + ) + } + }*/ +/* + @Test + fun tinyMessageCSV() { + benchmarkRule.measureRepeated { + basePerformanceTest("Hola, que tal?", 2960) + } + } + + @Test + fun regularMessageCSV() { + benchmarkRule.measureRepeated { + basePerformanceTest("Hi, honey, can you drop by the market and get some bread?", 3112) + } + } + + @Test + fun longMessageCSV() { + benchmarkRule.measureRepeated { + basePerformanceTest( + "My queen, you are nothing short of royalty to me. You possess more beauty in the nail of your pinkie toe than everything else in this world combined. I am astounded by your grace, generosity, and graciousness. I am so lucky to know you. ", + 3752 + ) + } + }*/ +} \ No newline at end of file diff --git a/benchmark/src/androidTest/java/com/vitorpamplona/amethyst/benchmark/GiftWrapReceivingBenchmark.kt b/benchmark/src/androidTest/java/com/vitorpamplona/amethyst/benchmark/GiftWrapReceivingBenchmark.kt new file mode 100644 index 000000000..10cd3307c --- /dev/null +++ b/benchmark/src/androidTest/java/com/vitorpamplona/amethyst/benchmark/GiftWrapReceivingBenchmark.kt @@ -0,0 +1,222 @@ +package com.vitorpamplona.amethyst.benchmark + +import androidx.benchmark.junit4.BenchmarkRule +import androidx.benchmark.junit4.measureRepeated +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.KeyPair +import com.vitorpamplona.quartz.crypto.decodeNIP44 +import com.vitorpamplona.quartz.encoders.hexToByteArray +import com.vitorpamplona.quartz.events.ChatMessageEvent +import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.events.GiftWrapEvent +import com.vitorpamplona.quartz.events.Gossip +import com.vitorpamplona.quartz.events.SealedGossipEvent +import junit.framework.TestCase.assertNotNull +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + +/** + * Benchmark, which will execute on an Android device. + * + * The body of [BenchmarkRule.measureRepeated] is measured in a loop, and Studio will + * output the result. Modify your code to see how it affects performance. + */ +@RunWith(AndroidJUnit4::class) +class GiftWrapReceivingBenchmark { + + @get:Rule + val benchmarkRule = BenchmarkRule() + + fun createMessage(sender: KeyPair, receiver: KeyPair): ChatMessageEvent { + val to = listOf(receiver.pubKey.toHexKey()) + + return ChatMessageEvent.create( + msg = "Hi there! This is a test message", + to = to, + privateKey = sender.privKey!!, + subject = "Party Tonight", + replyTos = emptyList(), + mentions = emptyList(), + zapReceiver = null, + markAsSensitive = true, + zapRaiserAmount = 10000, + geohash = null + ) + } + + @Test + fun parseWrapFromString() { + val sender = KeyPair() + val receiver = KeyPair() + + val senderPublicKey = CryptoUtils.pubkeyCreate(sender.privKey!!).toHexKey() + + val senderMessage = createMessage(sender, receiver) + + val seal = SealedGossipEvent.create( + event = senderMessage, + encryptTo = senderPublicKey, + privateKey = sender.privKey!! + ) + + val wrap = GiftWrapEvent.create( + event = seal, + recipientPubKey = senderPublicKey + ) + + val str = wrap.toJson() + + benchmarkRule.measureRepeated { + Event.fromJson(str) + } + } + + @Test + fun decodeWrapEvent() { + val sender = KeyPair() + val receiver = KeyPair() + + val senderPublicKey = CryptoUtils.pubkeyCreate(sender.privKey!!).toHexKey() + + val senderMessage = createMessage(sender, receiver) + + val seal = SealedGossipEvent.create( + event = senderMessage, + encryptTo = senderPublicKey, + privateKey = sender.privKey!! + ) + + val wrappedEvent = GiftWrapEvent.create( + event = seal, + recipientPubKey = senderPublicKey + ) + + benchmarkRule.measureRepeated { + assertNotNull(decodeNIP44(wrappedEvent.content)) + } + } + + @Test + fun decryptWrapEvent() { + val sender = KeyPair() + val receiver = KeyPair() + + val senderPublicKey = CryptoUtils.pubkeyCreate(sender.privKey!!).toHexKey() + + val senderMessage = createMessage(sender, receiver) + + val seal = SealedGossipEvent.create( + event = senderMessage, + encryptTo = senderPublicKey, + privateKey = sender.privKey!! + ) + + val wrappedEvent = GiftWrapEvent.create( + event = seal, + recipientPubKey = senderPublicKey + ) + + val toDecrypt = decodeNIP44(wrappedEvent.content) ?: return + + benchmarkRule.measureRepeated { + assertNotNull(CryptoUtils.decryptNIP24(toDecrypt, sender.privKey!!, wrappedEvent.pubKey.hexToByteArray())) + } + } + + @Test + fun parseWrappedEvent() { + val sender = KeyPair() + val receiver = KeyPair() + + val senderPublicKey = CryptoUtils.pubkeyCreate(sender.privKey!!).toHexKey() + + val senderMessage = createMessage(sender, receiver) + + val seal = SealedGossipEvent.create( + event = senderMessage, + encryptTo = senderPublicKey, + privateKey = sender.privKey!! + ) + + val wrappedEvent = GiftWrapEvent.create( + event = seal, + recipientPubKey = senderPublicKey + ) + + val toDecrypt = decodeNIP44(wrappedEvent.content) ?: return + val innerJson = CryptoUtils.decryptNIP24(toDecrypt, sender.privKey!!, wrappedEvent.pubKey.hexToByteArray()) + + benchmarkRule.measureRepeated { + assertNotNull(innerJson?.let { Event.fromJson(it) }) + } + } + + @Test + fun decodeSealEvent() { + val sender = KeyPair() + val receiver = KeyPair() + + val senderPublicKey = CryptoUtils.pubkeyCreate(sender.privKey!!).toHexKey() + + val senderMessage = createMessage(sender, receiver) + + val seal = SealedGossipEvent.create( + event = senderMessage, + encryptTo = senderPublicKey, + privateKey = sender.privKey!! + ) + + benchmarkRule.measureRepeated { + assertNotNull(decodeNIP44(seal.content)) + } + } + + @Test + fun decryptSealedEvent() { + val sender = KeyPair() + val receiver = KeyPair() + + val senderPublicKey = CryptoUtils.pubkeyCreate(sender.privKey!!).toHexKey() + + val senderMessage = createMessage(sender, receiver) + + val seal = SealedGossipEvent.create( + event = senderMessage, + encryptTo = senderPublicKey, + privateKey = sender.privKey!! + ) + + val toDecrypt = decodeNIP44(seal.content) ?: return + + benchmarkRule.measureRepeated { + assertNotNull(CryptoUtils.decryptNIP24(toDecrypt, sender.privKey!!, seal.pubKey.hexToByteArray())) + } + } + + @Test + fun parseSealedEvent() { + val sender = KeyPair() + val receiver = KeyPair() + + val senderPublicKey = CryptoUtils.pubkeyCreate(sender.privKey!!).toHexKey() + + val senderMessage = createMessage(sender, receiver) + + val seal = SealedGossipEvent.create( + event = senderMessage, + encryptTo = senderPublicKey, + privateKey = sender.privKey!! + ) + + val toDecrypt = decodeNIP44(seal.content) ?: return + val innerJson = CryptoUtils.decryptNIP24(toDecrypt, sender.privKey!!, seal.pubKey.hexToByteArray()) + + benchmarkRule.measureRepeated { + assertNotNull(innerJson?.let { Gossip.fromJson(it) }) + } + } + +} \ No newline at end of file diff --git a/benchmark/src/androidTest/java/com/vitorpamplona/amethyst/benchmark/GiftWrapSigningBenchmark.kt b/benchmark/src/androidTest/java/com/vitorpamplona/amethyst/benchmark/GiftWrapSigningBenchmark.kt new file mode 100644 index 000000000..da834c887 --- /dev/null +++ b/benchmark/src/androidTest/java/com/vitorpamplona/amethyst/benchmark/GiftWrapSigningBenchmark.kt @@ -0,0 +1,123 @@ +package com.vitorpamplona.amethyst.benchmark + +import androidx.benchmark.junit4.BenchmarkRule +import androidx.benchmark.junit4.measureRepeated +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.KeyPair +import com.vitorpamplona.quartz.events.ChatMessageEvent +import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.events.GiftWrapEvent +import com.vitorpamplona.quartz.events.Gossip +import com.vitorpamplona.quartz.events.SealedGossipEvent +import junit.framework.TestCase.assertNotNull +import junit.framework.TestCase.assertTrue +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + +/** + * Benchmark, which will execute on an Android device. + * + * The body of [BenchmarkRule.measureRepeated] is measured in a loop, and Studio will + * output the result. Modify your code to see how it affects performance. + */ +@RunWith(AndroidJUnit4::class) +class GiftWrapSigningBenchmark { + + @get:Rule + val benchmarkRule = BenchmarkRule() + + fun createMessage(sender: KeyPair, receiver: KeyPair): ChatMessageEvent { + val to = listOf(receiver.pubKey.toHexKey()) + + return ChatMessageEvent.create( + msg = "Hi there! This is a test message", + to = to, + privateKey = sender.privKey!!, + subject = "Party Tonight", + replyTos = emptyList(), + mentions = emptyList(), + zapReceiver = null, + markAsSensitive = true, + zapRaiserAmount = 10000, + geohash = null + ) + } + + @Test + fun createMessageEvent() { + val sender = KeyPair() + val receiver = KeyPair() + + benchmarkRule.measureRepeated { + createMessage(sender, receiver) + } + } + + @Test + fun sealMessage() { + val sender = KeyPair() + val receiver = KeyPair() + + val senderMessage = createMessage(sender, receiver) + + benchmarkRule.measureRepeated { + val senderPublicKey = CryptoUtils.pubkeyCreate(sender.privKey!!).toHexKey() + SealedGossipEvent.create( + event = senderMessage, + encryptTo = senderPublicKey, + privateKey = sender.privKey!! + ) + } + } + + @Test + fun wrapSeal() { + val sender = KeyPair() + val receiver = KeyPair() + + val senderPublicKey = CryptoUtils.pubkeyCreate(sender.privKey!!).toHexKey() + + val senderMessage = createMessage(sender, receiver) + + val seal = SealedGossipEvent.create( + event = senderMessage, + encryptTo = senderPublicKey, + privateKey = sender.privKey!! + ) + + benchmarkRule.measureRepeated { + GiftWrapEvent.create( + event = seal, + recipientPubKey = senderPublicKey + ) + } + } + + @Test + fun wrapToString() { + val sender = KeyPair() + val receiver = KeyPair() + + val senderPublicKey = CryptoUtils.pubkeyCreate(sender.privKey!!).toHexKey() + + val senderMessage = createMessage(sender, receiver) + + val seal = SealedGossipEvent.create( + event = senderMessage, + encryptTo = senderPublicKey, + privateKey = sender.privKey!! + ) + + val wrap = GiftWrapEvent.create( + event = seal, + recipientPubKey = senderPublicKey + ) + + benchmarkRule.measureRepeated { + wrap.toJson() + } + } +} \ No newline at end of file diff --git a/benchmark/src/androidTest/java/com/vitorpamplona/amethyst/benchmark/HexBenchmark.kt b/benchmark/src/androidTest/java/com/vitorpamplona/amethyst/benchmark/HexBenchmark.kt new file mode 100644 index 000000000..08ef9c360 --- /dev/null +++ b/benchmark/src/androidTest/java/com/vitorpamplona/amethyst/benchmark/HexBenchmark.kt @@ -0,0 +1,56 @@ +package com.vitorpamplona.amethyst.benchmark + +import androidx.benchmark.junit4.BenchmarkRule +import androidx.benchmark.junit4.measureRepeated +import androidx.test.ext.junit.runners.AndroidJUnit4 +import junit.framework.TestCase.assertEquals +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + +/** + * Benchmark, which will execute on an Android device. + * + * The body of [BenchmarkRule.measureRepeated] is measured in a loop, and Studio will + * output the result. Modify your code to see how it affects performance. + */ +@RunWith(AndroidJUnit4::class) +class HexBenchmark { + + @get:Rule + val benchmarkRule = BenchmarkRule() + + val TestHex = "48a72b485d38338627ec9d427583551f9af4f016c739b8ec0d6313540a8b12cf" + + @Test + fun hexDecodeOurs() { + benchmarkRule.measureRepeated { + com.vitorpamplona.quartz.encoders.Hex.decode(TestHex) + } + } + + @Test + fun hexEncodeOurs() { + val bytes = com.vitorpamplona.quartz.encoders.Hex.decode(TestHex) + + benchmarkRule.measureRepeated { + assertEquals(TestHex, com.vitorpamplona.quartz.encoders.Hex.encode(bytes)) + } + } + + @Test + fun hexDecodeBaseSecp() { + benchmarkRule.measureRepeated { + fr.acinq.secp256k1.Hex.decode(TestHex) + } + } + + @Test + fun hexEncodeBaseSecp() { + val bytes = fr.acinq.secp256k1.Hex.decode(TestHex) + + benchmarkRule.measureRepeated { + assertEquals(TestHex, fr.acinq.secp256k1.Hex.encode(bytes)) + } + } +} \ No newline at end of file diff --git a/benchmark/src/main/AndroidManifest.xml b/benchmark/src/main/AndroidManifest.xml new file mode 100644 index 000000000..568741e54 --- /dev/null +++ b/benchmark/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/build.gradle b/build.gradle index b401c47bd..d17ae80dd 100644 --- a/build.gradle +++ b/build.gradle @@ -21,6 +21,8 @@ plugins { id 'com.android.library' version '8.1.0' apply false id 'org.jetbrains.kotlin.android' version '1.9.0' apply false id 'org.jetbrains.kotlin.jvm' version '1.9.0' apply false + id 'androidx.benchmark' version '1.1.1' apply false + id 'org.jetbrains.kotlin.plugin.serialization' version '1.9.0' apply false } tasks.register('installGitHook', Copy) { diff --git a/quartz/.gitignore b/quartz/.gitignore new file mode 100644 index 000000000..42afabfd2 --- /dev/null +++ b/quartz/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/quartz/build.gradle b/quartz/build.gradle new file mode 100644 index 000000000..add2ed196 --- /dev/null +++ b/quartz/build.gradle @@ -0,0 +1,58 @@ +plugins { + id 'com.android.library' + id 'org.jetbrains.kotlin.android' + id 'org.jetbrains.kotlin.plugin.serialization' +} + +android { + namespace 'com.vitorpamplona.quartz' + compileSdk 33 + + defaultConfig { + minSdk 26 + targetSdk 33 + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles "consumer-rules.pro" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 + } + kotlinOptions { + jvmTarget = '17' + } +} + +dependencies { + implementation 'androidx.core:core-ktx:1.9.0' + + // @Immutable and @Stable + implementation "androidx.compose.runtime:runtime:$compose_ui_version" + + // Bitcoin secp256k1 bindings to Android + api 'fr.acinq.secp256k1:secp256k1-kmp-jni-android:0.10.1' + + // LibSodium for XChaCha encryption + implementation "com.goterl:lazysodium-android:5.1.0@aar" + implementation 'net.java.dev.jna:jna:5.13.0@aar' + + api 'com.fasterxml.jackson.module:jackson-module-kotlin:2.15.2' + + // immutable collections to avoid recomposition + api("org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.5") + + // Parses URLs from Text: + api "io.github.url-detector:url-detector:0.1.23" + + testImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.5' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' +} \ No newline at end of file diff --git a/quartz/consumer-rules.pro b/quartz/consumer-rules.pro new file mode 100644 index 000000000..e69de29bb diff --git a/quartz/proguard-rules.pro b/quartz/proguard-rules.pro new file mode 100644 index 000000000..4727a86be --- /dev/null +++ b/quartz/proguard-rules.pro @@ -0,0 +1,60 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# preserve the line number information for debugging stack traces. +-dontobfuscate +-keepattributes LocalVariableTable +-keepattributes LocalVariableTypeTable +-keepattributes *Annotation* +-keepattributes SourceFile +-keepattributes LineNumberTable +-keepattributes Signature +-keepattributes Exceptions +-keepattributes InnerClasses +-keepattributes EnclosingMethod +-keepattributes MethodParameters +-keepparameternames + +-keepdirectories libs + +# Keep all names +-keepnames class ** { *; } + +# Keep All enums +-keep enum ** { *; } + +# preserve access to native classses +-keep class fr.acinq.secp256k1.** { *; } + +# JNA For Libsodium +-keep class com.goterl.lazysodium.** { *; } + +# JNA also requires AWT, which Android does not have. So the classes are broken down to filter AWT out +-keep class com.sun.jna.ToNativeConverter { *; } +-keep class com.sun.jna.NativeMapped { *; } +-keep class com.sun.jna.CallbackReference { *; } +-keep class com.sun.jna.ptr.IntByReference { *; } +-keep class com.sun.jna.NativeLong { *; } +-keep class com.sun.jna.Structure { *; } +-keep class com.sun.jna.Structure$* { *; } +-keep class com.sun.jna.Native$ffi_callback { *; } +-keep class * implements com.sun.jna.Structure$* { *; } +-keep class * implements com.sun.jna.Native$* { *; } +-keep class com.sun.jna.Native { + private static com.sun.jna.NativeMapped fromNative(java.lang.Class, java.lang.Object); + private static com.sun.jna.NativeMapped fromNative(java.lang.reflect.Method, java.lang.Object); + private static java.lang.Class nativeType(java.lang.Class); + private static java.lang.Object toNative(com.sun.jna.ToNativeConverter, java.lang.Object); + private static java.lang.Object fromNative(com.sun.jna.FromNativeConverter, java.lang.Object, java.lang.reflect.Method); +} + +# JSON parsing +-keep class com.vitorpamplona.quartz.crypto.** { *; } +-keep class com.vitorpamplona.quartz.encoders.** { *; } +-keep class com.vitorpamplona.quartz.events.** { *; } +-keep class com.vitorpamplona.amethyst.model.** { *; } +-keep class com.vitorpamplona.amethyst.service.** { *; } \ No newline at end of file diff --git a/quartz/src/androidTest/assets/nostr_vitor_short.json b/quartz/src/androidTest/assets/nostr_vitor_short.json new file mode 100644 index 000000000..ffb46ce7f --- /dev/null +++ b/quartz/src/androidTest/assets/nostr_vitor_short.json @@ -0,0 +1,13261 @@ +[ + { + "content": "Do you know which relay has your old info? ", + "created_at": 1690301795, + "id": "fc0e838994bb66a8249aea78e883c6e98f98b93296fb5209e9e9bab54477fe3d", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "326a0f267def66d2733ae0d90fcc8cb52de711e5e93561fc90bcd9291f4cad00f135fa65470a52a1dfa3e758595a0057d6c3407f791f052836a263a95fe0f85f", + "tags": [ + [ + "e", + "e414229203fa467f99b4a20f84584e4389b9d22ae7203556d0c0da9012ac321d", + "", + "root" + ], + [ + "e", + "0eb3cb5cc57e25bf08590da5fcd7370b30b74ed2e3fcf4e909d7c03c4d3b7dbc", + "wss://nostr-pub.wellorder.net/", + "reply" + ], + [ + "p", + "eda96cb93aecdd61ade0c1f9d2bfdf95a7e76cf1ca89820c38e6e4cea55c0c05" + ], + [ + "p", + "d9dba0e072bdb353dfb0020de159126af47e69e133ea91bbd48e8bede37320e2" + ], + [ + "p", + "eda96cb93aecdd61ade0c1f9d2bfdf95a7e76cf1ca89820c38e6e4cea55c0c05" + ] + ] + }, + { + "content": "Some relays still have your old profile.\n\nIf you were using a given relay set in the past, changed your profile there (so all of them got updated) then removed a few relays from the list and updated your profile again, the relays you removed did not receive the update. \n\nSo, if apps are using those relays, they get your old version. ", + "created_at": 1690301420, + "id": "4ef323e0e32b6025b5e7c59e78f4ed0145805fbab9b95247357a10379ede375d", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "83caf220a6da34754d147f844f1d56ae61020bb14d2bab38b0498b94037c0ee153121f4e0c99e8be353f096cf72bfcaa6a04b5bacda50df06ffb96faa63b3357", + "tags": [ + [ + "e", + "e414229203fa467f99b4a20f84584e4389b9d22ae7203556d0c0da9012ac321d", + "", + "root" + ], + [ + "e", + "e428765c0b240bb6fc8baa027db1252c0a98ca5bb822bd81f763730374a0be0c", + "wss://nostr.bitcoiner.social/", + "reply" + ], + [ + "p", + "d9dba0e072bdb353dfb0020de159126af47e69e133ea91bbd48e8bede37320e2" + ], + [ + "p", + "eda96cb93aecdd61ade0c1f9d2bfdf95a7e76cf1ca89820c38e6e4cea55c0c05" + ] + ] + }, + { + "content": "Not that I know of. No bounties as well. \n\nIt doesn't look like people have any interest in this. ", + "created_at": 1690301261, + "id": "d5cce4e3b7a6cf4d2fec27cecb12e8e7f71951fa0fceef56fdf1b834c382843c", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "a4c39738640bbd6bfd10b949f4f641b964a539977bffe5c4028bb549fba99f32737b2605936979f76745fe3b9db7f1be5b083b0b74b50b8717d3dc5b855ba04c", + "tags": [ + [ + "e", + "5778111b09d78ecec02c9b7f52feccd655b8fbb049c40c380c03eead049bf7ea", + "", + "root" + ], + [ + "e", + "e673f98336da0b6884567adcf72dd6b4d86ab16eb036c1c6d6b859110b9233a6", + "wss://nostr.mom/", + "reply" + ], + [ + "p", + "eff0899a8d3e8ed7d7524b86f5a7077c1ec39ee305c191738b29b0bbfa20fe42" + ], + [ + "p", + "7a7cfab852cd457336ec2126c2bcd8b2c77d569054fae53009d1f4631bfa1448" + ] + ] + }, + { + "content": "qZOB2WyD9zuBMmN1tNBhojLDTNJtmsUOIqg2Ld86lyLioL3UDNiTT7jr1D0UdxVuRuGrwaLG4dKDedXWx3s5Bo2CKDBJ0w6fEE43TCqP88yZMjjDwjqLN+a8O1/aKEgP?iv=rwL3fBSM4pvyyMJZpWVGcQ==", + "created_at": 1690298384, + "id": "48a4acebd543263bd867fa41754dcb443c7816a91cd200dce977dc6e6d269060", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "9341cdb84ec7338fcf579abfaa484489aeb8858b97c3c8399d0dd4ee26a7932109b4660f9cca5809b8023a714dc38a15c745a2de51792f3773df10382405ec8c", + "tags": [ + [ + "p", + "f8ff11c7a7d3478355d3b4d174e5a473797a906ea4aa61aa9b6bc0652c1ea17a" + ] + ] + }, + { + "content": "AhyW0o7KjGgdrLZcI866xQ==?iv=oVtmzuGFBaBQ616f1JzXBg==", + "created_at": 1690298365, + "id": "c2763bebb1521a0d34a331785bf6d6a4f267f2fd093e4240cf309aad439efcad", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "834c99b2bdaa2a974b44907c2c8457c7ca63c929bf1f19fad960f8abacfb3f1d9b064c918ed4e7f326c88fa80c8b5d7cd85c8e675fac299206a5b9fa75baedec", + "tags": [ + [ + "p", + "f8ff11c7a7d3478355d3b4d174e5a473797a906ea4aa61aa9b6bc0652c1ea17a" + ] + ] + }, + { + "content": "{\"f412192fdc846952c75058e911d37a7392aa7fd2e727330f4344badc92fb8a22\":1690289907,\"42224859763652914db53052103f0b744df79dfc4efef7e950fc0802fc3df3c5\":1690289924,\"25e5c82273a271cb1a840d0060391a0bf4965cafeb029d5ab55350b418953fbb\":1688330562,\"d9185164dbaf1e36a856b8f8759f8f4fb35942da22bac7afc131c910314b1f6c\":1688750583,\"645681b9d067b1a362c4bee8ddff987d2466d49905c26cb8fec5e6fb73af5c84\":1688750587,\"89d1ce9164f1f172daaa9c784153178cb1dec7912bf55f5dc07e0f1dabe40e6c\":1688750589,\"4ff652622cbe22d93e3a0ce2487e86736a9a209724a7328c59bc29b064a42926\":1688750592,\"460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c\":1688750595,\"9989500413fb756d8437912cc32be0730dbe1bfc6b5d2eef759e1456c239f905\":1688750599,\"97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322\":1688750600,\"339e87a4ad5b32a7fa88c6a56a65a53bcfbea8595a86b5d87201a39b0408c29c\":1688750603,\"975d0ba9c395954e0d06a801aa27bbd7a631d9a9a8a461df191328cd1505419c\":1688750604}", + "created_at": 1690289924, + "id": "63407a41d95e8e78c33b0d88a329331968a1b6a8f0f3c8c5d1a5b0761d2d5923", + "kind": 30078, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "98e4157674a0fb090a91ffeacc8cecfc5f17df26310252b7bce000cf4e7aade32ba3611ad3ab6a9988fe0c0e951f64a1135d9ce0a07de24187b3a8ab2e5276c3", + "tags": [ + [ + "d", + "read-mark-map" + ] + ] + }, + { + "content": "TL4qxgYec/DKRDTc1GIS0utLHiswcT/c03jZvtSimCECbf1LQBKUlmgRUwQJqgAhmrFDjYD88goSVYyR+OkZ/K2mIC3K8sbYrnvkk93KA6k=?iv=Idl20mo4wuDM+NPMfnvayw==", + "created_at": 1690289826, + "id": "8556d3f5a7bb23f79f5749aefc75b4febd17877fd525ff9b5afab65854e17908", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "49edc54a022ece3f2826f347793042745be713bd4841efa1883dfa4fb35281d429aed42d2e1606077c2cb50dab1e9efd41510e16cabde309bcf57381e7926e5a", + "tags": [ + [ + "p", + "ad5eb2f02a967459a97d041a44cac14cdffe0394ca6fae48b7b354eb1c4fae18" + ], + [ + "lamport", + "6360" + ] + ] + }, + { + "content": "UKV5cwhYK7gCH5bnwoAwkQRrqmCMCfJMBeFzZw9qsco=?iv=aiK4ONfev1EUOMrB7cJ8hg==", + "created_at": 1690289810, + "id": "6fb5ba413998496d6efc3ad69e7673d91320327f6a54b3c049695f995d532194", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "aa039c210a32e919d1ccb7dbb4434265aac723f898a1729222cc7eaeee48e49399c92e67528ffd20c1a863783c64bdb1a60e8de56d4de6429f41c0b03993cae0", + "tags": [ + [ + "p", + "ad5eb2f02a967459a97d041a44cac14cdffe0394ca6fae48b7b354eb1c4fae18" + ], + [ + "lamport", + "6359" + ] + ] + }, + { + "content": "Yep. The amount of memory rotating in the background when you scrool is quite large. We are constantly working to reduce it, but a battle ", + "created_at": 1690289456, + "id": "ff08047596ad0eb7be11cdf66789b4982728d3522838aa7c79b0f173d9196e28", + "kind": 42, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "38c554b203d4128ab15681d149307cadd250a705f43cfe2c49c4bb454c0a82900ca6371aa214ab1e8e58af5bd47438f6d688b519bcd42cb6b23acf083d6893bf", + "tags": [ + [ + "e", + "e89d7c2b4e1aa72e41979b5b1acf5dc4aceeaa97d0c40aaeebcde5cd4ff56271", + "", + "root" + ] + ] + }, + { + "content": "s5pf5nJ1HZSJtnJye6/gZT2H1Ksq0ZOddenz1xOCD76rVJlKpGiXibeIBcGmmJ+M?iv=lgE2cTIHfsdJp2RIFA9kCA==", + "created_at": 1690289261, + "id": "9f48eaddca03a88dd02257a51fffdfc6e58847691e6449b46eda116826d3ee32", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "3765866916e6b9ee662b28d81d570265f0e116d5aeab50aad4d2ed503c938a5c4261f6e5712c7dc8e63cc5bfa6f86efad3a0572c285104299fd9945e82555b93", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "uDIFFjFeuxLWlBZ2QBqcxf6GnfFxadrtdwciH7laVOx85iQ9XAOrDbJaOWIllu95KxXuI7SK8bttv66qQjCQ+Q==?iv=47N/FrAOij7INTY45GngLw==", + "created_at": 1690288560, + "id": "29e0784695da2615a4a83a5e55036c9e749cd4cf98324d6b4e49aa20ac3927db", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "5ce3335af0da098ae483bfb758ff4c4ac355bf82721cce3587edb9912440044be28651b1a2f72fdcf05561c221c4e1c9f70bce5e4098e6095ca5cffa5a6d0e4f", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "NwfzYhOIbMzbc6dDEbnWWhgPEz89V2smVNkOMdc20k5QKjQWvE83O1UGviFWquSsgGv3GQrqCCi4EW9IQbhXvg==?iv=1xfL0/+De1Tl0PVON5sTMw==", + "created_at": 1690288549, + "id": "294991508f9fe42234c3937d85db77478389a28a2e1c8817c7be7189dd452fdc", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "0894f96fb95f158e727189cb3d4e0bdf59b4b4ac065e8972e7b44e94b0816a8330fd8175ee2a52260231fecc81b5429c4a3418f926bc5c548c10e110468d67f2", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "Uisi4OKioPOCqI/A0gDNKynLNV+ej0aNCY70P/vjgu21hbMRD1DCw/N7sRO7PeeE?iv=QNIoWu01HPHSdRUdeQYf+w==", + "created_at": 1690288547, + "id": "0600aa6b0e40e5057d6ff85b4d0eefd86bf661a109a0ea5e30a616f8a7509eb9", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "e1726e0ca65b41dbd13d6c46248d6beb9f7d28eb8a03a50c6f7ff55cee77c85fc7209a2306fda5b849c5f3127420c862d5849b0c5695d48acbb21c5ac651f8ed", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "🚀", + "created_at": 1690288395, + "id": "ac2fb0c9b72a6fefe60262fbce6eb8740380b7f964200cb8efdd2e72fcb1ddb0", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "6df6aeef98c21a0508a788cbe6a2a6825e5cc69e57dd843dc6e6d4ce2c28dd042947723fda3d8b24489305d86b1e81f9f66b390d6f7dabf9742cd3775e17e53f", + "tags": [ + [ + "e", + "2cc5b6e012c5a64fcf580fc1b53bed25ed0d7f785fd896744524b1a114dcc86e" + ], + [ + "p", + "c80b5248fbe8f392bc3ba45091fb4e6e2b5872387601bf90f53992366b30d720" + ] + ] + }, + { + "content": "tRYUKww0df3YH/uVQVDVuZMuxAwVlPxkCInhfjLdaJcaLOaP4nanBVJSiN/Mwd4TqDRIiENmB0VFvfICFVuSC9JWVRA5RXKwhNUvJA8lFhqyYZKJ7hu7vIv/pBsYmoodZkmIOm1k62krq6xcnMab9l5AeqgAGyWmPOM0nZM+B5LFp9s5iqc5uly52wpT4HFrbNEO7Tnp7yg5Zzrrl6wwUcmvgMf9ZdJHUusgy0y449WOglVIZI7CouMgjH4tfxbTr7jpZEb+Bl8PPMBRylEV0qniBEd46TAYTHZW7QOJRnSP18vMfESf+kjM9KbiQJhyOY8FKIMJ2/ofUjCiOlWhlME29JykleKz70KmsrJNA0bQH3MfzQ0M9qBdvSdpD0pPIRc9hFmAmPuSOQpb1k/+lF+lcNQc2SPdj3NOS0L6BialMn8fwWtpuBHFtdRJIj5WrHpgnmXxeZ2ES40KZUwA6izlW+YOYI8RtlkqxsrmOWg=?iv=diRnj/9ih+6dFgT9qGMIdg==", + "created_at": 1690287796, + "id": "856d60b6545084c4d8a450d8f079dddcb3bcff54aed5df0d84eb63aec1f9ce6e", + "kind": 30078, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "e7e2a040ec7c4fa8a931005b3fb2880c927107de970165d4869a403a2b3fcadd858ca4ddbfe6305d15b208fbafa15f0341217af5cb6f965aa4194c9b8a2c06a3", + "tags": [ + [ + "d", + "coracle/last_checked/v1" + ], + [ + "client", + "coracle" + ] + ] + }, + { + "content": "I am not raising money because I can't make the numbers work for investors. But we do take donations to build the team. :) ", + "created_at": 1690287547, + "id": "8a359c03413c06340f034cde37528c4a0bf49cc2b42e571ee806c86abe93ff1b", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "a08449b21dc283a0effc8a0ee4ad3254ed1905e0e5f53963b101a927d05cd8b7b5718d04ec9909e34986d743e5db272b0541b6b86b1749696f22883b2afad7ef", + "tags": [ + [ + "e", + "5778111b09d78ecec02c9b7f52feccd655b8fbb049c40c380c03eead049bf7ea", + "", + "root" + ], + [ + "e", + "4705531ded4c3dff81ff3435c28f2112cc789593fc6afe6d9ad2335b2619245b", + "wss://nostr.bitcoiner.social/", + "reply" + ], + [ + "p", + "7a7cfab852cd457336ec2126c2bcd8b2c77d569054fae53009d1f4631bfa1448" + ], + [ + "p", + "7a7cfab852cd457336ec2126c2bcd8b2c77d569054fae53009d1f4631bfa1448" + ] + ] + }, + { + "content": "ohhh good catch. ", + "created_at": 1690287166, + "id": "ffd37a3e6504bb5171ba0c201019628dea6d282b12c71e3a7e35e20ae4de538c", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "8cbf2035954db635d65b039d549c36f2111a6e8c5c831db5e5a3eed0260009462660e8d0d3923b48141f1b35366854890a3fbda91e1360d242175cecf0a96a7c", + "tags": [ + [ + "e", + "56887d01eebd3727ffc37ca54eb67b6e8427db4b03e7c003683931f5cbde82c2", + "", + "root" + ], + [ + "e", + "8154235a2796bdab6c7c0cc0777a8cc6fb6bdcb19607a5d1f901d02494648743", + "wss://nostr.bitcoiner.social/", + "reply" + ], + [ + "p", + "6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93" + ], + [ + "p", + "6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93" + ], + [ + "p", + "de14fe62f97e09429581f9e8fec3170f3ce5e7936a2134bf70c87c5ff229e53a" + ] + ] + }, + { + "content": "We don't have server. The main issue is that now the app uses up to 1GB to keep all the content the app needs. Most old phones will definitely struggle with that level of memory use. ", + "created_at": 1690286996, + "id": "5b3a569ab61dc0d88da2a93564de9da3e6f42c8479bb93a522370501ecd08140", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "515101902a9168031260d2cc889bef1a1e6b4e499397e7cfba08799b7503b81cbf3e4a9147a0cbd4cc9fcc252a66330c428e9a6ae4dd6751c551cf9dc1cd6c5e", + "tags": [ + [ + "e", + "5778111b09d78ecec02c9b7f52feccd655b8fbb049c40c380c03eead049bf7ea", + "", + "reply" + ], + [ + "p", + "7a7cfab852cd457336ec2126c2bcd8b2c77d569054fae53009d1f4631bfa1448" + ] + ] + }, + { + "content": "+", + "created_at": 1690286957, + "id": "0c97361806dd60f9b6f5a0ffaa25da846d5e4d4717287551530b665db9d39302", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "3770d5924fb47cbad974ea6be874dab133a90176e3a62502aff7c8a1ad32ed39a29387c88a1270f78a2d25e01cb926f6fde2b0f3a63fc2356b26e5295b03c3ce", + "tags": [ + [ + "e", + "4705531ded4c3dff81ff3435c28f2112cc789593fc6afe6d9ad2335b2619245b" + ], + [ + "p", + "7a7cfab852cd457336ec2126c2bcd8b2c77d569054fae53009d1f4631bfa1448" + ] + ] + }, + { + "content": "I am not sure why you would say so. Any event can be part of a community, including long-form content. ", + "created_at": 1690286892, + "id": "f65330aab9339f7c814b763a571c02a2c00de96e321e803a09e08140ec941138", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "5f391228b9a47d83978a304f0505a16b594ffe48fcb872e8bd69489557306b38cf926603f955e0ed742baabf59dcafd2934919cea4c600e285eebf239d42dfc0", + "tags": [ + [ + "e", + "9dd8ff6c397f19373006037c894b02f35da2b69ac12f62ec008889c9571dbd08", + "", + "reply" + ], + [ + "p", + "c80b5248fbe8f392bc3ba45091fb4e6e2b5872387601bf90f53992366b30d720" + ] + ] + }, + { + "content": "Well, Primal and others don't load everything we do. They just offer the main feed. That's the main difference. Amethyst can use up to 1GB of memory in heavy use. Many light compose apps will work just fine. They are definitely heavier than other UI frameworks for 2+year old phones but the issue happens when we try to add the all components we have on the screen. ", + "created_at": 1690286508, + "id": "07bdab60f70082150f6b50c8f9166244f7fefa4087b95409328c595cd17dce53", + "kind": 42, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "993391d5757ae264346c8db656d4fcfdec396a63c780d012e767a608087a673ceb262b64a9c0bd12ff18140a1d80b79645759e019c13a969e681092e6c0537c2", + "tags": [ + [ + "e", + "e89d7c2b4e1aa72e41979b5b1acf5dc4aceeaa97d0c40aaeebcde5cd4ff56271", + "", + "root" + ] + ] + }, + { + "content": "Probably because your are following a hashtag or a community. Those show up in your feed as well. If so, there is an identifier of the community or hashtag in the first row, together with your name ", + "created_at": 1690285153, + "id": "aae6aa51e943bdd8f9f09b2babbbf02397ca2c7e9c99dfa0042876ded4073ef1", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "3b79f668ec10f8fd8d2c7ae7a0a075c57e764440a4d0cb92b8a823941418180af07577f6fd46b9b8459c6cb64151176abea129261af861468fd44ecebc566847", + "tags": [ + [ + "e", + "7e374164ec625c01d4efce693a8d7a13225fd87bbf4a439390fd995ba077b038", + "", + "reply" + ], + [ + "p", + "2ebcd815589195d4fe00e1996323d41c3a455641d3065d7b82e68e574f0c0f48" + ] + ] + }, + { + "content": "🚀", + "created_at": 1690285082, + "id": "6b4c1249dcbebb07e1642ff72384a709ddaace107d98b34ee87028cf2ee151bb", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "71409c88d13a42740a17249bf2a5300c875b7a8fad471fc6097b5de1b9234db339c1f160d4156a661abb871a7e9f97015048735ef44b1af3c95517eaa8b143fc", + "tags": [ + [ + "e", + "69ddeaa2cbbf8954e8bfca9c58354512461de79691e0e57870b40cf13139aefa" + ], + [ + "p", + "e6ce6154325b54e69c9478c46cf1284e093f790e658b6a70f9df6eed275e3444" + ] + ] + }, + { + "content": "🤙", + "created_at": 1690283168, + "id": "1edacc7f9f091e63b8cd59498b98cc28c997b4381a343efbe67b5f0010f594a4", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "0c20f045b2cf70e5479ae1fea72bd4f766eb3cf5bc62a544466d907c14f212fcac3af581d4440f4c2d99dcb98eadad206e05dfcecc984aa940a133226d2401ff", + "tags": [ + [ + "e", + "6c766ae83204902ae112190f418eafd35fc977f8b64367a13d7a526fc86bbd73" + ], + [ + "p", + "f5f98ba54045a2fa8df2a97c35fc30299b9e0d51a701795c040ca80cedaf39b4" + ] + ] + }, + { + "content": "I am also doing a local database for the app. That will allow us to delete most of the unused local cache. ", + "created_at": 1690283062, + "id": "3a7b49772ed9223c3d5ec1d0aafe05739aca6b4b0a87da760f78d820a678cfef", + "kind": 42, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "bc768ccf0a6525851f30cd453bf78d1d26658422f56d08ea216132d15b11b773ff30f7612a126f14e16cf03b29b8d34b487a6d59f51802a58ff834af27617a4e", + "tags": [ + [ + "e", + "e89d7c2b4e1aa72e41979b5b1acf5dc4aceeaa97d0c40aaeebcde5cd4ff56271", + "", + "root" + ] + ] + }, + { + "content": "It could be the live data as well. Live data runs on the main thread.vwe could switch to Flow objects, which are heavier, but don't switch to main and back all the time. ", + "created_at": 1690283001, + "id": "cfb933727089ceb7735f9c7794217338f354cdd67421ee4582bbd108b8b875a2", + "kind": 42, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "9c5e74d3ddcdab7244866c27a71c54d78f82a95ddb74764a42a08a18c88299d9eae6c02627a68e8bd66ea867c3425aa4b6d2e272eef28e41883aa6b805b8372f", + "tags": [ + [ + "e", + "e89d7c2b4e1aa72e41979b5b1acf5dc4aceeaa97d0c40aaeebcde5cd4ff56271", + "", + "root" + ] + ] + }, + { + "content": "", + "created_at": 1690252421, + "id": "e17e96546af73ea49281aec14d8833cdc9a6c8758eb499eca64890d5e16dff1f", + "kind": 1063, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "01e3edbdabf4d7612977af8de5afe3f8ee53c0fd63bc211f2b7cae0c9e04af11ef21449a260bb3945e16f6999c1975d87b6f8cd52e74284083a90716ee3814fd", + "tags": [ + [ + "url", + "http://nostrcheck.me/media/vitorpamplona/nostrcheck.me_902a3245d00d506efc193b25f25f32ee994c365bbd73a515.mp4" + ], + [ + "m", + "video/mp4" + ], + [ + "x", + "c8d8226166e4c54ed87aa1151229301230a0b9936ada748ce2b02a3a2fc28cbc" + ], + [ + "size", + "844802" + ] + ] + }, + { + "content": "Are you using the latest (10.7)? It's about memory. The app is using up to 1Gb of ram these days. ", + "created_at": 1690251933, + "id": "85094e157439a0ede8ba0354b9be60aabb4d952bc3baa5838c1049f1e1f62b7d", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "8c43251aeb9eba5bc6a265a8060eb24ac4e699661eec156e33c1cd48678c13442d15ed3f29fdf6d3395317892d11a854853e9529dc0eb4113fd1a23723dbde88", + "tags": [ + [ + "e", + "5778111b09d78ecec02c9b7f52feccd655b8fbb049c40c380c03eead049bf7ea", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "7a7cfab852cd457336ec2126c2bcd8b2c77d569054fae53009d1f4631bfa1448" + ] + ] + }, + { + "content": "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?iv=wDDS+Cbpqw1TX2BT52Qf9Q==", + "created_at": 1690251675, + "id": "fe6e8976ed1f8ae9906457bf5a0f7ce6c2382844872628aed2b1b66eeff79558", + "kind": 30000, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "238d972238ce203e5d6d6e4b6f9d7aa3f815027b0e9adae80ae64ea7d59e6b2df08f4707962303cb9a4eeb19030a468961dec44590892c2af4c7cc5a4b14007a", + "tags": [ + [ + "d", + "mute" + ] + ] + }, + { + "content": "", + "created_at": 1690251675, + "id": "8dc884509db4f009054d39c4fc6873245f6bbdfad7322f4dcce8f9668d1b4be1", + "kind": 1984, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "f08f2ad807861b07ae6ca36048250889fa4bd88c5b0d767d6b62ccaabb48e602c5fb86a5cb58e759843abcf23755c99e3fe1709a1c1f86427e540ba684ae835f", + "tags": [ + [ + "p", + "2065474608976bb14e103389871a8a9d2c91ea1a71a49247228d8ed104afb068", + "nudity" + ] + ] + }, + { + "content": "Tell them to wear a contact lens.", + "created_at": 1690248352, + "id": "df011422245d4c13a97f589c45296cdc8e033f778f3ec62a79f1e601a6361796", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "73f25c2c5344fa80aa61af19e32c8675d44c7e9822fdc00b6998c6151aadb23e8ccb9e0c01d2178ebcc98d1c1061e7f520d6246a2c4906e524052d9a6f6f22be", + "tags": [ + [ + "e", + "2a6f72d18ce554ad81a90a552dc2d5e5e1799b3801139a299c567c20bbcaa615", + "", + "reply" + ], + [ + "p", + "e2ccf7cf20403f3f2a4a55b328f0de3be38558a7d5f33632fdaaefc726c1c8eb" + ] + ] + }, + { + "content": "", + "created_at": 1690246668, + "id": "2f7d62cd826a517f6153da75112d62bb4591bd7a9980632f11692653ee176fdd", + "kind": 1984, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "deccb7dd37b7d77db7712d8dfae4742274644bc443064c8c9237ad4d2663f8dda75d670faba06785bce2e4eab532aef3f3a2bae6d4e6d4b3fadf39addfecef50", + "tags": [ + [ + "e", + "db6e3abe953de42ee3e4499c298973d0c957f346e6a56ba9681d881a5a1c10b1", + "nudity" + ], + [ + "p", + "7b2dd801b71077284f0f64333a4a9e7c6a32699b68fec8776f86f90ab497109e", + "nudity" + ] + ] + }, + { + "content": "⚠️", + "created_at": 1690246668, + "id": "10ad1d3b9fae2dbb52b04eeef0ec80f3347f4675c5c2084f752f4eaaaabfe152", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "90be5cc5f4906d57ab629fcd285aa74b6e8bb5d10114e6c6b2f7daecb0b9b7335ac86f9390aa721a0cf3f5d997590a88d7f5c1b193a8e9956e526e80305164db", + "tags": [ + [ + "e", + "db6e3abe953de42ee3e4499c298973d0c957f346e6a56ba9681d881a5a1c10b1" + ], + [ + "p", + "7b2dd801b71077284f0f64333a4a9e7c6a32699b68fec8776f86f90ab497109e" + ] + ] + }, + { + "content": "🚀", + "created_at": 1690244222, + "id": "111997ddef6b12be593cb96068e0d016be081d4a718c5cc2c618d9519f1fce57", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "23e2c107252140431c0c845c38f3cabed50113ab04149d100ff53b8f30f5fa8d991d3f0c59573114577c39d38bb0634dfaf89a5c802fa5304a28131a31de56e4", + "tags": [ + [ + "e", + "3621f31be0bd7c5980c3497fde8f6d1d170641084632a62178439871249ccca8" + ], + [ + "p", + "a85f28306f6739230c0b96483f33fc894058c1f7e2248647c61c7d475d3db7c7" + ] + ] + }, + { + "content": "I wonder if there is a crazy person out there to reuse our jetpack compose ui elements and build a desktop app with it. ", + "created_at": 1690244215, + "id": "bb42bc6543d54910a38cf2a213da81d4d13278d130208dd05e56b16e6a01fc3b", + "kind": 42, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "814a28dd2fed0807907b63426fe61517f9a18c10dfdad23481919455282e076436c2364b3d1802608e3da96772dba9636c77822b3acdffd3b12b37d8de21e573", + "tags": [ + [ + "e", + "e89d7c2b4e1aa72e41979b5b1acf5dc4aceeaa97d0c40aaeebcde5cd4ff56271", + "", + "root" + ] + ] + }, + { + "content": "Devs and designers welcome. ", + "created_at": 1690242675, + "id": "5885b2edaef4155e17df4e0dc7af9db4121165f0708652955c5d11957c871601", + "kind": 42, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "888aa55504da091f0d786e330df76b2c29d8349e034dd529aa583fbca266b46d6f163638b1c67384f3568f9406266a37d3b4eb8435e2ba09784914db0ede74b3", + "tags": [ + [ + "e", + "e89d7c2b4e1aa72e41979b5b1acf5dc4aceeaa97d0c40aaeebcde5cd4ff56271", + "", + "root" + ] + ] + }, + { + "content": "FbLT7gYTHET9t9YxQOCC5rVKnX4AgpL0uZscQbjdqdmyK/HpPN3ZFtq2AAUqatmOV7dg2oOIafZ2sTYFSqpnXw==?iv=hvlO/iOLcRyNPebLu91jLw==", + "created_at": 1690242653, + "id": "c2b2c99123f9509df30ad497d5c7497e3dabed7a1f478c015843e4bd8de8772c", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "add8ac7f7ad0ab40dcdd158c2fd33f66f2f0ef113a296ae372a98e997950af6c4027e666243abaab264c86e9a1291999edd152f9bb603131302721d8ba29acb5", + "tags": [ + [ + "p", + "7579076d9aff0a4cfdefa7e2045f2486c7e5d8bc63bfc6b45397233e1bbfcb19" + ] + ] + }, + { + "content": "ZYM8lrGBHNK4kHXEOVZzN74I1UfT64sIkxDRJWopfnVSr3oxREm2+QAH5JSCzL5kwwLWUMZFueIj9s8178zs2c4onTx7JDc6ByCZGhjbY/gvAo2yK23fChDGdHoQPzqX8p53KTM3a38XHA/sNEO7YvKsoYd94R1Q0UZgQiF7ivVb5QLDFgyTSQVfKiH/ca6I?iv=d2t4j8CP9B8pJ3/cfoT6MQ==", + "created_at": 1690242638, + "id": "3c8f1e613e96ab9dd7b35573dd938cf21877df1dded96de49e74456c39470002", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "b6acf30bd79d64fe6056ea864f9e1132daf296626147df9afcd161a9406fd264c3f0106004894dc0f6310da30d76ae7a4804726b1d1d655ba193e008cbdabd06", + "tags": [ + [ + "p", + "7579076d9aff0a4cfdefa7e2045f2486c7e5d8bc63bfc6b45397233e1bbfcb19" + ] + ] + }, + { + "content": "+vCJukCAGqBNb4lXkeHcUbWo7Co8S3U/1hr8gbWdgx8=?iv=pYsP8v0FjaupHym497BEBw==", + "created_at": 1690242635, + "id": "6bd12d078b1579fb62f3a8bed7bbda20af983dbde9ee36844e11cff195c101b3", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "dd5c8aa6588d26c536d1dbccaf84e1208b18d411b2080c971a5af836e517a97ed20f44638dfe8d6ddc7760c33e95a37ae64da9dace0dac229ef79808564dc9ed", + "tags": [ + [ + "p", + "7579076d9aff0a4cfdefa7e2045f2486c7e5d8bc63bfc6b45397233e1bbfcb19" + ] + ] + }, + { + "content": "BRZoGneJdOYKd0brs+QhEg==?iv=SbDOAorgoLdzFI1CnvDJfQ==", + "created_at": 1690242630, + "id": "682b4eee106d4dce8e6dac8c736abc9f16762b47934c30b12447299b2cee5387", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "1408fa4fc6271e0ed4b90de165db36850ca4d09f9ced27e35179e3360d8180731df2180e07b429f76e1ac977cf4ff981a5220e3fd5fc6bd77c72c20dbb039667", + "tags": [ + [ + "p", + "7579076d9aff0a4cfdefa7e2045f2486c7e5d8bc63bfc6b45397233e1bbfcb19" + ] + ] + }, + { + "content": "IEyJCe4nxKc3oD9jgM1oORxiGagpXRf+veHnumcq9jN/7Pv+xruUY9rxYmyMbRw3Vm6tgusfzyIeaegKjfzzb0GKOjwkJ0ATdJcbJG8hGWV+2pMbxvRAKVRjy+bI8dvlOVGrhqlF5N97o4jcaTkPbDsBrGXePHXsIJau6O0omYa4sMSH6IIEeO3LHU8Qhgsi?iv=uwKdPGDkXcjSbo54u4xX+Q==", + "created_at": 1690242609, + "id": "7ecc386b5026262c448a0266cbc9fdb0c86bf5894681e48bee04fdf410210bc0", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "87fe2a64db4728b2b7129590bfbb573303a6d825323438fd60d6a6f433a0722045ea04ef3cc8b0bfe36e4650a65875eb1e3d535bfda7b3905471d1a8ecce80e1", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "Zzyg37FBq7HsOb9i4CqR0Q==?iv=I+N33Ubcnk2BOzO2wZiYww==", + "created_at": 1690242607, + "id": "dcf996c003eaae0bb47986c539d997bcfa04d4a7b6cea4dd2dbacdfa30fdce92", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "c5846d1006c431459e88cb3e50b49697756155c0c54d4a7565005bc7f89acb93d43658322cd5cbc107781df72c768f472c3f47c9cedda26aaa8046cb644e85c4", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "4fH6cWjO2fRxNwnpk/WEfGQV2d4BrdX7ePzU+u0eJYEQ3oQfSND3qqn3L2gM1o9q?iv=Kf5/gUOJ2HKcG3EQbPSjfA==", + "created_at": 1690242606, + "id": "857e84d663936020a3c3dfbf418e7af5ce93fc64f370368694e5e1966e6de565", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "39d1bc609f8b11bfc0aae3f9e65f43de46bab94370a44e23439b12e56b647c79169b789a802bc552e7b70b2790a1194073ba1993e2a7e6494867cfaa720234bf", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "{\"about\":\"Channel for coders and designers to discuss Amethyst development. \",\"name\":\"Amethyst Devs\",\"picture\":\"https://nostr.build/i/7548146ede4c08de8be3e19ee3b2d1e7af90fbef12d2c247f54e8aa23cafe763.jpg\"}", + "created_at": 1690242586, + "id": "89b9c20216de8fa443e1e10d808befd8cd0569f53158796b45202c82e1659b02", + "kind": 41, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "341bb56ae426689fefc6b769d5bc2bd3597b7f84725327e59c775a79c0a5d774e42ebdb9af6562e829f280f5586cb545be4786606c7c9291edf65395ff3c290b", + "tags": [ + [ + "e", + "e89d7c2b4e1aa72e41979b5b1acf5dc4aceeaa97d0c40aaeebcde5cd4ff56271", + "", + "root" + ] + ] + }, + { + "content": "{\"about\":\"Channel for coders and designers to discuss Amethyst development. \",\"name\":\"Amethyst Devs\",\"picture\":\"https://nostr.build/i/7548146ede4c08de8be3e19ee3b2d1e7af90fbef12d2c247f54e8aa23cafe763\"}", + "created_at": 1690242548, + "id": "e89d7c2b4e1aa72e41979b5b1acf5dc4aceeaa97d0c40aaeebcde5cd4ff56271", + "kind": 40, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "edcea8f6515a80792fd9e28842a6ea8c4d0de17788f56c3045198242a6938f3a9d3fed5e24e5e58d516e94fe1041478a6b4074d7c10a887d3db84a6db7000011", + "tags": [] + }, + { + "content": "{\"wss://nostr.oxtr.dev/\":{\"read\":true,\"write\":true},\"wss://filter.nostr.wine/\":{\"read\":true,\"write\":true},\"wss://nos.lol/\":{\"read\":true,\"write\":true},\"wss://relay.damus.io/\":{\"read\":true,\"write\":true},\"wss://nostr.bitcoiner.social/\":{\"read\":true,\"write\":true},\"wss://nostr-pub.wellorder.net/\":{\"read\":true,\"write\":true},\"wss://no.str.cr/\":{\"read\":true,\"write\":true},\"wss://nostr.mom/\":{\"read\":true,\"write\":true},\"wss://relay.nostr.band/\":{\"read\":true,\"write\":false},\"wss://relay.nostr.bg/\":{\"read\":true,\"write\":true},\"wss://relay.nostriches.org/\":{\"read\":true,\"write\":true},\"wss://relay.orangepill.dev/\":{\"read\":true,\"write\":true},\"wss://relay.snort.social/\":{\"read\":true,\"write\":true},\"wss://relay.mostr.pub\":{\"read\":true,\"write\":true},\"wss://relay.nostrati.com/\":{\"read\":true,\"write\":true},\"wss://nostr.inosta.cc/\":{\"read\":true,\"write\":true},\"wss://atlas.nostr.land/\":{\"read\":true,\"write\":true}}", + "created_at": 1690242548, + "id": "4efe027b19cc54a8f4c1ab8cc9f89ae3d88b3d93cfde079d6c8d9804fd6d1ec2", + "kind": 3, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "94eb3d76bf5be95ddb2f88fb9b5130316c8da617a5be637de39d46a81276df5068fc313935b6dfb138a75e28a3c3787faabd9509d503d94770b14aca46ca67a0", + "tags": [ + [ + "p", + "d0a1ffb8761b974cec4a3be8cbcb2e96a7090dcf465ffeac839aa4ca20c9a59e" + ], + [ + "p", + "b7c1a5ef7ccf5cfd5976fba251116ed3f3ae3d3ed175a9ce5e3d33a890b4684b" + ], + [ + "p", + "79c2cae114ea28a981e7559b4fe7854a473521a8d22a66bbab9fa248eb820ff6" + ], + [ + "p", + "80482e60178c2ce996da6d67577f56a2b2c47ccb1c84c81f2b7960637cb71b78" + ], + [ + "p", + "bfc6af8244dc2859efdfd0e81a6a79f4ee395bc78acb3202b6f287a1ca3a27b3" + ], + [ + "p", + "b9b0bb9edc3ecf01389c570ea6f44c55a80b9db066d0bca8a22237af185252e6" + ], + [ + "p", + "5b29255d5eaaaeb577552bf0d11030376f477d19a009c5f5a80ddc73d49359f6" + ], + [ + "p", + "4d62dd5e6ac55ae2405940f59f6f030a994ec2b3ecc5556c8dc542cce20e46dd" + ], + [ + "p", + "e75692ec71174e698df1f3d1f5771855bcc4e6e568489d2eaad489d81064ace6" + ], + [ + "p", + "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245" + ], + [ + "p", + "82341f882b6eabcd2ba7f1ef90aad961cf074af15b9ef44a09f9d2a8fbfbe6a2" + ], + [ + "p", + "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d" + ], + [ + "p", + "8c0da4862130283ff9e67d889df264177a508974e2feb96de139804ea66d6168" + ], + [ + "p", + "04c915daefee38317fa734444acee390a8269fe5810b2241e5e6dd343dfbecc9" + ], + [ + "p", + "35d26e4690cbe1a898af61cc3515661eb5fa763b57bd0b42e45099c8b32fd50f" + ], + [ + "p", + "46fcbe3065eaf1ae7811465924e48923363ff3f526bd6f73d7c184b16bd8ce4d" + ], + [ + "p", + "52b4a076bcbbbdc3a1aefa3735816cf74993b1b8db202b01c883c58be7fad8bd" + ], + [ + "p", + "3235036bd0957dfb27ccda02d452d7c763be40c91a1ac082ba6983b25238388c" + ], + [ + "p", + "d987084c48390a290f5d2a34603ae64f55137d9b4affced8c0eae030eb222a25" + ], + [ + "p", + "472f440f29ef996e92a186b8d320ff180c855903882e59d50de1b8bd5669301e" + ], + [ + "p", + "e9c0a9c12e3a04edd79afc77d89b6c6413cc942ef9e61c51e51283cbe9db0c8f" + ], + [ + "p", + "b17c59874dc05d7f6ec975bce04770c8b7fa9d37f3ad0096fdb76c9385d68928" + ], + [ + "p", + "e88a691e98d9987c964521dff60025f60700378a4879180dcbbb4a5027850411" + ], + [ + "p", + "ad46db12ee250a108756ab4f0f3007b04d7e699f45eac3ab696077296219d207" + ], + [ + "p", + "1b11ed41e815234599a52050a6a40c79bdd3bfa3d65e5d4a2c8d626698835d6d" + ], + [ + "p", + "85080d3bad70ccdcd7f74c29a44f55bb85cbcd3dd0cbb957da1d215bdb931204" + ], + [ + "p", + "f728d9e6e7048358e70930f5ca64b097770d989ccd86854fe618eda9c8a38106" + ], + [ + "p", + "83e818dfbeccea56b0f551576b3fd39a7a50e1d8159343500368fa085ccd964b" + ], + [ + "p", + "50d94fc2d8580c682b071a542f8b1e31a200b0508bab95a33bef0855df281d63" + ], + [ + "p", + "c2622c916d9b90e10a81b2ba67b19bdfc5d6be26c25756d1f990d3785ce1361b" + ], + [ + "p", + "eab0e756d32b80bcd464f3d844b8040303075a13eabc3599a762c9ac7ab91f4f" + ], + [ + "p", + "00000000827ffaa94bfea288c3dfce4422c794fbb96625b6b31e9049f729d700" + ], + [ + "p", + "ee6ea13ab9fe5c4a68eaf9b1a34fe014a66b40117c50ee2a614f4cda959b6e74" + ], + [ + "p", + "19fefd7f39c96d2ff76f87f7627ae79145bc971d8ab23205005939a5a913bc2f" + ], + [ + "p", + "090254801a7e8e5085b02e711622f0dfa1a85503493af246aa42af08f5e4d2df" + ], + [ + "p", + "58c741aa630c2da35a56a77c1d05381908bd10504fdd2d8b43f725efa6d23196" + ], + [ + "p", + "e41e883f1ef62485a074c1a1fa1d0a092a5d678ad49bedc2f955ab5e305ba94e" + ], + [ + "p", + "84dee6e676e5bb67b4ad4e042cf70cbd8681155db535942fcc6a0533858a7240" + ], + [ + "p", + "645681b9d067b1a362c4bee8ddff987d2466d49905c26cb8fec5e6fb73af5c84" + ], + [ + "p", + "e9e4276490374a0daf7759fd5f475deff6ffb9b0fc5fa98c902b5f4b2fe3bba2" + ], + [ + "p", + "d12feb34b3ee120423b818cd8dda47000639bbec9a6ee6d3317ea886ec5b084f" + ], + [ + "p", + "bf2376e17ba4ec269d10fcc996a4746b451152be9031fa48e74553dde5526bce" + ], + [ + "p", + "1577e4599dd10c863498fe3c20bd82aafaf829a595ce83c5cf8ac3463531b09b" + ], + [ + "p", + "703e26b4f8bc0fa57f99d815dbb75b086012acc24fc557befa310f5aa08d1898" + ], + [ + "p", + "6e1534f56fc9e937e06237c8ba4b5662bcacc4e1a3cfab9c16d89390bec4fca3" + ], + [ + "p", + "4523be58d395b1b196a9b8c82b038b6895cb02b683d0c253a955068dba1facd0" + ], + [ + "p", + "148d1366a5e4672b1321adf00321778f86a2371a4bdbe99133f28df0b3d32fa1" + ], + [ + "p", + "b8e6bf46e109314616fe24e6c7e265791a5f2f4ec95ae8aa15d7107ad250dc63" + ], + [ + "p", + "c73e75dba8adce307479d65575019ef5bee4dc8042dceeded3350ff89e9909f2" + ], + [ + "p", + "ea2e3c814d08a378f8a5b8faecb2884d05855975c5ca4b5c25e2d6f936286f14" + ], + [ + "p", + "63fe6318dc58583cfe16810f86dd09e18bfd76aabc24a0081ce2856f330504ed" + ], + [ + "p", + "3f770d65d3a764a9c5cb503ae123e62ec7598ad035d836e2a810f3877a745b24" + ], + [ + "p", + "7bdef7be22dd8e59f4600e044aa53a1cf975a9dc7d27df5833bc77db784a5805" + ], + [ + "p", + "2b1964b885de3fcbb33777874d06b05c254fecd561511622ce86e3d1851949fa" + ], + [ + "p", + "e2ccf7cf20403f3f2a4a55b328f0de3be38558a7d5f33632fdaaefc726c1c8eb" + ], + [ + "p", + "9b0247ea14361a453ea9d77f9fdabc858fac10063424ce0bb3aa560237ededcb" + ], + [ + "p", + "7d95baf9ac8486d06798348e580a944e2110740e88586af731dffebfc1301e68" + ], + [ + "p", + "c7dccba4fe4426a7b1ea239a5637ba40fab9862c8c86b3330fe65e9f667435f6" + ], + [ + "p", + "aef0d6b212827f3ba1de6189613e6d4824f181f567b1205273c16895fdaf0b23" + ], + [ + "p", + "1a1a7ff211f3762d6a5a849e3d29d288fd43b618423c9d030ae7d64b951ea183" + ], + [ + "p", + "546879d1ef626692ca8a54f9943e9629197b97c58ea1b4a3abd6ff968b280d09" + ], + [ + "p", + "2779f3d9f42c7dee17f0e6bcdcf89a8f9d592d19e3b1bbd27ef1cffd1a7f98d1" + ], + [ + "p", + "fdd5e8f6ae0db817be0b71da20498c1806968d8a6459559c249f322fa73464a7" + ], + [ + "p", + "08b80da85ba68ac031885ea555ab42bb42231fde9b690bbd0f48c128dfbf8009" + ], + [ + "p", + "34d2f5274f1958fcd2cb2463dabeaddf8a21f84ace4241da888023bf05cc8095" + ], + [ + "p", + "597b42de56a9e0c19ee2d0cde5797dd58d48ce8dd25c732b4c873af11161f9fd" + ], + [ + "p", + "74dcec31fd3b8cfd960bc5a35ecbeeb8b9cee8eb81f6e8da4c8067553709248d" + ], + [ + "p", + "0000006a13e10fb648049b5e78632a0c2bf09eaf6a9d55d081b82baf86c951be" + ], + [ + "p", + "9c612f8b770f0e3fd35cdac2bc57fcee8561e560504ea25c8b9eff8e03512b3e" + ], + [ + "p", + "4657dfe8965be8980a93072bcfb5e59a65124406db0f819215ee78ba47934b3e" + ], + [ + "p", + "1bc70a0148b3f316da33fe3c89f23e3e71ac4ff998027ec712b905cd24f6a411" + ], + [ + "p", + "7579076d9aff0a4cfdefa7e2045f2486c7e5d8bc63bfc6b45397233e1bbfcb19" + ], + [ + "p", + "d0debf9fb12def81f43d7c69429bb784812ac1e4d2d53a202db6aac7ea4b466c" + ], + [ + "p", + "6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93" + ], + [ + "p", + "246716c303cb0df99b45eba30ff058e506bedd4193957df34ba61fb1929dc73a" + ], + [ + "p", + "c5d4815c26e18e2c178133004a6ddba9a96a5f7af795a3ab606d11aa1055146a" + ], + [ + "p", + "df4cafee85f79769545851db202a8856f82dc917548093c760f3094896e987b2" + ], + [ + "p", + "7e2cb3b6793ffb7b38cecb1664c47f6216b4abec00c18a8d1eb9f6dbc0da1e02" + ], + [ + "p", + "dbf3d7c79a92995ccfb135997ac1612f41637c8a805be393204b3d1c2769d127" + ], + [ + "p", + "dd81a8bacbab0b5c3007d1672fb8301383b4e9583d431835985057223eb298a5" + ], + [ + "p", + "330fb1431ff9d8c250706bbcdc016d5495a3f744e047a408173e92ae7ee42dac" + ], + [ + "p", + "b945e8537bfd2ca3d36acc393e6ce948ad08471a44e5bc2f7eb1409cf5046619" + ], + [ + "p", + "8c3b267e9db6b0115498cc3efcd187d1474864940ae8ff977826b9d83d205877" + ], + [ + "p", + "aa9047325603dacd4f8142093567973566de3b1e20a89557b728c3be4c6a844b" + ], + [ + "p", + "25a2192dcf34c3be326988b5c9f942aa96789899d15b59412602854a8723e9e8" + ], + [ + "p", + "c7d32972e398d4d20cd69b1a8451956cc14a2e9065ad1a8fda185c202698937b" + ], + [ + "p", + "045681cf8d47413904ff6429753e6d5a41e05e8d9d50dbd4ec0125380d886f3b" + ], + [ + "p", + "da0cc82154bdf4ce8bf417eaa2d2fa99aa65c96c77867d6656fccdbf8e781b18" + ], + [ + "p", + "9fec72d579baaa772af9e71e638b529215721ace6e0f8320725ecbf9f77f85b1" + ], + [ + "p", + "489ac583fc30cfbee0095dd736ec46468faa8b187e311fda6269c4e18284ed0c" + ], + [ + "p", + "6f32dddf2d54f2c5e64e1570abcb9c7a05e8041bac0ee9f4235f694fccb68b5d" + ], + [ + "p", + "62cef883863022a4f1d60d54857c9d729650702c9fe227b0988c0b6e36c4bcce" + ], + [ + "p", + "eaf27aa104833bcd16f671488b01d65f6da30163b5848aea99677cc947dd00aa" + ], + [ + "p", + "4c8b51820cb56aef2462213fe6927ebb6efda2b94450db5ff8c0b38eec020d89" + ], + [ + "p", + "57c4ec915796158cbe0b7763f6dd0fadcb17495a8fd8db8d27f0122116504232" + ], + [ + "p", + "6e0f5f69570cc2f2565864b0872cfff43219a0b1946e8d46e9d9de1beacb3ab2" + ], + [ + "p", + "58ead82fa15b550094f7f5fe4804e0fe75b779dbef2e9b20511eccd69e6d08f9" + ], + [ + "p", + "fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52" + ], + [ + "p", + "933d97b01272a03d281deaec23d446a3f9c72c8dee83e30081f0db191c7e20e7" + ], + [ + "p", + "b7ed68b062de6b4a12e51fd5285c1e1e0ed0e5128cda93ab11b4150b55ed32fc" + ], + [ + "p", + "8cef25eebe711364a06f2e61251cb3361d05cc75283606bc52d74f674ca0295c" + ], + [ + "p", + "c1fc7771f5fa418fd3ac49221a18f19b42ccb7a663da8f04cbbf6c08c80d20b1" + ], + [ + "p", + "de7ecd1e2976a6adb2ffa5f4db81a7d812c8bb6698aa00dcf1e76adb55efd645" + ], + [ + "p", + "3d842afecd5e293f28b6627933704a3fb8ce153aa91d790ab11f6a752d44a42d" + ], + [ + "p", + "3356de61b39647931ce8b2140b2bab837e0810c0ef515bbe92de0248040b8bdd" + ], + [ + "p", + "7fa56f5d6962ab1e3cd424e758c3002b8665f7b0d8dcee9fe9e288d7751ac194" + ], + [ + "p", + "d61f3bc5b3eb4400efdae6169a5c17cabf3246b514361de939ce4a1a0da6ef4a" + ], + [ + "p", + "ff27d01cb1e56fb58580306c7ba76bb037bf211c5b573c56e4e70ca858755af0" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "b9003833fabff271d0782e030be61b7ec38ce7d45a1b9a869fbdb34b9e2d2000" + ], + [ + "p", + "958b754a1d3de5b5eca0fe31d2d555f451325f8498a83da1997b7fcd5c39e88c" + ], + [ + "p", + "520830c334a3f79f88cac934580d26f91a7832c6b21fb9625690ea2ed81b5626" + ], + [ + "p", + "07ecf9838136fe430fac43fa0860dbc62a0aac0729c5a33df1192ce75e330c9f" + ], + [ + "p", + "b154080cb49639bb079a6a53c1d98e7130eeab3c61aa95dd9e38f9e400027cc7" + ], + [ + "p", + "deba271e547767bd6d8eec75eece5615db317a03b07f459134b03e7236005655" + ], + [ + "p", + "e6a92d8b6c20426f78bba8510ccdc73df5122814a3bac1d553adebac67a92b27" + ], + [ + "p", + "bb1cf5250435ff475cd8b32acb23e3ee7bbe8fc38f6951704b4798513947672c" + ], + [ + "p", + "af9d70407464247d19fd243cf1bee81e6df1e639217dc66366bf37aa42d05d35" + ], + [ + "p", + "8083df6081d91b42bcf1042215e4bfc894af893cd07ea472e801bc0794da3934" + ], + [ + "p", + "7cb13cde0670e590f02cbe9ea0fcf1e05edbc5cc8a409731fa5436440181cf1d" + ], + [ + "p", + "97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322" + ], + [ + "p", + "ee11a5dff40c19a555f41fe42b48f00e618c91225622ae37b6c2bb67b76c4e49" + ], + [ + "p", + "facdaf1ce758bdf04cdf1a1fa32a3564a608d4abc2481a286ffc178f86953ef0" + ], + [ + "p", + "5b0e8da6fdfba663038690b37d216d8345a623cc33e111afd0f738ed7792bc54" + ], + [ + "p", + "17538dc2a62769d09443f18c37cbe358fab5bbf981173542aa7c5ff171ed77c4" + ], + [ + "p", + "1739d937dc8c0c7370aa27585938c119e25c41f6c441a5d34c6d38503e3136ef" + ], + [ + "p", + "e5308b9c04ec5cc2bae04b5a70a7da79b28501a0676c243375813eb0cf8f4c08" + ], + [ + "p", + "9b99745fa17b337f8a6857f4369a4e844f914bd739c41bfeb939eb0930d41d7b" + ], + [ + "p", + "e5272de914bd301755c439b88e6959a43c9d2664831f093c51e9c799a16a102f" + ], + [ + "p", + "9989500413fb756d8437912cc32be0730dbe1bfc6b5d2eef759e1456c239f905" + ], + [ + "p", + "e7764a227c12ac1ef2db79ae180392c90903b2cec1e37f5c1a4afed38117185e" + ], + [ + "p", + "f8ff11c7a7d3478355d3b4d174e5a473797a906ea4aa61aa9b6bc0652c1ea17a" + ], + [ + "p", + "7f5c2b4e48a0e9feca63a46b13cdb82489f4020398d60a2070a968caa818d75d" + ], + [ + "p", + "1989034e56b8f606c724f45a12ce84a11841621aaf7182a1f6564380b9c4276b" + ], + [ + "p", + "76c71aae3a491f1d9eec47cba17e229cda4113a0bbb6e6ae1776d7643e29cafa" + ], + [ + "p", + "e1ff3bfdd4e40315959b08b4fcc8245eaa514637e1d4ec2ae166b743341be1af" + ], + [ + "p", + "3d2e51508699f98f0f2bdbe7a45b673c687fe6420f466dc296d90b908d51d594" + ], + [ + "p", + "1539b0762732585a92290b32355aee503a3532959657f554b12caa979097421a" + ], + [ + "e", + "42224859763652914db53052103f0b744df79dfc4efef7e950fc0802fc3df3c5" + ], + [ + "e", + "25e5c82273a271cb1a840d0060391a0bf4965cafeb029d5ab55350b418953fbb" + ], + [ + "a", + "34550:f4db5270bd991b17bea1e6d035f45dee392919c29474bbac10342d223c74e0d0:Art" + ], + [ + "a", + "34550:3f770d65d3a764a9c5cb503ae123e62ec7598ad035d836e2a810f3877a745b24:android" + ], + [ + "t", + "Amethyst" + ], + [ + "e", + "e89d7c2b4e1aa72e41979b5b1acf5dc4aceeaa97d0c40aaeebcde5cd4ff56271" + ] + ] + }, + { + "content": "🚀", + "created_at": 1690242409, + "id": "0e184dda2b69d84cb2e0ae4ee2db7fc936ca33345f2899dea56bed3707161a06", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "ad4e6c68c56053aa6c7bf62e379fab9a8bc5379fcb9cd413a32e4ccaae77a4b09b6747588006dc386a091fdc991ba84faae7e7362027f3173511f9c7f3766372", + "tags": [ + [ + "e", + "c37445ad00b5628b11bf4cf91e318f5372ac977d73778e8ee17613d5e357c98d" + ], + [ + "p", + "d2704392769c20d67a153fa77a8557ab071ef27aafc29cf6b46faf582e0595f2" + ] + ] + }, + { + "content": "Check version 10.7. it's using less memory. ", + "created_at": 1690242311, + "id": "7afe29b6be3eab6b18c38ba80db6b2e3e0154c5d62c7d10b96b4a73ae4e543c3", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "0cd914ffb217298fd679625ea29319e953a09006bf542270817d563dd294f9eddd432f03e0b702d6ff4664c0110f3c5505b3c07fe7f8a4b1eb5dd283d0a900d9", + "tags": [ + [ + "e", + "df9b11fd6029e3b4c27bfb5cb59aa152442a03d57bc5b759684263864ae729af", + "", + "root" + ], + [ + "e", + "3e646fa6294a2a87e6ccd619c39a50974d6c70216eae79d700bca6c46179a389" + ], + [ + "e", + "f469473308fa5e222d3e5358bdd2eaf6b1c4c135f4ab4bf60dd6cd1c8ebfa7e2" + ], + [ + "e", + "649c1cf41e4c73a75604829b09a3a9f7042a685eaeb747a0158e2c70a6f39cd4", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "43d140f61e46792199dea8a8ab4634dd21f1aedaaa4fbd29add506f8029f1265" + ] + ] + }, + { + "content": "Does your strfry relay implement NIP 50, search? We really need more adoption of search. ", + "created_at": 1690241996, + "id": "0369c6437dcb238de1a62e0dc40432c0c3218774515b85bdde00a33921beac5b", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "5f4c9d0efb7f470ef3900e7b4082bb447276b8e33d89b64aecfc6f5580dbd0bc5246fba629504b0cd8f7cdaa1b6d0ed1ffd1ae2d528f101c34b4403942d95541", + "tags": [ + [ + "e", + "296e0cd484e6d03d7e316cf0fb7dee81c159fe09ff9497165f3eaef60b8515d3", + "", + "reply" + ], + [ + "p", + "d2704392769c20d67a153fa77a8557ab071ef27aafc29cf6b46faf582e0595f2" + ] + ] + }, + { + "content": "yWAWxGt2MBu3qv1x45J3CEVpaHvQq1lV7E1BuNGgbLKZ2RYbrC2mNJcmG4TRup0s?iv=sndyUVWm/4nas9Os4pF9Og==", + "created_at": 1690239415, + "id": "257c1c59ed183315bc7e62b01e6bf4c6f60ebd849b410113f235cd332438009d", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "53496c038f4f10700b95c8c665a637522c417bf560624e5ccb814c2d4f36e5f8c7862d70fa3a7c5baf9ec6f38108a327a3966a9f927890c0cb3764df125ed850", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "7PIEPW2iCjCHl16lfM4WwnzZVxdZmAQKwu6iXqRlUQUOs5mTn0CrgPwRUw/kyfRJ?iv=2aJX1EIfi/f0hT+pcBHvrw==", + "created_at": 1690239404, + "id": "222a45a2ff03a0323452d28f264c454c2cc776d0f447c6a3d1cc8a3851d7856d", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "99eb19b3d3548c6e91497aae7c8df7c467e1959c958be85336b6b16e50df644cfad4860c872eeb6fecaf3c816dc4c2961da9944f65b398f4aa8cb0e1c30b99fe", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "Play has Google's in-device translations and integrates with Google for the Push notification system. \n\nThe FDroid version does not offer translations or notifications. ", + "created_at": 1690239264, + "id": "4a3236c13d92cc3cae2017b186a114d1bea42452ec0da1d7f7b6c37d691cc5be", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "1c820adbaa8f6005e262c05843ae9360928a33f90e313589c98f5818420ac458e49ea1ba1695b3919555e849b949cdd35d4e13889143bf9f5afd0ea16315d601", + "tags": [ + [ + "e", + "19c3f76a4283f23d1f9f422eb114864ff4ccc56d47c6f6e4f8c10d6198bcedce", + "", + "reply" + ], + [ + "p", + "a85f28306f6739230c0b96483f33fc894058c1f7e2248647c61c7d475d3db7c7" + ] + ] + }, + { + "content": "lutGFIB1gMuvUV+eCwKXKNYL7z6TIm2kDAlbYQVPx2GQ38X02lKyoY1n2hFkfEnUPkVhuXzDpduaxSXtvPkyhOPgWksP7H6jeOicnK9hppM=?iv=HME/2DSrRY30pbrUFJKFlg==", + "created_at": 1690238899, + "id": "39b67b4dbc474ea200d367c0c9a61556fa34b6867479ed4fb577f8461611a2eb", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "0bd1227154260816c06eee5008a7c9218032b827c2f6d4be9e3428e63b8735f47afce8c5fa6fa4c6c9df572385010dcf5c405a89ebf1776312ff6fbb2d7e4329", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "2/8yfvCiP34LktEny5ATUg==?iv=UmruzcdgxrWaGP0yiKeb8A==", + "created_at": 1690237129, + "id": "b73fd5a3c23b46473847cd3a4b4ce0f1f97d5dc774ad9ace37a99386f84298a4", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "2af9b7d79b24f5b53a916f1afe8b56ce9f9370e326b28d5dfdf5120bc0ef325576eb48efb4d108b33f8752effff8331329d704539a616afcc4131d8d33206547", + "tags": [ + [ + "p", + "f8ff11c7a7d3478355d3b4d174e5a473797a906ea4aa61aa9b6bc0652c1ea17a" + ] + ] + }, + { + "content": "Q9dvA4/+KObTdjEDP0rnDA==?iv=xiQVTdvQrHxPo/72WBkT8g==", + "created_at": 1690237059, + "id": "8d9ae6ec863f8e8825b8ef87444cf994127f3f48a379b50ca2a3400cb6c7610a", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "9769552001ddc7666d756297d8de7654e202af09fe0e6f2a633affd452abfc04357fe1a6e4a9e265b27c2873a5ef385fef305866bb0c9dd135f775a407b75c67", + "tags": [ + [ + "p", + "f8ff11c7a7d3478355d3b4d174e5a473797a906ea4aa61aa9b6bc0652c1ea17a" + ] + ] + }, + { + "content": "C+LkAFAhExz9RWkcHhP3Eg==?iv=skqU97xEJJAVJfodGfTJlw==", + "created_at": 1690237054, + "id": "a438e87973913596c44ef1fcc3476217af9151c1eb924bcdd2cbc209b0a5746a", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "7202d13005954592606d39208c59cc172e870ab5734b17bc3bbf6c46116e1e184cfd524ef76be0d48cead9efb408686080aa758fbc3fe456c02d82c39d1d3dc1", + "tags": [ + [ + "p", + "f8ff11c7a7d3478355d3b4d174e5a473797a906ea4aa61aa9b6bc0652c1ea17a" + ] + ] + }, + { + "content": "bUp6adO8XbYh3Sr1zpH0Tw==?iv=NFUyntsKUNXwb1GCVHrkGA==", + "created_at": 1690237016, + "id": "9f231718910c64f0fd5815ddba10b6f86bacbb554f47e02e66c91527de9a84ff", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "8e0a14112190e4dad8552470767e464275b8eb66171a46075aac39601b0b814c0fa64d54ddc24adedca85f6a270b8f69c332f7d4e898b1e136043151d432777e", + "tags": [ + [ + "p", + "f8ff11c7a7d3478355d3b4d174e5a473797a906ea4aa61aa9b6bc0652c1ea17a" + ] + ] + }, + { + "content": "You would write a message and the message would not be able to be decrypted. Message would be lost. ", + "created_at": 1690234459, + "id": "ce6fb302782f0ada5c5b3ffec15a906b81ce681a8ff0bd6eda7ddf5b8a688538", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "c62e0d9fbe9cf9d901d50be9a06ba57ad45b12e2de3c11477d71966a402d1e93dcf0c9a06c8b2635ec1445581d3823853a1a9edf60a57a2165532a60965830bf", + "tags": [ + [ + "e", + "025bdab0900f6c0bf2036713aca293e43a743e17108134b82816d2adab53fcb2", + "", + "root" + ], + [ + "e", + "bc4b1cf5a43e096cb581ef42dcf175781b767dad580f4451d61538ef4646c71e" + ], + [ + "e", + "3f1570f86b94170334e666d69d136a2181c3794a15cdb31c64ca2083ac3e653f", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "9110fe860a5e40a41e03d52d306a7b337ecf32d1090812ceaf423ec9b94954c8" + ] + ] + }, + { + "content": "I used android's base64.encode instead of base64.encodeToString function. ", + "created_at": 1690233995, + "id": "bc4b1cf5a43e096cb581ef42dcf175781b767dad580f4451d61538ef4646c71e", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "f84634af97f84d1367c715079323912aa1c4e95c075d18891ed5fd26f347fa2c406722be048abc1f3c72a86ea8de970b4afad2ef83752d52eb406729b9a01ea2", + "tags": [ + [ + "e", + "025bdab0900f6c0bf2036713aca293e43a743e17108134b82816d2adab53fcb2", + "", + "root" + ], + [ + "e", + "d86189ed8e68f18a3c2578f30a2c210cc38aef8e2acea0d6161e2db4a83994d9", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "9110fe860a5e40a41e03d52d306a7b337ecf32d1090812ceaf423ec9b94954c8" + ], + [ + "r", + "base64.encode" + ], + [ + "r", + "base64.encodeToString" + ] + ] + }, + { + "content": "Qz4ewQ+n1+swMl4fTB6D5A==?iv=bP1lZMkZaTb+/TvOpcaYOQ==", + "created_at": 1690233455, + "id": "2b9a446fa07a6f76ab0efd6320f86f45c3724a75c1a7127f479a5772c10ec0d8", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "66a171a9de4a483d2f5503eeb559e6c788e14a4e0022e94cf6ac37e1edbe06c291814944b1843a4c9baeb8010c696cecc0076190b22790bbd076e209bd4beb18", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "GFHPMUZu/xt52Emyqe2/yOgPgRyeWFlJrL+1Y0qZu7WZj62+TMnyYzbSh45Er8qiu5HMTd3NBQDGdb7fcpqCvbqYIM9i+GZTaUGLxK4kN0IEx3uToJBURlAsvXQkoBZB3r4hx0nxYpMMvZ6vF0G14A==?iv=HoxnNfugsgE7IR3UsrlW5g==", + "created_at": 1690233445, + "id": "78bad12a81ae89278fe090f75f91c59f179366c7cb2e8f137af78500b69500bb", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "89ffa0617d9dd878a893848d3d2d4a891178d9785cd5b66d1c1b94d5ee1959638224ef5b3ca8a6fdf7fb3d3dd9f802f9c358e513a325abfeaa537ffe6e5e96d6", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "VxwuKCcgYzAgWi2niqNgp5PDat8/kgR5kgj6os7tBTKDJT3/gOqedH8twDrv64BZMZ3LvtdZGlQzLIcgNE7CAg==?iv=o0QVnuaCOW9yrN67IvWZCQ==", + "created_at": 1690233329, + "id": "fa22a5e06437a59b12babf7ca2f213817137741062424da50bab867f668da877", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "6b40692264d9b0aac45d8272c44a4bd07bf3623ce9993bf3074892b3c284e90353b4d022ded1537bf4023ec162cdd259fe023a19dab7195504ede33fe2f255a0", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": ":inky:", + "created_at": 1690233253, + "id": "d41516e423d2b7c3f4333c574f4120bc16ff6a820e42e2b946a389269a87267b", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "891aadb039c5e1e887f3c689e274d9b17710d085bebf71e61695020d74ed6950ef65699e7a0477e463b457b2784edfd85047a22d12207c5a60978c5f0e386eff", + "tags": [ + [ + "e", + "7d48910e219b9145d0dc6728032f393dd6ab4fc7cbaa1f230eb0e70b6a88cc44" + ], + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ], + [ + "emoji", + "inky", + "https://yunginter.net/e/invader/inky.png" + ] + ] + }, + { + "content": "gP4BTdaw8HAFyHiTD1l16g==?iv=AsRwobD8FAWgbZI+GS24ow==", + "created_at": 1690233247, + "id": "25fa7b6874d69b4674b5b835bf6e5557d51abe7df38e7f6da991c2179abe7135", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "48ebba404b944c20cb201323d7a729a6482895ae0d05284d752f6d8b22368aca598cd931173cd34b5c31a1182380bf6e33df572608ec32b92720170ff9968609", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "S/toRHn+x4imuEgpE3QBog==?iv=FcftlhIXXfoW8Jt8IAWWfA==", + "created_at": 1690233237, + "id": "a98032bead45c8a3129451dded37a1eac6e01da6504903c93fa0a1b62d59247e", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "4e556f453e9de83f83ef00f4370189735df123e41226f8a33c9927b02739aa5c9a3b2dce93e5cbd698a28192acf77dc80a47f0be880201cc5e50a6ddc80ea80c", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "not really, the F-Droid version does not have any Google framework, so it does not support Notifications and automatic translations. ", + "created_at": 1690233206, + "id": "9c597be469ced87df16e5085a19810af53ad36c5cd6b2d1f0bdbac24b4775e77", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "a368541efa152d50641999646842fb571dac8a24b754e71023cb30d33d89d94b87098c408a3a2b8e68521a13a771942d919f1e9fc5e2894c26181333213ae97a", + "tags": [ + [ + "e", + "025bdab0900f6c0bf2036713aca293e43a743e17108134b82816d2adab53fcb2", + "", + "root" + ], + [ + "e", + "3f3832ea69dde0c130aa13be5e9461a48548322be88f9980d68f5bfc0585c4b1", + "wss://nostr.bitcoiner.social/", + "reply" + ], + [ + "p", + "a85f28306f6739230c0b96483f33fc894058c1f7e2248647c61c7d475d3db7c7" + ], + [ + "p", + "a85f28306f6739230c0b96483f33fc894058c1f7e2248647c61c7d475d3db7c7" + ] + ] + }, + { + "content": "KdASbRnhHUXkBGGr6cZluHyz26/QGGb37ud5Mi0PXXrfNaqv8SJFDbM0SsspYGfkphxbkm+OBtqQ/uCOT+Kfv6yebKDzZc1OFFqtLFQ6FhnoB3RdB2zlzx5YLeBm2+zi?iv=pFCz97lTnwgdru7KL9vVNg==", + "created_at": 1690233173, + "id": "d4f4bf086674bbc8654ef1cf38d548e067a68fb7988c530c2f5435906c063c35", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "6743508bccfdfda8fce6e04e22b39f66ad2a7e80dc884a96b6a5e8e74c3fa31ec3332c6544840816ca43caf2e0ae8aa4f7808c26d788f3943931f99eb7fe0416", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "f2K+pgicmByWLG1+7gJo1+gHYNOWUMZ+JtDF32q/JYI=?iv=2Pq0gyLVHIi8Z74r49cG0A==", + "created_at": 1690233137, + "id": "e4b88e84fcb8678183bce2e37d1cac638f752e07dd8c94a74729f65862de4616", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "d61dd8721786c9969e0359a926f736a4fec4a7608c158aaef480fc4326a54541299ab3ef901613498829e7e4701851e43ef454dde8502fa42e2c955cc56c5bc4", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "bz+BVeVRvzE8GMyhbckpyg==?iv=i7V1ONc6Sfrao9ADzYJ0TQ==", + "created_at": 1690233110, + "id": "9c5fbe5cdac9797ad05de2ed9db76a5dcb04bb95bedbce1d46247007bf4c3d68", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "293198a3b3a0c3d9ca30e84b4f03d39e3eb2536e02c91572b41e55c6680d775ba611f1bbf0bde379ebe774f1a752716196ffe4a13c1818f0b5f702f209ba0651", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "+", + "created_at": 1690233094, + "id": "eab230246fad596b82ed49e50eb6c4ca97ad39a63f1170e7b3c630079076b294", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "771b470b3aae05e08353b4259c3b4c0e339dd257759f2ea3b75518237c775b3f15be3d5c188cdc72b78dd666e5e2c0d7a96681973ae7d92c531c2c217c418677", + "tags": [ + [ + "e", + "8e39d79d31dd146b5be3e2cd8fbc54dc7c0e8ddf1936e982cf223ac21045aefd" + ], + [ + "p", + "b6e13999da09d9fb2bea6ddf5ac65693d66ffa43738e009aac6d547be5fd3c80" + ] + ] + }, + { + "content": "0.70.7 if you can use the APK. Otherwise, just wait from the PlayStore/Fdroid/Obtainium. ", + "created_at": 1690232704, + "id": "b6244ed1c0c63352a8df29cb1a689cf8d920681aa29d5b19d6cfb8d43f5b3724", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "d2abc85bacebcb5da5ec1c8fd88fcbfcbbf789a6d53afa7d9f3f95ba377a4aa940dcfb4e6286c2eb56cee6bce2a975f2b24a6b7dbcf14fe0c884c7f1fdbbed7b", + "tags": [ + [ + "e", + "025bdab0900f6c0bf2036713aca293e43a743e17108134b82816d2adab53fcb2", + "", + "root" + ], + [ + "e", + "3dd05c239b3eead3467fc3966010c9236722c0dde65a2fef32701ceca6845255", + "wss://nostr.bitcoiner.social/", + "reply" + ], + [ + "p", + "a85f28306f6739230c0b96483f33fc894058c1f7e2248647c61c7d475d3db7c7" + ] + ] + }, + { + "content": "🚀", + "created_at": 1690232541, + "id": "98450fc53c6bf56129545c1cfd1710eee3c337381171e996a7c2d827ea1f550d", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "f0a92f7211f3806a685412084ca06a8d62605780d509f3f2f1846e2d08c1a19fd2809672a71081839b2d46d8cb9d976a2e3e1437336bc14ab616189b624410af", + "tags": [ + [ + "e", + "0916d8bb10357ef41e467ca5df22f1a5972848b6e37e53deaf776498eb9930e1" + ], + [ + "p", + "444eaf65c2d35511fd0dbdbb0fe3c74139fcd144de00d22d57819ae5fdc76ae8" + ] + ] + }, + { + "content": "🤙", + "created_at": 1690232403, + "id": "f698c1f427edd31e0e568f9799545b441e4d9ba1fd1ae7283eee93ea5b921245", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "3f1345b5bea6f2ffe95c042a79e9fbc50cb81cd55e52a822090f465e06bf0e09eba273786a6c6081297e6a82b85d081438621c05ccb76a6c27ba1fd846143fde", + "tags": [ + [ + "e", + "05844e361974d2f429b58f3121098397c14efcf6b5f01cf12792d406c9d94da2" + ], + [ + "p", + "7ab1d3867722b4cbabb6c8503ab3f9265daa4f82e228cefe302621f4e5ee1f1c" + ] + ] + }, + { + "content": "### #Amethyst v0.70.7: Coding is hard. \n\n- Bug fix for the DM encrypting bug\n- Bug fix for the back button going back in the stack instead of leaving the app\n\nDownload:\n- [Play Edition](https://github.com/vitorpamplona/amethyst/releases/download/v0.70.7/amethyst-googleplay-universal-v0.70.7.apk)\n- [F-Droid Edition](https://github.com/vitorpamplona/amethyst/releases/download/v0.70.7/amethyst-fdroid-universal-v0.70.7.apk)", + "created_at": 1690232204, + "id": "025bdab0900f6c0bf2036713aca293e43a743e17108134b82816d2adab53fcb2", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "8bacaafc49225c0eef14edbafa84cc784973437975f44228742e91293f1c21b413ffb83324a91ab64400193c5765d3bd7d72478b40b912a810303e41941916a1", + "tags": [ + [ + "t", + "amethyst" + ] + ] + }, + { + "content": "A/e5KObtOus9SzOgkNcHMlfQgCLHcWdCivaz3lfPoygriVTNoNDuO1XudVbM7ZY5ChnivB4u6Gj2odhYVTT7hg==?iv=SxkaG4il8/q4Zn2uTtmiDg==", + "created_at": 1690231960, + "id": "fb28220996d832bdf65a884c43c3e0fa1887225543313e7c223af1e18a3863dc", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "5a54e12b362c66c3a4a4234d15c5f2a2f988a1786af4c5e171f86eed16a44ba327c80ea43f65c68a80aca17354be9df3a45fe00be09df3180d701164ebe725a9", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "1nx3MjyOTjE9i+BNK/hEZc4/b79lFMz08xElOLD7ogY=?iv=hwTj8iR7LfwqoHtLz3NZmg==", + "created_at": 1690231858, + "id": "f24bc09b4f67ac27baac41681704a97a450895223c2a3a1d2df7d95d28e91261", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "021cc84269b26c4e73ca5614030b49f18bfc58e65a92c3cfec8003d0210a327dd87479d91fe2e470e826368a1103eb05af1c018daca2fb96e2a316c2ef04a317", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "+", + "created_at": 1690231061, + "id": "30c908f6de4b1540adc20dd9ee8c54f954806753041c4e09f1a45475317ae2b4", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "f4121d7b80ff896340a85fcbf0812b78a7b0bd41d184bedc20d4cc3adeb57068fadc4feb615b25a42288d2ad34c7360de53d67440ca3db8b918091e527175be5", + "tags": [ + [ + "e", + "806bf35434fe8274e3e903ddc2bcbd761edc4cbd895e2a184bd879519b22578a" + ], + [ + "p", + "f1ea91eeab7988ed00e3253d5d50c66837433995348d7d97f968a0ceb81e0929" + ] + ] + }, + { + "content": "Lvf0zVwlwHUtikVDSv1RXA==?iv=uVw4/+FGz10yZRjdp45HCw==", + "created_at": 1690230486, + "id": "1834ceeff3d3c1a81054b9b4fb57f8ad08e277503ea8ca0800a6fea26940562a", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "bf4fbf6bab096234c166c1ffaf220eb91505f27eea0e8ccb4c4b2a87c00fb534f51662669b98664546cbce1324738d2ac227f7c5a035221992ecb4252d1accdd", + "tags": [ + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ] + ] + }, + { + "content": "73jzDyeieTrjiwJoTnNKZw==?iv=x4Yn/MQpDRXqOFJ8tN47Mg==", + "created_at": 1690230482, + "id": "060df5b6bb4d97478ed9f54bcee5cc1f5abeebf1fbf162f2bd10d46cfb3b7e35", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "01024d0a7c43b80be39140a28d311a66f86ac105cd465efd3f9698b4ff3e1b432924a2385c3aa4d757897e012decdb0e385abf892be4f398778c1f015191848a", + "tags": [ + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ] + ] + }, + { + "content": "[B@8d25849?iv=[B@9ec054e", + "created_at": 1690230354, + "id": "ce065bfabf37a72ce7ce604c69da4b6e7bf1eb175f1ffa3f256580a47d637c06", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "f4558138d334b34b653c44eaa5df46432ce1b5a93b4eed8d67bf09b6ac07824db55c605cc5d177274a4766f05f2a3ad6f10f20a4bfe0b323245dc8b0cc70401c", + "tags": [ + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ] + ] + }, + { + "content": "ovBLFoTTdd8TOTzjD69NYg==?iv=Q6muB1flX0fXudU7Box7Kw==", + "created_at": 1690230346, + "id": "da53a14a794809086bc065c1cd60e2c0f42a5a94809cd6f60b14b6a2df2022b1", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "a0314cef159927d1d2925942595034e2e7a3ee3f1e97161106114f9b40e2e9012bc76c823cd42f3370844b3cd154d6132da0439c9ca2bf94148928ed353a37e5", + "tags": [ + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "client", + "coracle" + ] + ] + }, + { + "content": "Folks we have a new bug when encrypting messages in this version (we updated our crypto tools). \n\nI recommend not updating yet. \n\nnostr:nevent1qqs0lvtq2hfp39hy9krkk8ztc8y8ck5hafs8sexs6umzfe2azz5vjcspz3mhxue69uhhyetvv9ujuerpd46hxtnfdupzq3svyhng9ld8sv44950j957j9vchdktj7cxumsep9mvvjthc2pjuqvzqqqqqqyt233p2", + "created_at": 1690230275, + "id": "bbda567a7e9ada22cff285af2b7af45239a0bb91022355dba78e72a629f18345", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "a206a2202235726776f0fe90c52f8d780a6c240ed0cc3a509ac4d444bb97478856f59d497774e5d769077d74deb863ec7278907d507b12d06d16aa8323be7d75", + "tags": [ + [ + "e", + "ffb16055d21896e42d876b1c4bc1c87c5a97ea607864d0d73624e55d10a8c962", + "", + "mention" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "", + "mention" + ] + ] + }, + { + "content": "Tu2w55+Du9shxbY5c/XJTAH7P9gpzolIVU40qRwMZr8K44HlgcZgXUnf+Dpmx7JdFTignWLS0dbc7c3EtV9JfA==?iv=kuysIu6gBOGKjEkgOVQTig==", + "created_at": 1690229940, + "id": "2e9380fa35888db71b7a34f718f3498537d8fa0f908eccc32bcdaaab4e3743f7", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "3ae5ad7c3d55d7b6fde18e9f534494724ac7032fc6014d494ba3fec8f70236fcfaf8c50b224490d1ba4339a8498b98cb3bd7f9f9b8b3495580b882b655bb5a9c", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "TCnpqllIWnsFTtu3sjc7OQ==?iv=SGT6iPifAUL6ZaC/lOaDKw==", + "created_at": 1690229836, + "id": "4ac2618bda32746e23dd03d4f4b8b284c86e6f1c1b3729f755ef67c22a2147e5", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "07f8b94b38d9f9c13f2e6b05c62097a7f019fbe62c850d2ea19dc3e42a98952e06a42b922fe8ed14308ef0050cbb64b0dc7562185573ccf12dd18f5b1fa596cf", + "tags": [ + [ + "p", + "f8ff11c7a7d3478355d3b4d174e5a473797a906ea4aa61aa9b6bc0652c1ea17a" + ] + ] + }, + { + "content": "nSTEB5yiTJ4P5rUuIgymnK8WzsU2D474gZuIUMnPpu8Sv/pJjmXqAUSnHvu5xVzC?iv=12q9C6xeozl3+7XGJOA5Vw==", + "created_at": 1690229516, + "id": "049d7746738bcd7e3d08699dfeca3ff343c0e87cd7f120fc88deeba0b7c45900", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "e3c2791ab4e94d129a5b639dc95e2cafef1f891435cf994974d153c42e7b0c834f18884f0651d0ba2ec5dd8b309f4374ae402246bd0bb3d078cc5e686a491f75", + "tags": [ + [ + "p", + "b1f94c43bcfa4ef78bf24f9792169fd66aa644ff37e588734f1b42df2f319048" + ] + ] + }, + { + "content": "[B@a24d242?iv=[B@ac9d253", + "created_at": 1690229467, + "id": "ca97e741fa2666883892aa47fa6c1afaf5d92e9b7f9b6777227de0ebcf947090", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "3f91893f237a82c249d3b950ab64fab6e26906a495e83336b93389a8f88130bf7edc961702b6ce0ef6e4cfd5992551d34c76211f6a974533b43ae24cd0dd2870", + "tags": [ + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ] + ] + }, + { + "content": "[B@30f641e?iv=[B@b42f4ff", + "created_at": 1690229418, + "id": "cee035666cd2135df68562f2a8841a9a8ee1fcbcacab0e2eb529735155d35809", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "38dcbbb36ff2b9a69292722d136381308f9d1dd71fc20305b6e3544bcaf9a491e78e7c5688eab8efbc306e6feb98fea6b9840bd8387742aeb4c931d099c2ee02", + "tags": [ + [ + "p", + "b1f94c43bcfa4ef78bf24f9792169fd66aa644ff37e588734f1b42df2f319048" + ] + ] + }, + { + "content": "### #Amethyst v0.70.6: Slighly more stable\n\n- Fixes a crash when onNewIntent is called before onCreate\n- New Post, Relay Choice: Select/Deselect all options by nostr:npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5\n- New Post, Relay Choice: Fixes missing switch when url is too long by nostr:npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5\n- Adds missing OptIn when using GlobalScope by nostr:npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5\n- Refactors Crypto/Hex/Bech classes and dependencies \n- Simplifies relay connection status\n- Moves to OkHttpClient on URL Preview Queries\n- Moves to OkHttpClient on Image uploads\n- Refactoring of the Connectivity Settings\n- Avoids crossfading animations when loading NIP94 and NIP95 content\n- Moves playback service startup to the IO Thread\n- Activates Strict mode in debug\n- Updates Firebase version\n- Updates Hungarian translations by nostr:npub1ww8kjxz2akn82qptdpl7glywnchhkx3x04hez3d3rye397turrhssenvtp\n\nDownload:\n- [Play Edition](https://github.com/vitorpamplona/amethyst/releases/download/v0.70.6/amethyst-googleplay-universal-v0.70.6.apk)\n- [F-Droid Edition](https://github.com/vitorpamplona/amethyst/releases/download/v0.70.6/amethyst-fdroid-universal-v0.70.6.apk)", + "created_at": 1690229318, + "id": "ffb16055d21896e42d876b1c4bc1c87c5a97ea607864d0d73624e55d10a8c962", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "2fe7528a93ac8f89d1d1af8a112e3cab60e616c244b29ac10b87afcd452f7f2e55916381ccfbf24169a0134e7e61e3ca4d39b3fac0acc4d7209edc2d03b4532a", + "tags": [ + [ + "p", + "7579076d9aff0a4cfdefa7e2045f2486c7e5d8bc63bfc6b45397233e1bbfcb19" + ], + [ + "p", + "7579076d9aff0a4cfdefa7e2045f2486c7e5d8bc63bfc6b45397233e1bbfcb19" + ], + [ + "p", + "7579076d9aff0a4cfdefa7e2045f2486c7e5d8bc63bfc6b45397233e1bbfcb19" + ], + [ + "p", + "738f69184aeda675002b687fe47c8e9e2f7b1a267d6f9145b1193312f97c18ef" + ], + [ + "t", + "amethyst" + ] + ] + }, + { + "content": "f0rxFkXgSlpTYJRIga6xkw==?iv=pkfpyqUbMS9WPb82bwVHBA==", + "created_at": 1690228620, + "id": "8deec47d7370fe50914436b50d46e3e9781bb5a01b9cdf57744e05ea9a44ac81", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "de222d3c13251b4f350050b27599a84577dc45865cafdd1802581eae735291346c4063a57bbb48d136ea307fe2564bdc7a5553d864c8e95bd01622fbed8cb24c", + "tags": [ + [ + "p", + "b1f94c43bcfa4ef78bf24f9792169fd66aa644ff37e588734f1b42df2f319048" + ] + ] + }, + { + "content": "5IXoOnU0zP2tbig0jrI/eaMHmHTmqe4G0hMJM4JTvQMfnXV4ARJu7K5X8P0dtIFmuE/LJ/rXjjGe8KK6M1LSIbFoE2u10thYAGCspZTFmqvvaBqtWO1NiRlLoEYHK+h3U0W8VAv+/RsMRjUeEVEoVTeCf6FvLrFZpjL5x4pB2uk=?iv=rvsakuPh8qVCx3bTDHtXEA==", + "created_at": 1690228608, + "id": "b4babfe9e28154ec2c49e4ce6ff357946adc7218d8faef5fdb97a6bcc0aba755", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "69fe9bed3f5bf09a70cebf02f93a8bf7678ff2b6c9f536ee824546fd81d943009a950ff4ecb07f777ed3a09316f7bd8025283d2ab40c7b60b44236a77e5c5237", + "tags": [ + [ + "p", + "b1f94c43bcfa4ef78bf24f9792169fd66aa644ff37e588734f1b42df2f319048" + ] + ] + }, + { + "content": "e7YlqY3i9/YsfIv436ynsmIgk69dMdhiNLpU5Im8cv9o5IigoU9O64wUr/8phC38KRCOqL379X03kC7/MkoX1Q==?iv=C4RfGcjbmCwARvXaUJ3Yog==", + "created_at": 1690228538, + "id": "a3078be67b927101c85c94b18d3612186adb9668d40b8883ff3d4c158774cd13", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "fb4c05e3a908b05329b306ecc418afd06f745bcf7be1c48e6ebd4940c98787c557d6ffe88b697916879770a3543cf56d2939090d07e00c67f5a1522b0dd1c7ee", + "tags": [ + [ + "p", + "b1f94c43bcfa4ef78bf24f9792169fd66aa644ff37e588734f1b42df2f319048" + ] + ] + }, + { + "content": "wFpRKzRmd0CE8Er6sSdFOaW+SLRywldsT9xuc3gyxJ0=?iv=4n0/TMTuAAmzPgZMQLqixg==", + "created_at": 1690228503, + "id": "04fd69bcf970a32314cf0d89075521e349cee6e1138847cd30a91bc24f6359df", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "bc0182f52b3135918c9de527bcb295571970940586b1a563b59edd81e64b9d81b72a67b701f10d3a78ccb4239088d93fb5506e84ddfed0b4fc5df4f7ece6059c", + "tags": [ + [ + "p", + "b1f94c43bcfa4ef78bf24f9792169fd66aa644ff37e588734f1b42df2f319048" + ] + ] + }, + { + "content": "G2fjhfEAILx+EERl5rBcT8MiB6OJpJO+YSBVFwl0NHg=?iv=jN2FU7QB9W8RbTfPSMuIGQ==", + "created_at": 1690228433, + "id": "f06da5c6ccebd61777bb9ea7403f8cae990348e04eb533a321e603d986d5f818", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "331f43a63744baaeef49eb46e8308dabe78dd699a81bcd9113724924296352225f0025daa5cf0fe4accf425224f3d817861dfa11425260f47002f8a1ad6b8e40", + "tags": [ + [ + "p", + "b1f94c43bcfa4ef78bf24f9792169fd66aa644ff37e588734f1b42df2f319048" + ] + ] + }, + { + "content": "Zv6wgC9t3LH/CepLmgk2W18K+/TJSmVd5spsy0DXu/z9ihTGoyOrUQ36qwVGlXvV3wDsZNSh0GbKmIcqtlBUVrGmbx4xH5/SeT5j4M/VpQXlfK5sH/9YaSi8ljvx8ukKsJoao4abVsfrY88FbnZEhw==?iv=VR7r/xc6QJ2HkDfHLSsqXg==", + "created_at": 1690228423, + "id": "b4b7ec12901324d608dd17692f09c22c6b3e8b34d32cb68159c9871225fbd1e4", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "710df5f81ac0dba5bc27dfa4272e9fa33e5057e1c573ab5a13cc4d3e59eef31aefe5af8368f1d95c33b9bf5aa1363e0c889a45780ddbadd151364b59ea78db71", + "tags": [ + [ + "p", + "b1f94c43bcfa4ef78bf24f9792169fd66aa644ff37e588734f1b42df2f319048" + ] + ] + }, + { + "content": "NtMkCfX5hIj1XxHNo4bfPBzMGEBs9fT+OVdIG4wINrRh6HEs4Qz87Bn5bFkagTc6?iv=b/mnWmOf5k2wSImYITU8hA==", + "created_at": 1690228342, + "id": "4a70cb34f63ed31520032823021c713467df32bd648de0989b37f35326ea6f16", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "0638f065e9d88fb8f930b2a5f97dd6a8845cfe3f453060d9e5b926d4866735deb1e63ccb04c8c70de43a5e0b41820d87125b15aef716e2167bd52d97e5ad3bd7", + "tags": [ + [ + "p", + "b1f94c43bcfa4ef78bf24f9792169fd66aa644ff37e588734f1b42df2f319048" + ] + ] + }, + { + "content": "KsvZMEAGgsnCrhObxHfleeyGrrrUj0+7b6W/dmI7kKbgvZdRrxc+99AtetHSgEPH?iv=8Dzaf+ZPo20rymUi9gLMBQ==", + "created_at": 1690228325, + "id": "aa4fd0a517095fdf6e1805dd65e2933eb9060cd48d1057408cadd8f0bf0b4f75", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "70fca6c5e521629504e3e70eb57fd5dbd41564946bc53ba875ac8f47794b699c3797e4891326777d03451e03623cac3fba5dac221a55a8535f2b2b47496afd96", + "tags": [ + [ + "p", + "b1f94c43bcfa4ef78bf24f9792169fd66aa644ff37e588734f1b42df2f319048" + ], + [ + "e", + "3b90e6bc6ed1dc8d54cd7d16b31fd55227ea422dd6d3877c6176fa0f1adab26b" + ] + ] + }, + { + "content": "hOoDDnlWlF0POet6CinuxFBVdITw1XpHmXkuFQm/ijXZ5dJO1kVbgcMStOh1ob4/?iv=RxSDrWU5WZL5AAwJpM6/7Q==", + "created_at": 1690228290, + "id": "ea66a129fd8ea1d89ae1edcf883385210b199834b7659f88925772758005111c", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "1032781f5e623eaa8a0b936aacf177f86d2620db8bb62a2e80d5d151ee020268b1cdc93f2ac6395175f55ecf62bb75f44c355a05a5a39b4448964c50eab0d2fa", + "tags": [ + [ + "p", + "b1f94c43bcfa4ef78bf24f9792169fd66aa644ff37e588734f1b42df2f319048" + ] + ] + }, + { + "content": "OgJTFpAbiLGECgMTDUUqaiE7imMVLEo6xgC+UMXsdkM=?iv=vWJbTiA1NAH88r6W5sAkVg==", + "created_at": 1690228276, + "id": "1b79f0dd1cbfc588c73267a81d7a5fe339116f5b3e7482dc0e888ccb62c49b41", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "6e0bf43c28dd4f887c5636d86b78cc6f5ab8b49a78e3c47998303d58e0b4750b7c601a36d77bebf37b0419d85d3b0b492f57f40c9fed6c934c68967acb2ec98d", + "tags": [ + [ + "p", + "b1f94c43bcfa4ef78bf24f9792169fd66aa644ff37e588734f1b42df2f319048" + ] + ] + }, + { + "content": "Wa4cXONJIYkjZ7UF1W38RXF8RGOYF1Ga8H2Wu9f2Qm0=?iv=jz9nL8hnlLnyb0nicyHBiQ==", + "created_at": 1690228095, + "id": "071d645bd306db51ca237a9b97978b50553734023bc27866b5e63372e5325edc", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "51208ce6b3fbfd750ea7dec69988b5b1d5d460829dede36e9550f3c38102a275f0fb556879c9137cc0bcbbb2dac53c6f89ea5d72742ed00e715b571ecc502046", + "tags": [ + [ + "p", + "b1f94c43bcfa4ef78bf24f9792169fd66aa644ff37e588734f1b42df2f319048" + ] + ] + }, + { + "content": "aP/EaL6KMt0cKss6Ou+Cj8gSeEiLNwz4lxBmo21lLp1Oxrbpyhb7AiPB/yaouzi6L34ERksQXG90Qm0iL6Yxmg==?iv=dJU3gVfMgoeCeTN7FmTL3w==", + "created_at": 1690228088, + "id": "a5464ad10b971eb8f6f5111bda5a64b9d76fad5b4bfdb9f26aa40db369eb56f0", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "59c5f55ff8176d65b6bc2249ab42f73c53700a12aefac764eb34b47ab2c8497b59629a3b1a1f58f662c2e22f9df8407fff59d5765125abb9149235044b7565b3", + "tags": [ + [ + "p", + "b1f94c43bcfa4ef78bf24f9792169fd66aa644ff37e588734f1b42df2f319048" + ] + ] + }, + { + "content": "UBrSmGFZyQMMAmYON6Z0ppQTcoU/35ZllF3z69xyc9a1TtJr+vNCA/9+FhZH5ahhIbjTE6ZRjk/d/JGyXbS3gmkVkYK01xGi2kkwVCW6JD0=?iv=05pAWlAlwMAVbWzQOoq7VA==", + "created_at": 1690227805, + "id": "58f3fd95d3afee12a33547c3f793d7a8def09adb3ffb6ef3760d69288c66f56a", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "d973fc6baeeeb7af8d476f13482c3d6a1d14e68ebcdbe22be72a31b11d9258e0b5ea46a84f6341028075d2c525d22ba27a3fe5dcf9edc71f9f317c702e9aced1", + "tags": [ + [ + "p", + "b1f94c43bcfa4ef78bf24f9792169fd66aa644ff37e588734f1b42df2f319048" + ] + ] + }, + { + "content": "uppuL+KowTG72APQiuYQzEAKl6opOeCI6jaBifrt4BvrJnP0SYvg5JvAyijt6XRmAJs9HjO83GJ8nExLYZsPqA==?iv=CcFmyDxQnHbOUqNJDgbEZw==", + "created_at": 1690227791, + "id": "44e95b224b6998c70fbd3f20bcdd17345fe2fa881e0cdd81c80a10af00e4aaa7", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "368cb4004b40583c3fd71a37de17b4977b7c9d8bbfef8d976e79d090175d173b85b902f514b2ef2123af8c5fa8e71bcac2d43f72d56f3caf12de3775618d8733", + "tags": [ + [ + "p", + "b1f94c43bcfa4ef78bf24f9792169fd66aa644ff37e588734f1b42df2f319048" + ] + ] + }, + { + "content": "EaRIVyoO1jSDRUYVqLN8g/yllaPPxFSAnmbTSdtyab6O8Y3YGMkRO0Wg1RRphDRM2nEaTZcngkvg40ayVQzgv1mTqhxkEiWP+YFFLV5H6Xc=?iv=IDdLzaZDUjIXAq4s7YYPpA==", + "created_at": 1690227754, + "id": "276c7ede298ca1a7b642c28e72cc9efe263e656e2e7c12fbe6607b07fe7871cf", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "80997a5c0787a7fa042568bbb43c147117da062fae9801275015a6cc21596b20f6944eb51c34b809890a5d2499bc1916e988d57718e6663c6ce19d7f5127308f", + "tags": [ + [ + "p", + "b1f94c43bcfa4ef78bf24f9792169fd66aa644ff37e588734f1b42df2f319048" + ] + ] + }, + { + "content": "🚀", + "created_at": 1690227628, + "id": "efef075535252bbeeb40f003ada1a7f295f583a56bb38443778318d17b6a128f", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "3f5659f79dd35cb3b5ae418cc62a7e28284cace0ae69b66a2b39e81770e368bf6dca9dfbbacf6522914bccc78610c601d887af774c946ffd1e71f2e57908d783", + "tags": [ + [ + "e", + "23a9662d410b7000b2b387b0fc7edbfe709449e8af56cd88ab0205ace1cd2c74" + ], + [ + "p", + "fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52" + ] + ] + }, + { + "content": "cd7zf88DXaEqGtgPPfoyAL4HcfQy/q6DtAUhhu8MnJSTEHb3CKmN3uMi7EJbWiRM?iv=vgZdKLxwPhshs3Mh4O9C0A==", + "created_at": 1690227507, + "id": "cd53313a1754ba05f4b6ce93adfa39ebd09f3234f978a911fa054272296f0191", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "b0ab7330919cb4698aa671989ffe34a4f0864b311d389c9935238fda82ed238f471ab9f211cfcd883866e7aa479778ed6522f32b35a288f9a4caecb469df1e9a", + "tags": [ + [ + "p", + "b1f94c43bcfa4ef78bf24f9792169fd66aa644ff37e588734f1b42df2f319048" + ] + ] + }, + { + "content": "we5Ld/YAGVvuGerqzNpvT0+m2DKMxDuuEZsdj+ONxeo2NIzwzP2VfsU6gfu0MBp2?iv=i+YzLjzuAAtDTXNdLEluig==", + "created_at": 1690227490, + "id": "0a7a433e967a942c56c61148603568f473f0a05f7abffda23f493fe5c4dc385c", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "460c4329424abf9fe6ab5dd4af6cedd96aa0d9b7e367159f61562c082d4d893142a6c07dc339ea320eaedf3eeb2641b344f26b7102fe1aa83c900b7163d07d0a", + "tags": [ + [ + "p", + "b1f94c43bcfa4ef78bf24f9792169fd66aa644ff37e588734f1b42df2f319048" + ] + ] + }, + { + "content": "+699S2I9lB0O3ivY+8B1btsWTArJsDJJCrBn9FgU5JX/H9emLLrkzql41Q68FLgh?iv=hih4I9oS/uZGPyD1e4nJ/A==", + "created_at": 1690227474, + "id": "30dc3c835502332ea13fc39e86ba050d541408eaaa5aa8e9746cb552dfdad582", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "b5b726b12a911c57c390293e71e1af2f7ec22b062d1ca70e9eb3c7d3d6c6d8027269cbd5b3526b7446b4fb9f437e3edfdc1eae09064772144db84311e537691a", + "tags": [ + [ + "p", + "b1f94c43bcfa4ef78bf24f9792169fd66aa644ff37e588734f1b42df2f319048" + ] + ] + }, + { + "content": "1UIB/MzWT/7eZpeBwTDiL7rCj4X6zANvyLUjidDqTb5aQknFxJs6y+wMpjwoSiZf085nzV8EGMy0Q40+bZ5RhQ==?iv=V3+jmN+XsSkq5H/koJE+6Q==", + "created_at": 1690227338, + "id": "fcec1f5080b1a3804ddbfd8e8f4511767e866ae5197a541948fef8a48c97ab12", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "38596c01b3657c7fe45b3dc9b4c57e350e865acb0e4551ce38634c52ec7031c4db8d9f9a653072669556788ad0c10d1594cd143a56ded585319a44600b5c03d2", + "tags": [ + [ + "p", + "b1f94c43bcfa4ef78bf24f9792169fd66aa644ff37e588734f1b42df2f319048" + ] + ] + }, + { + "content": "3xR4YgFOWvu+mwlBXCHBcxKkbImhQBAwqrt68/YWq9bhCLUnmAb3ug9hIm1vQACw?iv=FjLifC80ldIYZoUhlZUZhA==", + "created_at": 1690227306, + "id": "b98730e230d2e0d2a5989591828bd102b14c5d9daacb8bef89070c63a3c516ca", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "f50a1cc8c049b954b51841132ea92e2b913c550bc81a9bfbb5fdc03a2aa018c233e11048db7b45a13826f3a5ddf3f7242f31f5d10aa1bd4e63ed5577c4183fda", + "tags": [ + [ + "p", + "b1f94c43bcfa4ef78bf24f9792169fd66aa644ff37e588734f1b42df2f319048" + ] + ] + }, + { + "content": "oC5quZsBkzBT7QbwF8IaboEGgtQkfp9vsJHBhCZC420=?iv=I7afX/EYBNynEoXLx/Gfog==", + "created_at": 1690226941, + "id": "c1dd8bdc3032122a8fdcc7f646e35e499eaec0872f0455f61732e28b268467ed", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "afd4b73d65d83a14af2f8e33795a25c2c736a3241b670852abb254851e99fa2023a9a82c4d53b46af8a0348cad40c29fcc9b295ab01d6e8ebecee711baa12d27", + "tags": [ + [ + "p", + "b1f94c43bcfa4ef78bf24f9792169fd66aa644ff37e588734f1b42df2f319048" + ] + ] + }, + { + "content": "on it... I need to massively reduce the amount of memory we use. ", + "created_at": 1690225524, + "id": "b127a0cf66668468bb6a1bf83ae6837cd394edab9b0c9db875f68a29e7046262", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "d956e9f64a6ce9bdb2332ea3c6ac9f2196a848ac011d6898083bf924d7bca3a377469afefd05e4baa8b28270ea6e4189f6109f42c83b05afaf5e265dcda3bfe0", + "tags": [ + [ + "e", + "b346ca28b9063b0d6d9d81715a716ee5472e99e7a0be48d1e53e94dcbcf2e807", + "", + "reply" + ], + [ + "p", + "e2ccf7cf20403f3f2a4a55b328f0de3be38558a7d5f33632fdaaefc726c1c8eb" + ] + ] + }, + { + "content": "🚀", + "created_at": 1690216404, + "id": "cd60ef428467bd132a1c9aad9f99eae847563c8ebc8eec0e41a753e1e060c91d", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "1d5354a460dd7e1a29a7e15f783bd456c47f4439679862a799e01c4ffdc6a7054440272d4600ff8410243556e6d653100063c78822057e24cfe402471acb1061", + "tags": [ + [ + "e", + "c7662cbd99c71e97772a6399985b658316a46cba499a1fd8e220e09c915534a3" + ], + [ + "p", + "f5f98ba54045a2fa8df2a97c35fc30299b9e0d51a701795c040ca80cedaf39b4" + ] + ] + }, + { + "content": "+", + "created_at": 1690212757, + "id": "f6a137add3e53b6f5f447ccc35fcf84a0a07e69dd06bd8aaa19d6808c6a20b88", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "a370fa9b8e5a070f7cd98c966f91b6c2c763cbfad9412a94d3250e55a7b0efdf2fa1812c57f5d34f699a16d4a598eb9241704b50baf113872de8558722d1994b", + "tags": [ + [ + "e", + "3a9d72b17813409f277e464f823a36d81415bad69dab3efe7851abb848751218" + ], + [ + "p", + "5c508c34f58866ec7341aaf10cc1af52e9232bb9f859c8103ca5ecf2aa93bf78" + ] + ] + }, + { + "content": "People's favorite punch bag. ", + "created_at": 1690212178, + "id": "c380b568b96380709a679b97f1ff03bda1707dbf7c486e2f00610475e1db889b", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "815038531ead8cb887ef5648aa6389dcaa51475a57295f87cfbaea64c69f8975aace31240a926c26b1f650547fe8f08c14e92a82f147e178204e3a13fc5a58b1", + "tags": [ + [ + "e", + "72820a1aa7f666673f7542abb7ab672b330582efda66339ad291189c2710a3fd", + "", + "root" + ], + [ + "e", + "6c78d72cdb718c818f872b463abb331294663b339823388b8284359761581d2d", + "wss://nostr.bitcoiner.social/", + "reply" + ], + [ + "p", + "3f770d65d3a764a9c5cb503ae123e62ec7598ad035d836e2a810f3877a745b24" + ], + [ + "p", + "577de06dce160a0379163a4bb7b680be3e0a0e1c68de6e6ba8c01134b44064dd" + ] + ] + }, + { + "content": "We all have multiple identities", + "created_at": 1690210832, + "id": "dc092b256c585056a6cf94f3b1c5a560d5524a7ffba61a85fc84fbc56727edf7", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "05d53d798b60ae9b7970cc027106c04daf72458f42be131d2fbee901b90e74cfd5e6a8962a03f593c5354ef0da5daa436b68e1fd2d7b6f9790dcefed92711009", + "tags": [ + [ + "e", + "ff7c9d42b017c4487ea0608a61b792a5e52e86d5816521ca25cc7da2053aca7f", + "", + "reply" + ], + [ + "p", + "f728d9e6e7048358e70930f5ca64b097770d989ccd86854fe618eda9c8a38106" + ] + ] + }, + { + "content": "Yg/ItlxjLuKDzlhNZxNzxUFW005logbVHbRYOs1iCjc=?iv=VB8/JXO4MSxwX+I8wS43pQ==", + "created_at": 1690208557, + "id": "4efcb194e78ac43494f6f83c4113470880931392bb682bdbaa1dea63b671fc22", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "3ad28c322bf12d3fc32d4ce05a42468ff299676b923ab408f9f72d1ec04ebc3565472dc2e998407800584fd92fa4cd22dc1d3db87f3b9b51716daa53a473b236", + "tags": [ + [ + "p", + "f5f98ba54045a2fa8df2a97c35fc30299b9e0d51a701795c040ca80cedaf39b4" + ], + [ + "e", + "eed8c3d0d10c88c26ddf9afdd5f15d407da027fa811b6aa33ed634e81835ed59" + ], + [ + "p", + "f5f98ba54045a2fa8df2a97c35fc30299b9e0d51a701795c040ca80cedaf39b4" + ] + ] + }, + { + "content": "Yep, I just have not had the time to work on it yet. ", + "created_at": 1690208431, + "id": "6c4bd9de4e6142f6aca5107f8f88bc021142f2e70ea25a7d569d38f49934de48", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "3688bfafa385f849b731462f1f10324b54f5a08489ed55b6fd1fe52d190d2d4e40426c3ab3bfe79a2c72564df5021aff7e7215f69def3148175f415222add0b7", + "tags": [ + [ + "e", + "1b3d29f67935201aab597b4194a92a56f9d55ae23a24558527454b2284b82f20", + "", + "root" + ], + [ + "e", + "6dadc904610d86e20a7c364bb152237fe0185df7e3ac8ebff5b2f89abe751c04", + "wss://nostr.bitcoiner.social/", + "reply" + ], + [ + "p", + "456cfdb590144b9cee34dc09130217a938446b2558f06624f1cf160accd0e57d" + ] + ] + }, + { + "content": "Interesting... is the Community available from the relay set you are using on Amethyst?", + "created_at": 1690208409, + "id": "9adbdee8fce306d17e61e72d0931bd5697da102f95b5d17b0508b3238882e557", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "6ead4535864f2f8b092158d16bd2b4811d0819464b0a5d3aa63aa46f482fd1895b142f52a9e0320933f3b72f1e2e31b7ae488eec14e1acaf0440ab9aa083d217", + "tags": [ + [ + "e", + "3eb890730dc61b60344b8b2f832943fcb41faa9288049a3e41c2523f7a84d39c", + "", + "root" + ], + [ + "e", + "3576a8688b06d3e39f107ab0b7da6aefc03a32231223af6a52f5b353711f94a0", + "wss://nostr.bitcoiner.social/", + "reply" + ], + [ + "p", + "6bf33edbbfe348c1f04d9b708fd51fb6004485812adab49f1d70ad0b66d7c715" + ], + [ + "p", + "6bf33edbbfe348c1f04d9b708fd51fb6004485812adab49f1d70ad0b66d7c715" + ], + [ + "p", + "efc37e97fa4fad679e464b7a6184009b7cc7605aceb0c5f56b464d2b986a60f0" + ], + [ + "p", + "1739d937dc8c0c7370aa27585938c119e25c41f6c441a5d34c6d38503e3136ef" + ] + ] + }, + { + "content": "+", + "created_at": 1690201062, + "id": "be0a53286c98adb52eda88de58f83793c159454533a225dfb5f141362d5635ab", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "d2ac7b39051870c9cca6086e889f515d0168a0156a1c636a0006c0d549cb5a06a3eac7d3f4661470e51a0692e51e60c9ddc10dd5c43fe89765f565393bd5e50e", + "tags": [ + [ + "e", + "154e8961290541af45697deaf2537663da54456cda58565fe8350e4db201dfa1" + ], + [ + "p", + "1739d937dc8c0c7370aa27585938c119e25c41f6c441a5d34c6d38503e3136ef" + ] + ] + }, + { + "content": "Hummmm this one? It was the 6th in my feed.\n \nnostr:naddr1qq8yummnw3eyx6rfv9mx2mnwvypzq9eemymaerqvwdc25f6ctyuvzx0zt3qld3zp5hf5cmfc2qlrzdh0qvzqqqyx7cm9ctex\n", + "created_at": 1690198600, + "id": "256b47a26fdd08ce0e2040850d7328a55938c5bdb2eff7598f15779b15ed781c", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "cd94f05a2af150bbe32a5297d897eaaf53510b7905a28bff1c4ab581cea8e6701e4646dc6c188ccad884eb5f76ca4a2d9f6d20933b6c3d7dbc30a46638ccdb5f", + "tags": [ + [ + "e", + "3eb890730dc61b60344b8b2f832943fcb41faa9288049a3e41c2523f7a84d39c", + "", + "root" + ], + [ + "e", + "b08691e0f9e4d9254981f1876a430ac9a9f248bf26e54f06109a7002a78a6e91" + ], + [ + "e", + "dabcd7ee3d178ab8efba9949dc273ad96c106e2d2394a986af153ddc17a6390a", + "", + "reply" + ], + [ + "p", + "6bf33edbbfe348c1f04d9b708fd51fb6004485812adab49f1d70ad0b66d7c715" + ], + [ + "p", + "efc37e97fa4fad679e464b7a6184009b7cc7605aceb0c5f56b464d2b986a60f0" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "1739d937dc8c0c7370aa27585938c119e25c41f6c441a5d34c6d38503e3136ef", + "", + "mention" + ], + [ + "a", + "34550:1739d937dc8c0c7370aa27585938c119e25c41f6c441a5d34c6d38503e3136ef:NostrChiavenna", + "", + "mention" + ] + ] + }, + { + "content": "👀", + "created_at": 1690198560, + "id": "b24c556f1f979dc09c6720e851c7707ae907ac272a6bdde25d3d48c1df51b800", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "720c6e740aab5bfe7caa84dd8fdc82bac0d6c4666369f79d8217ded86a91c48691cd8ed0ff59d8b63054eb5e6efe72770d42a1186f1052d70522bb27872c990a", + "tags": [ + [ + "e", + "9aa0a176088c0c2b2e7be88c65c49c0872aeeca70602776d915e9d05ff7005d0" + ], + [ + "p", + "1739d937dc8c0c7370aa27585938c119e25c41f6c441a5d34c6d38503e3136ef" + ], + [ + "a", + "34550:1739d937dc8c0c7370aa27585938c119e25c41f6c441a5d34c6d38503e3136ef:NostrChiavenna" + ] + ] + }, + { + "content": "🚀", + "created_at": 1690197065, + "id": "2c60ea99918ede4de03f2d193a5bd90eaa27cd3eb77f4248e7545fbf3cd10ca6", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "8c520ae3c6846e504aeb7154b11b4f1f74c4408f059f756eeafa0542675c3a8306242ce3b1b10865ef543351f2c85308f9ced483e93bef5036c4bd96fac6b959", + "tags": [ + [ + "e", + "3ba8420929d76e222190d23f28cc8a1871c0a38ee15bcabe749e78e4a3685d54" + ], + [ + "p", + "a9434ee165ed01b286becfc2771ef1705d3537d051b387288898cc00d5c885be" + ] + ] + }, + { + "content": "🚀", + "created_at": 1690196883, + "id": "f40a4a59a641bd45869ff6950d16a03c09c856afd25ea81e84f53ae22014c3f4", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "17d0aed9b66ba569d6073a56ce2bcbe82c14e5efc9f0173bbaea699d7b5f4d8b675125d067c36e454015e44a234f7b04e356155de64de5444c74ad1632393f39", + "tags": [ + [ + "e", + "e000d1594ab01fd630fd7d635150fce287ed77a1bcb5087360b0000d016176eb" + ], + [ + "p", + "c43bbb58e2e6bc2f9455758257f6ba5329107bd4e8274068c2936c69d9980b7d" + ] + ] + }, + { + "content": "🫂", + "created_at": 1690196838, + "id": "af60844f79ca0fd418e34883cee61a9cb0cbea8e890ce110267c419ae256fd3a", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "d3bae96968d29b6f1ab47e3aa6e482fd825802443e4baf9fd09bd2bf260a346011e6c336589fcbb0ba20b97689f46ca35f6ef9b912c31c2138a6b6a5a2b2161b", + "tags": [ + [ + "e", + "a284954804a64168b23f5e9f179ac5a2dbf8d01812deafff3e3c452adf872f7e" + ], + [ + "p", + "8decf18b154e3c1f8450df95a501581e64dac7ca09bf9a83e95c783b695ab6db" + ] + ] + }, + { + "content": "🚀", + "created_at": 1690168165, + "id": "f505e57ff50b2fa767db7bdfdf4b294ed7f6f8ecc92edbeadb7086335edf8d7b", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "1a6789532ec1ae5b91d992f091d88ffb5889e4d1fba76da7bae3a624db24ff6d9176dde9323b78fe517f8c2c1769deb376591ac670eaf65f2355919f8410178e", + "tags": [ + [ + "e", + "ed5c3ff7a4ce9a16367646b9de3b342e06f5ce9cd1db92547d9764d2d54105ef" + ], + [ + "p", + "04ea59bf576b9c41ad8d2137c538d4f499717bb3df14f5a20d9489dcc457774d" + ] + ] + }, + { + "content": "", + "created_at": 1690166988, + "id": "480e76bf0c518a68f30fec75a613f7e93ac3b40567c55c04d3d99c4939dd0fd7", + "kind": 1063, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "80fb0c2cc3ef946a63ee4fc9439ecf6ac68b30bd3bc2021b333cdf456c04f0e71c9767f97777fab6170cbb2a536700c368954363f9510d585bf4a033bbabae71", + "tags": [ + [ + "url", + "https://nostr.build/av/9a5ab1d24c343007c57d1fcc15c0062b8aa10417b9853373b494dc0a4ffe3865.mp4" + ], + [ + "m", + "video/mp4" + ], + [ + "x", + "9a5ab1d24c343007c57d1fcc15c0062b8aa10417b9853373b494dc0a4ffe3865" + ], + [ + "size", + "378735" + ] + ] + }, + { + "content": "🤙", + "created_at": 1690164742, + "id": "2743a30ac796bca3d84379e02c2c151a683cacd0c95e436c9944c75fccbd1775", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "950321f75b1abce3ae87ed53692cd681f9f75cdee99e2bd3f55c2dddbd5c3b677762c70ad15b1e465588256e2a93cf0a2f9da9fc0118dc62b82e993f31656618", + "tags": [ + [ + "e", + "1e5fa48d69a1f37cf7d5777c664c2db8a305f3348fdc67cd85de66a23dad1e3f" + ], + [ + "p", + "f5f98ba54045a2fa8df2a97c35fc30299b9e0d51a701795c040ca80cedaf39b4" + ] + ] + }, + { + "content": "We might also need an extension to this nip https://github.com/nostr-protocol/nips/blob/master/39.md", + "created_at": 1690164717, + "id": "d03b49913572ef0628c03cf431ac5cc7e05f37c23ab25f418b798be8aa2819a9", + "kind": 42, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "d9f9ab2c46276d1684de49938273d172c58a04352ca3e1b8c6616737d79875925104285d6286c0e1aa5a0dfe2f4cd266ed5d7d3187b229787e6ef2fb7a9cd7b1", + "tags": [ + [ + "e", + "42224859763652914db53052103f0b744df79dfc4efef7e950fc0802fc3df3c5", + "", + "root" + ] + ] + }, + { + "content": "Ohh I see. We might need to find a way to verify that this is the public identity and not one of the links to be kept private to avoid mistakes. ", + "created_at": 1690164593, + "id": "402d8aacbec848091fb77eb84fee6cd7483bb051bbd5bdeac068561d37056752", + "kind": 42, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "3861611c96d4e7d62ec3689c8a3afead9441f4c3f927dac52a381c4322c2747ad84e9294596b687722dd6743e7e22e1aa6d875c867085d6319f4126f1847a469", + "tags": [ + [ + "e", + "42224859763652914db53052103f0b744df79dfc4efef7e950fc0802fc3df3c5", + "", + "root" + ], + [ + "e", + "150fda08135c4a4d05b7b2efc6f41f519696d4543dced36a0b0cd4093575c780" + ], + [ + "p", + "b70bcc7ad2ef996c7939d91653aa1472e0b7b3a741d194fbb26fe8c1786ed4af" + ] + ] + }, + { + "content": "🚀", + "created_at": 1690161505, + "id": "a88d6e1c7b8b9e83839c15f05bd1b9244dd1e1aaf69408fc53088bcf88d938e5", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "7bad72a24620794f1a337602c5416d6980420f20aaad77fabafbd03f43391053ace15018cc9044f48bdde6475072a6d6b51b25d10f0cae061504c260f78b06b6", + "tags": [ + [ + "e", + "8e11fddd2171c00c8cc93b5c7a3e1dbc1789cb41e9bbbc9d3cb57bfaa9b193b2" + ], + [ + "p", + "93eb23ad1d9274e3e284babe1d507f2c80d1eac2f3ef54969361a8a1f926cdaf" + ] + ] + }, + { + "content": "I am not sure if that is a good idea. The point of SimpleX is to not associate your chats with an identity. If you place it in your profile, it might break many if not all privacy guarantees. ", + "created_at": 1690161330, + "id": "3fd93179c24eb3122ccb49fac0be6e6eae50f9e091d7b0eedf350407553ee66b", + "kind": 42, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "0ef0f98973d9a18a12a62aa4ef939eb8062dbdf0e63146d5d6fa3b3aceb7ff9c419a48956244b2d06470a3da5c2d35f9417529e9e87a0f6123ad867640743703", + "tags": [ + [ + "e", + "42224859763652914db53052103f0b744df79dfc4efef7e950fc0802fc3df3c5", + "", + "root" + ], + [ + "e", + "8ad94c49e2d56130ff28c11159233d834aa0acffc2c26ebff60d9fb61eca3258" + ], + [ + "p", + "b16a48eed39254385a8754f989045d2b7110e35123ae188e354ab2b3926d925a" + ] + ] + }, + { + "content": "+", + "created_at": 1690154636, + "id": "9fd566b3366e9ed28e0e21bdbb64dfd32d47df582a7e0dc1bdec1658bf698b0a", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "57e6ef3a82458da584a807f665839564e929d309c137c33f30dbbea7396b797fda170328663e1d10eeec65b2d9dea67e428a2414dceef3a3d1da0b3b23487d44", + "tags": [ + [ + "e", + "203ac0002170f40a7204961a2d9f767cd398a86da66d483677ce526e7da523c3" + ], + [ + "p", + "e2ccf7cf20403f3f2a4a55b328f0de3be38558a7d5f33632fdaaefc726c1c8eb" + ] + ] + }, + { + "content": "", + "created_at": 1690147047, + "id": "dcab77b29cb67b63a70a816f489781e662de54c9d7700c326e5eea796ac1e3f8", + "kind": 1063, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "60dcc3d5b4ee38c8f736d5655be8846010b804e59587550f80699eef95a5917ca9cf5f83e8ad60422e0d6b052f9934994e03a6d085a48d9e198fcaf1891fdbb6", + "tags": [ + [ + "url", + "https://nostr.build/av/21267a60f742ee85cda5b6025cc96a56980082d18f299786f60dafd8f1778b2f.mp4" + ], + [ + "m", + "video/mp4" + ], + [ + "x", + "21267a60f742ee85cda5b6025cc96a56980082d18f299786f60dafd8f1778b2f" + ], + [ + "size", + "6007727" + ] + ] + }, + { + "content": "", + "created_at": 1690146416, + "id": "3873f4f5dbf76a19d6704b05019017f7c42270fc3aa08e3bcf7b263c637d976b", + "kind": 1063, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "6b0dcfe92b2984f3f02bf6cc917b5283909dbde0690bc50891805342cdc1e5b987f240f18ebd748152297e06e0d2eba483bdcffcbad6324c6bac2e095584a213", + "tags": [ + [ + "url", + "https://nostr.build/av/0a04db3be1b25964c6b524df3deb0b31d33d8380d5a4a05a1dc66d541f51ca64.mp4" + ], + [ + "m", + "video/mp4" + ], + [ + "x", + "0a04db3be1b25964c6b524df3deb0b31d33d8380d5a4a05a1dc66d541f51ca64" + ], + [ + "size", + "9910725" + ] + ] + }, + { + "content": "🤙", + "created_at": 1690146413, + "id": "97abf6fc744ca35ac884549ad7bf7ba7607b282047badd8422c4837a14eef612", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "6fae6d3f4351602af9b930fae47439d469d5cdce3d73625926a02a94397488ac359012551a2aee439a45a42f993667c69487a20c53fc18fbebbe90cfed00e15a", + "tags": [ + [ + "e", + "2b75ed8899dac01b919a7e6c78803145cb8643a0def9069b0d31d8062810cae2" + ], + [ + "p", + "7538994d9cdbb870be588f44a44a16fe7c2cde7ab203b7dd5fcdef76b8a2ced1" + ] + ] + }, + { + "content": "🚀", + "created_at": 1690146218, + "id": "f75d1da64a3ecdf3fffcffc0e117d86329896647429acde4938d8180e0ee0d4d", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "97f0d2c7ec025279f71b5a25434ef8358bc1f40d05e46b7d69868dd4d521f12beddd77cf3509dc0283b91afd9c103c700c49f10d7421b7ad8f8239a6fad92aaf", + "tags": [ + [ + "e", + "aa79b7a1b2833c8ecde7623691870f290f70cfc7b578a02de9fffcf4b0bd4cfc" + ], + [ + "p", + "693c2832de939b4af8ccd842b17f05df2edd551e59989d3c4ef9a44957b2f1fb" + ] + ] + }, + { + "content": "Hi", + "created_at": 1690145711, + "id": "1fad5cbcb12c2dfc878755e9d36253994d744c3234bb7f126e108681c20dcacb", + "kind": 42, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "7e89e6af46236aa7d6d1ecb3886561e6b3ced76a8eae6dbf21ffca4581a9311dd0affc5ea44f3ff2fd6a10fd8efb9bba5e756ccc0afa8b0994706fa9e84cd2f7", + "tags": [ + [ + "e", + "42224859763652914db53052103f0b744df79dfc4efef7e950fc0802fc3df3c5", + "", + "root" + ], + [ + "e", + "72b24ba015112bd0d9dfe0b19036500113c5727bf509c5f1f6b66a54a0e24f68" + ], + [ + "p", + "93eb23ad1d9274e3e284babe1d507f2c80d1eac2f3ef54969361a8a1f926cdaf" + ] + ] + }, + { + "content": "🚀", + "created_at": 1690145702, + "id": "64cd298c3d576f3e71c3a49eaceac2fbd576ecfacc5b9310fb55f8059da287e4", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "5bff5e7e5353ff5626db58fb2d0422298a7fa34a3584473f2a07645d103bb1269f4de2e10ba9465557b49e610ee58b5bf2eb86e208e504e849205983b512b912", + "tags": [ + [ + "e", + "72b24ba015112bd0d9dfe0b19036500113c5727bf509c5f1f6b66a54a0e24f68" + ], + [ + "p", + "93eb23ad1d9274e3e284babe1d507f2c80d1eac2f3ef54969361a8a1f926cdaf" + ] + ] + }, + { + "content": "Sorry, is this on Amethyst? When you search for a hashtag, the first reply should be an option to see the hashtag feed. The button is not as clear as I would like, but it is there. \n\nLet me know if it is not showing up for you when you type #word on search. There might be a bug somewhere. ", + "created_at": 1690144629, + "id": "062f556e82c36c6515f86f4e7c27c22fe464f0096aec5a4d10a131ae9abb4547", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "b55589ad969ee964ddfdddfcd59bd6ed59c1283f1660b3b8e80b3f66f7f4460783cbb94521145999f3b86df2a43cdfb6b384efc6c8489600dff8d155dcf4c61e", + "tags": [ + [ + "e", + "10d0e4bb3a880b36610703cf2101b8bf49b91ffe3edcbf1002564fc86e6c4913", + "", + "root" + ], + [ + "e", + "508286bb1e1589f1339a50fe488c126287cb7c68a627433253e949b03c2aa9ed", + "wss://filter.nostr.wine/", + "reply" + ], + [ + "p", + "8decf18b154e3c1f8450df95a501581e64dac7ca09bf9a83e95c783b695ab6db" + ], + [ + "p", + "f8e6c64342f1e052480630e27e1016dce35fc3a614e60434fef4aa2503328ca9" + ], + [ + "p", + "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245" + ], + [ + "p", + "ee6ea13ab9fe5c4a68eaf9b1a34fe014a66b40117c50ee2a614f4cda959b6e74" + ], + [ + "t", + "word" + ] + ] + }, + { + "content": "I don't think that is an iOS vs Android thing, it's just the app design style. \n\nOn Amethyst, the notification is supposed to be a glimpse of how your content was received. There is no need to go anywhere else. \n\nI think the idea of meaningful reactions (which doesn't exist on Damus yet) is confusing for those not used to seeing and quickly parsing so many reaction possibilities. The emojis tell you a lot: Those who agree, don't agree, are happy to see the post, or the post left them thinking more about it. We want you to look at it and go: oh cool, I got a few people to laugh at this and two others to think about it. Nice. ", + "created_at": 1690144150, + "id": "e9f43494d02050b4cda38b4618ace86b14ff46d96b816a9434959b9e7699b036", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "bc9e359ecc2d6a09470631bb9f8fb32b608d1f40b16c91d60f4a52529b93efafca74f22224b1d1d621bf1b7c26891e25d37eddf7b3b82118c789a117c07bf3db", + "tags": [ + [ + "e", + "10d0e4bb3a880b36610703cf2101b8bf49b91ffe3edcbf1002564fc86e6c4913", + "", + "root" + ], + [ + "e", + "00d94cc83d7c26eed1a915d4a927e6897627997659144f2bcecf6e761b16f71c", + "wss://nostr.bitcoiner.social/", + "reply" + ], + [ + "p", + "693c2832de939b4af8ccd842b17f05df2edd551e59989d3c4ef9a44957b2f1fb" + ], + [ + "p", + "f8e6c64342f1e052480630e27e1016dce35fc3a614e60434fef4aa2503328ca9" + ], + [ + "p", + "ee6ea13ab9fe5c4a68eaf9b1a34fe014a66b40117c50ee2a614f4cda959b6e74" + ] + ] + }, + { + "content": "Neither in Nostr nor in centralizing apps out there. It's indeed a challenge. \n\nBut we have to embrace it. Or we risk just being another centralization force in the world. :( ", + "created_at": 1690143743, + "id": "e3623f238ba397fd9fb22e4f4a72d159f4cc47feb3663788da9a282d6f1c7a56", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "6795f9ce277ef0eeb41be85317d6b68ab8b6ccfe8e1e5decfd2814a134bf5407c3b5c24988e4b151dbcfcdaa53e98809423a1ba085c49cba8285c1292ea64df2", + "tags": [ + [ + "e", + "10d0e4bb3a880b36610703cf2101b8bf49b91ffe3edcbf1002564fc86e6c4913", + "", + "root" + ], + [ + "e", + "3edd892b48748d552d2426ca32e8da671b966bf6476668460d14b91104f4536e", + "wss://relay.damus.io/", + "reply" + ], + [ + "p", + "ee6ea13ab9fe5c4a68eaf9b1a34fe014a66b40117c50ee2a614f4cda959b6e74" + ], + [ + "p", + "f8e6c64342f1e052480630e27e1016dce35fc3a614e60434fef4aa2503328ca9" + ], + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "It's better than Twitter's for sure. Especially for complicated reply structures with multiple conversations at once. Twitter's one only works when you are following a single branch of the conversation. It works because it forces you to go into your follows branches and ignore replies at each level. Which is not ideal. \n\nBut the current view needs work. We need to code a way to \"close\" branches so that when they break off and you are in the second branch, you can click to close and see the post the author was replying to. \n\nLots of work yet. ", + "created_at": 1690143600, + "id": "78de29f56dc8981d1c04a08f49dfc0f4aca4fdf6b7380fe53fc06c758543c066", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "c6a343af4611e7c0288a040eb91e91fae70dbbddfbc7780d6b311303ef10ef46bd28ece5381bc54c5d9aa905a4af363a43ed4037269c699b4ace98ec1157c31d", + "tags": [ + [ + "e", + "10d0e4bb3a880b36610703cf2101b8bf49b91ffe3edcbf1002564fc86e6c4913", + "", + "root" + ], + [ + "e", + "8300def46c069d0f10fc9e16b6feef71c1c810821e73bf76e8e3984d4531f457", + "wss://nostr.bitcoiner.social/", + "reply" + ], + [ + "p", + "ee6ea13ab9fe5c4a68eaf9b1a34fe014a66b40117c50ee2a614f4cda959b6e74" + ], + [ + "p", + "f8e6c64342f1e052480630e27e1016dce35fc3a614e60434fef4aa2503328ca9" + ], + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "I wish we had more forks. The more the merrier. \n\nFunny story: my initial vision for Amethyst was to require every person to fork the repo on GitHub and when they did that, a GitHub action would change Amethyst's name/package id and release the user's own version of the APK, ready to install. One-click deployment type of thing. That was the only way I found to not centralize it on me. \n\nThat's why the app is in my personal repo. I was going to change the app id to people's usernames at every new fork-install. It would have been beautiful. True decentralization. \n\nBut people love to centralize. \n\nThey gave me feedback, I listened to it and decided to ship the app myself in the stores. It's worse, but it got us going. ", + "created_at": 1690143259, + "id": "76688fced94a5746890fcd7c79d23674e7e84e36f29ef3ff75a1f4b7de62b1f2", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "f1fe4a9f07e4137f4d5f98f570b28054f56d7b84c894c50b0fda60739557cc5246ff09f0d76c0a3cbcc4d733f20b61b87ade4df22e34d53078cb846bd8a167f4", + "tags": [ + [ + "e", + "10d0e4bb3a880b36610703cf2101b8bf49b91ffe3edcbf1002564fc86e6c4913", + "", + "root" + ], + [ + "e", + "999243d5a5643ba565a8f9f295101d66c70050388e68f771f1ed70688de120a8", + "wss://nostr.bitcoiner.social/", + "reply" + ], + [ + "p", + "f8e6c64342f1e052480630e27e1016dce35fc3a614e60434fef4aa2503328ca9" + ], + [ + "p", + "f8e6c64342f1e052480630e27e1016dce35fc3a614e60434fef4aa2503328ca9" + ], + [ + "p", + "ee6ea13ab9fe5c4a68eaf9b1a34fe014a66b40117c50ee2a614f4cda959b6e74" + ] + ] + }, + { + "content": "It is the Reddit model. Basically, posts in the same number of lines are replying to the same post. ", + "created_at": 1690142625, + "id": "cc908556894f1207f2b6fa108a61c6b1d6f47a93f56b4cbe430d9f18048eaf15", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "bfb61f208a2a20d8dece7b0e1e1946dbdebad5768c00ad756ab003b08ccdb2425367ede7fbf930c1480f73a569d4d11aaa546f912419f6fb618515d88919e6dd", + "tags": [ + [ + "e", + "10d0e4bb3a880b36610703cf2101b8bf49b91ffe3edcbf1002564fc86e6c4913", + "", + "root" + ], + [ + "e", + "b398f36ea69452fa77c6aa09b2cda032efc3a41a4f826a9bdcbdf935e4507cdc", + "wss://nos.lol/", + "reply" + ], + [ + "p", + "ee6ea13ab9fe5c4a68eaf9b1a34fe014a66b40117c50ee2a614f4cda959b6e74" + ], + [ + "p", + "f8e6c64342f1e052480630e27e1016dce35fc3a614e60434fef4aa2503328ca9" + ], + [ + "p", + "ee6ea13ab9fe5c4a68eaf9b1a34fe014a66b40117c50ee2a614f4cda959b6e74" + ], + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "nostr:npub149p5act9a5qm9p47elp8w8h3wpwn2d7s2xecw2ygnrxqp4wgsklq9g722q's new icon set for Amethyst is awesome. I am happy to have more help :) ", + "created_at": 1690140751, + "id": "158cd5feb11ec8292d4b9441a0b948dc5d91027b33792990ce33813fa6c39297", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "96731754da8e1be93910fb52675c1aad1b51a7ed2429d534f9f1703856632d61e5e11bc1cba457f153a5ab20a307286e1f96b690f84b469ef3db8fb8f794e662", + "tags": [ + [ + "e", + "5a03b6a7d21f8b76e5ebca4e04cdaaba732a6da4537e7b75d9c57381d84eddc3", + "", + "root" + ], + [ + "e", + "47f1806284a61de31e8cc587a5c66f84fe25b0e6024b40c2851dd1d607aa72d2", + "", + "reply" + ], + [ + "p", + "ee6ea13ab9fe5c4a68eaf9b1a34fe014a66b40117c50ee2a614f4cda959b6e74" + ], + [ + "p", + "a9434ee165ed01b286becfc2771ef1705d3537d051b387288898cc00d5c885be", + "", + "mention" + ], + [ + "p", + "5c508c34f58866ec7341aaf10cc1af52e9232bb9f859c8103ca5ecf2aa93bf78" + ] + ] + }, + { + "content": "👀", + "created_at": 1690140234, + "id": "0d4467e19a71a4a5c372a96bbeb23fd46f91ea39230791ecb203852f80094c11", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "2ba1790c77db5062ee64b7ec4f8fac7ea5d0cac65eb6f95a828e005d0b9ec6b0da429014c020c9a7243ed1f16414cad16da8a09705d1cd122a0879ec2d2676f2", + "tags": [ + [ + "e", + "d63d391bd694b9e1ec5e2de2210771ba5596ad18bd996a4059466a1c0af2a100" + ], + [ + "p", + "b6e13999da09d9fb2bea6ddf5ac65693d66ffa43738e009aac6d547be5fd3c80" + ] + ] + }, + { + "content": "Then I am just confused why are you comparing this with a notifications screen. ", + "created_at": 1690140198, + "id": "fb72346b3a189ef576609b2b2e5af56f52546722d84094f41733675aa55e4db2", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "8a7d4b654828e11f8dc94355ecb50b507ee8430599b1187b0ae63b534b5f1b283c74f3b78e641c0301d2bd8c9d58be9e4e276d7be6afbcb0acb4123fec6a0922", + "tags": [ + [ + "e", + "10d0e4bb3a880b36610703cf2101b8bf49b91ffe3edcbf1002564fc86e6c4913", + "", + "root" + ], + [ + "e", + "bbc7290015806dc41ab15d37f8d5b6b66e469371f052abf36738017e4d41db71" + ], + [ + "e", + "d6d3bb1689a95eb9e69e9fe143951c2c2fe402740a4bf35fe5255d86fd9a0227", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "f8e6c64342f1e052480630e27e1016dce35fc3a614e60434fef4aa2503328ca9" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "ee6ea13ab9fe5c4a68eaf9b1a34fe014a66b40117c50ee2a614f4cda959b6e74" + ] + ] + }, + { + "content": "Also, it looks like you are two clicks away from notifications. Is that right? ", + "created_at": 1690139942, + "id": "bbc7290015806dc41ab15d37f8d5b6b66e469371f052abf36738017e4d41db71", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "eb3b73acc14478f87a3dc92f946cf8831a63cc1c647bd7fbe1ff585ae7b0d97f588852ed42e8ff68d22dbd0b866dffc045f50468fe0c054e9c0898f46ee900e8", + "tags": [ + [ + "e", + "10d0e4bb3a880b36610703cf2101b8bf49b91ffe3edcbf1002564fc86e6c4913", + "", + "root" + ], + [ + "e", + "7cbb8c290f9c2722e094cf95af3e51069ef97171300d49d84108f66f53de7558" + ], + [ + "e", + "bdf5ddb752eb601777f835846a60f8e7ea34fe0e807afefa515e700ece0040b0" + ], + [ + "e", + "6ea171a5dc97b971fea2a551cfbd418c308c436f2b851aaab8737367f9196838", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "f8e6c64342f1e052480630e27e1016dce35fc3a614e60434fef4aa2503328ca9" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "ee6ea13ab9fe5c4a68eaf9b1a34fe014a66b40117c50ee2a614f4cda959b6e74" + ] + ] + }, + { + "content": "Why? Did you ask your users to see if this is what they wanted? ", + "created_at": 1690139749, + "id": "6ea171a5dc97b971fea2a551cfbd418c308c436f2b851aaab8737367f9196838", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "060d4e3a9202d09af5388d11c51089677f725845e96d8f2c7d07747a8be73dfcfb33c8836057d099974d9310ee23161eb78ddf3842560fb7040e8a6acbcde8b3", + "tags": [ + [ + "e", + "10d0e4bb3a880b36610703cf2101b8bf49b91ffe3edcbf1002564fc86e6c4913", + "", + "root" + ], + [ + "e", + "7cbb8c290f9c2722e094cf95af3e51069ef97171300d49d84108f66f53de7558" + ], + [ + "e", + "bdf5ddb752eb601777f835846a60f8e7ea34fe0e807afefa515e700ece0040b0", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "f8e6c64342f1e052480630e27e1016dce35fc3a614e60434fef4aa2503328ca9" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "ee6ea13ab9fe5c4a68eaf9b1a34fe014a66b40117c50ee2a614f4cda959b6e74" + ] + ] + }, + { + "content": "It was in the very early days, but we did. \n\nNotifications tab is not the mood for follow and detailed info. This is more for a regular feed, when you are in the \"get more details about this post I just saw mindset\". On notifications, you already recognize most of the faces. \"It's all duplicated\". There is no need to explain or occupy more space than needed.\n\nOrganically, in over 100k downloads, no one has ever asked me to add a button to follow in that page or display the about info, which should speak volumes about the need since it's one of the most used tabs in the app. ", + "created_at": 1690139394, + "id": "e1c04a093203e1a39fa51775e79645d9303330e3d5fc0a6ba4f1ba85568fe260", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "9bb5bbe24d10e80f88d117e52c5ec9598a7d45ee6941a0bda09db4aa9efc9ec2623a80fb10453ed7e097284648cf15628d6812a7b41c6613b7772e404cc5e56f", + "tags": [ + [ + "e", + "10d0e4bb3a880b36610703cf2101b8bf49b91ffe3edcbf1002564fc86e6c4913", + "", + "root" + ], + [ + "e", + "27cdfcce9c8f291ea1519567d2d3180a131f3e276801c2b0b208fcec3a4a56de" + ], + [ + "e", + "39a3badfb3a96cbca72aeb6b6319b7ca2b2aafda06c9060158c9c2b56e71dcb9", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "deab79dafa1c2be4b4a6d3aca1357b6caa0b744bf46ad529a5ae464288579e68" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "ee6ea13ab9fe5c4a68eaf9b1a34fe014a66b40117c50ee2a614f4cda959b6e74" + ] + ] + }, + { + "content": "User's last seen is a very good idea. \n\nnostr:nevent1qqsxnj27sn2xud90fyqre6jgakzxwcu2axnj9kcec9jch66cph5u7uqpz4mhxue69uhhyetvv9ujuerpd46hxtnfduhsygymuzlquexn3g56nnkf5hyw7hv88s4l55mz5j643kjl76du8jacrcpsgqqqqqqsuu0vvw", + "created_at": 1690138954, + "id": "c9ab82b0a6b2ef1adf14106f3c660f9fc06fc063d54fa89c092f64fe24d0193a", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "529d56a80125fa7b0e0ba5d9592bb457473929449c775d5860c142d64c6e08a655381bcae282540ab3198636cbfe9aa5074fd237344e93c38dd087ee9e8c0629", + "tags": [ + [ + "e", + "69c95e84d46e34af49003cea48ed8467638ae9a722db19c1658beb580de9cf70", + "", + "mention" + ], + [ + "p", + "9be0be0e64d38a29a9cec9a5c8ef5d873c2bfa5362a4b558da5ff69bc3cbb81e", + "", + "mention" + ] + ] + }, + { + "content": "Last seen is very cool idea. ", + "created_at": 1690138907, + "id": "6ae05de6606182d1f3f3afec4b42cd0fcd37c4b12b4807f1f1971f16d4a42273", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "2c593ad41af45511a937c5f95e50aacd4ff953e1758faa13c96f71a5c68832f08cf513926fe318dcf52bdc55ae28ee3aeb615a3b12aac553474cb4f4406a8396", + "tags": [ + [ + "e", + "69c95e84d46e34af49003cea48ed8467638ae9a722db19c1658beb580de9cf70", + "", + "reply" + ], + [ + "p", + "9be0be0e64d38a29a9cec9a5c8ef5d873c2bfa5362a4b558da5ff69bc3cbb81e" + ] + ] + }, + { + "content": "So, you have to click on each section to see who zapped and each reaction? Sounds like a click too far for me. \n\nAnd why does it display people's about info and follow button? I am not there to follow people. I just want to see how people reacted. \n\nThis is weird. ", + "created_at": 1690138829, + "id": "27cdfcce9c8f291ea1519567d2d3180a131f3e276801c2b0b208fcec3a4a56de", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "b9e256fc3ab93ecb522625669dfd5f50bd4468d2c1d0f5328341c559c4d5cb1f44f707bb30949a93fa9d91ac8738786d433f4141e0bd0db625984ab8e6187344", + "tags": [ + [ + "e", + "10d0e4bb3a880b36610703cf2101b8bf49b91ffe3edcbf1002564fc86e6c4913", + "", + "root" + ], + [ + "e", + "546fbf068c293c15c5c48232570d12e81e551891fbc611b1fc186a798ad0dc92" + ], + [ + "e", + "2d59b8711e9aac9f6f6cc1025ce215e744e94979f4af33e7b9a586918e24bd18", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "deab79dafa1c2be4b4a6d3aca1357b6caa0b744bf46ad529a5ae464288579e68" + ], + [ + "p", + "ee6ea13ab9fe5c4a68eaf9b1a34fe014a66b40117c50ee2a614f4cda959b6e74" + ] + ] + }, + { + "content": "Show us how Damus display the same notifications. Now I am curious to see why is it so much better. ", + "created_at": 1690138505, + "id": "7cbb8c290f9c2722e094cf95af3e51069ef97171300d49d84108f66f53de7558", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "5cc460d2f1812da1372b2e1e5bb883ea09e14fd7b33c2ce0fb3324e1b77e5f21cf451226465950061ab59d49e7c766f6f9010116dd0a68a2bca796e2f45bfc33", + "tags": [ + [ + "e", + "10d0e4bb3a880b36610703cf2101b8bf49b91ffe3edcbf1002564fc86e6c4913", + "", + "root" + ], + [ + "e", + "1874dc3c39bf3dab4d9fc3b6022ad850ad5a4aa7ef4d40aa24b019f4f1e4b841" + ], + [ + "e", + "f8c6955a54a8f9c254d85c8c28d9dfa22b63d6b98c7903a8e407a20ff1152f18", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "f8e6c64342f1e052480630e27e1016dce35fc3a614e60434fef4aa2503328ca9" + ], + [ + "p", + "ee6ea13ab9fe5c4a68eaf9b1a34fe014a66b40117c50ee2a614f4cda959b6e74" + ] + ] + }, + { + "content": "🤙", + "created_at": 1690136517, + "id": "9f8f3d9d1e5bb57492d8fb2c6a654ec0953515e5ed009f86fedd08fd788cbb70", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "db59f7ddd49bcb186e12483cc07b819c45f8dd0e1719c3a6dad063595eefb7df34c963ccb206cbcabd37041b4df4d6b5fa4013d4b39217d59cb2199e76181e75", + "tags": [ + [ + "e", + "10fe6f028555c905ce355d042b50605f0eb13b925ba4742855537ffb5a50be60" + ], + [ + "p", + "20d29810d6a5f92b045ade02ebbadc9036d741cc686b00415c42b4236fe4ad2f" + ] + ] + }, + { + "content": "🤙", + "created_at": 1690136496, + "id": "b30e186018667152d83b1b2a366150907bc4cfc5158c2a74e095fc63eb75cc0c", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "14a4b1db558c64a679e02c944b5d63b7d41df6faba4f02d700d92e742a48a21c241c161415416ced8d5bd3663553b071533cfc2b4dbed88979f07ba41176d22d", + "tags": [ + [ + "e", + "eac398b0b928cb10dc9337df29acf7cdf621ba05a4b300792b8aa4d1125e0c55" + ], + [ + "p", + "18affadacb471657941485d8e3053e2be0daa95aa42f9c6f8680d62c758a9ab3" + ] + ] + }, + { + "content": "🤙", + "created_at": 1690136491, + "id": "ee2956b81136a28caf94c12a47a4879a75dc2c204a911ebfbba85243613d4cb7", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "7bd2df393c2d65b4240a001c7e67efd7a069f83f50b51f8047bbd3c1c45eea4d1967b066aed45dc3bceeb054df9078d5f451e43427d7063daa1266dbf83b44ea", + "tags": [ + [ + "e", + "df6924922f7fdcf06a802348b28b26cb4eb0eece4d0af995e8c352b6887d04aa" + ], + [ + "p", + "5f2b6a543f5083b79dc22227867507a12a999e365f0af741b1f5852bc1974226" + ] + ] + }, + { + "content": "🤙", + "created_at": 1690136489, + "id": "e28b0e4bcf4c16bbc83a7a4d4c4d3ce4159a3798a7ad7a4fb2bb95e5178d0da6", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "ca878cea73fb03a532452b6fdedc6cb0ec1a4259d9e5ba428cec6b27d8ce2e09605cb079c5d251a45072544de907eeef01219cde2264a8ee6597c2382cdf3b84", + "tags": [ + [ + "e", + "0127ccbde49aec4c9f88ea5f18c2f442383f403d59ba060142f08535f09ee4f5" + ], + [ + "p", + "18affadacb471657941485d8e3053e2be0daa95aa42f9c6f8680d62c758a9ab3" + ] + ] + }, + { + "content": "🤙", + "created_at": 1690136483, + "id": "ceba0d38900e9b7f3ffa6e2935c3e9654aee754f3dd3ad15ff416a061bd6beb1", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "954b2b32fdf7cc393722296b1b5639ef7ba9889a0e850746c8a91f8cb817facb9cf16881f6a1a6f7aa51e924baabf19c796e33eec1dc41c9e30cbc30c9225552", + "tags": [ + [ + "e", + "bff7c2588efc33f94e24ed9e9b9e24e560e5e2c4460cb6bbd6ecbd5cb074528e" + ], + [ + "p", + "18affadacb471657941485d8e3053e2be0daa95aa42f9c6f8680d62c758a9ab3" + ] + ] + }, + { + "content": "🤙", + "created_at": 1690136480, + "id": "23751602d5fefff93fdb7d202f5c0ac4b856d93f674ac24db7675693b1e8c33d", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "122735ff28c4bd0e45b43618767c1a12df1d1c22244d78ed24906ccc9f5194da01540386e75dc74775363fa744b4e2ce338857d4f0013876806e5b9c6c5dc5a3", + "tags": [ + [ + "e", + "107fbdd98adbce0798b6858248213be4262ae1301fbac29e2e5ed7b838534b15" + ], + [ + "p", + "18affadacb471657941485d8e3053e2be0daa95aa42f9c6f8680d62c758a9ab3" + ] + ] + }, + { + "content": "🤙", + "created_at": 1690136460, + "id": "e1404352314e0ea33f8b70f23a9f833e475bd118b0f49886c0d34b01dca6be80", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "286b6470e0c2a51b07d1c7cf72d919d7e06d0f303ad2d6bf05c2a525e37fa17b6b9c1d05d7c80f49dfa954bc08f51c865a6e3e5b0a5feb184d5f96adec613530", + "tags": [ + [ + "e", + "5fb517843bf3accd6ce60e69d5f7b964323f582238242f6776a58c9daa59a3c5" + ], + [ + "p", + "18affadacb471657941485d8e3053e2be0daa95aa42f9c6f8680d62c758a9ab3" + ] + ] + }, + { + "content": "🤙", + "created_at": 1690136457, + "id": "1d8c8f7707f365909ecfffc890bf58ac28489b81f1fb71ceb506b8d9a1417140", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "e8a21f42780365e514b9bee4dbf8335722a9520068f312da2b7b8185a8a6041de17e2b631f06edf1aa7959f4436658855688e011b971c2653d83a7f36784d6a6", + "tags": [ + [ + "e", + "28f176f094da6a46ee195eac39ca4154d0d94d86d2e545532f697238f3e52f9f" + ], + [ + "p", + "31da8e96a0d372f657280a3b678c5c8398b053d0891d458b7c8b0a752737a9e0" + ] + ] + }, + { + "content": "🤙", + "created_at": 1690136453, + "id": "f81ec9b259fedf292974205e6d2523cb527f53825e7b16ab794bac30021e5c3c", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "f207099dd78a41e9fb3f09359acd0fc37199cac970cbeaa0f96e01d3c6e2d1f444f4dc4c7624e5ebed94ca6e936a7d7c60a5f43a753e822e67d4b04ae709585a", + "tags": [ + [ + "e", + "92e9e94ee0da6fd08c62fc2477a8a2c825fecbf0ad91a2c5d060d2978f20d6cd" + ], + [ + "p", + "4ff36a4d67fa327ef1a686a575d0106b4781600900f68ccb5a40f7e455530baa" + ] + ] + }, + { + "content": "Ohh interesting. Thank you! ", + "created_at": 1690134858, + "id": "20e91ddf23a4b87c138fc41c50bd6baeee6bfa352b2f156a51cb914c29927847", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "5cbc7535ec7ebc60a21faa27e3bb61d3ad5b5381270209fc50ba7b709c40df4c02fe5c7865b7881aefd4bafbce90abd24f45d058beeda22d94eb6ebc388a9695", + "tags": [ + [ + "e", + "a08a26900f0c1aedf142e61d122abde0f764ff5fe61cf5660c61547a9ad0f79c", + "", + "root" + ], + [ + "e", + "4e2cc89c76dd14bb69fb38d2c6faec03f85f1ef0ef40227ccbbc3c7b05e6e3e7" + ], + [ + "e", + "56ea1f92baa9008920ab905465776d55cf623539069f406b0cfb057fd5442ef7" + ], + [ + "e", + "1dd32c99b5e875b90617599580270c16e2f7e3be233f029bc73345eb591ba294" + ], + [ + "e", + "3ca18ec56b18d5c17bc31576b80edb9ba355b4cc82dc7fb671effbdf90a79562" + ], + [ + "e", + "682a31ccafec8eb46dc6ae3b8e94471e6d4bf2f98289236e164481f50cd76630", + "", + "reply" + ], + [ + "p", + "ec9bd7465546ba061f5dfde716a4f20f3f27ecc28ca4870775e5e853df11a9d0" + ], + [ + "p", + "b6e13999da09d9fb2bea6ddf5ac65693d66ffa43738e009aac6d547be5fd3c80" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ] + ] + }, + { + "content": "That is very weird. It should definitely work. I will investigate. ", + "created_at": 1690132862, + "id": "3ca18ec56b18d5c17bc31576b80edb9ba355b4cc82dc7fb671effbdf90a79562", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "d35335a2ee1d8b813b5a63bd86716561356de9c0208162927e3efb1ec6cbb89df04d3d7ceada1c71848d7456037999df947e55a17a7083960b362ba252d2b246", + "tags": [ + [ + "e", + "a08a26900f0c1aedf142e61d122abde0f764ff5fe61cf5660c61547a9ad0f79c", + "", + "root" + ], + [ + "e", + "4e2cc89c76dd14bb69fb38d2c6faec03f85f1ef0ef40227ccbbc3c7b05e6e3e7" + ], + [ + "e", + "56ea1f92baa9008920ab905465776d55cf623539069f406b0cfb057fd5442ef7" + ], + [ + "e", + "1dd32c99b5e875b90617599580270c16e2f7e3be233f029bc73345eb591ba294", + "", + "reply" + ], + [ + "p", + "ec9bd7465546ba061f5dfde716a4f20f3f27ecc28ca4870775e5e853df11a9d0" + ], + [ + "p", + "b6e13999da09d9fb2bea6ddf5ac65693d66ffa43738e009aac6d547be5fd3c80" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ] + ] + }, + { + "content": "Does it stay on after you Mark it all as Read? Sometimes very old messages arrive and they are all the way back in the list, but they are still unseen for that person. ", + "created_at": 1690132343, + "id": "82ed575f4d9bc4f19660e277890c34ff4f0aa0d023b86d91fbb809d3457483e2", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "5c3e81917835a58561b20a6d559a85530aface929422fca1c06e837975932c33124217e5073a13e251fa8ec8d7aed6ccc5aa3fbadf7f996743a9018f21d275bb", + "tags": [ + [ + "e", + "a08a26900f0c1aedf142e61d122abde0f764ff5fe61cf5660c61547a9ad0f79c", + "", + "root" + ], + [ + "e", + "4e2cc89c76dd14bb69fb38d2c6faec03f85f1ef0ef40227ccbbc3c7b05e6e3e7", + "wss://nostr.bitcoiner.social/", + "reply" + ], + [ + "p", + "ec9bd7465546ba061f5dfde716a4f20f3f27ecc28ca4870775e5e853df11a9d0" + ], + [ + "p", + "b6e13999da09d9fb2bea6ddf5ac65693d66ffa43738e009aac6d547be5fd3c80" + ] + ] + }, + { + "content": "Back button? That's new. Any particular place? ", + "created_at": 1690132236, + "id": "56ea1f92baa9008920ab905465776d55cf623539069f406b0cfb057fd5442ef7", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "ee7f13431181d04a1c8b0ce211c2ee788c2890a978f35636c8fde70fd1bd56feb16230f40c90eabf1b6ea3016d324d08e09b24e5513dfccc334ff5489e29b217", + "tags": [ + [ + "e", + "a08a26900f0c1aedf142e61d122abde0f764ff5fe61cf5660c61547a9ad0f79c", + "", + "root" + ], + [ + "e", + "4e2cc89c76dd14bb69fb38d2c6faec03f85f1ef0ef40227ccbbc3c7b05e6e3e7", + "wss://nostr.bitcoiner.social/", + "reply" + ], + [ + "p", + "ec9bd7465546ba061f5dfde716a4f20f3f27ecc28ca4870775e5e853df11a9d0" + ], + [ + "p", + "b6e13999da09d9fb2bea6ddf5ac65693d66ffa43738e009aac6d547be5fd3c80" + ] + ] + }, + { + "content": "Same risk as using SimpleChat with the same outgoing IP for all contacts, right? The relay can bundle your messages/queues. ", + "created_at": 1690131040, + "id": "5a97c5a5397b6f222d660713269dbd08ef14933f1868d5f20edae897e0be5ac2", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "432af5b48d193d0d069dcf2b292edceaba44f0381df378d1e491a9ba5d84a4e0c2d5f755f8a9e8df0c8d55cef22b189014c7a0a138b4119d1a3e9a4b2f814c06", + "tags": [ + [ + "e", + "4591adeb9ecc789599b3f20f51714fbd005c5b38943f91b5ee1174443a63246d", + "", + "root" + ], + [ + "e", + "1fc5133e2cf877c6dbb2ce5478a5780fb252c77b7683b7871d4944e1f309c82d", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "b7ed68b062de6b4a12e51fd5285c1e1e0ed0e5128cda93ab11b4150b55ed32fc" + ] + ] + }, + { + "content": "+", + "created_at": 1690130924, + "id": "ac1fa90872d0848def9120db1cb0ee16fc13e90b4e5725365fea651d7a939737", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "d8a4cc59e04de535673bb2eeddd7a65348d8daaf3d5c7c694cf4a0df2f1af7ed7d74f7f0d075264e77144932b9701f7fdc35eb2ef089837c59d2b376e80fb4e5", + "tags": [ + [ + "e", + "1fc5133e2cf877c6dbb2ce5478a5780fb252c77b7683b7871d4944e1f309c82d" + ], + [ + "p", + "b7ed68b062de6b4a12e51fd5285c1e1e0ed0e5128cda93ab11b4150b55ed32fc" + ] + ] + }, + { + "content": "Simplex doesn't want to have a link to a known identity like Nostr would have. ", + "created_at": 1690130888, + "id": "273b7d10c62906e48866911ce18fe3735099bc1f2b352e1c7b8a6f26195d0cf1", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "9014e9eef179975957e241cbcab1e9b5ffa04b9a527b3447b67dcc17946a8fab0209c384badb255d9e81c7e22a44c1402f8699d794e4fbdfcec22b0db2acad8e", + "tags": [ + [ + "e", + "4591adeb9ecc789599b3f20f51714fbd005c5b38943f91b5ee1174443a63246d", + "", + "root" + ], + [ + "e", + "0df509f7198ea50bd1e62d3a63d876f64180ab31752b6271facf16e34a6bbaea" + ], + [ + "e", + "cdefd0a3c55e3fe120d6a4fd93666a04f9a94e3349f47e9ccb39c57696e0af38" + ], + [ + "e", + "a34f5bf152db8de7cd90c7dba18ddb1ce8ca0309b778af5db99dd9e0afd0055b" + ], + [ + "e", + "1c3241c983d9423dd321ed6cacf17012a38b3a637e1d886a19f21f068a6be1a2" + ], + [ + "e", + "26929187391d11f6428433b304a0d19e72c3766a405cb31edf54f5a6b668db6e" + ], + [ + "e", + "f71fdb383382be27b75a45c8d201f43a9086a5704fc948165d428b52f3fec539" + ], + [ + "e", + "5bfcab4ddb3d59528974588f1c16a1e7633d7720e2fe8ed370e856c20b57882a", + "", + "reply" + ], + [ + "p", + "c060b31fe2bbb0be4d393bc7c40a80848a25b8f0e0f382cb5b49c37bf7476cb4" + ], + [ + "p", + "c060b31fe2bbb0be4d393bc7c40a80848a25b8f0e0f382cb5b49c37bf7476cb4" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "c0605aff47b9330575f4865671528832323c6d0a8320a8568c9e044272e266c5" + ] + ] + }, + { + "content": "We can rotate keys, but if you discard them, you won't see the messages address to that key anymore. In all cases, you will need a collection of all your past receiving keys to move to a new phone, for instance. ", + "created_at": 1690130151, + "id": "f71fdb383382be27b75a45c8d201f43a9086a5704fc948165d428b52f3fec539", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "ffc4b2fd51e22628d66fdf10f01b93551a6ed69c42f115f9e880858b13445e87a913a569ac1832c6394d9658fd600dafa297c13b9228ae3b9bc06c251f95c7dd", + "tags": [ + [ + "e", + "4591adeb9ecc789599b3f20f51714fbd005c5b38943f91b5ee1174443a63246d", + "", + "root" + ], + [ + "e", + "0df509f7198ea50bd1e62d3a63d876f64180ab31752b6271facf16e34a6bbaea" + ], + [ + "e", + "cdefd0a3c55e3fe120d6a4fd93666a04f9a94e3349f47e9ccb39c57696e0af38" + ], + [ + "e", + "a34f5bf152db8de7cd90c7dba18ddb1ce8ca0309b778af5db99dd9e0afd0055b" + ], + [ + "e", + "1c3241c983d9423dd321ed6cacf17012a38b3a637e1d886a19f21f068a6be1a2" + ], + [ + "e", + "26929187391d11f6428433b304a0d19e72c3766a405cb31edf54f5a6b668db6e", + "", + "reply" + ], + [ + "p", + "c060b31fe2bbb0be4d393bc7c40a80848a25b8f0e0f382cb5b49c37bf7476cb4" + ], + [ + "p", + "c060b31fe2bbb0be4d393bc7c40a80848a25b8f0e0f382cb5b49c37bf7476cb4" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ] + ] + }, + { + "content": "Not if you need to save all these keys somewhere (locally or on the cloud) to see the same feed in another client or device. That's what SimpleX does with the local database. Keys don't leak randomly. They leak when you are inserting them in a new device/client or when somebody gets access to it. If you keep your keys and the local db together, the attackers gets both. ", + "created_at": 1690129188, + "id": "1c3241c983d9423dd321ed6cacf17012a38b3a637e1d886a19f21f068a6be1a2", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "9378974e955039364618a0ad76df16e4c2ba1e18fedbca954896008fcda96ff469886df88c648d5590e99b6849f8d188a959731ecdab7f191554a66696bc2669", + "tags": [ + [ + "e", + "4591adeb9ecc789599b3f20f51714fbd005c5b38943f91b5ee1174443a63246d", + "", + "root" + ], + [ + "e", + "0df509f7198ea50bd1e62d3a63d876f64180ab31752b6271facf16e34a6bbaea" + ], + [ + "e", + "cdefd0a3c55e3fe120d6a4fd93666a04f9a94e3349f47e9ccb39c57696e0af38" + ], + [ + "e", + "a34f5bf152db8de7cd90c7dba18ddb1ce8ca0309b778af5db99dd9e0afd0055b", + "", + "reply" + ], + [ + "p", + "c060b31fe2bbb0be4d393bc7c40a80848a25b8f0e0f382cb5b49c37bf7476cb4" + ], + [ + "p", + "c060b31fe2bbb0be4d393bc7c40a80848a25b8f0e0f382cb5b49c37bf7476cb4" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ] + ] + }, + { + "content": "The new idea does use ephemeral keys to send. We could do ephemeral keys to receive as well, but I am not sure if it actually adds much security. ", + "created_at": 1690128558, + "id": "cdefd0a3c55e3fe120d6a4fd93666a04f9a94e3349f47e9ccb39c57696e0af38", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "ea935c0dce11832e87a7dee58bead19a6fe74eeaf4dbfda227f82501ba4b8da987eb9644e4fa6feeae8e5da99670878fccea63b351267fa5b732859f121bdc25", + "tags": [ + [ + "e", + "4591adeb9ecc789599b3f20f51714fbd005c5b38943f91b5ee1174443a63246d", + "", + "root" + ], + [ + "e", + "0df509f7198ea50bd1e62d3a63d876f64180ab31752b6271facf16e34a6bbaea", + "wss://nostr.bitcoiner.social/", + "reply" + ], + [ + "p", + "c060b31fe2bbb0be4d393bc7c40a80848a25b8f0e0f382cb5b49c37bf7476cb4" + ], + [ + "p", + "c060b31fe2bbb0be4d393bc7c40a80848a25b8f0e0f382cb5b49c37bf7476cb4" + ], + [ + "p", + "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245" + ] + ] + }, + { + "content": "I don't see it. As long as there are two clients doing DMs, we are going to have this issue. We only need two good ones that compete well and people will be lost. It gets attenuated when people use a client on the desktop or a tablet and another in the phone. They want to see the same feed in both, at all times. ", + "created_at": 1690128385, + "id": "43baea1d165172f1fb7ece392e3d227921d7a2558e0ae25bc29a39c9889528bb", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "6899b4e30252916d97848ea0f26bf89834528e7d1fc47c566c61a16246f32f6041db75a44c62e5fce44f3cae02a70d2ffbab6b58982f649411698f9425a23956", + "tags": [ + [ + "e", + "4591adeb9ecc789599b3f20f51714fbd005c5b38943f91b5ee1174443a63246d", + "", + "root" + ], + [ + "e", + "cefaf39fa34dbc1e01b28930f269af13d9d77c90b2e121f6166b4a7933c998a2", + "wss://nostr.bitcoiner.social/", + "reply" + ], + [ + "p", + "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245" + ], + [ + "p", + "c060b31fe2bbb0be4d393bc7c40a80848a25b8f0e0f382cb5b49c37bf7476cb4" + ] + ] + }, + { + "content": "SimpleX chat relays do keep your messages for a while just like Nostr does. And the receiver also has a copy of your messages. So, it's not that different than in Nostr (with the new idea, dropping step 4). ", + "created_at": 1690128254, + "id": "ceafe9e1ef47db0d1a62dadcfd38dc621121beb555a5937579832d3dfb5cbcd3", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "8d5efb0bbce9a5c0cc7fe2855e2d33747a2c904fa2c37fc2bdefbad2fcb8a196f3a649fb658dc87e8268bdc6c4eebc24638c78149ab0e62f4a8811fabdb910cd", + "tags": [ + [ + "e", + "4591adeb9ecc789599b3f20f51714fbd005c5b38943f91b5ee1174443a63246d", + "", + "root" + ], + [ + "e", + "f1208fe67ea4647e66f4c1245c42ac8eb15fa94cb635969b025ac5fec07ab0da", + "wss://nostr.mom/", + "reply" + ], + [ + "p", + "c060b31fe2bbb0be4d393bc7c40a80848a25b8f0e0f382cb5b49c37bf7476cb4" + ], + [ + "p", + "c060b31fe2bbb0be4d393bc7c40a80848a25b8f0e0f382cb5b49c37bf7476cb4" + ], + [ + "p", + "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245" + ] + ] + }, + { + "content": "I am not so sure. In practice, the security is as faulty as with Nostr keys. The things that would cause a key leak in Nostr would also cause a chat database leak in SimpleXChat. And since on Nostr, people want their DMs in every client, there will be a lot of export and import happening, which yields bigger chances for leaking the entire thing. ", + "created_at": 1690127530, + "id": "d1d6ae797dd7a9900dc6696e3bebc884f5d06a523d010e6cad62a70aea755589", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "9748ea22ea7336a436133085fa8052a1b60f146ef9ef49bb27676d72e55f047165385fc409a3217fbb01f3178a76deb889674d9cf51a9f657a5fe9693a068f65", + "tags": [ + [ + "e", + "4591adeb9ecc789599b3f20f51714fbd005c5b38943f91b5ee1174443a63246d", + "", + "root" + ], + [ + "e", + "90c441fe992e9277e2b5ab4cb40c249d1d3ca64f41ea4dd33e1e5734cd6bb869", + "wss://nostr.bitcoiner.social/", + "reply" + ], + [ + "p", + "c060b31fe2bbb0be4d393bc7c40a80848a25b8f0e0f382cb5b49c37bf7476cb4" + ], + [ + "p", + "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245" + ] + ] + }, + { + "content": "+", + "created_at": 1690126785, + "id": "0601df915b7a6b6e0aec792879ed95a7c05edea54e339bfa330be013cd9087f3", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "ffa70983b791fb19bb5a15da05b4e71b6a9d5d65a7df796e1c7d9633187fb1b52000a21d18c8f8d29ec278bab88bf159c24a1620ac0b64cfdd95836951c43cef", + "tags": [ + [ + "e", + "0001d512384cff57a0a051ca705e2913269c8d7ad2563f7717f988acde2e0d71" + ], + [ + "p", + "2ef93f01cd2493e04235a6b87b10d3c4a74e2a7eb7c3caf168268f6af73314b5" + ] + ] + }, + { + "content": "People can opt out of the 4th step if they don't want to recover their own sent messages. \n\nI am not sure if there is a practical solution for the DM history leaking issue. If people want to keep their history between clients, they will keep whatever is needed to recover the history together with the key. Once the key leaks, the rest is also leaked. :( ", + "created_at": 1690125971, + "id": "8e763cfbd52dcae5c9d14e772a36d1114ab129b9d1fee0725387d4979f43af44", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "9da781d49e1d952b4f11633bbb67e22d4ecd54460f9d3ff99ce5908b83d49f4d123dd9996a62cc65090279a9c3798bc913d5aeb136d53e9faaa59eb0b2d0c06e", + "tags": [ + [ + "e", + "4591adeb9ecc789599b3f20f51714fbd005c5b38943f91b5ee1174443a63246d", + "", + "root" + ], + [ + "e", + "ddbaa33cfe39957dfb381ad963d74951902bb907f9c07e167c2e336a27d34e95", + "wss://nostr.bitcoiner.social/", + "reply" + ], + [ + "p", + "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245" + ] + ] + }, + { + "content": "🚀", + "created_at": 1690125054, + "id": "9f7e02cb022e9efab2fde0dd13493ce8c9753c4189be3e057cd3ce88d7a03c93", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "224e654f8599b4f25e53dfb49462a359bcddd37ff5c9e0374e11b538cdef9641e7197babc7984de626577b10940c54ece892f6824ee49548d6e541a756ae5cff", + "tags": [ + [ + "e", + "098f01242f5d18f7dfe622ed292090b7c008c55f8185e5b972cfdbb8df7a4c00" + ], + [ + "p", + "ae39bf0aab59bfb1bacc784bd7b230ce762a671eb33d5c0c586ef7e96c8ae25f" + ] + ] + }, + { + "content": "Yeah, I need to figure out how to use less memory. :( ", + "created_at": 1690125040, + "id": "b735f0cc3f6fc10d2a15bf6da690ffd8f94e1f03cc7ea24869b14b10d7fe8533", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "2d709feacb2657707eeb80219d626cc397ddb8815bf5b28aa5592f486d66e45dd2163682cefbf063a263ae4079e0d482c685fbcd2832c0849fed9c310b702aad", + "tags": [ + [ + "e", + "e362d1324f7672556d6e8fdfbac3fc3a26906abb2b32824b43ba1d2fb80305e8", + "", + "root" + ], + [ + "e", + "a122d53b0340257911cc8e2f7d940279dd5e4100a708b70c9b3dd20eced7f18b" + ], + [ + "e", + "a38e734e65750bbdf679e6564f52e49a19ee8424e590319935f05625820c83be" + ], + [ + "e", + "669c66fe822ba472e5b4b603409f9116badf3a1af439de357c9ec159b894dde4", + "", + "reply" + ], + [ + "p", + "269b0b280b99e4724daf5718a6c8e412c59269cc472a70b472b1acf0dec91bca" + ], + [ + "p", + "356875ffd729b06eeb4c1d7a70a1f750045d067774d21c0faffe4af2bf96a2e8" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ] + ] + }, + { + "content": "Yep, just an extension of that. ", + "created_at": 1690124736, + "id": "8d4bd3ea01e934d6553372da70175e07fb63708e34cd2cd6e99b903d7eecad32", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "fabc98d48f0f3a3910418899c1eed968ca9b15f7b2b4cb19c32934fd4ae83cfcfc480e26e074fd091d331ada5dfac6689350921c6df53bfac7a40998ac6dd6cf", + "tags": [ + [ + "e", + "4591adeb9ecc789599b3f20f51714fbd005c5b38943f91b5ee1174443a63246d", + "", + "root" + ], + [ + "e", + "38a91f7ab267336f20745f74312d4dba3fad6c8a965cd61aa8b294e86e7b4503", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "Isn't this better than SimpleX Chat's protocol? \n\n1. There wouldn't even be a queue to correlate messages on. Each message comes from a different random key. \n\n2. Send and receive payloads can be separated in time (the receiver sees the DM immediately, but the sender logs the message, or better, a group of messages, in the future or the past inside Nostr relays).\n\n3. As we add more private event kinds, the anonymity set increases. The public won't even know what is a DM and what's not. \n\n4. Yes, anyone will see that you are receiving \"things\". But GiftWraps can wrap Noise (events that don't mean anything and should be discarded upon receipt). No one will know what's noise and what's an actual DM. \n\nhttps://github.com/nostr-protocol/nips/pull/468#issuecomment-1646858226", + "created_at": 1690124517, + "id": "4591adeb9ecc789599b3f20f51714fbd005c5b38943f91b5ee1174443a63246d", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "86eb89acac53fd87f975c1b3799113c9841ee92c0802a15547e9ae6f4914233a95224a1364c087434e758f57190229db17fcc1d8a45951d785824bed063beac3", + "tags": [ + [ + "t", + "issuecomment-1646858226" + ] + ] + }, + { + "content": "Really? Hum.. I don't see any crash reports when writing messages yet. Is there a particular procedure that I can replicate? ", + "created_at": 1690123683, + "id": "a38e734e65750bbdf679e6564f52e49a19ee8424e590319935f05625820c83be", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "2bd6a3dc8b8e16a2a3474e59d2b7fb8052dcc374cbaf2cbf387306fb8b482e54f972a29ff2ce8e9fa4acf872334e322dcb0ac02498862c4f96940e28f7e326be", + "tags": [ + [ + "e", + "e362d1324f7672556d6e8fdfbac3fc3a26906abb2b32824b43ba1d2fb80305e8", + "", + "root" + ], + [ + "e", + "a122d53b0340257911cc8e2f7d940279dd5e4100a708b70c9b3dd20eced7f18b", + "wss://relay.orangepill.dev/", + "reply" + ], + [ + "p", + "269b0b280b99e4724daf5718a6c8e412c59269cc472a70b472b1acf0dec91bca" + ], + [ + "p", + "356875ffd729b06eeb4c1d7a70a1f750045d067774d21c0faffe4af2bf96a2e8" + ] + ] + }, + { + "content": "Each page has it's own setting. You need to change it 3 times to get the result you want. ", + "created_at": 1690123610, + "id": "b6fc9e80837196ee50661ec7dccae9e4780efacb2f1c041eebced362819e9066", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "d206951c7acd7ccbadad68edeeabdc91952600c8f438055fd57a0d096c2192e73c28fce4b78cca04f04a8b249b762997cb2242c589af79090ac2f4e5e994f99f", + "tags": [ + [ + "e", + "c26effa4ceb95606db038a88d7be714328a4819be98e52fc7536c8deaed67b14", + "", + "reply" + ], + [ + "p", + "ae39bf0aab59bfb1bacc784bd7b230ce762a671eb33d5c0c586ef7e96c8ae25f" + ] + ] + }, + { + "content": "Yep, block is local. Report is when you let everyone know about a person or a note ", + "created_at": 1690115660, + "id": "d35a705e248e0d748938bd403a3041895396babffd227e41eaae2c8006a1929d", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "44fb41d3992aeee7343a65c3ef11abbd34b6399c8fc7fe244e2a0f23e928ea78b7c9f68470358f8e165fbda7e68c088b754b2942e19c362c1eb0212df6489977", + "tags": [ + [ + "e", + "c038888ec69c6c8987f5b2dfd224ddb55ca039689b0a20a22287303ef8894f36", + "", + "root" + ], + [ + "e", + "e8091b484dff5afdf25f0f4a4d1199944cb1ee13f3938f78030fccbd6da92a33" + ], + [ + "e", + "806796cf44e651a4f91b9e3f645024a1df19e0fa62aa95db444e15e8939377b0" + ], + [ + "e", + "121b4044bc989a3b0139372d7ccf27890fea3a5b77af370311f778ea57695bf0" + ], + [ + "e", + "ab1d298ae27795f0fea2c9446fabbbc41b2e5b6a127bf4f200598a71295eb569", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "0c9b1e9fef76c88b63f86645dc33bb7777f0259ec41e674b61f4fc553f6db0e0" + ] + ] + }, + { + "content": "Fight free speech with more speech :) ", + "created_at": 1690114179, + "id": "121b4044bc989a3b0139372d7ccf27890fea3a5b77af370311f778ea57695bf0", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "56f0634768de22c8bf3f396e30f3249ed6a3f6d68be81ba9c61f82d77b92699f58320a0f59be3c69aad77b81287af066211ac43f298942940fa2846fcf412671", + "tags": [ + [ + "e", + "c038888ec69c6c8987f5b2dfd224ddb55ca039689b0a20a22287303ef8894f36", + "", + "root" + ], + [ + "e", + "e8091b484dff5afdf25f0f4a4d1199944cb1ee13f3938f78030fccbd6da92a33" + ], + [ + "e", + "806796cf44e651a4f91b9e3f645024a1df19e0fa62aa95db444e15e8939377b0", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "0c9b1e9fef76c88b63f86645dc33bb7777f0259ec41e674b61f4fc553f6db0e0" + ] + ] + }, + { + "content": "", + "created_at": 1690113754, + "id": "dc34c01e8f71b64c206ed9ef324beed9b233a298f8df3227702b0ed2907603fc", + "kind": 1063, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "789c4078488b2eecde89c63d63ce93f8a6803cc704728465d3ab4657128474de9b17cb12eb8b8dcf03cd0659c1d34e248829ab3f6358f079baf3d71817a1aae4", + "tags": [ + [ + "url", + "http://nostrcheck.me/media/vitorpamplona/nostrcheck.me_d829c52bb54e2125989bc4c7876c2523f0c7945e20ed1f59.mp4" + ], + [ + "m", + "video/mp4" + ], + [ + "x", + "a61a285079ad066ed4a31e6dc59bbd6e187c32225c66895342f7ee6b82121a5f" + ], + [ + "size", + "2054861" + ] + ] + }, + { + "content": "Him: I don't fall for placebos. \nAlso him: \nhttps://nostr.build/av/6a92ccde091c71316a28f8652a40147a82d7e573076414095cac12b9d2a3b1aa.mp4", + "created_at": 1690113542, + "id": "ad1d69d0565ca03d3329fa91e93e7d5e7ec21df3d8729ab8b8696379f04605ed", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "95758a89bbc4251e022aef31d0e5f98b342e26f20889e836e39ac59ea8f02131897053ecf4b9e2cdde66ff78dbfd209afd35f0dec754e0f6707a1a9974e7d1a3", + "tags": [ + [ + "r", + "https://nostr.build/av/6a92ccde091c71316a28f8652a40147a82d7e573076414095cac12b9d2a3b1aa.mp4" + ] + ] + }, + { + "content": "🤙", + "created_at": 1690112771, + "id": "6b5de9eaa52f1c889dd1c49b44696a53709d119784f3b8859b27b350d75df2e4", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "3e79410fae3b7223997edc61a6da17df8ec3978723a2931680d8636b64e7cb9ed420d0ec275aecd2f7733df56978166ae568076f106b1cc1ac81ed01c0236950", + "tags": [ + [ + "e", + "ad079dc69fee2dd362bf444404e71b71a4709b790bdf7cc45c4a38b95c9b87c2" + ], + [ + "p", + "ee6b33fc72adf103af33ce25a018179e4458e79d1e898bbe8d460eaa7818bb90" + ] + ] + }, + { + "content": "🤙", + "created_at": 1690112700, + "id": "ed1aab29b697e44b5a6237e7859df7e8217b8d2f42627be6745a7031774e6939", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "6cdb924b825c5982738b2bf16090f49356fd76eedd098c8153f6071164cc8d8c53956d385f8fd7f7f1e26cb5f35ac3f07f27f3128dd122efbcba58bcc4c061a9", + "tags": [ + [ + "e", + "b69250498d25feb15d65e2e8270154a65cc241593be32cce4efd299c78619e99" + ], + [ + "p", + "a12fb7fe051724a34ef3409ebcdb377b9d1157a79b7a2fcd8d008995f190d9fe" + ] + ] + }, + { + "content": "🤙", + "created_at": 1690112681, + "id": "0bebf55a12f843aa3fbdac0481db0939a5926561f1d76a0a3c7ce3d8cb3cafde", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "952547cddc189995dc5aa3b2b34e4c21d540d7cb3203eee559419feaf7f97b4415f00a51dcbb8a719ae7b8d3de87990ccb6448622a64489142cdd5dae0bf6577", + "tags": [ + [ + "e", + "b5a56ca5ca5535609b08a9d1f7985cdc0c96d7ecf5fad484145ad0b1060575ae" + ], + [ + "p", + "be0435d2baff7c44dcf0c38ff53a26720f2729660141a5dbc0dbcc25d0cc619d" + ] + ] + }, + { + "content": "🤙", + "created_at": 1690112674, + "id": "3d1f0707a14218b295716537e7ee77264da6f380f5f868f66e625c83e9ae4e95", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "9b4e2c701c7f36b0de297227d627180594010e157a199e9801db8f869d99e4d6e8baa5693ab30e5aec75bc35b0496868ac79373b170ce211992964383c49bd45", + "tags": [ + [ + "e", + "40970fd0dcec2d6e95fcc70385b37cb4387d234acfe7ad483ece089072e5adb9" + ], + [ + "p", + "31da8e96a0d372f657280a3b678c5c8398b053d0891d458b7c8b0a752737a9e0" + ] + ] + }, + { + "content": "🚀", + "created_at": 1690112212, + "id": "e24e855089aa4769587b61792cab3314a521703da921197aa80543b6d6a4a778", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "b1fae809b4a20dd954f78877c33c872c647fb73043c945c7ccf24355f95b73bc382a2b3490f87791b320633dcf307c4178ab9bd4a8a416c7673f6dc13a10d779", + "tags": [ + [ + "e", + "9ab63d4a2a5d3c5154f1da7359cc4dbe78be286e120e863b3d5ea7aa0ae8d23b" + ], + [ + "p", + "3a5ccf9f1eced28f3a34db176054f17e0fe25492a33d734b4c0482a09a275eca" + ] + ] + }, + { + "content": "Report is part of free speech. You can say whatever you want. People are free to react to it. And then everyone can react to reports. \n\nReporting is part of Nostr, not only amethyst. Many clients implement it and relays use it to delete users and posts. Amethyst just displays them for everyone to see. Hiding it won't solve anything. \n\nOn the warning side, you can disable warnings on the security filter screens if you don't like it. ", + "created_at": 1690111912, + "id": "e8091b484dff5afdf25f0f4a4d1199944cb1ee13f3938f78030fccbd6da92a33", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "26b2ad6f938e396084629c10d48b85835bc4f0571fdcbde974e5b0eab052cd0f829265bdc80efd86790adb8ed2e51207dc6ca467d62bc8d949d8cfeccdbeacae", + "tags": [ + [ + "e", + "c038888ec69c6c8987f5b2dfd224ddb55ca039689b0a20a22287303ef8894f36", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "0c9b1e9fef76c88b63f86645dc33bb7777f0259ec41e674b61f4fc553f6db0e0" + ] + ] + }, + { + "content": "Change the keyboard. Graphene uses a very old version of the keyboard that doesn't work with newer UI frameworks. :( ", + "created_at": 1690111377, + "id": "600b878282a93e2fbd1533727127ab4ab3473fbe0fa80c263e9877bdba46e912", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "5ad458d6a0de654da1370b0e88b6ad2478182e78a05c7c4d0df5d089863f4aa70f0683ad871f96b89f7b87af7b68c6fc9893f9d7a4ee393f99b579fd73eef712", + "tags": [ + [ + "e", + "6d195bd88b4a7d4b3522a862fad439d4351e0bc87659a5d50a34aea8c8499e1e", + "", + "root" + ], + [ + "e", + "1ee94a94cc5028a217a1d8159454145ccdaceb73206cc85791ac47d84d79e1ca" + ], + [ + "e", + "c9045bcc1bbba5a5934ca475cfb9b6eb94dd7863b4d56c841d4e0f112d541882", + "", + "reply" + ], + [ + "p", + "27154fb873badf69c3ea83a0da6e65d6a150d2bf8f7320fc3314248d74645c64" + ], + [ + "p", + "27154fb873badf69c3ea83a0da6e65d6a150d2bf8f7320fc3314248d74645c64" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "3a5ccf9f1eced28f3a34db176054f17e0fe25492a33d734b4c0482a09a275eca" + ] + ] + }, + { + "content": "Nostr is open and all reports are public. Anyone can build this. And I can use as another input to the filter. ", + "created_at": 1690084953, + "id": "de7c95cf799612ee6fb6f4e4d3d353e765fced03e8176ad112433e12c9950c08", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "9cde5c0b0ad14f2d7466ae995af622562284576202b40ebbea462a67fd763ae25a54fcb83ef43709146f9e088cdeda3fcd9490ce167052d61bd1f5e3f3a914dd", + "tags": [ + [ + "e", + "fd2f4cd8122c3af6871458e7939c14a589d3af0fbdb0cd27208dcc67cf98df7c", + "", + "root" + ], + [ + "e", + "595c5a0f0cb5b6d06a0a7219c62d11a4283e122b3469fdc5bb57ed30e4ab25cb" + ], + [ + "e", + "c65fe276c2338588773707dfa2294a313721594ec93a04d6078624ebd2d13632", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "ba2883fb4a7f62cb851b9f5411659791cffb2e3fc8b90f683ee5091f413880a1" + ] + ] + }, + { + "content": "Just build a system to expose false reports. Fight free speech with more free speech. ", + "created_at": 1690084772, + "id": "595c5a0f0cb5b6d06a0a7219c62d11a4283e122b3469fdc5bb57ed30e4ab25cb", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "6f63e1c98bdb9b2fa9d34c47afe17a06d0a5d9da12c1c4d37355952e34ff4db9e0707514a73b4f86b7c4190584f4a31c7a2124493ae088eacc61f02c81779bc3", + "tags": [ + [ + "e", + "fd2f4cd8122c3af6871458e7939c14a589d3af0fbdb0cd27208dcc67cf98df7c", + "", + "root" + ], + [ + "e", + "b2231c9bc27017f9f57892ef75eeeba2a31a255e43401b689ebf3660caa6b22c" + ], + [ + "e", + "20a22ad4b7db92df61d4f8338846a3b322612d52efbd60a9cfc5c8d6aa791acd", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "ba2883fb4a7f62cb851b9f5411659791cffb2e3fc8b90f683ee5091f413880a1" + ] + ] + }, + { + "content": "Nah... We have too many kids with the app. By default, the experience should be conservative. They can open it up when they are ready. ", + "created_at": 1690084580, + "id": "b2231c9bc27017f9f57892ef75eeeba2a31a255e43401b689ebf3660caa6b22c", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "e0cf116ac3872a4af3ea99bb84255fa46a6d0e99054a00936c5bdca4912d31c37f4687e27af77b17d4a3919c66de87ec709ce6d1432806e68881b54167ece253", + "tags": [ + [ + "e", + "fd2f4cd8122c3af6871458e7939c14a589d3af0fbdb0cd27208dcc67cf98df7c", + "", + "root" + ], + [ + "e", + "094aced9e82bcf37d554a6967aeef0f7cadad963ff6f84495b16b26269ddbc26" + ], + [ + "e", + "07cf4cfdccd7746e1dec48784a78569d106efce752d6dd0c0b196c1c395613d4", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "ba2883fb4a7f62cb851b9f5411659791cffb2e3fc8b90f683ee5091f413880a1" + ] + ] + }, + { + "content": "Allows people to block you, yes. That's not censorship. They can always opt out if they don't like it. These days, we even have a list that only shows the blocked feed so users can confirm they don't want to see your posts. ", + "created_at": 1690084378, + "id": "094aced9e82bcf37d554a6967aeef0f7cadad963ff6f84495b16b26269ddbc26", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "f0bf30ddeaf6e19c1a13146c98142d36b3559a909d330c866e1e2a9abd196801a88440a31cca574e7da2b1ce8f37c2f57374b720a570fda697b25e1aa54a2041", + "tags": [ + [ + "e", + "fd2f4cd8122c3af6871458e7939c14a589d3af0fbdb0cd27208dcc67cf98df7c", + "", + "root" + ], + [ + "e", + "52b562f2f95654d2b2a84b742285337eba5cc400ffc33bdbe21e7ee4a5f6198c" + ], + [ + "e", + "7994583bab3bde80a01b4a9b8703913eacac1e4fe7ee20cb21220ea5b5605bfb", + "", + "reply" + ], + [ + "p", + "ba2883fb4a7f62cb851b9f5411659791cffb2e3fc8b90f683ee5091f413880a1" + ] + ] + }, + { + "content": "We also need a data heavy client to make people accountable to their reports. If a report is false, everyone should know about it. Falsely reporting people should damage your reputation. ", + "created_at": 1690083028, + "id": "52b562f2f95654d2b2a84b742285337eba5cc400ffc33bdbe21e7ee4a5f6198c", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "39e55f79a467361e56eb2d1cd49c321c99965855af3e0a976605b0fe494b7b1a963a1ff122baee02c01573c0665b5025e990258105816e75f3e0ccef764d630e", + "tags": [ + [ + "e", + "fd2f4cd8122c3af6871458e7939c14a589d3af0fbdb0cd27208dcc67cf98df7c", + "", + "reply" + ], + [ + "p", + "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d" + ] + ] + }, + { + "content": "Hum.. I am not sure what you mean. The domain is clickable right now. There is no expectation from clicking the user name (there is no email or web address we can point to) ", + "created_at": 1690079870, + "id": "bde7b3599fde0d7a80a96b20393563382c5d1c622afb062940b0770ce1bd7e7e", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "201da0302b41f0b1ad45c723870c6b82a2352eea67ee890cedbeef394e8c32536a7fa3117e4057972002891e7f89bb3bec60214b14f3bb02a0e94295a87ffac6", + "tags": [ + [ + "e", + "f2845de7cb2d774af657ce57b2886debd9b5b9bec9660664bd40910ade0bc769", + "", + "root" + ], + [ + "e", + "f90bf3162e5430fa9398709f39c9fee0b81b175ab4fdc26f648b1c90fc5caa17" + ], + [ + "e", + "d5a7523bfba9a9d6144fe3f6de462555b6b4ee3aeb6e581ab308003bfb9d4660", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "89d1ce9164f1f172daaa9c784153178cb1dec7912bf55f5dc07e0f1dabe40e6c" + ] + ] + }, + { + "content": "", + "created_at": 1690063233, + "id": "a0b29a3283c10b5bc63632e9d4e6554e46580b6320513a62da68c8298f464cc1", + "kind": 1063, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "44aa72f7f5644f6f3f07e7ab5c76f00c2bf7621e6ff172743591672bf70a27e0deb5961b9e043c4bd3e95007320d75c470cd283b799b9cf8f9022e987465d86f", + "tags": [ + [ + "url", + "http://nostrcheck.me/media/vitorpamplona/nostrcheck.me_581d924e2f04b41cf2bb258623ec6800a7420f83bd81ff44.mp4" + ], + [ + "m", + "video/mp4" + ], + [ + "x", + "9180a00d8de2209c1d2623af0b5a492471f967d080e6620ec28e6f003ffb49bd" + ], + [ + "size", + "2371930" + ] + ] + }, + { + "content": "Spam :) ", + "created_at": 1690062330, + "id": "9edeca1c1c29db5cbee94c2f38637eb46774b84dd52c9d2a6d5910c8352d3898", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "071c1ff194a234f1009628994191b3e77a22874a68dc4d82e799d2f35f6c6f9edbe83eb79ad07fda3b8fd096fa83c938d340c49fc271bd197ecd640978c4ee74", + "tags": [ + [ + "e", + "ff460e6c65591f7c43bca28d26c9d67e01d32743e7b676abfdb54e7378c3b9eb", + "", + "root" + ], + [ + "e", + "93fec67f101706b4ab832466153df265c75593fbea8e3ef302410710fe833a56" + ], + [ + "e", + "bb953fe6a64516caa9a0c2285a29e5ded168572be6cae1f3daa63bd8321965f9" + ], + [ + "e", + "aa6f251e957f4ae00f0596359f3185b9579c3602e351bfdb0dd10da1ca3c2c44" + ], + [ + "e", + "be4b56d812d4ae5f1c31b147b18be3b60bbf3cbdf636a4f02e61fd850cfecc9c", + "", + "reply" + ], + [ + "p", + "ae11573ff5b6d1fe250da805e8278b8d7488052a84a3463f110c9cf2e920243a" + ], + [ + "p", + "5fd693e61a7969ecf5c11dbf5ce20aedac1cea71721755b037955994bf6061bb" + ], + [ + "p", + "c75160732ebd0d6f98238ffc4f87a269841b05f7ef5b008f0a6eb7d8b3235b35" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ] + ] + }, + { + "content": "🚀", + "created_at": 1690062314, + "id": "f2e1535fb76026dc640c6a9ee171637553fa45a7beac7be1d61c59727f421a94", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "94953d6006f0d76f29f5b4b097ffdd3ef3becccad9020b1ef4620a3d567c085c5eda72fa139ebe845219e4be1b33ee54b78735df4ae9eafb563746d717de46ce", + "tags": [ + [ + "e", + "d84e9c154142dfb6327e6003358822b808d1e13f64d6be4182b05b97e4cd56bb" + ], + [ + "p", + "c75160732ebd0d6f98238ffc4f87a269841b05f7ef5b008f0a6eb7d8b3235b35" + ] + ] + }, + { + "content": "That shows that you are following this person", + "created_at": 1690061566, + "id": "f98bf74282c9719d53a89764c270b1338e9d3ee9bc81e48022e7d825bd48a52f", + "kind": 42, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "0af6b4e3005dec7a59105e3c7d038f29c0006930ef934841864e241cb2cac4445e88c2786b7314e6ea4cefa2e172fdc1e8cf2ab2a75831bfd5dffe5e618457cd", + "tags": [ + [ + "e", + "42224859763652914db53052103f0b744df79dfc4efef7e950fc0802fc3df3c5", + "", + "root" + ], + [ + "e", + "370eb5809959295eae9693ee07e1183501363a587f482d8e2fee7044994d97a4" + ], + [ + "p", + "4081035ac927281b3a086d12b6a6aed9f11872a2d82b8f5f1d0706244e84d535" + ] + ] + }, + { + "content": "Those are all from strangers. The spam filter can be disabled in the Security Filters option from the side menu. ", + "created_at": 1690061413, + "id": "8dba54845e5bcee2c3391a34843ac9faefa452961f9cb89c9e70f0233e5c03a0", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "01881e8ad06f625f446c48fdd7ca3ceff54f07c4c52d47c0b0e8c25b896b75879222e9481fe84024d73524d02bcb83eaf67850918202f7ab1e95580034f7d32b", + "tags": [ + [ + "e", + "ff460e6c65591f7c43bca28d26c9d67e01d32743e7b676abfdb54e7378c3b9eb", + "", + "root" + ], + [ + "e", + "f19ab878cd9aed173d5ca6f12fb0036a2bd992091e2f9e13f20887f7442b3413" + ], + [ + "e", + "4daa7e033c8cc3fc6e1e98fce4569c876ffa56897016a92e5e78586bc15a5d59", + "", + "reply" + ], + [ + "p", + "c75160732ebd0d6f98238ffc4f87a269841b05f7ef5b008f0a6eb7d8b3235b35" + ], + [ + "p", + "ae11573ff5b6d1fe250da805e8278b8d7488052a84a3463f110c9cf2e920243a" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "5fd693e61a7969ecf5c11dbf5ce20aedac1cea71721755b037955994bf6061bb" + ] + ] + }, + { + "content": "Yeah, that screen is up for a massive restructuring :) ", + "created_at": 1690060494, + "id": "f19ab878cd9aed173d5ca6f12fb0036a2bd992091e2f9e13f20887f7442b3413", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "db85ee76fb66a3eeee6f8036e283c5fd8974323225a47535014658e08eacdf220d3197997909c80f180b15adb71d4cc0842f5e4fe5280618d0e3d4199f3a8493", + "tags": [ + [ + "e", + "ff460e6c65591f7c43bca28d26c9d67e01d32743e7b676abfdb54e7378c3b9eb", + "", + "root" + ], + [ + "e", + "06ba84837bcda8cc94d9a11f45e2cf0c0998972c4686a17da8b63500be31191e", + "wss://nostr.bitcoiner.social/", + "reply" + ], + [ + "p", + "c75160732ebd0d6f98238ffc4f87a269841b05f7ef5b008f0a6eb7d8b3235b35" + ], + [ + "p", + "ae11573ff5b6d1fe250da805e8278b8d7488052a84a3463f110c9cf2e920243a" + ], + [ + "p", + "c75160732ebd0d6f98238ffc4f87a269841b05f7ef5b008f0a6eb7d8b3235b35" + ], + [ + "p", + "5fd693e61a7969ecf5c11dbf5ce20aedac1cea71721755b037955994bf6061bb" + ] + ] + }, + { + "content": "Yep, but on the private side of those lists. Only the author can see it", + "created_at": 1690056576, + "id": "25e3140b1d838154f06ee1f7dafd52d16b52d38bbf679245f65e3ab889758e7c", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "adfca8fb093f442e66d51bec2a063f22e7a293157063a8637fb191aa7e41a4f0f1a06e126116dae11027406e958e7dc0d98eacc830281e8a5d3298880e51915c", + "tags": [ + [ + "e", + "ff460e6c65591f7c43bca28d26c9d67e01d32743e7b676abfdb54e7378c3b9eb", + "", + "root" + ], + [ + "e", + "aa6f251e957f4ae00f0596359f3185b9579c3602e351bfdb0dd10da1ca3c2c44" + ], + [ + "e", + "acba23d2aae16f161b6489515746febbf3b3d5a581ab581d464e7b93cbcf5c42", + "", + "reply" + ], + [ + "p", + "ae11573ff5b6d1fe250da805e8278b8d7488052a84a3463f110c9cf2e920243a" + ], + [ + "p", + "c75160732ebd0d6f98238ffc4f87a269841b05f7ef5b008f0a6eb7d8b3235b35" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "5fd693e61a7969ecf5c11dbf5ce20aedac1cea71721755b037955994bf6061bb" + ] + ] + }, + { + "content": "👀", + "created_at": 1690055271, + "id": "3be55d0c79a7803d31aa9aabbc72ee943d253fc4bb9b69655d54163b05a2b9df", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "a5f26620c693bbe87a824c60f829a8d9a20afe982224c0e811bcb10c2ad7cea824761da226796d8f53041b25c60e8a7883fda40a8d68770ae826d19d7f8e7c61", + "tags": [ + [ + "e", + "011d95918a2c4fe8c6666784d8229984999126bb24520ef2f3ff2bb799c725fa" + ], + [ + "p", + "5fd693e61a7969ecf5c11dbf5ce20aedac1cea71721755b037955994bf6061bb" + ] + ] + }, + { + "content": "Block just hides the person from your view. It doesn't affect the person at all. Reporting does. Block is just for you. Reporting is when you are warning everyone else ", + "created_at": 1690055267, + "id": "aa6f251e957f4ae00f0596359f3185b9579c3602e351bfdb0dd10da1ca3c2c44", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "ac3e68c9002292121c89b7ada44df8f69b54c9f3562c300d6d40b5a0979d293c907ceae39b266db368eb473064772e21f205152445e43c9141132125a649223f", + "tags": [ + [ + "e", + "ff460e6c65591f7c43bca28d26c9d67e01d32743e7b676abfdb54e7378c3b9eb", + "", + "root" + ], + [ + "e", + "93fec67f101706b4ab832466153df265c75593fbea8e3ef302410710fe833a56" + ], + [ + "e", + "bb953fe6a64516caa9a0c2285a29e5ded168572be6cae1f3daa63bd8321965f9", + "", + "reply" + ], + [ + "p", + "ae11573ff5b6d1fe250da805e8278b8d7488052a84a3463f110c9cf2e920243a" + ], + [ + "p", + "5fd693e61a7969ecf5c11dbf5ce20aedac1cea71721755b037955994bf6061bb" + ], + [ + "p", + "c75160732ebd0d6f98238ffc4f87a269841b05f7ef5b008f0a6eb7d8b3235b35" + ] + ] + }, + { + "content": "🤙", + "created_at": 1690048291, + "id": "6ebe2878b5bca21ab869d71278c4ee25f1249a960b5f2c873d97b0a2d5f154c5", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "8446c68226f4c486ecb40ca82817ae12eaad2ab31dba5985e16adb1e7a6b39830df81a371367e5ba7a10be2627b5b47f4e8fb02d68726b814a74667213bda6a4", + "tags": [ + [ + "e", + "927c65129de519fafecef2bd2cd75785f6843b2da0ba0697d574131f9953782c" + ], + [ + "p", + "1f297398e7abbfade212d7bf1e98bfbf682064a9a5cea4a5f3de49df63330302" + ] + ] + }, + { + "content": "🚀", + "created_at": 1690048258, + "id": "84ec8afc369b68af39a44177b8a7e7a6146642bb3ebae85485eacf2a1195f4c2", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "8be5d9851ee5fc0d0589ef960d1b7f211c6cbed005d06b8693d18f5fcfc1b8949e5353842fa3887de2875b25a528032fc55fcffa43af3df89509a4e28d987bbd", + "tags": [ + [ + "e", + "1de83a4e1cccd7a424ce97f67cc45d7cd2b41766dcca3fd59a59138aa982b9a7" + ], + [ + "p", + "f4db5270bd991b17bea1e6d035f45dee392919c29474bbac10342d223c74e0d0" + ] + ] + }, + { + "content": "🚀", + "created_at": 1690048141, + "id": "8f3ba22a76f92c56e0670f8c47d47d190aef401bfb4699d896d0b575f52ef455", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "bbc4655749a64f7cd973364e9fdd77a94b8900fbe874e140bdc1b7221e7e6a38441aa893ce9c1cdfcbfef91f307233ee6e39aa7e7bff40f5bb782aebef268f38", + "tags": [ + [ + "e", + "661435f046df5f20399924de66c34672eaeaa04f6b5b3c3918a2f74d2c768694" + ], + [ + "p", + "672196e844d54702dc5933bf339d53e1b2641a767264384323957f424fd57b04" + ] + ] + }, + { + "content": "Each client does it's thing ", + "created_at": 1690044425, + "id": "ec0f4b6f3d7f08c2183cc397527b48f47973deba9eec2c77a6cedbf2652cc1bc", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "04e00c840222bbf02da8c15aac1906d2861a123bb4324b84f14e663b3975930d932eb7f85a4d16335a1afcf745577d177b4e81adcd2aa20c14f890eb5e321d89", + "tags": [ + [ + "e", + "e1574ee2757c6443502ad1de2e9bffabe146f6ed0edc15be6cee7fa9725af430", + "", + "root" + ], + [ + "e", + "8ff6ab31d730b8934e6a788be0a686c71ca41985ad87f6d15f3cf2d6ba99ea55" + ], + [ + "e", + "ccc770aa2e496461dd8c328e889e8f4ac3a02e4e2e0496bb083bd280e6bc2266" + ], + [ + "e", + "d4b98b5cdd30cf226fed081467dcd16caf6948b1cd389b2f6d7a1469d36ae864" + ], + [ + "e", + "e1bd0e07369d4fbc9141f767f8d643ef20db243bfbb5f171e1799dbeb33d27de", + "", + "reply" + ], + [ + "p", + "30782a8323b7c98b172c5a2af7206bb8283c655be6ddce11133611a03d5f1177" + ] + ] + }, + { + "content": "Only if you create a list of nsfw authors right now. ", + "created_at": 1690039711, + "id": "04ffa93f7c9c765191f6ff7c33b89870a5521226193b46739d283166e0457493", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "8cfb4c7d3ea59ff087f801e6aac44bdb0f82dbb17241caf80f1896df5237d8398b446729456d71c296c47538661c0ee99403e5ce71c2c1d323e6279097720fbb", + "tags": [ + [ + "e", + "21db8800e3654871004b7653e549d5dc9c03028d05abb1c9417bed4405a47d77", + "", + "root" + ], + [ + "e", + "163d779823264345dc473001dba0987423c4c61438ec2b887695ef3f4d18e636" + ], + [ + "e", + "d9a46441a3df57e1549ad2d2d458fa4e95b73a9dc5034a6212e3a61112d58e92", + "", + "reply" + ], + [ + "p", + "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "e2ccf7cf20403f3f2a4a55b328f0de3be38558a7d5f33632fdaaefc726c1c8eb" + ] + ] + }, + { + "content": "People can just flip the always/never see sensitive content on Amethyst settings. The relay option won't matter. ", + "created_at": 1690038798, + "id": "163d779823264345dc473001dba0987423c4c61438ec2b887695ef3f4d18e636", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "0e835e8b5e6e938dfd5ae6f42a7ae6d593725a42bc57985c729e12f709f5128ea83665b051edaa49aedbc50a4c2a91998481a796b3d75bc3509c068d9b534301", + "tags": [ + [ + "e", + "21db8800e3654871004b7653e549d5dc9c03028d05abb1c9417bed4405a47d77", + "", + "reply" + ], + [ + "p", + "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "e2ccf7cf20403f3f2a4a55b328f0de3be38558a7d5f33632fdaaefc726c1c8eb" + ] + ] + }, + { + "content": "Nip 50 is supposed to be that. But only very few relays implement it. ", + "created_at": 1690038557, + "id": "d4b98b5cdd30cf226fed081467dcd16caf6948b1cd389b2f6d7a1469d36ae864", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "2a6152d146f5bdb7bc10e6e86fceee6ec2010c5ecff107b89f51d2dd577738b727f8fcfe6ede555b6a64799454e9f73c68baca41b9d0c18b55c44ac1949e9470", + "tags": [ + [ + "e", + "e1574ee2757c6443502ad1de2e9bffabe146f6ed0edc15be6cee7fa9725af430", + "", + "root" + ], + [ + "e", + "8ff6ab31d730b8934e6a788be0a686c71ca41985ad87f6d15f3cf2d6ba99ea55" + ], + [ + "e", + "ccc770aa2e496461dd8c328e889e8f4ac3a02e4e2e0496bb083bd280e6bc2266", + "", + "reply" + ], + [ + "p", + "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "d61f3bc5b3eb4400efdae6169a5c17cabf3246b514361de939ce4a1a0da6ef4a" + ], + [ + "p", + "532d830dffe09c13e75e8b145c825718fc12b0003f61d61e9077721c7fff93cb" + ], + [ + "p", + "30782a8323b7c98b172c5a2af7206bb8283c655be6ddce11133611a03d5f1177" + ] + ] + }, + { + "content": "🤙", + "created_at": 1690034791, + "id": "5814e68e1a5f5cae768c0661065449b7bf981162b9e31553740a11749df1a668", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "1bf9fae5ef84654c3b79598a72396072eb59f588151a132deac8948712774ea4c1f790e47075d7bcdeb09a993011896fa0532e69e5efeca9bee32c7f105d559b", + "tags": [ + [ + "e", + "84179e0bcd619efdd068c9a604f4fb3f1ed158c7798a2f7c8af6b4e1c9f1ab5b" + ], + [ + "p", + "31da8e96a0d372f657280a3b678c5c8398b053d0891d458b7c8b0a752737a9e0" + ] + ] + }, + { + "content": "🚀", + "created_at": 1690034686, + "id": "297d8d5ef9a77a74348fe0e490e515e6912e8bda2173a20ce31f6ceca1dc3c90", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "19e249457e3e695dab747a373dced6fbbf625c39d5212e9f020d73f30e39187b66a232d89cf070e1a5e147f012165fe1d5bde4c45ba4314dea4be43259469852", + "tags": [ + [ + "e", + "47e702b7a6c69e43d5113a0eeb49c2bf934611f3cf7eff98e215d798f53f4492" + ], + [ + "p", + "1c6b3be353041dd9e09bb568a4a92344e240b39ef5eb390f5e9e821273f0ae6f" + ] + ] + }, + { + "content": "Did you try specialized search engines like Apache Lucene and so on? Some of them seem to run very well on Android. It might be true for iOS as well. ", + "created_at": 1690034653, + "id": "8ff6ab31d730b8934e6a788be0a686c71ca41985ad87f6d15f3cf2d6ba99ea55", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "d989836b6e209dfec45244ee467ae7a92ad9b6d35b5b31b81884191e81e75a726bc1064901874a463a3f5f63a2c454d00837f5ee668a3eecc4784b923bb3556b", + "tags": [ + [ + "e", + "e1574ee2757c6443502ad1de2e9bffabe146f6ed0edc15be6cee7fa9725af430", + "", + "reply" + ], + [ + "p", + "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245" + ] + ] + }, + { + "content": "Unless you are going to do a massive bounty, bounty hunters will be either professionals with 3-4 hours to devote to the solution or high schoolers with around 10-15 hours of focus. If things feel that they will take longer, they are not going to do it. Neither group will have the time to learn any WoT concepts. \n\nThis means that the more especific you get, the easier the chances of somebody completing it. \n\nHere's a template: get code of server X, add a listener for event kind Y, which runs through the data Z, organizes in this way, calculates a score using this equation, sorts it by score and writes the result on a event kind W and sends it back to the network. You have to give them every detail. ", + "created_at": 1690034428, + "id": "79531a6456980a95d5177bb0904a116b771eef37a374c30621e3fcf6b57edb56", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "1fc94a332ae92f993ef384e0613c2a62101776cb910e69c1a818f0fec165c8cd2af1471f514af41164793ca40345c7fbc2c6fbc260de6838040da9f9efd4f7ae", + "tags": [ + [ + "e", + "2738282425cf2d147fc0d01ff9d95ecd475202399a3805c40e193d2b20244bac", + "", + "root" + ], + [ + "e", + "622cf2369280653f92b3b47b802feb93038a9db3d1253cbb1af23303fde84c72" + ], + [ + "e", + "084cb0d0d8e7cb6ee7cc3b4e0c14e1746c6192a329e5e644cf2aa42b0702dc87", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "e5272de914bd301755c439b88e6959a43c9d2664831f093c51e9c799a16a102f" + ] + ] + }, + { + "content": "Too many options. Keep it simple. Focus in one VERY simple use case. Fix ins and outs and let them fill the middle. Remove all the jargon. Otherwise it will just be too much for anyone to be interested. ", + "created_at": 1690030365, + "id": "622cf2369280653f92b3b47b802feb93038a9db3d1253cbb1af23303fde84c72", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "a67e5db83686746310d721b2896cd14bd36343010cdd4b1e295e38e9b3f7bdd461904912e07f352cfe0bcf34b44f242edfd28cd14e7dc4b1e4bcf6fd1001e7a1", + "tags": [ + [ + "e", + "2738282425cf2d147fc0d01ff9d95ecd475202399a3805c40e193d2b20244bac", + "", + "root" + ], + [ + "e", + "311df23c765f2c44322acd39b0838474cd6c911bdbbe5133561a63d7b81c8245" + ], + [ + "e", + "0fc743840d438b7ba2472e9a4c922a72f38ad9822f05e885e48dd5a70c9de141", + "", + "reply" + ], + [ + "p", + "e5272de914bd301755c439b88e6959a43c9d2664831f093c51e9c799a16a102f" + ] + ] + }, + { + "content": "List of posts or other people? If it is people, you can create/update nip 51 lists and Amethyst would offer then as top bar feed options automatically.", + "created_at": 1690029264, + "id": "311df23c765f2c44322acd39b0838474cd6c911bdbbe5133561a63d7b81c8245", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "a4fbeb9f8b2f90e3bf578cb6ee7d3e144dee810ed20210a9ac862db0ad501829088fbccf5893a4d9052a6ecc6fb7577e6614d3472e29a742958e3b7fc1b66106", + "tags": [ + [ + "e", + "2738282425cf2d147fc0d01ff9d95ecd475202399a3805c40e193d2b20244bac", + "", + "root" + ], + [ + "e", + "c936aea32b162c762c3b26ad7ff303869cd018a55804c28f5486c4545c37b55d" + ], + [ + "e", + "fc9a175bbd853076754d9ea1a3272e089875ded5c03b1d3b7d11e4c567ad1364", + "", + "reply" + ], + [ + "p", + "ba94849433a724544ab6794f79700bc980613aa93bc8c872a59c4f7fb85d36a5" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "89e14be49ed0073da83b678279cd29ba5ad86cf000b6a3d1a4c3dc4aa4fdd02c" + ], + [ + "p", + "648c0f5302c75f38382a4d2c85a482b927cc61b2828a0794e36c6cc796de86a6" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "e5272de914bd301755c439b88e6959a43c9d2664831f093c51e9c799a16a102f" + ] + ] + }, + { + "content": "", + "created_at": 1690028553, + "id": "f4c3fa3b4e18028b986728b70fbd4f24747b28840ac2dc880fe128552332c37f", + "kind": 1063, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "3b7d8c66c8c7c8db6c12e274e455e072b9964c92915bf51421e421a61fdd0eb7822705a251f6a1faee7c02462bff739d18825f4c06cf23feb231336e0c3417e8", + "tags": [ + [ + "url", + "http://nostrcheck.me/media/vitorpamplona/nostrcheck.me_77519b031bb3bfe7956b501a01197a9508f376697f378577.webp" + ], + [ + "m", + "image/jpeg" + ], + [ + "x", + "667c8409013988802a168043034a06d4501719aa27ab6ebbc4b825db417f281c" + ], + [ + "size", + "26866" + ], + [ + "dim", + "510x640" + ], + [ + "blurhash", + "_BRfkB%M~qay-;xuofxuM{ayRjj[j[t7_3RjM{xuM{ayRj-;j[RjWBWBj[Rj4nt7%MWBxuRjxuWBt7ofRjRjj[fQ?bM{RjofRjofWBt7%MM{WBt7RjM{-;ayWBRjayWBt7" + ] + ] + }, + { + "content": "", + "created_at": 1690028054, + "id": "ab3df16710d9ccc53c08e9b54232ef0b378e3eaadf0acd0f7649800fd4787857", + "kind": 1063, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "3cb3fc0059720310a950543e3f14d84830b3b8ab748e7f29b6d4d8e4ee4abb60858056bcc1d438a2a549da236f83e78cf52ef8488389f4cdb3371c4e1e63c78c", + "tags": [ + [ + "url", + "http://nostrcheck.me/media/vitorpamplona/nostrcheck.me_4b1b9cad209ed9ce79cec1bea6c76836bef273d9f26ea42c.webp" + ], + [ + "m", + "image/jpeg" + ], + [ + "x", + "d9af8e835f0fe1024bebea6efd45348c6abecc2cd6cb12a5c217061f03cccb44" + ], + [ + "size", + "71462" + ], + [ + "dim", + "700x804" + ], + [ + "blurhash", + "{nK_5qWBogay-;t7%MWB_Naxjsa}RjWBRjof?cWBt7oeM{fQayoL%MofRjWBofj[ayayWAjtofj[ayjZWVayIUoeayWBofWVj[ofM{WBofoLayj[jtayWBayj[j]ayf6j[j[t7oeayayazj[j?WC" + ] + ] + }, + { + "content": "⚠️", + "created_at": 1690027967, + "id": "b69a97ffa74a84b2cd1d7ba53f6b02d4b84024cf32de1c3df6eb7be819ee90f5", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "f50ba3ebf9dc452d8ea8862b7602c2837f96b23515caa05222353f82f2c30228f74d942121ab4a1acca3ee2304c501f5d92e1fedf77d0122614f59f40f8f68cb", + "tags": [ + [ + "e", + "2583ec8975b63ddd5c373d2c8bc7bba419362b8c9483945a78214edea52227c7" + ], + [ + "p", + "4796eb254645a3b0db24e77dd7bae72eadfe18fc4c24f2bc6c4e658c4fec4ed4" + ] + ] + }, + { + "content": "", + "created_at": 1690027967, + "id": "08c3212fa15443ee5b0b7c71e0192ec47e79deababfdd5637f7eac30d9d1b387", + "kind": 1984, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "e48a9824005948ca96d4b16696a0ea75e255ba1f44a7ba9abf823b14992faab2b57d58b8198b36a3598ea075f2c5d1b38188dc3c4f90ccb8f84a636c1c87ce7d", + "tags": [ + [ + "e", + "2583ec8975b63ddd5c373d2c8bc7bba419362b8c9483945a78214edea52227c7", + "spam" + ], + [ + "p", + "4796eb254645a3b0db24e77dd7bae72eadfe18fc4c24f2bc6c4e658c4fec4ed4", + "spam" + ] + ] + }, + { + "content": "Have you built a data vending machine for that yet? https://github.com/nostr-protocol/nips/blob/67e950a2009e81df1b8c91b0a2ade0596e83f168/vending-machine.md", + "created_at": 1690027938, + "id": "c936aea32b162c762c3b26ad7ff303869cd018a55804c28f5486c4545c37b55d", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "0a25b1c1855391a31be333daeaea31b0654cf804f0c620b3c44651ab7d59d48816fbd26bd519e0a68ac558d4b9233931f0f20624e91e1291220cda94d67f8c28", + "tags": [ + [ + "e", + "2738282425cf2d147fc0d01ff9d95ecd475202399a3805c40e193d2b20244bac", + "", + "root" + ], + [ + "e", + "467b16aa0975ae962b9322438448a5b94d28c9677aa0bf783f0d5a97c85238bb" + ], + [ + "e", + "8ac9aea5873049675b1340276158bd332f955230c7eb3c606a160bb15dad91df", + "", + "reply" + ], + [ + "p", + "ba94849433a724544ab6794f79700bc980613aa93bc8c872a59c4f7fb85d36a5" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "89e14be49ed0073da83b678279cd29ba5ad86cf000b6a3d1a4c3dc4aa4fdd02c" + ], + [ + "p", + "648c0f5302c75f38382a4d2c85a482b927cc61b2828a0794e36c6cc796de86a6" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "e5272de914bd301755c439b88e6959a43c9d2664831f093c51e9c799a16a102f" + ], + [ + "r", + "https://github.com/nostr-protocol/nips/blob/67e950a2009e81df1b8c91b0a2ade0596e83f168/vending-machine.md" + ] + ] + }, + { + "content": "Yep, that makes a lot more sense :) ", + "created_at": 1690027857, + "id": "d8c51aa8ff8e880bfc229b556b762a8322d25a0273bf138f55a3bb5a4e6f3683", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "52fdfead0a8c473b7a467a820cfc19f0214f7dcce763223e0c74b35e627c97ae0f86875348592b551f006a8b0ef386d9c5f51c26330a6bd1f708ad7c14244fb4", + "tags": [ + [ + "e", + "2738282425cf2d147fc0d01ff9d95ecd475202399a3805c40e193d2b20244bac", + "", + "root" + ], + [ + "e", + "9a88b1aa5e514e33a721a8e036e1e49654b31133f8922d27e9bc71d0f463063e" + ], + [ + "e", + "1326e784c89aae0d495b933710689757ffd307e4193e7de396b04e1b49c194a4", + "", + "reply" + ], + [ + "p", + "ba94849433a724544ab6794f79700bc980613aa93bc8c872a59c4f7fb85d36a5" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "89e14be49ed0073da83b678279cd29ba5ad86cf000b6a3d1a4c3dc4aa4fdd02c" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d" + ], + [ + "p", + "fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52" + ] + ] + }, + { + "content": "", + "created_at": 1690027511, + "id": "e97c4db1ec0cf8701dae216a0883239fb870ef8e477f0f83c9935c8225d0186b", + "kind": 1063, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "70803168e9f3a53c4f05ddb26ed8d68d716680ae5e77b1c41efc732abce1541adfc5d01b263d868169a0ee5791d69db982944db8ecc48c4f1ffbc8f75b2ff31b", + "tags": [ + [ + "url", + "http://nostrcheck.me/media/vitorpamplona/nostrcheck.me_fe2f3b78ab59248cd0e65015d39ab827b60f4bfbc1e91162.mp4" + ], + [ + "m", + "video/mp4" + ], + [ + "x", + "7e9ed8613fb4d077afded5b131cc9238c3e5e9737e85ea697028ee0acf9cd3c5" + ], + [ + "size", + "393081" + ] + ] + }, + { + "content": "No, the kinds to classify nip89s apps by. Right now it's only by event kind. We need to do “I use DVM npub1XX for kind:68001:job-req-feed-generation\"\n\nSo, you can filter nip89 apps not only by kind, but by each individual type job being offered. ", + "created_at": 1690027384, + "id": "9a88b1aa5e514e33a721a8e036e1e49654b31133f8922d27e9bc71d0f463063e", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "95dd34d7ff940ad5e92d0fe11ceac901494d5f62eb6c14f3cd53ed3872a46978a4e92859ee09645bee1c2bf5381ad039b437345c93bbdf18bc12412a3a929ef4", + "tags": [ + [ + "e", + "2738282425cf2d147fc0d01ff9d95ecd475202399a3805c40e193d2b20244bac", + "", + "root" + ], + [ + "e", + "619c69ba1e8343d87ccf36260954a45bb52b8210c5facfd87861a06fcf5561b8" + ], + [ + "e", + "71bd71e53f0e857bf5915a181ffae08b26557158690170f32c3976d20727b2b3", + "", + "reply" + ], + [ + "p", + "ba94849433a724544ab6794f79700bc980613aa93bc8c872a59c4f7fb85d36a5" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "89e14be49ed0073da83b678279cd29ba5ad86cf000b6a3d1a4c3dc4aa4fdd02c" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52" + ] + ] + }, + { + "content": "Sorry. We haven't optimized for old phones yet :( ", + "created_at": 1690027143, + "id": "f469473308fa5e222d3e5358bdd2eaf6b1c4c135f4ab4bf60dd6cd1c8ebfa7e2", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "7dbc9e95c3ccd98ad00dc84fb50bb78fd3a88e1d280c6fda72f4cc7155755aea71b377445144af8017f1c03d98908d67e3d46c2800368354c67c95ddc2519f5c", + "tags": [ + [ + "e", + "df9b11fd6029e3b4c27bfb5cb59aa152442a03d57bc5b759684263864ae729af", + "", + "root" + ], + [ + "e", + "3e646fa6294a2a87e6ccd619c39a50974d6c70216eae79d700bca6c46179a389", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "43d140f61e46792199dea8a8ab4634dd21f1aedaaa4fbd29add506f8029f1265" + ] + ] + }, + { + "content": "Eventually, yes. But specialized apps like those are always going to be better, simpler, faster in their specialization than Amethyst can be. ", + "created_at": 1690027096, + "id": "ae01161cfb1508092b9b4d9ac9a16809b354b2753490c870585da6b001e979f2", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "d25cd417e0cb9917d472a3d5707ff031c70654486ee79457496103af389f3434a530a2f2f3979ae36501ef81d160d3babb221f9aa98056b0bbe8d612be98d1c6", + "tags": [ + [ + "e", + "3d995935ead0e9a10af53b465a2c2c0d1e309d5b9cc563e8c0d6f0c569bb8c97", + "", + "root" + ], + [ + "e", + "540605b2e4ab1cadca0abe9806e96c06b643de78e34e1275133cf1dfb3817cbc" + ], + [ + "e", + "e79e452b991dc561d99eb33f278dcc26e0cb105eaf40eb9a3aae87ae62db315e" + ], + [ + "e", + "50719f470bc924b46617433b06dd67aeba0f9b19bcc810e89e5428a7118f81ee" + ], + [ + "e", + "3b992f41a24e66a78cb3c5779edd18c300a6a8a04afc722f8a9e6efbddac8f23" + ], + [ + "e", + "5d4e39e25d2453b8d42b2093d82ca99da9c65f6e8d56f3b97fee4e3b271299b3", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "5131f3572c960cfa0b5d262687565fe53a98c8d35bbfaa2daf029bc3f6eaec88" + ] + ] + }, + { + "content": "As long as there is a way to break further down from event kind, it should work. ", + "created_at": 1690026998, + "id": "619c69ba1e8343d87ccf36260954a45bb52b8210c5facfd87861a06fcf5561b8", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "f9a77aa366699537f4e52d284bf4608c3959115b0ae2804adc47f69b39298385857f94c077c01d3a0e646d0f003c9104516f451d71af3a90ee3bb72ad6f5994e", + "tags": [ + [ + "e", + "2738282425cf2d147fc0d01ff9d95ecd475202399a3805c40e193d2b20244bac", + "", + "root" + ], + [ + "e", + "1fc961d0a4f87cd225eef96695507f5a42aa446620090c4841faa4a84c22751b" + ], + [ + "e", + "d2c109bbcdb0ac2b0f6166b367d164a9d96e72605bd4f5c86dc31fca0be7ff1d", + "", + "reply" + ], + [ + "p", + "ba94849433a724544ab6794f79700bc980613aa93bc8c872a59c4f7fb85d36a5" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "89e14be49ed0073da83b678279cd29ba5ad86cf000b6a3d1a4c3dc4aa4fdd02c" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52" + ] + ] + }, + { + "content": "🤙", + "created_at": 1690026846, + "id": "e799c69de8fa38f99997e48dbc2b5d203a841bcf1a20de848456c38d1199d29e", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "f705dc055fa87d21e15579f6691d12cbe9270b1682edb81f0861780fbb09c4fddb92cc20659d2214db6b7436830149eefad724defbdb56a55abc24d143714326", + "tags": [ + [ + "e", + "3365db2747c4f5ee69b30cccf7c20eac703d2c61f2f4e0b1bdb6973ba211a037" + ], + [ + "p", + "4ea28e364020611166ad3f826fd476c05b2c7852fe3d691a2c43381ebe704d0a" + ] + ] + }, + { + "content": "Yep, DVMs the user can subscribe to are way better. But we need to figure out how to log down which DVMs the use wants to use for each task. ", + "created_at": 1690026543, + "id": "1fc961d0a4f87cd225eef96695507f5a42aa446620090c4841faa4a84c22751b", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "7fbc9ab6433ebe48f29bf9c4cc3e6e48ad1fc057cfa8a292600a12ca4e95c14022770b7d679ebd248663b949b7cb1408862715e395082601232c11f462175b60", + "tags": [ + [ + "e", + "2738282425cf2d147fc0d01ff9d95ecd475202399a3805c40e193d2b20244bac", + "", + "root" + ], + [ + "e", + "16ccafb23b3ea34d29a5ed546e30e21c29457458b389e59010d3f577e83937e5" + ], + [ + "e", + "9ed61ee9d569308861842675798444bd50f133a63bdb07deb6345be9efefe73d", + "", + "reply" + ], + [ + "p", + "ba94849433a724544ab6794f79700bc980613aa93bc8c872a59c4f7fb85d36a5" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "89e14be49ed0073da83b678279cd29ba5ad86cf000b6a3d1a4c3dc4aa4fdd02c" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52" + ] + ] + }, + { + "content": "Create lists of people on Listr.lol or highlighter.com \n\nThose appear in your amethyst's top bar as options. ", + "created_at": 1690026476, + "id": "3b992f41a24e66a78cb3c5779edd18c300a6a8a04afc722f8a9e6efbddac8f23", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "fbbf7043f61a63c1bee4f3d986fe6e6b9a58a9225cce97fc45acba1e6ddebf3310daeab1cd121e020f35d015830c843e02d8d0006abcf63d785d347cf4f1e923", + "tags": [ + [ + "e", + "3d995935ead0e9a10af53b465a2c2c0d1e309d5b9cc563e8c0d6f0c569bb8c97", + "", + "root" + ], + [ + "e", + "540605b2e4ab1cadca0abe9806e96c06b643de78e34e1275133cf1dfb3817cbc" + ], + [ + "e", + "e79e452b991dc561d99eb33f278dcc26e0cb105eaf40eb9a3aae87ae62db315e" + ], + [ + "e", + "50719f470bc924b46617433b06dd67aeba0f9b19bcc810e89e5428a7118f81ee", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "5131f3572c960cfa0b5d262687565fe53a98c8d35bbfaa2daf029bc3f6eaec88" + ], + [ + "r", + "Listr.lol" + ], + [ + "r", + "highlighter.com" + ] + ] + }, + { + "content": "Yep, I don't think it's good. It just reinforces large accounts. We are not here to centralize everything again. :) ", + "created_at": 1690026412, + "id": "467b16aa0975ae962b9322438448a5b94d28c9677aa0bf783f0d5a97c85238bb", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "356c955f44848aae2f188efa7a26c2f6f0fcb3784c22ded65b992d0a4b26dc967a818b890cd8e7c8228136c25589e9ecf4f5fcac766c53e339b96eda42b805bd", + "tags": [ + [ + "e", + "2738282425cf2d147fc0d01ff9d95ecd475202399a3805c40e193d2b20244bac", + "", + "root" + ], + [ + "e", + "088c6a88368f2b7c0bcac5be688b8a493161add325c32742ac2e37439dcae5cf" + ], + [ + "e", + "d4bb741326defb5f62196196c4fdc6c899cf9f2be20de1de1a6c6dc9cf131e03" + ], + [ + "e", + "16ccafb23b3ea34d29a5ed546e30e21c29457458b389e59010d3f577e83937e5" + ], + [ + "e", + "670401ddf5959ddb5bbc72451d31e36d526d1879280dd3bb89321dd5fb46164d", + "", + "reply" + ], + [ + "p", + "ba94849433a724544ab6794f79700bc980613aa93bc8c872a59c4f7fb85d36a5" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "89e14be49ed0073da83b678279cd29ba5ad86cf000b6a3d1a4c3dc4aa4fdd02c" + ], + [ + "p", + "648c0f5302c75f38382a4d2c85a482b927cc61b2828a0794e36c6cc796de86a6" + ] + ] + }, + { + "content": "We haven't yet figure out a way to make trending actually work. Right now all implementations look like Netflix movie algorithms that just bring a bunch of stuff you don't care and the things you care are harder to find :( ", + "created_at": 1690025979, + "id": "16ccafb23b3ea34d29a5ed546e30e21c29457458b389e59010d3f577e83937e5", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "644876edca3832f919ba921368d97a48ff95c63881825ee7c8bba53ea8d7016395b57c83a41f097b095e378ccb0bf2880c3af4c2b7ce3abfeb10b75f03743f7c", + "tags": [ + [ + "e", + "2738282425cf2d147fc0d01ff9d95ecd475202399a3805c40e193d2b20244bac", + "", + "root" + ], + [ + "e", + "088c6a88368f2b7c0bcac5be688b8a493161add325c32742ac2e37439dcae5cf" + ], + [ + "e", + "d4bb741326defb5f62196196c4fdc6c899cf9f2be20de1de1a6c6dc9cf131e03", + "", + "reply" + ], + [ + "p", + "ba94849433a724544ab6794f79700bc980613aa93bc8c872a59c4f7fb85d36a5" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "89e14be49ed0073da83b678279cd29ba5ad86cf000b6a3d1a4c3dc4aa4fdd02c" + ] + ] + }, + { + "content": "🤔", + "created_at": 1690025791, + "id": "4e750cceca0a0377fd97bc3fbe02329afac6753be8273d4051091d8b2cea2b87", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "1e9091ee1f8df139d36d948c50f3a28df024f52fb4736eaa013304c17a92a915a214a7f8e5e0ae1ee05491510be63ea037f7bf31776a3e18d94c4bf2bb89e28e", + "tags": [ + [ + "e", + "ac3798231044db275288061a933064011544192f3b867644a1952ea76bbfbf23" + ], + [ + "p", + "c4f5e7a75a8ce3683d529cff06368439c529e5243c6b125ba68789198856cac7" + ] + ] + }, + { + "content": "Put it on a list and access it only when you want :) ", + "created_at": 1690025656, + "id": "e79e452b991dc561d99eb33f278dcc26e0cb105eaf40eb9a3aae87ae62db315e", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "768d7cf56d649dffba187a7d8e04f8f2f7aec4850277189d4025da4c37d741d4e05007393b775ced3e335747ada23ecce57d43a0d124c0462aeda070c274a2b5", + "tags": [ + [ + "e", + "3d995935ead0e9a10af53b465a2c2c0d1e309d5b9cc563e8c0d6f0c569bb8c97", + "", + "root" + ], + [ + "e", + "540605b2e4ab1cadca0abe9806e96c06b643de78e34e1275133cf1dfb3817cbc", + "", + "reply" + ], + [ + "p", + "50d94fc2d8580c682b071a542f8b1e31a200b0508bab95a33bef0855df281d63" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "5131f3572c960cfa0b5d262687565fe53a98c8d35bbfaa2daf029bc3f6eaec88" + ] + ] + }, + { + "content": "🤙", + "created_at": 1690024223, + "id": "817f132a4daf21a41f30096ffdc97fddfd4681f9e66e9decc1548a7e5ad41d85", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "d5b6fe39efad7254f37894035bc52edc508bd97911e53dbae69ad058644fc0f35100ac36598c2118fd2288178f3b1ac55e4881cd7ab016a5907d40b6bd296fa9", + "tags": [ + [ + "e", + "3e0242a1e3afac94f6ec5f72da83429287d8b726c04223342fc738e151a616a6" + ], + [ + "p", + "7ab1d3867722b4cbabb6c8503ab3f9265daa4f82e228cefe302621f4e5ee1f1c" + ] + ] + }, + { + "content": "🤙", + "created_at": 1690024192, + "id": "1c467891446567ff979de8c0aa3900c1f6d125131f119df522feff8929afcd86", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "8e75d7e513399ddaf8800926b1c63554b96539ca7df4fcbb3e53240e1a4f8d359f1597d5af157626d3c777d4b95bd2a5fe9fe107d0adec8fcec0dcfbeeee166b", + "tags": [ + [ + "e", + "c581efd5a4d700022e040db861eecc0f5167539cb19f57b7bd1417b2360aa165" + ], + [ + "p", + "7c1521d55a53580a05990c6cc4bae09c9822169b6e544b1ee47005a6c3e9e9be" + ] + ] + }, + { + "content": "Amethyst doesn't have a local db yet :) it's all in memory. But search is only used to find new profiles when you click the search button. ", + "created_at": 1689999260, + "id": "c1309e7769630260fdfa5ff25858f3416eab72e78c8a80b9ecf33244b62b3848", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "904e705f75a25b9840589fbe86455b5929d6e1755a43b35e24ff339bdc7edd578e8c4e9580c6134ed86bb8af78fab6503ce4085342dc0e6244993d5e157bbc8a", + "tags": [ + [ + "e", + "dca4527bd76908cd8071fa80d9241b552c3c2348719bfa42c6bd8137a568e9d3", + "", + "root" + ], + [ + "e", + "a1c52b61bd6c9096a98ff51ff63e1cf54e868f481eea2a503f6fe3e806946d43" + ], + [ + "e", + "a1461580c93fc038bfad8c9a457b6e4156d4217e0d9f3b7f95e51ba82ce95c2b", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "7cc328a08ddb2afdf9f9be77beff4c83489ff979721827d628a542f32a247c0e" + ] + ] + }, + { + "content": "nostr:nevent1qqst4hmuwdt88ru05r99mqlf9e0a5c76hus738ns6p90d8s865mgqccpr4mhxue69uhkummnw3ezucnfw33k76twv4ezuum0vd5kzmp0qgszp55czrt2t7ftq3dduqhthtwfqdkhg8xxs6cqg9wy9dprdlj26tcrqsqqqpp8z68rfc", + "created_at": 1689998418, + "id": "2529de5d4177178cd1bc495ab3c9fd47728f1a8d3f2e33615918d57a33d88e77", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "6545f19adb258d6fa5cd2ad10b648c15f0eb5c2ef12f19c0aff96e4afcf04f6a2c1cdb9f822a5ced89a62acc54c755b1356c6ef55b5b131c98f15628a327b3fd", + "tags": [ + [ + "e", + "745b854705717741bafb74d36e968e6dc120aa8a6abae7d6934abbbc4b0c0c11", + "", + "reply" + ], + [ + "e", + "badf7c7356738f8fa0ca5d83e92e5fda63dabf21e89e70d04af69e07d5368063", + "", + "mention" + ], + [ + "p", + "ee6ea13ab9fe5c4a68eaf9b1a34fe014a66b40117c50ee2a614f4cda959b6e74" + ], + [ + "p", + "20d29810d6a5f92b045ade02ebbadc9036d741cc686b00415c42b4236fe4ad2f", + "", + "mention" + ] + ] + }, + { + "content": "Yep. Let's hope more relays enable search. Right now just nostr.band and nostr.wine do. Without them nothing works :( ", + "created_at": 1689998365, + "id": "a1c52b61bd6c9096a98ff51ff63e1cf54e868f481eea2a503f6fe3e806946d43", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "6dfead703845bf105b7908a6007de6cf0ffb0ccd62d371930e2022dfe636e7c8d12c82c8370073b592c96ee4c08b89dffc1e310778cebe4d867bb5422aba4b24", + "tags": [ + [ + "e", + "dca4527bd76908cd8071fa80d9241b552c3c2348719bfa42c6bd8137a568e9d3", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "7cc328a08ddb2afdf9f9be77beff4c83489ff979721827d628a542f32a247c0e" + ], + [ + "r", + "nostr.band" + ], + [ + "r", + "nostr.wine" + ] + ] + }, + { + "content": "", + "created_at": 1689997153, + "id": "cb3c8ab48e449fd9f312bcd3dfc1706dd4dfb997853b8b6f8006c06603654c56", + "kind": 1063, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "1905563b8b682aea269c4cfb2a247cfc8ca4b2162f24a68ffa20b94d83d8ed54fea47d8cd94fde821d84b10ae6dd5ac1eeff31f062b4e12631b316571c82f3c1", + "tags": [ + [ + "url", + "http://nostrcheck.me/media/vitorpamplona/nostrcheck.me_e64adb648e5ff82dbcb1f4df76d3378c58b7a60a24738a3d.mp4" + ], + [ + "m", + "video/mp4" + ], + [ + "x", + "592e1b0c982a4dae025e35e6d08bb4df41aa330c542fefd1fc942a6cc605ded4" + ], + [ + "size", + "974483" + ] + ] + }, + { + "content": "", + "created_at": 1689997049, + "id": "07846fa8245c0ddb620debcb3fd735cc3a8df6b4a010e97e211eee20d58c6bbc", + "kind": 1065, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "61baf4dc3e84de957caf11deb63076de6db3bc28ea9dc1472b4e6ebfcf69be9d53a5c0533040585a255418706fd113e31e1ec847de56ebbae231fc04e172f42c", + "tags": [ + [ + "e", + "782621cb24a3a8ab85f31c15774bf1a78b4c8446430515a702976bd7a416d5af" + ], + [ + "m", + "image/jpeg" + ], + [ + "x", + "ad80abee20daa3a220763272a7e3090242188f71833edf970c42121a4e6d5504" + ], + [ + "size", + "36172" + ], + [ + "dim", + "554x554" + ], + [ + "blurhash", + "UUOOIzkC}@WU9]W:ELoM$+bIj]jE=}jZs,bI" + ] + ] + }, + { + "content": "🤙", + "created_at": 1689996772, + "id": "c8df2b4bed40245191d8703bcacfdff60d18b79f9571a0fb4a83f3d7a206d019", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "e83d039b5624f2a17914037b46727697ea63c64b54de84b66a14e996784f2d818349ef213368ef2b6c8d7e1202dd977235fb19bba376e0ccc173d89ed1cf80d8", + "tags": [ + [ + "e", + "badf7c7356738f8fa0ca5d83e92e5fda63dabf21e89e70d04af69e07d5368063" + ], + [ + "p", + "20d29810d6a5f92b045ade02ebbadc9036d741cc686b00415c42b4236fe4ad2f" + ] + ] + }, + { + "content": "", + "created_at": 1689996403, + "id": "e9f0ea803d47d2a4088a85160ec5e3b460d4d7ce80d8005706b43a670c9ec8ff", + "kind": 1063, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "874d491cca43ac519c2fdc2b28203609b0d66f07a950bba18a72b51577237131ea131c22049753960f20a28cad8dd8bceca7da5f16d398f0469850c06b031c7b", + "tags": [ + [ + "url", + "http://nostrcheck.me/media/vitorpamplona/nostrcheck.me_c69a040d82b8085ee667b5c439f0ede384f3f9fcf758860c.mp4" + ], + [ + "m", + "video/mp4" + ], + [ + "x", + "b9af7ba10a32bd5ba80b375fe461724991f0c36216f175a2c68a8a9645d89e1e" + ], + [ + "size", + "1912315" + ] + ] + }, + { + "content": "", + "created_at": 1689996260, + "id": "83218f8e706f092398a99a458a64b847e1cd39d0eaf1813f20fcae34663f72e3", + "kind": 1063, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "188e44752870fcb55594f0f5465fb17a6ff248aed5717b9b66c89ce69cb82f44ee55853c6798e828ffa3163ca11579395ad84374e71217b0ee0a481efcdf3b9a", + "tags": [ + [ + "url", + "http://nostrcheck.me/media/vitorpamplona/nostrcheck.me_d130b03e7f6a25183e930a37f1b35f5763896067d60b79ca.mp4" + ], + [ + "m", + "video/mp4" + ], + [ + "x", + "f3e8510dba57c20c8f3e00910cfa27bf660994d04d82f255f7822abb0e023cba" + ], + [ + "size", + "854488" + ] + ] + }, + { + "content": "", + "created_at": 1689994614, + "id": "5d9e383311d5e2da43c252e5029a311b43ad63f5a97a79b47f96b3654e419981", + "kind": 1063, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "fbebdff8e5077364ecaa8c6e9e71a743990b0ba12db0d346f0abdecded0abf65c3ab8d2be65da0ac6ab67788f93fd35e2ed3dbc950d07b6518212cca06e1ad6c", + "tags": [ + [ + "url", + "http://nostrcheck.me/media/vitorpamplona/nostrcheck.me_b6b4f0f16fc4cde884220091e8f43cbfa1ca1c9b7038fcf3.mp4" + ], + [ + "m", + "video/mp4" + ], + [ + "x", + "baa579aa8bd19a0c2bdc6d091012b67db89526eadf454cb5e5ee3863fc25bb51" + ], + [ + "size", + "14207658" + ] + ] + }, + { + "content": "🤙", + "created_at": 1689992751, + "id": "6227574060cd0e32ec7f0e6c4c1bd59a049db49b88eb4a7fb72675c76fd3314e", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "ab33e1e1b8399b9e0030c578c2a79f2468bc7bc8d0b5279abbf80c7fa23b05b89dae373f68a98fdbd2de081e8b27cdedf07bba8195b2e366f0c2f032446055ea", + "tags": [ + [ + "e", + "5fffbe60a6107d0492b0ad0a18586957472ec472762b931e3fdd2b5f5dd38ec9" + ], + [ + "p", + "7f14df43e1782029254e2b6aed560440b0d1d202ab4855fc70f25584d8d4d732" + ] + ] + }, + { + "content": "🤙", + "created_at": 1689992748, + "id": "bcd6ffd307fb1497422afe873c12d021df5f825039411aaaafe9c43700db972c", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "c43c4182dc8c06306f094c83e18f08ff54b0fe3964bddbca35ac66a1b73d2d4ff16891c37fc08f5e0528e4a157ea246de17028b6a638383b9e87a7cd38c33474", + "tags": [ + [ + "e", + "411f4bcd1a717a1b8266a47e646f27838f349c773b55298fb264a749dfd945d5" + ], + [ + "p", + "7f14df43e1782029254e2b6aed560440b0d1d202ab4855fc70f25584d8d4d732" + ] + ] + }, + { + "content": "🤙", + "created_at": 1689985609, + "id": "3e8962e2fe9a240531d3971d70f40f87e3a3fd6ded501631ab95aee313ca6eeb", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "1e1ce8acb6e9ec11bea55e6ca8a2cbcff2674d28a6336eda6d1c3b2e761670b10114c6b5f6d86cb54f2cb294b9ec6b92c2dfc024f183e72cf23d644437d2149a", + "tags": [ + [ + "e", + "fc2b936584da862e4926d85437accb5412cfe9c983edd517b88cddfdbf618954" + ], + [ + "p", + "20d29810d6a5f92b045ade02ebbadc9036d741cc686b00415c42b4236fe4ad2f" + ] + ] + }, + { + "content": "🤙", + "created_at": 1689985596, + "id": "ae40b833935fa4844c9fc7e62622e653a67beff93d02091f0a4dd529e75e03a0", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "e2a520fe8e0424d0c2310d1e9d1aa827f338348105d85d295b6e3165324da8ab2db219fdaf4c6851302839658ae077b654e9be02da34a8e6c0fd499adc482660", + "tags": [ + [ + "e", + "e91e975b8da19b4c092ac7581734e2168d45fe73e4b8f2049aab3788fa35ae54" + ], + [ + "p", + "4ea28e364020611166ad3f826fd476c05b2c7852fe3d691a2c43381ebe704d0a" + ] + ] + }, + { + "content": "🚀", + "created_at": 1689984810, + "id": "f4bcad31c092a0042bb445f413c593e320b6a6c26941fbe106ca111ab52d7166", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "04b17cedec6de4e85b759eef2049da4492e1961106573f1e61bb4b79accf7b183ca20744e039c40939a3f7c8a3fd4e003783b68cad554f0f1795dafb283841e6", + "tags": [ + [ + "e", + "d269571c1d2ee39df436b3890d75373fededa88f48155df92f0469f80e69fd93" + ], + [ + "p", + "c6f7077f1699d50cf92a9652bfebffac05fc6842b9ee391089d959b8ad5d48fd" + ] + ] + }, + { + "content": "I am very happy with that idea. I think we should do this. ", + "created_at": 1689983150, + "id": "8bbfbb3a847fc22fd3446b68a7428fd1071d4e3b17a85502f2c9d7dd21471925", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "c0e8227f5f211a1bd932742635c919f2f2d7cf749c15f069d7977c312f5bc952765cd5b5076a454b5f0acaa1f48f31c5c22a1cd5693c1258fa24d9b8b9780efb", + "tags": [ + [ + "e", + "f7ab0a2197676c2da1af737bb1c09e4c750b6ebad3223acf72c3648372540755", + "", + "root" + ], + [ + "e", + "7523b31c7ebf3c7230943b33076e7afcfafd69c10aa7deca5c455cbd41bcfa67", + "", + "reply" + ], + [ + "p", + "3f770d65d3a764a9c5cb503ae123e62ec7598ad035d836e2a810f3877a745b24" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322" + ] + ] + }, + { + "content": "I have missed it myself. I am not sure how to make it more clear 🤔 \n\nI am just happy it's not a bug. ", + "created_at": 1689983110, + "id": "766c8ad5a213902deb33c7177b3a83559e4f140425ed9e5c96a4bb10305fb634", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "ca0841bd17b42b5303e0923bc81f2065b8e44e1880480a6b8340f3e6b1bcbc25685eb6f1dff7101a11ea3417be632eafd761d8c3fd3104157f9c8cdadbd9c6c1", + "tags": [ + [ + "e", + "3d4837be2f1101014ff150cfaa71da66d4507d136f0befb535403ed4ff08f768", + "", + "root" + ], + [ + "e", + "a7bf27944116662a24a1fb68b420081aacce90f36ecad03965c45d81574b80ca" + ], + [ + "e", + "7ed23adc9508bf4bc57fc76af8874c09c9af9d6a4afa0e4b04db199a04461d62" + ], + [ + "e", + "40900f8a39b67e8688c2cad1f2ccc73f13cd0bb4af8ef8d88fa86f0bfc958b4f" + ], + [ + "e", + "56f22ef8b1c40cb9721b208f4231c88ee9fdd0372d7affbe426edeb8bd2803f0", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "c6f7077f1699d50cf92a9652bfebffac05fc6842b9ee391089d959b8ad5d48fd" + ] + ] + }, + { + "content": "And this is marked as Global? \n\nhttps://cdn.nostr.build/i/cdf3decc75007b18174c3ece49f94c51f930e28a01c126bac1045b4c3b67dec2.jpg", + "created_at": 1689982919, + "id": "fd4e2a1222c0c7b24d48c7dc9359a7d8311246c4f076914b8e72b94e1ceefce3", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "e2bbf02d867d2b5d971e11131449805d7025abe446846c0400c8d0cdf3b61066d42c30dc23990d00f0f7a8454ae132d4f6b16553f9fbaff0bb708a4f976e3794", + "tags": [ + [ + "e", + "3d4837be2f1101014ff150cfaa71da66d4507d136f0befb535403ed4ff08f768", + "", + "root" + ], + [ + "e", + "a7bf27944116662a24a1fb68b420081aacce90f36ecad03965c45d81574b80ca" + ], + [ + "e", + "08297c8b2ce0bd53a336a3328d9b9a9970e2a81a28ef70a7b5734bf4bc26bdd1", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "c6f7077f1699d50cf92a9652bfebffac05fc6842b9ee391089d959b8ad5d48fd" + ], + [ + "r", + "https://cdn.nostr.build/i/cdf3decc75007b18174c3ece49f94c51f930e28a01c126bac1045b4c3b67dec2.jpg" + ] + ] + }, + { + "content": "We got a name! \nnostr:nevent1qqsdqxyjenhfw85v5gx7kxqen8055s7cw2puclm94js4gtddflvagmqppemhxue69uhkummn9ekx7mp0qgs0e0trlf8y0g8mel484etgx9qyma39x83nzlmhrzuazss0lh08d2crqsqqqqqp44zurc", + "created_at": 1689982779, + "id": "1abfbd6067af774e88a049b44885148337fb870595595c31c2510abf9159f86f", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "8ddd006e5ce070f94588bf136490682e585d506c377e7c86822ba7bdc704d88538a69da09e9ad9e037065db0985c9a147ae60b69148f791d848cfeed67e36e63", + "tags": [ + [ + "e", + "d01892ccee971e8ca20deb181999df4a43d87283cc7f65aca1542dad4fd9d46c", + "", + "mention" + ], + [ + "p", + "fcbd63fa4e47a0fbcfea7ae56831404df62531e3317f7718b9d1420ffdde76ab", + "", + "mention" + ] + ] + }, + { + "content": "Also, check if you haven't chosen the All Follow list in the notification feed. That will filter your notifications only to your follow list. ", + "created_at": 1689982726, + "id": "40900f8a39b67e8688c2cad1f2ccc73f13cd0bb4af8ef8d88fa86f0bfc958b4f", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "a816b3002595152cb878bbe3c74d6602f38c4ce12679229bddbb85efbad8aea025825c0c070ac79ea2ac29ebc225969aa99b163a9a3d5b783d61239710a55b0c", + "tags": [ + [ + "e", + "3d4837be2f1101014ff150cfaa71da66d4507d136f0befb535403ed4ff08f768", + "", + "root" + ], + [ + "e", + "a7bf27944116662a24a1fb68b420081aacce90f36ecad03965c45d81574b80ca" + ], + [ + "e", + "7ed23adc9508bf4bc57fc76af8874c09c9af9d6a4afa0e4b04db199a04461d62", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "c6f7077f1699d50cf92a9652bfebffac05fc6842b9ee391089d959b8ad5d48fd" + ] + ] + }, + { + "content": "Of course, we also easily allow the author of a reply to remove your user from the post. In those cases, you should not get notified anywhere. ", + "created_at": 1689982674, + "id": "7ed23adc9508bf4bc57fc76af8874c09c9af9d6a4afa0e4b04db199a04461d62", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "10a36e75f8fcd7a27d73eb9ea967487552eb3351acaee2e950e4301d713a7695cd053e8d5a94843469092fbd15104a4056a497c680bc7f2cd5a94c4bcf717e38", + "tags": [ + [ + "e", + "3d4837be2f1101014ff150cfaa71da66d4507d136f0befb535403ed4ff08f768", + "", + "root" + ], + [ + "e", + "a7bf27944116662a24a1fb68b420081aacce90f36ecad03965c45d81574b80ca", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "c6f7077f1699d50cf92a9652bfebffac05fc6842b9ee391089d959b8ad5d48fd" + ] + ] + }, + { + "content": "Amethyst only shows notifications when you are an author of one of the e tags (if you are the root, or the last reply, for instance, you always get it) or if you are directly cited in the text. This was a response to the hell threads that keep happening. In those cases, cited amethyst users receive the first citation but none of the replies to the post you were cited. ", + "created_at": 1689982605, + "id": "a7bf27944116662a24a1fb68b420081aacce90f36ecad03965c45d81574b80ca", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "c540d90d6126d14ffe15d082050bf07c50a551c34d515857d6017086697af1713f003e1280d7074f85914d7b8175df722e912f0cf3a3c6da60aaa510c8211667", + "tags": [ + [ + "e", + "3d4837be2f1101014ff150cfaa71da66d4507d136f0befb535403ed4ff08f768", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "c6f7077f1699d50cf92a9652bfebffac05fc6842b9ee391089d959b8ad5d48fd" + ] + ] + }, + { + "content": "BHz4QOLgtnkLFMkWLeT7vYEog9hMj00OCdIOFn5tC0I=?iv=B7sbT7bbjVS23Vsa3XdClA==", + "created_at": 1689981957, + "id": "7fac13ad33c8cc8805b50d1cd944e50383af754597dcb24be3bcb0e7d73fa34a", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "3f3f0d2d07998b8b164a4f8a463422ae1d0711d08e66d2956871926aafdafe9eb1530027766f1b8edbbb9b7078e154b9cd51cd73d1fab8c4fc6d60888a040b4d", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "zvK4PV/zfIScLBttRMRYRvJBOKjoxxy5++CuSB2un7eWdV5lfuXbdBMBn/e+jSu4?iv=ic1MXHOOCfk7LNg6+qfUFw==", + "created_at": 1689979685, + "id": "cab93844a5464ea9c3a9101f2818bc72e20531c49c061dba55177659f7ec6e3f", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "d2c685d86c9cc220c0cb0436fe26ae92625d5df71575f6bfb9630258120a7309c9c3e440b02ef45129c2cda4299efd4c230b34f00dc52789bfd32708a05b47c2", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "Y1YSzKaLNfyzk/rAeHjbnpqCwdNZVhz2Ogk4LaVOew0QLUQux/MkYL1POQb+icsD?iv=GuVyD9MvvB8prX7SuwzEvQ==", + "created_at": 1689979669, + "id": "a8899213890ab028d13961a1f4b7962140ca083ca0d834f537ecfe52a50f1b1d", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "4cb381c6cb5287bd8df253d540947c84f441c7a73dea56f32584ee1f860179ea04fa7500f3ad58f76630a02a09f127f93bd39052fb0c993238149d4024d939d0", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "9873Ylo0oUHthBI5gHDkuQ==?iv=NAf6J1gwgBYCX9aX19WXUA==", + "created_at": 1689979646, + "id": "b26f9295f51ea0498ef9008c208b27adbed68833c570c2d6ca9451b6ac8eec49", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "3a96d2ebf9a2695a031daa48afcd4f5f21ce0f7406bb495d8c7513ac162e37986165d989dd1b6d302a753babb5e4d87358783dbe66fd18067ec3e5c89b5f2027", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "Makes sense ", + "created_at": 1689979221, + "id": "840c1578c4e6c49f0a623dd0d50d9aacfafb3728e986f0bb529863987caaeb75", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "15e6d9161334d3abfebaf2ca2b9f292498d35d7199f6cb0b9974682f0339e95be8c972982e4aee0cfe95855db3a3a8cfb244f813c3236697ce9f4212a96715f2", + "tags": [ + [ + "e", + "bf7ae8649a76c977606a13ddd453942a3ba501783b23c121d1bd685a218cd002", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "84eaf37660225a312d27dbf72acf588106664d444bd432b1c8004c18fa109d63" + ] + ] + }, + { + "content": "OUQDJlyIyVPZEaJsh0Zh8wjpdPNqri3ua3KzNdVERNk=?iv=LMJ9yIbIEj0va6BSF4lOGg==", + "created_at": 1689978881, + "id": "cff285496df7108a40a3d78ad158848b4e6a0c85e34bfa45a2e5cda587ff6575", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "6a701ec9868cec9a12926443d3f5d4ae09b1d114fefc3529bb59f09ce4ab712eb722ed94be7e0952251e474f4c5cdcd4bfd3cce7c80a2fdda73df7d7c9a21396", + "tags": [ + [ + "p", + "672196e844d54702dc5933bf339d53e1b2641a767264384323957f424fd57b04" + ] + ] + }, + { + "content": "AJcI/HvqWp4WtZwC/jSwUavXG46/NPMV1gzkxyaMgYYNRoSZIvq6bR0+b7H+ImfbJvzq1HI81eCvVsyt/eM4JA==?iv=7jXjtbkrppHdmcQT3Huerg==", + "created_at": 1689978874, + "id": "b74800c167733cb13dd0241e212cfbd5e3b729d245912b810f51caf844059693", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "c66d201aa976d4c0d37c9d435633e5b8d693d0c6a9e258f3618523899c46984772c3d58fc097ac2489ddbb2a3bcd4c6d4a48ea2ff6cc78b513bee81c0032578d", + "tags": [ + [ + "p", + "672196e844d54702dc5933bf339d53e1b2641a767264384323957f424fd57b04" + ] + ] + }, + { + "content": "e0wITUuIQONaGOLT8tzD1liObF9LHsVScktSpgkgrPlpUo/YjzbyugjGZ3h5D+t073G2ZK0X7B4idNPZNhDrAA8HFcRqP2Vc+ADn3RUHD0Gx6BoQ/jwIy3gOnEV9oRttkawDv4HputQaeWYroIX19A==?iv=ea1Zp+6AM6Hs7Grc3EdzmQ==", + "created_at": 1689978795, + "id": "966dba764185afd72a596a74c91e706f5a28618f16962ddd3ba41ac19904b9d0", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "dc43d1cd5b000d94a453c9dcd3caf5d400ea2d23b200996be1367852b92f9575fc2894ed63758f24bf1d130dd3c6a044016ea70717aaf1772921544e9332fe35", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "AfKccxXWtZjL0ZV0U0gZzXjxmtomauxe9f0sQTIVN9+2cYL8njKAxEsWSQZbrgIZ?iv=lxtITUPcoSK15HeDT0S3TQ==", + "created_at": 1689978633, + "id": "fa2f35b2f2841f92d64a3a006792a3f361c2ad60507b55081bac5c4f0f3f464d", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "49b0d07eb6eaaa38e73c11f24fe4037f11e2dcd224168ea681a04283e1f3149368dd819eebe51957a5b5705d8a48c9b2b6ef575140f3cd842bcbe2851abed92b", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "8YAcpa1MZfvtAwVJ5/w16YQ7sipjBjbBRj1Fe2nnHJkT7O3GdIlk0V5TpREHDL5a?iv=AtGcsKmCEh9MTuofv/Xkzw==", + "created_at": 1689978554, + "id": "0219e6f056c0cebc919dc9e1a6043b5a5302f4a0fdb327c87d3216a2a4b8aa2b", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "97c587f226bf35d2aea3c4ab1b36c02008e792630cbf329af28a59dd06a4ecb7339260fd4e186d8e15eed6ac8a47549956c7873d783e5507cad3b57ce9dce041", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "TColF2a6KOL0tPR2Cq0oUUJ53oRsJVJ83q/rSEYCDcbpihSgLh2sPk43OSJ4hujoNTvkyy/TmIqq9x7U8R15gFb0WIw1lVvZ2owykU+2iDtnVJkcicXROLQVtj+x5nu0rP4NYJxsp275G0YzfwsY2ngigSX4a5aT3FXwloP649rYCuG+C1Uv2nqLbYl0lbkt1PkoubEc7MsqboDAZ5a02QFpS1QQ3kyscrPWlF8/MG97dVVnKZKmXgpt5e/uyZKkvCHQCR910qJTFt2el5t1Bb8uII9k6VMtXJWMO/KLHywH/kgbM6GC5l0enohwvnqK?iv=chSXqVgngEDxdbcjTXDNzw==", + "created_at": 1689978540, + "id": "e30b18b795404ca81ebaf2a5bac9b82301de22f598786e267b4dfb93335656ae", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "5ac4871503ab5e78e5949e1301ea9a6286d44e18124c6f193447c96783a809eb942b1d571ab64c9afcb8016ae5ca41c66f67d8c1e71a56af6f9f3d198f08d5d6", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "yM5XtJP7JyKfg+F1bx/3Gu2FpOPx3dzjbvrM8O7HSok=?iv=yWgjpXyDICJWVFvWoSEdnQ==", + "created_at": 1689978135, + "id": "fb7b2ff803042667144416fada94d9e919ae1a6442ec644d609365380ca34c3d", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "f0dfbf44bc54410fe14567236711175f5b842579bc942fa18d5979d2b58880fd6c879b8d4ae2e17fada6555ba08284ab8d75a49413588759c200fa8c389c8225", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "UkCJkOqT153btoDiD+4+VlToAtl2UlfFsLH/8sKr2lce5J7oQWBcLdQ5OiDjYjzJ?iv=UiYcO7+BONYURJf6Ezap7A==", + "created_at": 1689978078, + "id": "3b00f93d6ee7b42832aa34575170a74f50618b1095e65e0d325ef1c498b2171e", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "0dd1469c4f6d8be190f828f9345477115e66176de9a4401f578b053b6b14f6c7c62896d7c74d88552e0dc2ec3494492b0cad807f1cbd0926cd1116176eea7380", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "G+wV6IdMdJ93uV0aa0lwQe1noHo7ctUiXuqmX/AbctZQrBkSGgpX3XUbr+0m1Zy08pALk0vRlBmve7NmdhLk1AT/Am23vbxxq5i9ox+UOMgw46VyjB5g01XrLhKDUHg8?iv=WxHcPBEYuLrFZOohJLlrlA==", + "created_at": 1689978068, + "id": "8a2da86643dbecb3272e72319a7a85c687648ed68e64b4530a163727a66b2fe1", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "30578d318a41da4e61aadcd8cc9ede9150f2adfecec92727a7d126c58dcab29ef86e923e458ff67b465cc31d42947ed90d2d5b9c21f8c6f56887cde860121b2f", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "Qn7zesOytPT+WF1W0uRDFnEbltsxbbc2ie7+NBqSHyGlLJBAesuJ2Nay9ALOntBk?iv=fnhLxP/1sYXgjjqJKiTOBw==", + "created_at": 1689978037, + "id": "add78bec9b1669dfe4776b4029e9910f88af60e7cb4a3832feafd408b5093d04", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "5cfcb4532dc1c18f9bdd3d1b695e58313a11fc780a6f6613f10524b55f47d7da6182b1c1043d9b9692549615264658e570894f8c853fabeec53e92892344845e", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "gU/iheSDEaeFKtJLVs+7IA==?iv=LlKtkWuSJfH4ErPRKWh2TQ==", + "created_at": 1689977622, + "id": "b1241ca4526477334d56cab686836dc3fdeaf6ab910c1fd7e474db135c87f48f", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "b2a67ce55251f5b0ef42ec5cfa8581e99fdd069ba592d1f288d70f5801935f52fa8bb45ee89d8dcbf73b4879d189a16d64b674b7b02dfccf6f1b91f0295b43d6", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "Lc5utJWxQ1j5dT74uZmgldkNzwufFEKXIEi43a2V5JoSqaAjjZj4SYgYFo81UbyCsX8+WvoOpyUBS9pmZ26+kw==?iv=fNF9u5WfZg1lWTUQY4w3Ug==", + "created_at": 1689977617, + "id": "8e0e0de3cfbcbbb8c40c6643524a599c9b445f3f00579d88f6595fa19031448e", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "0a576c229f0959b34c47cd76d18c45f047f338c2280b9e435d04e6e94ea27cdc82223775942060741b2514a0a1f3fdc9a7a11ce646af79642cc038f0cff4cdf1", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "ptJxRhe3oiOuSJ84UqDxqg==?iv=DG1s8TtDwB89j3zBOnt2dA==", + "created_at": 1689977604, + "id": "98c010a3bf59659061d710791df4874d979f1131d8292a8cf423916b07196d49", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "41ad18e5cfef67760dc24859fd52b44b982ebd1ad10ffc50d8e5cc9cbc0d41e391dca0160aaf92d1ee3593720dfeca05f6bd13595e722ffc8e9c1e1d6779ae62", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "eIl+2IGO/rzItb9UkRntaMrt80VQvAMXu2p8o0G476Ed33CINCc7r2MrBS2OZCLMFIysREZmipm0FOwC4zMfwDdQ2VDuSvKx1Wr9yp0QeHaQuMO+fvXbAM8SAtmmmu8sJFIm1nHByF+IxvGHMZNyC0WdhJsLFcikwLREXX5vfn72PXNIt6CjOtoT3GfWYR9lXYZoikvcYoL7yMYEqXHqS9exQl3oJSa8aMQ11K197xUikSG8lnbMBrbPCTBljMdx74+0x5aEGXGtQwQKV25eGY+MImxAiMi2XBneI4JzEqUvXCgMZwYVz1QbtYY0ajOZGWKTV/P/IT/81ItgdMkpgEPC/+QaEegaZknxDCbNU8MeytI5uGEGKZSdKeJSk3vIsDKaz4DStlIFcLKtVi2tam8Op9JLpGYF8TThe1WlfWU0sCdlCut1LN+eDkt0LqaW8k8z9Fo2fD5lXvLNrdU2M8kco77dGAKcyvz1DB7uGTCXQJkrbfdZTW5BObF9EDALJPY1wGFt1IFkFYaXj5k27dO4q+NLMuDYOoREyVPedcyv9zzy/CIllOu0LlQN7JStufo2y4pNSdDKk53izyqQX2aoPH1X7ABN3MPaOZXZ3Frt9UYMrsZiZ1m3kPcGH+wrRocYl4uWwQUbfS2dvTfarOq1vi38m1ZdpLvaEVKWgrZ39gjBup5UHfv0LMiyYWEioBauxLBmyRnfsoU7wgszHhn5Wu0835Mv1wvgRvnlvSqj4NnaneV5d3U+DadNifgBReQyjNDLUGT/UlMdgso3gWbjPF4Q4M8dmCdlomwOa4KR/eFE2Sw1KPqO836/6K5xhkRcxuqEzIG7RKwEIMLGWg==?iv=/CzyaHppYO841qCLbDCo9w==", + "created_at": 1689977531, + "id": "7f86c6b8a04bea04f4b1097622aab3a7c1da0dbe402cac74b8119d3c7282b1c6", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "f842721f12e20f24fd6a332d32114caec583d4e229ec3240c13def3292e260ca093eb22bb82fc8d8deaad9cddc59458275e89e5f68e86908c63875f45d5acb0a", + "tags": [ + [ + "p", + "c63c5b4e21b9b1ec6b73ad0449a6a8589f6bd8542cabd9e5de6ae474b28fe806" + ] + ] + }, + { + "content": "F5A58GD77ZjLyVrHN+JifSYzbBG+npbhJw6vnVbGtbI=?iv=ll19k4Ar2luPdqXHcsj/Qw==", + "created_at": 1689977465, + "id": "7b54d2c1cbedbace05ff968de66e95b7969c1e83dd5069f65a6de6be2cd9ebd5", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "fcf6705371dfeefc15281d9ca5b7df534682a93531d1cfb6e13e1df57408cb079a390de2a861a2f2b60300a9dadee57933f006e091f646ead558868a9cf43b1e", + "tags": [ + [ + "p", + "63fe6318dc58583cfe16810f86dd09e18bfd76aabc24a0081ce2856f330504ed" + ] + ] + }, + { + "content": "VHiN84CzKCUh8uPgqS0n3SvulaWO2Ztg0FAMxoB52GQFsKLwTMFafvp+UVu/9o++fSHaQlsnUuobtwfS5Jv7PFhQpFrApLrFjRdOO7ijkhWwvHBqAQ3umh63aNjhS1MQ?iv=bnjEyVyuyYl0N+IFn9uvyA==", + "created_at": 1689977293, + "id": "59640cdddf28828cb3f75c6aeb4212811137ec990e3bf418c2ba19d764e6b198", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "1f40ff28659001a244af4d73e41962b7bfd52d263bac36296616da4d0cc93cfbd391e9589b3711938412981cbeec17809b31d90a78eef4d7f6e7506e9815d6e1", + "tags": [ + [ + "p", + "63fe6318dc58583cfe16810f86dd09e18bfd76aabc24a0081ce2856f330504ed" + ] + ] + }, + { + "content": "These release scripts look familiar :) ", + "created_at": 1689977034, + "id": "aece58f5f5c7b98f5494ce7db0165adc8df7ae0c6b9bab581441bd91b0df3ce3", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "c169b8e506011a263ff013bf56f3f52718e44a12e50f5a06b6679d20f12d28e8818aead329419667c41eef111e0b1927ee2ba2f689f7ce4883a46a240dd300cb", + "tags": [ + [ + "e", + "31c2e724b2c44fc395e24382ba8d80e8174160767bd02ec16f0a9ca3a6d220ff", + "", + "reply" + ], + [ + "p", + "df173277182f3155d37b330211ba1de4a81500c02d195e964f91be774ec96708" + ] + ] + }, + { + "content": "", + "created_at": 1689975807, + "id": "f0afbf83bb2e8c64b989776a7e674d917a6196c24cc313bd0d9a90a8032e3874", + "kind": 1984, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "547c76ef76f139814ab6ae33fa5efe03e5dd899003c182af97e11e0aea9739d68e5a95ed1c316533856f8b63674b9337b1ca6d73f4c9816fdabb563904ba2eeb", + "tags": [ + [ + "p", + "352b917a5d3d447b7078a9e6178b6514210564a927bb4003844df48d98419d11", + "spam" + ] + ] + }, + { + "content": "LITEQ50g9GvYEMlz/4HxI2O616p4Nizdsva6JPXL0TolilM+bAWGxSJ6R/hnInV7G3y+3HvCTxAwAQnV9UpS09q8Q2MEKg+eOptLCZdzd50=?iv=1fVnYnkBqLvHshEaqi00hg==", + "created_at": 1689975101, + "id": "6ceb478d0e6e01c4cbd06ef9957b85e37b57a3a04a3c63dd3e66a92b9a512c59", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "f883a65cd1ad833cd24805eb3d1347aeff98e244f2c43d8956782ea1a6aaff71fa75a1e5a952a8da6309b02cc9add291c8e6332e279da44b2b0a494be745554b", + "tags": [ + [ + "p", + "63fe6318dc58583cfe16810f86dd09e18bfd76aabc24a0081ce2856f330504ed" + ] + ] + }, + { + "content": "4BwEVTjQtwPalZOqQLSS4wlZnOc6Ncf/7wnv6YGXxYKhplB9c81H0CtK9y1GYVWa9ld8hxNyM8QggB6xB3zmVLowrDqT1z3KEPohY0nRoRw=?iv=YrIYMh52kA3yj5g/akYRtA==", + "created_at": 1689975078, + "id": "bc79b93654de0d04a4abc0c881a9240ff4337da92f8062e69d69724d6df9ccd2", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "93d9a154ad18e29eabc67913cab8cb6d2ee20b6c55469afaed55a6c3942f2b100cdc7096b427f82313dbba5bebff2f2d724af4b587245ed36f611e9ec59a7e30", + "tags": [ + [ + "p", + "63fe6318dc58583cfe16810f86dd09e18bfd76aabc24a0081ce2856f330504ed" + ] + ] + }, + { + "content": "Make a script to update every hour. :) ", + "created_at": 1689973771, + "id": "7faf1a1ab9f093bf3f5696c8e7c4ea3473fe4142079198eca7efbb722aecd480", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "dc86d190b84b44db717f48eed16b29e5707bb336f59ebe1dd38b04525e6bd5d11977e6c2733d212ec1ee0c0fc6e3f76f2c6dfee398098408f26320daf0dcbef8", + "tags": [ + [ + "e", + "84b084e1d31a27a92f76cefd5e745a089e09f64e92e679c238b268af5406723d", + "", + "root" + ], + [ + "e", + "72efbd2fce58b9cc92ec861bc875b02a7252503192e7e3795e78ddc4a80af8fc", + "wss://nostr.bitcoiner.social/", + "reply" + ], + [ + "p", + "55f04590674f3648f4cdc9dc8ce32da2a282074cd0b020596ee033d12d385185" + ] + ] + }, + { + "content": "A DVM to find which DVMs to use. ", + "created_at": 1689973691, + "id": "f4e1b1f74ebb814338a1c452dbdbf3aa97a849ffcc3044833bb338eb4528374b", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "17a447a47002507cc4f58b1985e9112551d51453d48d076be16824bb0361b3378657faf79e4868b64b1cb82f9ed58de16b0030afce0a09b1194aad1451d9a948", + "tags": [ + [ + "e", + "49f06defee1977eb5a9a2ab86fae6311c616b5455c3f63227753442f5175a0b3", + "", + "reply" + ], + [ + "p", + "fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52" + ] + ] + }, + { + "content": "Not on chat yet. But it should work on other screens, assuming that the profile is loaded in memory. ", + "created_at": 1689972970, + "id": "f8a2486f4b5e24e31a653d99358062c67e13d20d68efc940504048385b7b4639", + "kind": 42, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "a9e75594a467ede55727aa5160e4241b8bcfcd741f42524b16c06819f749e3737d307d24ff278bafcfb8f3b6a98318f8c1cc13a4337a0e22c9cb1e46ec06c6e6", + "tags": [ + [ + "e", + "42224859763652914db53052103f0b744df79dfc4efef7e950fc0802fc3df3c5", + "", + "root" + ], + [ + "e", + "7d2ae83cfd768993ecdc105e6ecfb864f53a3a84945ac2cc7bef20a93eea9a48" + ], + [ + "p", + "aaaaaada01484648a650df7a59f4e6b0d48e226edd959aa237095f3b6a6faa79" + ] + ] + }, + { + "content": "🤙", + "created_at": 1689972368, + "id": "6fc7fe8d7eb7b9d6e17b7ae1c8a42d5bd5c15de0f3d543b0899961d827bf2e12", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "e8a9f9ccc5592892080e09ce9414da1ff75f9a4d7d4885fb9e011a0029d67aed8c305fb841b1b3fdcb0f839c851a59692aaef37a36a679c7be9328c67e904d8d", + "tags": [ + [ + "e", + "297b09d4c973412fefb9a47ad724e4f7ac62c7350eb32c45abdea99af98c2588" + ], + [ + "p", + "4ff36a4d67fa327ef1a686a575d0106b4781600900f68ccb5a40f7e455530baa" + ] + ] + }, + { + "content": "🤙", + "created_at": 1689972158, + "id": "9c250df48d9899d18e634573297aade8e1e81175b272bc60a155e50274c130e4", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "c78c7b2d9cf42561aba618a11f94814aa6a6f86dd0791b89bf3b1d5db8d86782ffcd3bff3f5fd3f4e9e148d656f2b615128c7dd4217a002a8d91db96bf310e54", + "tags": [ + [ + "e", + "6a7a47dfef9bef875b58763dc6185903ffa4bbeb6f3d01db9999c2cc4bfb1800" + ], + [ + "p", + "21d98206ea80a4aed5a7efa97965b5ef08f8f1cf22ef295c1d14bcfcf4efc3aa" + ] + ] + }, + { + "content": "🤙", + "created_at": 1689972155, + "id": "75f95f238fc8912757dc4d8720a1b76ad471bde1235e11f304c8b4bd8548826a", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "ce8d68a1d67d24366870915dabc044be2f39e714a9c40dff0b988007cec7db7592c66f4e79b1c01a11ec9a7c4bc1f9dc95bf3bd936522165f9af5b360a0b92c1", + "tags": [ + [ + "e", + "38b911cf18013676cdab7699818415c52c8f3f76c673bcb7bd93eb8946caeb3b" + ], + [ + "p", + "31da8e96a0d372f657280a3b678c5c8398b053d0891d458b7c8b0a752737a9e0" + ] + ] + }, + { + "content": "🚀", + "created_at": 1689971326, + "id": "b90073d643d6632831d65d76098be4a5bb2ef1f1edb040dce63965a09166d3a0", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "11352b96b205a1588c64b2c7941199370a80d13fcda0f507fc608fc86a53ffcb20641d365a1213729dc87676d359a5bf2594fb136ddd5c2e36c3b034c7225051", + "tags": [ + [ + "e", + "306f1ce3434139c9761742f13b3f30a91cc0287dfd187d19a0a314a93a1f5696" + ], + [ + "p", + "4149bd2ca7c08ab6321dc1f54176c78acd295daa2030dca04e8010ad992e714d" + ] + ] + }, + { + "content": "Yep, no full profile hiding yet. Though it could be possible to mark the entire profile as content sensitive. ", + "created_at": 1689971219, + "id": "5c2964fdd3a2c531ddb6dae4008f4c8daa26a12b1fdd1c5f23c93e8c2502977d", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "fb6230e03f1c7e2ad6ebba17e299593566f3f3e25e00e9f770e0a55d70e47a119b0692412dc3686891815c78cfc094ffbb323adc59684de8ecd398b949206145", + "tags": [ + [ + "e", + "f1b86fbbcdf3def82c539ea1cb47116eaeb81806cddf2b55986f79f73b9a1b97", + "", + "root" + ], + [ + "e", + "a2b6c4f5ce2f59e2b665623624935ab9a12ad899809de109eb62497a20674c39" + ], + [ + "e", + "825bbee3f59a086aea0f4ddbcea235e156ff10db4169af01f2b7b240eae42cb6" + ], + [ + "e", + "957ad7b333d2b068d42b3eccdcf1cf4aa2a7e3fd9b4fc3932fd4f43dc9c9d5b6" + ], + [ + "e", + "99ca15337411022cd6dd6ebd12970c678e039ce64b16dc801698a220d010707d", + "", + "reply" + ], + [ + "p", + "3f770d65d3a764a9c5cb503ae123e62ec7598ad035d836e2a810f3877a745b24" + ], + [ + "p", + "1b1e7b22eb297be33b16dbc01d89cf2ee88704390710069feee7ab9ed91deb1d" + ], + [ + "p", + "dd840e433b978795bb35a408bc61ef7e99688ba0b166f8cb4c7cebcb5318ecb0" + ], + [ + "p", + "c6402125e90e82792f580003bbf81a130bab2540d553331c5035ff0864e5a54b" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ] + ] + }, + { + "content": "D9ZDPT+ym8SiZVDXLY5r+ccfMfJOLZr/Fb34eYAkSNhE4bfz6VeucqqRflgqiZtnpJXzxzVu+ccVMlmOQKKBA0BQD7juHaaaHAXMUXbhLjw=?iv=Fax6ymzr/o0Vj+8pJqHyiA==", + "created_at": 1689970514, + "id": "10bb476b7e35472b292f69e14aab8825ba2921eed14bcfb175e71f5bd84682ca", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "fc82e33f3737423385466c4f825cbb8de6232a5d81eb6abf0d0e09405ee0ca5217e307994becdd6f32b23dac4ff625218ffbe930810f372247cdb0f786985df0", + "tags": [ + [ + "p", + "8d9d2b77930ee54ec3e46faf774ddd041dbb4e4aa35ad47c025884a286dd65fa" + ], + [ + "e", + "2721a5c224fdd7b786fb97d5c173444a735b42903ce8daa9d7ac636658360ec6" + ], + [ + "p", + "8d9d2b77930ee54ec3e46faf774ddd041dbb4e4aa35ad47c025884a286dd65fa" + ] + ] + }, + { + "content": "Top-right button. ", + "created_at": 1689969132, + "id": "87f3e8669d345ff58a7314b59966dac2091c6bcd9f78f8670d0f559acec70216", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "b112cd109be777d321ff77d9b2a51bf81da709547c21456e29e2e6340399021f313cddfd9e9f170f85a82b6cdd54aa66cdf59e38b49478f3ff71f3ae5097f933", + "tags": [ + [ + "e", + "2ae6e0e1978e9514561bb989f5da7e8adbcf8f1630d7034a3a9ec7118888fe26", + "", + "root" + ], + [ + "e", + "9f3e00e694697dbdd682a83ba9328956fbdee15ee98c8247f609c619d5b1ba48", + "", + "reply" + ], + [ + "p", + "55f04590674f3648f4cdc9dc8ce32da2a282074cd0b020596ee033d12d385185" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "7bf7db83f73228f5df6ba34849f2af9fd54bf565b5ad698ac708249b310079a0" + ] + ] + }, + { + "content": "l0giUaY9CWhvb9TJDppm/TxERuBTIKu7EDV9iJn9pfAtoQAzhq6DOOZxspsFc54b?iv=0xlAHbPb/lU6u6M+mMrVgw==", + "created_at": 1689968865, + "id": "e79169091e1262551ce7d9720910ab4276e9ba3a90375f0eb6b82133d5033d37", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "8b7559ccd3d527efad3e1f0de07fc73957d39d1261f665a7fe21c4aaccb9fce895eb7ce1371aadc06ef9ce2dd7eba6a2cc140ec05de6f1b7cbc53b6cf5612d1a", + "tags": [ + [ + "p", + "97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322" + ] + ] + }, + { + "content": "B0LQfQWsazGI7Z1U0YbsslTRgrikDPkURzlU/ZaA1dNb8xG/62ZJI6glJTmSTh7Nx0ZlnqviisPqU17cxWwjJe3vPM1xop/FDsha3ZdmFYY=?iv=jIcTUYXKc9pnAWlEvwNX8w==", + "created_at": 1689968856, + "id": "60b7f72e911d92f54f3db9d207a71fede0cf78692e110859c9e8915b7f745175", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "0e227cf32752a175bb5be027064d6eed57b7f6913f092871533693124da6f6eac0ccb0491ec5fb88fc23995d0bed303c5f5e01a7a61adb6c76791767c84f62eb", + "tags": [ + [ + "p", + "97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322" + ] + ] + }, + { + "content": "GTncRNSHERzHjokQ4zWRCk8q+0Tj98EIWVfDlETRdnb34tUvZoK1NQ97BXzyj/aRJz3t6Qc91z46vLursOK2Sg==?iv=5v/i58l4GDhGx3BpXQciFA==", + "created_at": 1689968831, + "id": "c96f42508779710b8d09b8f3308e5e3ed8069983e574ae64fdcb23eea01877a6", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "9a32548210a39226d8eda5ae21bd4f0d7159e4bfc4b7bd11014deebe735e8ab7cb80a525dc73b67127c4bb0646f738b8f4ac0ceee687daad02c6a55461fc7678", + "tags": [ + [ + "p", + "97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322" + ] + ] + }, + { + "content": "Hummmm.. looks like I need to fix tagging live activities. :( ", + "created_at": 1689968448, + "id": "860c9594fcdde6307bef4f6acb99f7f155e1061458b8c9894e3989b023c59d2f", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "6fbeae674d410eb00ee2a17a0735ad0c3e746bf6695d8239c1cd0094e45750752d8b68a4998724894448e887865cdca56c60d2a1e0cc07633b9e4d6f7bbde939", + "tags": [ + [ + "e", + "2ae6e0e1978e9514561bb989f5da7e8adbcf8f1630d7034a3a9ec7118888fe26", + "", + "reply" + ], + [ + "p", + "55f04590674f3648f4cdc9dc8ce32da2a282074cd0b020596ee033d12d385185" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ] + ] + }, + { + "content": "Turn on Amethyst, go to nostr:npub12hcytyr8fumy3axde8wgeced523gyp6v6zczqktwuqeaztfc2xzsz3rdp4's radio, pin it to the background and keep browsing. 🤩\n\nnostr:naddr1qq9rzd3c8qenzv34xgesygz47pzeqe60xey0fnwfmjxwxtdz52pqwnxskqs9jmhqx0gj6wz3s5psgqqqwenslj8h0y", + "created_at": 1689968401, + "id": "2ae6e0e1978e9514561bb989f5da7e8adbcf8f1630d7034a3a9ec7118888fe26", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "c43f4af5b693201d6073e3034dccf272954812547470c6f9a0f73b5dc6afa8b129de124676da58dc52efffb3f73449484508306e9d55154f70af8dfcb3a76d68", + "tags": [ + [ + "p", + "55f04590674f3648f4cdc9dc8ce32da2a282074cd0b020596ee033d12d385185", + "", + "mention" + ], + [ + "a", + "30311:55f04590674f3648f4cdc9dc8ce32da2a282074cd0b020596ee033d12d385185:1688312523", + "", + "mention" + ] + ] + }, + { + "content": "🚀", + "created_at": 1689968322, + "id": "34f6196dd0ad0cdd727f936783cfd705271fe8504c5a114d18a03a16f0b2d825", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "1b02863fcd487cbea1b8e6a45ffdcbfefd130e3560af1192398ad02349df452281b6b2ac5b2135791d8f80f64cf21957eba5951fa85a5eddbbdd9781a8de4629", + "tags": [ + [ + "e", + "c9d976864bcbe0a3be5b025c89e671874d16354dc34632f340bb4387124a80dc" + ], + [ + "p", + "55f04590674f3648f4cdc9dc8ce32da2a282074cd0b020596ee033d12d385185" + ], + [ + "a", + "30311:55f04590674f3648f4cdc9dc8ce32da2a282074cd0b020596ee033d12d385185:1688312523" + ] + ] + }, + { + "content": "", + "created_at": 1689968220, + "id": "e6e3cc971eaac101d1086cc6f8bdc140a631aba8cafbd12fd795b7c07b6ae333", + "kind": 1984, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "1c2bd83a4745bc62684d4a78c6a0b000466ab95b49daba18115a9e92bb57525294f62f3df31e4397d87224f0644e7ede7140636eae36b0094a9cada49949507c", + "tags": [ + [ + "e", + "0a7c4bea9affd6a5614a17889514c7a2aeba60e63dc001743739f7598e3fed70", + "spam" + ], + [ + "p", + "9b0d19ebfbddc17922a0cd8df1d97e73d8ba106fc80a4d43b3f815f3f1a08983", + "spam" + ] + ] + }, + { + "content": "⚠️", + "created_at": 1689968220, + "id": "7878ced274809d1c8d0935de9f4ca67e12f61a6d3e8688e0f939e9616efd78b0", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "86d8360ec24069f6736c46edc01dd713555e0a7f56da5c48b9b015878f422f5a36faaf68dee1f77360f56890d7d4b9081df08da370a02489d30777fc9994afb1", + "tags": [ + [ + "e", + "0a7c4bea9affd6a5614a17889514c7a2aeba60e63dc001743739f7598e3fed70" + ], + [ + "p", + "9b0d19ebfbddc17922a0cd8df1d97e73d8ba106fc80a4d43b3f815f3f1a08983" + ] + ] + }, + { + "content": "Keep updating that event. Amethyst marks it as ended if you don't update. ", + "created_at": 1689968204, + "id": "84b084e1d31a27a92f76cefd5e745a089e09f64e92e679c238b268af5406723d", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "d7f66d9f224580504fd39bd6a8caca7941ec40efd015aa114c8b0b6500b32c74ed96622e57a5b907f39df73b753b2f20e765ca0ed533d36ad5dfa15473825a7c", + "tags": [ + [ + "e", + "6557bea21d980ce1fdf671fcee3d3295a6beb78f63d29729f5d284815cb57751", + "", + "reply" + ], + [ + "p", + "55f04590674f3648f4cdc9dc8ce32da2a282074cd0b020596ee033d12d385185" + ] + ] + }, + { + "content": "hDAdqWH/tj/dzqyXNL+7fzEZ83mJKsbHRXMdln4y+B2nnCWKkNTdrFxU+4L7DdQC?iv=Puix1vCTdriA+pLxfC/qnA==", + "created_at": 1689967568, + "id": "28cdc408713dcc255edcc8db05bc0e40eb486321d25c43b8d203de5e70941f4b", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "c797ef7c1b05d81c24c1aa60cf491b2df71386634175bb2ebffa9f8c78c7f956d9f56fe586366cca91c3f25a3f9b951688aa8965c690c4b70150baf096c24f61", + "tags": [ + [ + "p", + "97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322" + ] + ] + }, + { + "content": "HqXbmGO8PjLriW8nFNTMsQ==?iv=llg6zk1KYvXem7OaE9bl8A==", + "created_at": 1689967556, + "id": "f88c0965f79b79d2fb58f93e844f46d91776c2d366374f226ddb935be6d95ded", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "7e1b3c32dec8c5dd3ceb310ae2bc881aa8ce838a1fc9acc33ca9ba9907665e1cc972d0d229294c56c34f4c490b621f1f9a0df0f081181ed0c9e06dee7bf2c476", + "tags": [ + [ + "p", + "97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322" + ] + ] + }, + { + "content": "Sx4QIMpVV0QEq6oeXH5MylS1Y733BReuPr0otd423lI=?iv=LBuyRw8BsOpaBbU5xG+BAg==", + "created_at": 1689967552, + "id": "6af5ca2203c5b93249bd7fce7d6ff3fb426df38159927c85e0c263905ccd91b4", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "68d0d30378769c1ae389df6ed0bf20af7d35311f8fc26ea3067929d24d7a5ae896e78f3d38ebb264344e8f066782b230f51337e0941bf2f4ef83e74829006557", + "tags": [ + [ + "p", + "97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322" + ] + ] + }, + { + "content": "xGwYwz9X3f0s3xYD8tjeG0eWoXaDzLwXGth7ID6o4YzWNZv9uj245SNdQvYQuqzg?iv=UnnU6U0xomni3FQFRqQmKQ==", + "created_at": 1689967546, + "id": "90060a1cd906ce9ea5c790839ab1232aaff691e8931c44f57ccd725953f5a40f", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "b6d27a3c34fc53bfc816693bdcbe77010b4c1f9d7e4817af043922746d7f200133243cf5e2f85837dae935c393e5c4c4b6cfb4ec22c245620facb2f2afceb246", + "tags": [ + [ + "p", + "97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322" + ] + ] + }, + { + "content": "Video is so hard :( I will keep an eye on it. ", + "created_at": 1689964286, + "id": "49b412af98a3b519f18266a67bf10577a68a7cdb3df26d234e491a54980d87c7", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "2fb538efc3a33e80100a3dc78ddf779e15945f5b676afa5150f0b66382a409554087f2f9e8a1a983b41435db48911aba6b7a30664e12f7313ed4cd98a4356ac6", + "tags": [ + [ + "e", + "438c70e797d8bb3ddda9a1c15726a25f2034c1c9a96337d801a377448ca754c8", + "", + "root" + ], + [ + "e", + "885849c65696f340433c58a054df5ef27937ea5efe87405fcdcc60741748f7b5" + ], + [ + "e", + "dc6a448e730342262f978f1638137b3621e3166d1fa17efbe0ae972a24de0282" + ], + [ + "e", + "74d50ebd3d2104014265ddf72a81671e6d15cc6fdb68f4706eb5a6b3612d3c10", + "", + "reply" + ], + [ + "p", + "4b52aa385912d5ec98b773211aa884b1a6656e8fe6bf7a151a6a6f6adf45c417" + ], + [ + "p", + "4b52aa385912d5ec98b773211aa884b1a6656e8fe6bf7a151a6a6f6adf45c417" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "b9e76546ba06456ed301d9e52bc49fa48e70a6bf2282be7a1ae72947612023dc" + ] + ] + }, + { + "content": "", + "created_at": 1689964202, + "id": "b2a975890c554d6071d9dd1200cfd2020bc8be752d5e845e8d6ab6e5eb92f7ce", + "kind": 5, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "6682fb0170db6a48da22983af8ee44aea60c80b42f303599c0119d96e395c74ecb4ce6a10efb8c6dbc810b427e72d29374cccccac5a34dfdd418caa656faec2d", + "tags": [ + [ + "e", + "8b22b43b5c93e5b84830446c7ec610fa88155dc62ecca4d32514e63d49081335" + ] + ] + }, + { + "content": "Last message: https://github.com/nostr-protocol/nips/pull/468", + "created_at": 1689964112, + "id": "5ee95e9c26d48954d6e842bbde5aa2f54d3cd5cdd1e42eef1625f3fbdcda7795", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "861af1f7cfce98b5d84c728e4a0d666d91fa42b5a1d58eea1cffabd39215b2441f39bf1a8bac41dcf9778ca4b01fd1d45b535a51c423f7f591b551b7ac901858", + "tags": [ + [ + "e", + "f7ab0a2197676c2da1af737bb1c09e4c750b6ebad3223acf72c3648372540755", + "", + "root" + ], + [ + "e", + "ea9ff60451079f154495ce532c537e0509e2f9add03b24b0d5a16166732e4ba8", + "wss://nostr.bitcoiner.social/", + "reply" + ], + [ + "p", + "3f770d65d3a764a9c5cb503ae123e62ec7598ad035d836e2a810f3877a745b24" + ], + [ + "p", + "3f770d65d3a764a9c5cb503ae123e62ec7598ad035d836e2a810f3877a745b24" + ] + ] + }, + { + "content": "It's a very effective way to avoid reports. ", + "created_at": 1689964080, + "id": "d2186814284909245032b96a0ca44af635d4a4c2cf77e57c2119704df80ac9cb", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "d2f1032e162dfc502edce54e862eed06e944677134c7e831e2caced19f2a6614d78440deb6e7cbad3c72c6f6bc834308ebb19e4df248a8b9d93bfd9ebc8b4aa6", + "tags": [ + [ + "e", + "409233edfd6dfbe4c052e53552cea2b5d99427107e638c08a5f76412638e2997", + "", + "root" + ], + [ + "e", + "c0c727063a3ba2e9c21604df63444fb97b7c39dc788734762f2bccea31fe45a3", + "wss://nostr.bitcoiner.social/", + "reply" + ], + [ + "p", + "c6f7077f1699d50cf92a9652bfebffac05fc6842b9ee391089d959b8ad5d48fd" + ], + [ + "p", + "79c2cae114ea28a981e7559b4fe7854a473521a8d22a66bbab9fa248eb820ff6" + ] + ] + }, + { + "content": "get the video urls and send me over if you can. ", + "created_at": 1689964038, + "id": "dc6a448e730342262f978f1638137b3621e3166d1fa17efbe0ae972a24de0282", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "62f6f79c609297e102ac206ab6e5d46f6132c0c6db1cedc27afa96e1e1883159cf9c36793aa6bfaf943e05edc67b2e908df87a38b7769c2768eea615848cd5ba", + "tags": [ + [ + "e", + "438c70e797d8bb3ddda9a1c15726a25f2034c1c9a96337d801a377448ca754c8", + "", + "root" + ], + [ + "e", + "885849c65696f340433c58a054df5ef27937ea5efe87405fcdcc60741748f7b5", + "wss://nostr.bitcoiner.social/", + "reply" + ], + [ + "p", + "4b52aa385912d5ec98b773211aa884b1a6656e8fe6bf7a151a6a6f6adf45c417" + ], + [ + "p", + "4b52aa385912d5ec98b773211aa884b1a6656e8fe6bf7a151a6a6f6adf45c417" + ] + ] + }, + { + "content": "Bt0pzANqo6JDNMOVSZtRGduXq7HpQB4pXZxi+jE6ziUhQor/HhA/iDUO5BbtMD5AfpOpqisuLzf7HywST79t5TVbtM7UGBm9/iTfcZeg5Fkyt+3V9G1ef/lTMw8b3BvB?iv=6T5YVB0wcifzlVwyasCJjw==", + "created_at": 1689963534, + "id": "fd438f5148e6e847ff748d564f806cb15a4603be5e0c27f8fb192bd3c3f6ed67", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "f4f1e999f951e672340d01a8c1891fb475fc54b4275597f2ffa4d92f5f0085502d5345741542239a3bb508411bc9670dc22125c46e78957e99d4df415322abd5", + "tags": [ + [ + "p", + "97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322" + ] + ] + }, + { + "content": "Thank you for using content sensitivity ", + "created_at": 1689963327, + "id": "796d257f6e06d8145d0ed795f3695bc4c175d7a24890922be3852e4cd246e096", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "7b2b3eec7f5c1cad7d655d59d521464c6ed429eda787ef31cb3d44b90e30d770419dc4034e0b887c7091a933f51fde3c7e92880a2bf2e17621f62617a1b5476a", + "tags": [ + [ + "e", + "409233edfd6dfbe4c052e53552cea2b5d99427107e638c08a5f76412638e2997", + "", + "reply" + ], + [ + "p", + "79c2cae114ea28a981e7559b4fe7854a473521a8d22a66bbab9fa248eb820ff6" + ] + ] + }, + { + "content": "8Ab731Z61Ct6sIERglBUgqRxjGrJHnyrq820HqMEywNhu1gIIPW+7dvM/XC0nv6BjXBLGuLHDswYbGhVMXxopQ==?iv=EKyBALmNq+k2B46m3v+mPw==", + "created_at": 1689963305, + "id": "0d7ea4e5dbcca7d6c7ce3e7013b2261fbdbd8b767821236c4c059b51da3bbe65", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "625170fff7fde4f0949ec574706cbf39b1eb8813bf676bf6ea22a5973cda0333467e0f748ddcddbdcfc357d6cddb8e4f49b4f8f0c7cdecbfcd80e40ec585f048", + "tags": [ + [ + "p", + "1c6b3be353041dd9e09bb568a4a92344e240b39ef5eb390f5e9e821273f0ae6f" + ] + ] + }, + { + "content": "0ONkFjclPM/XKdRfSCPfpobIMumwXkIEW2y6u13PG3M=?iv=sLeGSt50ih42yHN6V9xIvQ==", + "created_at": 1689963292, + "id": "df3e74b5af761d6f1ef71c0258e27d9894dffc346c9d4df3c3da29e0889975b2", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "8c1f8338736612bb6f5de0d4f6deecba028a66e41c74d63f83cc85bb1d4e2b8106a82b7b58e1353a54fd8529363fac11514f67d5426a2aa06048c7c19d2d8a54", + "tags": [ + [ + "p", + "1c6b3be353041dd9e09bb568a4a92344e240b39ef5eb390f5e9e821273f0ae6f" + ] + ] + }, + { + "content": "Super strange.. all of them? ", + "created_at": 1689963074, + "id": "0ec5ff7ca4b1585cfe21db0e071f6d49c839ddbbeae9d322f1c30b016145276a", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "3f2e3efdc3d54eff17c5ef2d2cc86985582fd8cddad7e2ec214b2f2bd52e0e40b3414fc43ad6578ceed602ca29084a0c7332a6c19ab5710b4901a79964b72078", + "tags": [ + [ + "e", + "438c70e797d8bb3ddda9a1c15726a25f2034c1c9a96337d801a377448ca754c8", + "", + "reply" + ], + [ + "p", + "4b52aa385912d5ec98b773211aa884b1a6656e8fe6bf7a151a6a6f6adf45c417" + ] + ] + }, + { + "content": "Yep, just click on Auto and set it for German (make sure to have a German keyboard installed in the OS) ", + "created_at": 1689959447, + "id": "aab95307fedb358bc79fa51699cb627e31774e5305bc178857d1a38d624932a6", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "2461b06ff9a8c141646312c5a59a08a44b842f43386f73d32c925c18a62ae0b993560c6480719f3e1252d5a0d521bca7d077efe614f864e82421a8d19403f249", + "tags": [ + [ + "e", + "0b6153cc21d36e51edbd2c30c7c45dd2dde66c6bbd0b0b5d508a613f277b1ea6", + "", + "root" + ], + [ + "e", + "81d53f4fa555d6aa29175ff2235e34cba40a949eb3be8104176255451ebfadcc" + ], + [ + "e", + "01186521fa18cecbe9bebcf6d3b6194cef6dd36ae43a3b1306601e2cdf0debec" + ], + [ + "e", + "f8ec20358eb2d8c6f3335aa0a1da2ae40b0e3163fada3a543fd2c7ff2a1085b8" + ], + [ + "e", + "c7bf286ba483b4bceaf758b372d3d35d58398962e5e31a6b76ce38a614e5e5f1", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "b6e13999da09d9fb2bea6ddf5ac65693d66ffa43738e009aac6d547be5fd3c80" + ], + [ + "p", + "ccc0c31d1067eac417d2cf562e09df0bfb8f6724addfcb01be9600a75116446a" + ] + ] + }, + { + "content": "We should have both implemented. Market decides. ", + "created_at": 1689959301, + "id": "47652f48803fa5e109ea9ffe514feb183a613ada5ad23df64f6be09971ed06bd", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "c402d5cd2a50e0d0f26bcb1c15ee09b419d2985898aa83fe89a353270a0900ed6750cb6354222afa316ed29e16c61492f75215580323c1aa5cf47e82e89846fb", + "tags": [ + [ + "e", + "f7ab0a2197676c2da1af737bb1c09e4c750b6ebad3223acf72c3648372540755", + "", + "root" + ], + [ + "e", + "ea9ff60451079f154495ce532c537e0509e2f9add03b24b0d5a16166732e4ba8", + "wss://relay.damus.io/", + "reply" + ], + [ + "p", + "3f770d65d3a764a9c5cb503ae123e62ec7598ad035d836e2a810f3877a745b24" + ], + [ + "p", + "3f770d65d3a764a9c5cb503ae123e62ec7598ad035d836e2a810f3877a745b24" + ] + ] + }, + { + "content": "", + "created_at": 1689959268, + "id": "92dc035f4ee6747cf9b12f5d3265c6f015f4e0e2ed89ef78fa46dfe8f4536b24", + "kind": 5, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "300b8bb33684e433b4d7908c51f80286d4d51b2d3b82967aff78355fda768e0cbdce22fa58b5630a68ea622248f0d9363ce1dba86f7f743b25e778ebd6901b1f", + "tags": [ + [ + "e", + "8b22b43b5c93e5b84830446c7ec610fa88155dc62ecca4d32514e63d49081335" + ] + ] + }, + { + "content": "Very interesting... Maybe the app is never deleting the cache automatically? How much space do you have in total? ", + "created_at": 1689959088, + "id": "bf1866daf7c88ee0272062b10c26fd4d77c37e29fead13820b55f4307c25df28", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "26bd4ab68f0889678c6c8d17e1a2a612e2435cf3055bdbbbe81cb4795bf9897e930c6b82c5474e05946f4ff5cd31da6bad5256397a8bb0c9db0de411df3d930b", + "tags": [ + [ + "e", + "df9b11fd6029e3b4c27bfb5cb59aa152442a03d57bc5b759684263864ae729af", + "", + "root" + ], + [ + "e", + "c87acc1325604410e041e4a2a363e1d9ddd0c6eb97c05d5cf79a41101729b281", + "wss://filter.nostr.wine/", + "reply" + ], + [ + "p", + "0d1dd56ae3204328e45f78b1a64ac8f06d227129f775493ebe84cf28250d1ec6" + ], + [ + "p", + "ee6ea13ab9fe5c4a68eaf9b1a34fe014a66b40117c50ee2a614f4cda959b6e74" + ], + [ + "p", + "ca89cb11f1c75d5b6622268ff43d2288ea8b2cb5b9aa996ff9ff704fc904b78b" + ], + [ + "p", + "7579076d9aff0a4cfdefa7e2045f2486c7e5d8bc63bfc6b45397233e1bbfcb19" + ] + ] + }, + { + "content": "You can do it in a new event kind that is similar to private messages. In that way, the only way to leak the message is to leak one's main private key. \n\nIt's possible to leak it but it has a cost. ", + "created_at": 1689958824, + "id": "19e4caf71bf318b48942caaeb8c10eda847ded4240fc51831ec8e73e52e09b39", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "49bad4e3a8e9511baac9c58d7de984dd754dd205f321c2dc4e92b757d043e1ad4f04fd9e605bcca5244134a87e1471377bbedb085f66c3630bce59f6698a4e60", + "tags": [ + [ + "e", + "f7ab0a2197676c2da1af737bb1c09e4c750b6ebad3223acf72c3648372540755", + "", + "root" + ], + [ + "e", + "3bddcbc6ca72750f7ed63e1468a632dae75ecce119a18a52c624c7c047fe2b42", + "wss://nostr.bitcoiner.social/", + "reply" + ], + [ + "p", + "3f770d65d3a764a9c5cb503ae123e62ec7598ad035d836e2a810f3877a745b24" + ], + [ + "p", + "3f770d65d3a764a9c5cb503ae123e62ec7598ad035d836e2a810f3877a745b24" + ] + ] + }, + { + "content": "Then just wait. ", + "created_at": 1689958465, + "id": "c7ea022e8d7826ecb7e92a7842e3cb6d29c18c9542b872aa56f08fecd3ec09c2", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "ee20a289e0d45068f04fb0c7fb6b98af8f020131b03246be70796f93227cf181fa4f637e55c4ca3271741de7efa67bc6f712ad5a6c53e1d2677b9f7c9184102c", + "tags": [ + [ + "e", + "df9b11fd6029e3b4c27bfb5cb59aa152442a03d57bc5b759684263864ae729af", + "", + "root" + ], + [ + "e", + "d1aa5d57ae4fb0fa142acbd0554f92ecbd7b43eb95811e9874710d17ae1c3988", + "wss://filter.nostr.wine/", + "reply" + ], + [ + "p", + "b45aca09dce5a9d8af39f5b116f306ba5b9cf175d54b99ef7fe44b14e176dfee" + ], + [ + "p", + "ee6ea13ab9fe5c4a68eaf9b1a34fe014a66b40117c50ee2a614f4cda959b6e74" + ], + [ + "p", + "ca89cb11f1c75d5b6622268ff43d2288ea8b2cb5b9aa996ff9ff704fc904b78b" + ], + [ + "p", + "7579076d9aff0a4cfdefa7e2045f2486c7e5d8bc63bfc6b45397233e1bbfcb19" + ] + ] + }, + { + "content": "Once you sign and give that to somebody, you can never block its spread, independent of Nostr. We can make it harder, but somebody else can make it easier. ", + "created_at": 1689957408, + "id": "4145fe4ef02e0f19b43cbf5a360093b828ccf7eff205f6a92498354f10f3e584", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "583f5dbd61495a31b663e9eaa337d3d4e9f63a795bed5d578e85374c289ac75de32de47f7d08c41cb0352d1bfa3ff491484c14e01ebfe3eabed7833d0ea68a10", + "tags": [ + [ + "e", + "f7ab0a2197676c2da1af737bb1c09e4c750b6ebad3223acf72c3648372540755", + "", + "reply" + ], + [ + "p", + "3f770d65d3a764a9c5cb503ae123e62ec7598ad035d836e2a810f3877a745b24" + ] + ] + }, + { + "content": "⚠️", + "created_at": 1689956888, + "id": "fa03a5d6e5f2ea0b52bdb88c1656d90a18709cb1b9ab9ab184a22aaeeaddee85", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "1d2ac2e49963532028beb37bec2ab69fa1ad09de2015fcb9d3fe54c0015c768b09096b0133f78e3d51c1e017bc3565ee10f615f227704cecec86645b969ac823", + "tags": [ + [ + "e", + "dd89366d32893dd2ee4f8b22a68c9d19673b031dbe7a780e1ac14a39354f1e58" + ], + [ + "p", + "c1a6940f84cb4d32564837d9ae055b036545c8e5f61cdd24f29786876436df8a" + ] + ] + }, + { + "content": "", + "created_at": 1689956888, + "id": "db4a85c524e8675494bab0cf0c1ef3a83809d1a954b159cd3a27b3fc0bac91ba", + "kind": 1984, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "ca9b7e59d54d109f789fa4ae6e67ecad738f5bd266f8d71ae5561d03aedbbe63dd70264a203662138b2e1addcdf1c4039b6a708d66a27555a213b22c247f8405", + "tags": [ + [ + "e", + "dd89366d32893dd2ee4f8b22a68c9d19673b031dbe7a780e1ac14a39354f1e58", + "spam" + ], + [ + "p", + "c1a6940f84cb4d32564837d9ae055b036545c8e5f61cdd24f29786876436df8a", + "spam" + ] + ] + }, + { + "content": "", + "created_at": 1689956881, + "id": "ec4dfdfecf7979e5a5e8240d8a522893d414012e961e8dbe653c278bb82701dd", + "kind": 1984, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "84d0b6acda593495ea135c074c539c062826727568039ca0e4e575c4f30b63416a8501faba8088b5b4d19ba9275d3ad8dde05397c6d5d5d55cb868719af8153b", + "tags": [ + [ + "e", + "91d440406cbb8a6514e225723c42d4efc3d359da1ee57098a1d86cad3ab879cc", + "spam" + ], + [ + "p", + "ccec23ef54ebcfd3bcbf71c4e28d8c32087addda00710197e72275a04828648e", + "spam" + ] + ] + }, + { + "content": "⚠️", + "created_at": 1689956881, + "id": "d2ba718ea610c9f2715fa8e0a65f5568439b31a604ec33383e51654767e03116", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "4c0dfa3a5d1da1f14e5d1fd4e092d44e78d1dffb033b5d64af9ccb691bf0b9e23153867f71a42d768ba107988e752b800ff8b9f4972df5a3f420aa4a2200715f", + "tags": [ + [ + "e", + "91d440406cbb8a6514e225723c42d4efc3d359da1ee57098a1d86cad3ab879cc" + ], + [ + "p", + "ccec23ef54ebcfd3bcbf71c4e28d8c32087addda00710197e72275a04828648e" + ] + ] + }, + { + "content": "Actually, it's the second. It's just the first I advertised 😁", + "created_at": 1689956873, + "id": "72bfb72cd240f6fa6ad0f6aa502fb9f0f9d8d862bf61df28bac61c35ea2c531f", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "21e168c8bad482131f6bf06b69540d11152911de296e657450c92214fe9073742d93d0063164c0516ee959c2f41610e61d0bc8c87a304695d05acd69c0cddfb5", + "tags": [ + [ + "e", + "fca1af2a576ce6f8455faa518475687e857c8dac514fad4148f56b68b25de64b", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "3f770d65d3a764a9c5cb503ae123e62ec7598ad035d836e2a810f3877a745b24" + ] + ] + }, + { + "content": "Thanks to nostr:npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5, Now you can choose which relays do you want to post to.\n\nhttps://cdn.nostr.build/i/d43712f8f8ec312dde3b376afe1339cab94b1750c1f89185cb69f5ba0c9a6687.jpg", + "created_at": 1689956778, + "id": "277fbd58c7f1ebcb09f7211361a540a38f07c717663b5494af1b9847236bb560", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "2f60d9776f1453f24a70a471f73395660240931e541003154c48bb9e6f6358252ec678e3e5f6213ca209bf768ecd935fc1d266b1eb51b9852c62c0133121b335", + "tags": [ + [ + "p", + "7579076d9aff0a4cfdefa7e2045f2486c7e5d8bc63bfc6b45397233e1bbfcb19", + "", + "mention" + ], + [ + "zap", + "greenart7c3@getalby.com" + ], + [ + "r", + "https://cdn.nostr.build/i/d43712f8f8ec312dde3b376afe1339cab94b1750c1f89185cb69f5ba0c9a6687.jpg" + ] + ] + }, + { + "content": "Did I forget that part ??? ", + "created_at": 1689956705, + "id": "60b045e3acdc14f003c241e78d6c802420375bd324e85660c43be3e84dbc9de2", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "4f6c79243266abba1e55952a95ccee0c33ae8c9d7be5503a9765407c545ebd2e80c4b65a6310f6538dc6d7b4b1ec0672afe6a2bef17b3f11882494e9771a1071", + "tags": [ + [ + "e", + "df9b11fd6029e3b4c27bfb5cb59aa152442a03d57bc5b759684263864ae729af", + "", + "root" + ], + [ + "e", + "bd3a2dcf591c43e69bf1d54d8a5fd7a379ad19458f79b08df6b756059558569e", + "", + "reply" + ], + [ + "p", + "ee6ea13ab9fe5c4a68eaf9b1a34fe014a66b40117c50ee2a614f4cda959b6e74" + ], + [ + "p", + "ca89cb11f1c75d5b6622268ff43d2288ea8b2cb5b9aa996ff9ff704fc904b78b" + ], + [ + "p", + "7579076d9aff0a4cfdefa7e2045f2486c7e5d8bc63bfc6b45397233e1bbfcb19" + ], + [ + "p", + "7579076d9aff0a4cfdefa7e2045f2486c7e5d8bc63bfc6b45397233e1bbfcb19" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ] + ] + }, + { + "content": "### #Amethyst v0.70.3: Fixes and Improvements\n\n- Stops Video playback when switching in and out of Tor\n- Adds a space when rendering inline images and url previews for nostr:npub1aeh2zw4elewy5682lxc6xnlqzjnxksq303gwu2npfaxd49vmde6qcq4nwx\n- Updated se/de/cs translations by nostr:npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef\n- Moves the video caching service initialization foreground services.\n- Fix boosted notes from blocked users appearing as blank by nostr:npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5\n- Fix KeepPlayingButton color in light theme by nostr:npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5\n- Refactors ChatroomHeader compose\n- Moves the loading of an Accounts backup contacts to the IO Thread\n\nDownload:\n- [Play Edition](https://github.com/vitorpamplona/amethyst/releases/download/v0.70.3/amethyst-googleplay-universal-v0.70.3.apk)\n- [F-Droid Edition](https://github.com/vitorpamplona/amethyst/releases/download/v0.70.3/amethyst-fdroid-universal-v0.70.3.apk)", + "created_at": 1689956180, + "id": "df9b11fd6029e3b4c27bfb5cb59aa152442a03d57bc5b759684263864ae729af", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "f36eca3f55f6a575ea5cb44e73ed5f98f8fb0c44086d4dba1e8f7e57d837e8749c5bf14825898572bd8cf612abeec12d825e4ad5fbdbf911540c77f241428da4", + "tags": [ + [ + "p", + "ee6ea13ab9fe5c4a68eaf9b1a34fe014a66b40117c50ee2a614f4cda959b6e74" + ], + [ + "p", + "ca89cb11f1c75d5b6622268ff43d2288ea8b2cb5b9aa996ff9ff704fc904b78b" + ], + [ + "p", + "7579076d9aff0a4cfdefa7e2045f2486c7e5d8bc63bfc6b45397233e1bbfcb19" + ], + [ + "p", + "7579076d9aff0a4cfdefa7e2045f2486c7e5d8bc63bfc6b45397233e1bbfcb19" + ], + [ + "t", + "amethyst" + ] + ] + }, + { + "content": "UFNglwaQDiNRbqo4P7NHfA==?iv=gRBjwGJVDFtiGR/XEWGfgg==", + "created_at": 1689956136, + "id": "a42b28e1008356cccd329e3fc9b8f33d42bdfc02891d32bfa2218853f325344b", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "159df581567f73f2eec769c8b785399eb20a42211a7c569592f7359406c915432d353d6af8011fc723393e3057bcd23f5b8b1ccf52a682544ed0e1f367e249e2", + "tags": [ + [ + "p", + "ca89cb11f1c75d5b6622268ff43d2288ea8b2cb5b9aa996ff9ff704fc904b78b" + ] + ] + }, + { + "content": "It's 25-50MB for each translation model (each language pair that you see in the feed) + raw images and videos (which are big because we don't have a central server to scale them down, etc). \n\nMay profile pictures for instance are 10-20MB in size. Some GIFs are 50MB each. \n\nSo... It fills up quickly. ", + "created_at": 1689954869, + "id": "f13fa631fbfd476b06f7027d2944dd5b0cdb67d0755148c95d6030af213178a6", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "c78bbcf217fd0b528876dde5443e429edf45536d079d14e844e41e126225893735c4ac025525f5e437ce6546e7eb2a5d21f09dc83bb2677b7077212c34d5c6bf", + "tags": [ + [ + "e", + "d8b836d465e495d4aba08c1ec2ad934009824c0bcf4274cd5a36828b25138503", + "", + "root" + ], + [ + "e", + "5660cd2929f688d17a0fd713301c4d3be0f9c8c76f9b4fde611f23385576f327", + "wss://nostr.mom/", + "reply" + ], + [ + "p", + "8ad25d02882c05d6ac20fa7c230dfd1c3d7f6de3976d9c5bd5ecc7bbb63495ab" + ], + [ + "p", + "ccc0c31d1067eac417d2cf562e09df0bfb8f6724addfcb01be9600a75116446a" + ], + [ + "p", + "0d1dd56ae3204328e45f78b1a64ac8f06d227129f775493ebe84cf28250d1ec6" + ], + [ + "p", + "8ad25d02882c05d6ac20fa7c230dfd1c3d7f6de3976d9c5bd5ecc7bbb63495ab" + ] + ] + }, + { + "content": "You know.. you can create lists these days.. http://listr.lol ", + "created_at": 1689954628, + "id": "c233de5e1d9e9d342c24484d694ddaf1a8f5b874f10de2b26ca1a76102f3db18", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "f9c10d14b065f1d0ad82418e38231a03bb3dcb728c54431e3944b67068cd5405ccbce3fa690bae8f485da2647d8d7c61543b52cde87187709eac0daddefd2d93", + "tags": [ + [ + "e", + "51c78616f2de35d6c0b3a15ae2d23dd3c084bb976d20162ae5accd81a136571f", + "", + "root" + ], + [ + "e", + "30555fb1b6bf99910d21c243c236dc3fbd5488a06bf7151f21fe2385316f7f5d", + "wss://nostr.bitcoiner.social/", + "reply" + ], + [ + "p", + "916b7aca250f43b9f842faccc831db4d155088632a8c27c0d140f2043331ba57" + ], + [ + "p", + "f8e6c64342f1e052480630e27e1016dce35fc3a614e60434fef4aa2503328ca9" + ], + [ + "p", + "e034d654802d7cfaa2d41a952801054114e09ad6a352b28288e23075ca919814" + ], + [ + "p", + "ad9738030ab84c04ffaec64abadd6cc682cb3501d193a5ff1c94b90770915558" + ], + [ + "p", + "385eacfa42fc0831b4975983c485e0c7c55ed0f5e4f56d79fa7a7151fb0a06d7" + ], + [ + "p", + "5b0183ab6c3e322bf4d41c6b3aef98562a144847b7499543727c5539a114563e" + ], + [ + "p", + "8fb140b4e8ddef97ce4b821d247278a1a4353362623f64021484b372f948000c" + ], + [ + "p", + "cfe3b4316d905335b6ce056ba0ec230b587a334381e82bf9a02a184f2d068f8d" + ], + [ + "p", + "c89cf36deea286da912d4145f7140c73495d77e2cfedfb652158daa7c771f2f8" + ], + [ + "p", + "52387c6b99cc42aac51916b08b7b51d2baddfc19f2ba08d82a48432849dbdfb2" + ], + [ + "p", + "5c508c34f58866ec7341aaf10cc1af52e9232bb9f859c8103ca5ecf2aa93bf78" + ], + [ + "p", + "958b754a1d3de5b5eca0fe31d2d555f451325f8498a83da1997b7fcd5c39e88c" + ], + [ + "p", + "d4338b7c3306491cfdf54914d1a52b80a965685f7361311eae5f3eaff1d23a5b" + ], + [ + "p", + "6f0ec447e0da5ad4b9a3a2aef3e56b24601ca2b46ad7b23381d1941002923274" + ], + [ + "p", + "ecfa3c5c82d589c867c044056f75d6cff794f1886d5ebcdd48ad851da47adae4" + ], + [ + "p", + "b83a28b7e4e5d20bd960c5faeb6625f95529166b8bdb045d42634a2f35919450" + ], + [ + "p", + "a8171781fd9e90ede3ea44ddca5d3abf828fe8eedeb0f3abb0dd3e563562e1fc" + ], + [ + "p", + "8be2fd2cf7cce65a56f0820b022125e9ab4044c7dc5e444e2c0c0eab7501b0d7" + ], + [ + "p", + "50c5c98ccc31ca9f1ef56a547afc4cb48195fe5603d4f7874a221db965867c8e" + ], + [ + "p", + "9f807153876ccb1db650a96fb7ada5a1dbaaa0dc3f22fd3fcf545204aeef43f5" + ], + [ + "p", + "668ceee55475f595ec0e8ef44c64bf9da8d9dd6008ac54dcd24b2501930b960e" + ], + [ + "p", + "3f770d65d3a764a9c5cb503ae123e62ec7598ad035d836e2a810f3877a745b24" + ], + [ + "p", + "b5ba65fbb0221a32b6c14400f505cfdd3651d43938a248a9265a516ec0c54240" + ], + [ + "p", + "ee6ea13ab9fe5c4a68eaf9b1a34fe014a66b40117c50ee2a614f4cda959b6e74" + ], + [ + "p", + "c82bf12d7eb3df7e3cc7766e54363133ac17024a5df2e179c603106cdf203e15" + ], + [ + "p", + "404211c6e9763f49c8c0d8622e6fbf216550b748674247400a2527e0f95e3a79" + ], + [ + "p", + "b9e76546ba06456ed301d9e52bc49fa48e70a6bf2282be7a1ae72947612023dc" + ], + [ + "p", + "47d519cd3bfe5cc6705e32063ef39931946979eebb53425db5f2e4f19c3a3af5" + ], + [ + "p", + "00000000827ffaa94bfea288c3dfce4422c794fbb96625b6b31e9049f729d700" + ], + [ + "p", + "f1b911af1c7a56073e3b83ba7eaa681467040e0fbbdd265445aa80e65c274c22" + ], + [ + "p", + "8867bed93e89c93d0d8ac98b2443c5554799edb9190346946b12e03f13664450" + ], + [ + "p", + "7560e065bdfe91872a336b4b15dacd2445257f429364c10efc38e6e7d8ffc1ff" + ], + [ + "p", + "f1f9b0996d4ff1bf75e79e4cc8577c89eb633e68415c7faf74cf17a07bf80bd8" + ], + [ + "p", + "803a613997a26e8714116f99aa1f98e8589cb6116e1aaa1fc9c389984fcd9bb8" + ], + [ + "p", + "a1c1984994512025327f52c7b6d3a1434a37fbb7a318380cab4832f8daacbb52" + ], + [ + "p", + "9984188a6578eb513fddcf658f389dbd532e54b82b628ad36666f7aa8f731b79" + ], + [ + "p", + "9168772564e66c07a776a3e2849b02d1a0ac88a7f8e621600c54493ca0de48ea" + ], + [ + "p", + "6fda5bce2882176bfbabfab503a1b5281329582d71c4be84bbb567e65c1a791f" + ], + [ + "p", + "a80455732d5bfa792f279011a8c871853182971994752b9cf1169611ff91a578" + ], + [ + "p", + "971615b70ad9ec896f8d5ba0f2d01652f1dfe5f9ced81ac9469ca7facefad68b" + ], + [ + "p", + "31da2214d943b6db29848bfe7e3cf8ec0380014414f06cddb0eeacc9af2508e2" + ], + [ + "p", + "26bd32c67232bdf16d05e763ec67d883015eb99fd1269025224c20c6cfdb0158" + ], + [ + "p", + "c43bbb58e2e6bc2f9455758257f6ba5329107bd4e8274068c2936c69d9980b7d" + ], + [ + "p", + "4ffc11bfa2f8516ae8bc7c6bf82275d358e47045446250be2d0e5612e2140828" + ], + [ + "p", + "50c59a1cb233d08d5a1fb493f520c6b5d7f77a2ba42e4666801a3e366b0a027e" + ], + [ + "p", + "a3c1a5ceda8b86b7cb64d5d6af58fc787ba400f2912b907969d27547f96545d0" + ], + [ + "p", + "1e9d809ea96f8d7227f06025f4ea2dd41e9426c4276d96a70770987c8013d21c" + ], + [ + "p", + "a12fb7fe051724a34ef3409ebcdb377b9d1157a79b7a2fcd8d008995f190d9fe" + ], + [ + "p", + "c02bedab495a8d73e23192fa161a0b8344821f48446811b1e810fac65b584f49" + ], + [ + "p", + "fe2d5cf62e95aab419b07b6f8a7b75d3cb3066fae25c6b44ace0f9f30c59303d" + ], + [ + "p", + "5133a0947abe801445c34e2f56151d8690f4789ab4c763275b14166e74c5830f" + ], + [ + "p", + "deab79dafa1c2be4b4a6d3aca1357b6caa0b744bf46ad529a5ae464288579e68" + ], + [ + "p", + "b43c91f2a7b9d21bba3ddb08cc321840df249364fb716213508bb17383e1d930" + ], + [ + "p", + "eeadea6cbb5018a190f0117857de513cc271d24c947d56cd82c54a6b64ae47a4" + ], + [ + "p", + "de90c5db36a4011f9d584dfc18de1a5724686867984793ef526331b51f8b43e9" + ], + [ + "p", + "6a02b7d5d5c1ceec3d0ad28dd71c4cfeebb6397b95fef5cd5032c9223a13d02a" + ], + [ + "p", + "cbb2f023b6aa09626d51d2f4ea99fa9138ea80ec7d5ffdce9feef8dcd6352031" + ], + [ + "p", + "df0aed92dff00d4ffeda2f4cd88d967dc576b5549400b92afb98a419aa06e6f5" + ], + [ + "p", + "72f9755501e1a4464f7277d86120f67e7f7ec3a84ef6813cc7606bf5e0870ff3" + ], + [ + "p", + "6e0a1f4852bc8fa42b8047d60a81930d88904ca3f2acdfb5b8413ab8c9f444e5" + ], + [ + "p", + "18905d0a5d623ab81a98ba98c582bd5f57f2506c6b808905fc599d5a0b229b08" + ], + [ + "p", + "90b9bec74789688e515125596ab6350bfe646176ac75742275063922c5fea010" + ], + [ + "p", + "ee603283febc4c31b09903392408a2fff1daf69ac2244a5e4ad07eca3bc79dec" + ], + [ + "p", + "f508d64aeb31bac052327841cc7dd59c9d37c182102a048a439098a8bb816dab" + ], + [ + "p", + "f07e0b1af066b4838386360a1a2cbb374429a9fbaab593027f3fcd3bd3b5c367" + ], + [ + "p", + "b82b98dad630f797edf2ee7e48224577ac93cfe899b3ca2a26d91b3edfaa2ae7" + ], + [ + "p", + "4ca4f5533e40da5e0508796d409e6bb35a50b26fc304345617ab017183d83ac0" + ], + [ + "p", + "7b2d73a3ac9714b06500005454b1b24ff255304eb488076822122101d0fcf7a2" + ], + [ + "p", + "4308ff20ced73871b69ed8bcada2a051bc3a05610d1183c54d67b47cd0f7035e" + ], + [ + "p", + "7f1b2d20466fd5ff836c6bca1a0849f9c77162cfc00b7e708a9142763c021673" + ] + ] + }, + { + "content": "Yes, because you can receive an order from the state to provide everything you have about a given IP. You can hash the requested IP to find somebody's past actions and deliver it. ", + "created_at": 1689952040, + "id": "b35f1b545a37833991adb956498d55fb652e3e19a9cfd1cb6cc658c0da547a6b", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "b46fce54c4e8e3136f73c769240149bf1fed84c293c6b19ee1909a305e92a943f889ebb9637bdf1f632058c1e80a4c1393112cbf18007b54a544ca2c8fb6b23d", + "tags": [ + [ + "e", + "d5fbba30ba547c6335e843400d698e5d9e87463fa7f1d03ca555dcc70fb17c12", + "", + "reply" + ], + [ + "p", + "e2ccf7cf20403f3f2a4a55b328f0de3be38558a7d5f33632fdaaefc726c1c8eb" + ] + ] + }, + { + "content": "cxVTHgjC0TXaOTfTi0b/KJk+MLCff4HbxDT6zjwDG69KgMHIw/Yvn0NjHxW87PmHSDTlDaBGXKeDS/7BcY2nqg==?iv=f2tzSqTrlQoXwG8/46dOlw==", + "created_at": 1689951312, + "id": "ca2cd04e3cf4efc9534aed57b1899feae816e02c6a2e8671c2027d4d9f6893fa", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "af1214a7deb8c740b0e7ebc1f55d04e813fc69a4b1f225d7b4a47176230eda817a70f7730a21f518128abb415fb0107475d05a8a0c935a6f6864f26861810421", + "tags": [ + [ + "p", + "4b6147b45bbde75c2ce4cf93444675945c47f41ffd51e3446287bbd56ba668d2" + ] + ] + }, + { + "content": "https://github.com/nostr-protocol/nips/pull/673", + "created_at": 1689951049, + "id": "416181632a67703a81b42b9fea5ce5eae64e8d6c13e7abf46de4a1d66a2c509c", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "70fb4cb049e4f4399327272847007fca1f7958c818053aa92679e7e3a665b64af019c0000f0004a13f2ba520d69e61529a8b7c35acfaf85b37cc9e1c7bab1c69", + "tags": [ + [ + "e", + "88c9c9b3fa3b378414e5225e78b7ec5c2a93ba5a508f43c380e70cafa3ade713", + "", + "root" + ], + [ + "e", + "cf98d38c498d3c21669d9e7fa9843589a0a481d17392c1d72848bdc0f9743e99", + "wss://nostr.bitcoiner.social/", + "reply" + ], + [ + "p", + "dd840e433b978795bb35a408bc61ef7e99688ba0b166f8cb4c7cebcb5318ecb0" + ], + [ + "p", + "c02bedab495a8d73e23192fa161a0b8344821f48446811b1e810fac65b584f49" + ], + [ + "p", + "77ce56f89d1228f7ff3743ce1ad1b254857b9008564727ebd5a1f317362f6ca7" + ] + ] + }, + { + "content": "We use 'e' with a 'mention' marker ", + "created_at": 1689942025, + "id": "05a786d700033851ba5bce7733e3259e9cfdde7c0cb0139406f5ab42744618b9", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "82707d97e8fbd4e5075bbfe86c377385113db6cb231160153ba9f21472466d7217cef48c0fc161a1d1aa83115dbfdea6abd568789808c3d2e5123d335130a716", + "tags": [ + [ + "e", + "acdd96b1297da7ac202c288e76bc7d85ebbacfb2339b1837cb35a0bfcc817a58", + "", + "reply" + ], + [ + "p", + "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d" + ] + ] + }, + { + "content": "It's because our terms and conditions is hosted on GitHub, and F-froid doesn't like anything hosted in a non-free service. ", + "created_at": 1689941382, + "id": "664ef39828f333615e41daa08e975d69c4bbdf48eb94e4d78be94a2c8c53cba4", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "7c767e3d95a36374ba2f79ad6eb3547309067e5f87d65dbd12cfe126f373eadb70ad20e3d5edd55f7eff165f0adb91503f8d8b5b52c501ae3cc580e508ddfe36", + "tags": [ + [ + "e", + "42416b010364982b8df9b9a696083b9df982b57fcf4dc907d3b978f42cdb36c3", + "", + "root" + ], + [ + "e", + "b648656bb2536f74e3ab7528e660d93c1400ca12ad6aa8fd06ba59e50643c905", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93" + ] + ] + }, + { + "content": "🚀", + "created_at": 1689941261, + "id": "0d71d842517f97ecd4b8df42a46e0dacae609e5db7d48540a25cad3808eaf346", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "34cb3ebc088c09bd4ddd9ae21a00efe862894bfe2140bfe99139b08aa8189a59456edf3dde9da08fb9870c2a366905cd9e96d41daa0d9e9353c332ea2be450dc", + "tags": [ + [ + "e", + "846479a923ab551c827422073e09b704249b5540e7a8728d4636bc27fb286647" + ], + [ + "p", + "7fa56f5d6962ab1e3cd424e758c3002b8665f7b0d8dcee9fe9e288d7751ac194" + ] + ] + }, + { + "content": "It only does it on the Play version. F-droid doesn't allow the Google model we use to translate in device. ", + "created_at": 1689939108, + "id": "f8ec20358eb2d8c6f3335aa0a1da2ae40b0e3163fada3a543fd2c7ff2a1085b8", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "e622c5c274ab4ed8acd99d1ccc9918a47deb9e64aec0f4a5172740ae4e0118d2f3743ee178f77bac79c73f3f7b14b9cc07fa1a314e6d0a756b659ce09895482a", + "tags": [ + [ + "e", + "0b6153cc21d36e51edbd2c30c7c45dd2dde66c6bbd0b0b5d508a613f277b1ea6", + "", + "root" + ], + [ + "e", + "81d53f4fa555d6aa29175ff2235e34cba40a949eb3be8104176255451ebfadcc" + ], + [ + "e", + "01186521fa18cecbe9bebcf6d3b6194cef6dd36ae43a3b1306601e2cdf0debec", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "b6e13999da09d9fb2bea6ddf5ac65693d66ffa43738e009aac6d547be5fd3c80" + ], + [ + "p", + "ccc0c31d1067eac417d2cf562e09df0bfb8f6724addfcb01be9600a75116446a" + ] + ] + }, + { + "content": "Not in the plan, right now. But since Kotlin runs on desktop as well, somebody out there could make a desktop app using our code base. Put a bounty. Let's see if we can attract more devs. ", + "created_at": 1689939061, + "id": "5646ba53503e6a10c538f5f9789b47b4cc55a6a0d51f9cd00fe026e8d0223b9c", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "25a749d25096b1e8e1fc8ec0c078bfc24b7ce7c9b453449a97017f95636d797dbe001f7f9b1af2ca5ef770de5492739ecaceb3ec06396ab774ce36e4dd4d2615", + "tags": [ + [ + "e", + "42416b010364982b8df9b9a696083b9df982b57fcf4dc907d3b978f42cdb36c3", + "", + "root" + ], + [ + "e", + "f6ebe924faf115031927d851b4d09bc981370d38bba28895078f0f5908021afa", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "ccc0c31d1067eac417d2cf562e09df0bfb8f6724addfcb01be9600a75116446a" + ] + ] + }, + { + "content": "🚀", + "created_at": 1689937268, + "id": "fe40d759d27e61ffe6be02d68c45c65bc9545b90247eefa3f668f4bb7dab6566", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "35002734dd66eb2c3088f053673c647e8ba7d6e4e5fc6bf73a6460d8b5a1a4691c828a0ff51ab4764bf4515b3597654b499bc8b1c54d65df472e94303d8d44d0", + "tags": [ + [ + "e", + "b43c9bb1520dbb4a30405c27b1dfe442232e53ace78168bbfb13258c6a7ae569" + ], + [ + "p", + "84eaf37660225a312d27dbf72acf588106664d444bd432b1c8004c18fa109d63" + ] + ] + }, + { + "content": "https://nostr.build/av/7b9b8019fecf3ae30a25f82ddd22c9fef7adb07cf444d87e078c93fc9ca74845.mp4", + "created_at": 1689907768, + "id": "e509d1900262f4ff82816e5f3250641cc29e7b07f4be966629b193718c59979f", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "e8f1a409c356a736019eb4a0d210fded04653bc1a1c869d245fd6a0b150e11c455c64bb838c868c488c9104e55cec2a0b187f8ca24786402f7e83a0d8d018257", + "tags": [ + [ + "e", + "50dafc0709a63aec5a1ccb97e979b4e6ab41faed89ef15590ed498b1bd654a7f", + "", + "reply" + ], + [ + "p", + "c4776f31e10298e4fe5b6a4b9d5ae240042f2ca17b5a37208f31166f2e88f05a" + ], + [ + "r", + "https://nostr.build/av/7b9b8019fecf3ae30a25f82ddd22c9fef7adb07cf444d87e078c93fc9ca74845.mp4" + ] + ] + }, + { + "content": "Imagine when you see the live streaming :) ", + "created_at": 1689907532, + "id": "019568d32c6507fd8677006e47afca2cc78bca9c3806158eb3e84838a23eddae", + "kind": 42, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "da67f7739fb06bc8faf7a8f5bc0b3672fa190b896ed4c8ba40f55ec1b0d7d2cf4f9a98652baea76dcca5409f5649ec2cb467852c3ee0ab3d015f0aad4708b91b", + "tags": [ + [ + "e", + "42224859763652914db53052103f0b744df79dfc4efef7e950fc0802fc3df3c5", + "", + "root" + ], + [ + "e", + "4a5c12f52b19dd1f9c62a90e6a05d2dbfe4a0c04bba189ac2f7991732ed0a20e" + ], + [ + "p", + "f3ff8e7774e3b3a85c54041bfd73b60fa2b32ee1c5dc316a1d564234552116d9" + ] + ] + }, + { + "content": "XbR03T+g66nPBK8Qzo9y3YKZJVnusRAkq6WJDgZr6HaoTre+IMvp4t1XyXc2nft4rDy8hY9ll4dkdD7Rz1TWwykgaPTY+Y/SjmUDfiPzoG7gEFaFUUPTXQLrOuTfZUmXy85NwHIsHRC/O6P/YFpfVAzkaSZZ2HWWEn5xDCQ2wodYJNxR1o/so9RAyzRg5PUOvS/5JigbohCQea/yjedxjmFdA5YqNJEKi6QoOvUtEhA=?iv=OQVBz1rnHxytQ+E7rQv4MQ==", + "created_at": 1689901355, + "id": "0d778eeaf231b9c5cbf775446e520e265465ed4e1db864c0415e55eeef45d862", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "ce58c8d40edad01244fadd38b5819f6fd11062e023f3244f21bc176abad1e42b9c286fd6f963869c1fc96c860b746fcebecd915992762c843c4ec38e5c7c5aba", + "tags": [ + [ + "p", + "7eb29c126b3628077e2e3d863b917a56b74293aa9d8a9abc26a40ba3f2866baf" + ] + ] + }, + { + "content": "Usually 1GB. But with the way many profile images go for 10-50MB, it can easily go up. ", + "created_at": 1689900854, + "id": "05a9d71cfe8ec6b931d980c2993b696cd7a4fd5043a3f5c35ea05b301a5411e3", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "c46a68c8d2918707061b283c20308c397570c086953d54442b9fac8179a97ef5e2cb6f9e84be0d4db25cff63f13f5ed3316edd20ae0847be93ea10d87aa5f1cf", + "tags": [ + [ + "e", + "d8b836d465e495d4aba08c1ec2ad934009824c0bcf4274cd5a36828b25138503", + "", + "root" + ], + [ + "e", + "49b67dd8f173d56b99758522087aca6ab2a757e9ef1a17aec988558a3c0f0ce5" + ], + [ + "e", + "ec2980452b7025ac26449110486794c76fee7d48444d5435e983c72385457654", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "ccc0c31d1067eac417d2cf562e09df0bfb8f6724addfcb01be9600a75116446a" + ] + ] + }, + { + "content": "Ouch, 2GB? I recommend buying a new phone :( ", + "created_at": 1689899880, + "id": "49b67dd8f173d56b99758522087aca6ab2a757e9ef1a17aec988558a3c0f0ce5", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "b8c2b7a564b932f2e582e4d53b063877a48b7414ace4c72a6289df20740e4eb06997045ee37c575673fdf4bfe25fedb8478dc80728a5378df49a1277307b0a30", + "tags": [ + [ + "e", + "d8b836d465e495d4aba08c1ec2ad934009824c0bcf4274cd5a36828b25138503", + "", + "root" + ], + [ + "e", + "2e94de4d2a46d61aa549f9e83545f5dfe4bcc404d49bdaae9a42dd202b24dc16" + ], + [ + "e", + "9fbc8f192e8e6e3006aba7567cb29c6f60ad7c583b050a8765ea91af95faab37", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "ccc0c31d1067eac417d2cf562e09df0bfb8f6724addfcb01be9600a75116446a" + ] + ] + }, + { + "content": "🚀", + "created_at": 1689898662, + "id": "8ddae69f32ccb558e49222bdbbe9ec4137a0fbf4ae9614990fe34860f8ba173c", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "d7ef27a7a3ee6a1cdb1fcaf131f045e9fa98d8a7f18bd507e051bae262c5ab51643b4321fea5bcf733e22a48ee61f612792f5003c97b15f87b40a1bf32cf90a8", + "tags": [ + [ + "e", + "a3f71ef8b8fe3542df4c8a4bc88539a53db31c23f3a780543ea2c3ee599f9a3b" + ], + [ + "p", + "fa47eab76aedb2895442da765a3a11d8a5a9a679884ebef8b977e0f36c912f0c" + ] + ] + }, + { + "content": "### #Amethyst v0.70.1: Quick Fix for F-Droid users\n\n- Restructures the spacing in the first and second rows of a post\n- Fixes Wake-Lock permission line that crashes on the F-droid version\n\nDownload:\n- [Play Edition](https://github.com/vitorpamplona/amethyst/releases/download/v0.70.1/amethyst-googleplay-universal-v0.70.1.apk)\n- [F-Droid Edition](https://github.com/vitorpamplona/amethyst/releases/download/v0.70.1/amethyst-fdroid-universal-v0.70.1.apk)", + "created_at": 1689898519, + "id": "42416b010364982b8df9b9a696083b9df982b57fcf4dc907d3b978f42cdb36c3", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "a4f06bffed259dfb747c001c4e58ad9547e1ba5eda174a4d3c6f63903efc70742027d12443fb845b6a86e9de6a6d397b2cd2f520ab8274213c8f5b50c1c0293b", + "tags": [ + [ + "t", + "amethyst" + ] + ] + }, + { + "content": "🚀", + "created_at": 1689898498, + "id": "effe7e685b36a6cbd3dadbc74ff6d59c44c103f784ebf3f9faeb58ad2a8afae8", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "af8d2f662d454ed7b221118af7a1324675dfbd5dd90a3582c4259b848917df01b1a6373e2c5233035508e578bfb3b8f14cae18306c0073d2f7ffbbd93b4c5847", + "tags": [ + [ + "e", + "99d97b784f54e315731e04e2fd3ff9166b2ea2093eb494844b10ad37b86c36ee" + ], + [ + "p", + "8e567e90f3214bb221a726c53c0b901dd23bdc4281e4dfe425014e33f1dd217b" + ] + ] + }, + { + "content": "Well, I only make this particular app for Android. People can of course install others. I'd just would like to avoid the extra work if Android solves it for us :) ", + "created_at": 1689898471, + "id": "06d414ca9e36bdfa02eac2f27b62298dad203dbf784e69d5c339e138ceeaa476", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "812cdda0e068cd30b21b4f700b1e738dc55e85bdaa1f03073479958d345bce6ed5a1e6c735cd9eed0ee773ccb26f1306b06708b5b70054f40d584f16db0e23b8", + "tags": [ + [ + "e", + "15280e46bcba956ac0be0ebb5de1c19d25beae8db5223951e16ecdd24b524519", + "", + "root" + ], + [ + "e", + "bfe8b13fa0a8a63ecfb3b7ad3bc26216efba5ae6aae7b95ec5749db8124d33e9", + "wss://filter.nostr.wine/", + "reply" + ], + [ + "p", + "b45aca09dce5a9d8af39f5b116f306ba5b9cf175d54b99ef7fe44b14e176dfee" + ], + [ + "p", + "b45aca09dce5a9d8af39f5b116f306ba5b9cf175d54b99ef7fe44b14e176dfee" + ] + ] + }, + { + "content": "PlGM8/MtS+vQnbR5HHbc9YXs+DaKNeKeP/JQwTHL7Gw=?iv=+CyNjnad2EJ/djDiMYeJKQ==", + "created_at": 1689898356, + "id": "901df0b16ee3ff8e864d278876093827f15dd9a39dff49b059775dbb319831c9", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "126f482832059ead0ea012dc7a5508517d4e08e7000e8681d2ba637993d49dc3b36735cd1a7b5d673c04245e8e02f2a27844a2b28fd2da6c02418fb5bdb11536", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "See if this version fixes it: https://github.com/vitorpamplona/amethyst/releases/tag/v0.70.1 ", + "created_at": 1689898240, + "id": "2ea9c229e5cf6d8e6cc8c2c018ef08d1366ab70bd9d7dbb499e2e388666fdbeb", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "52c8716c3d7afb35c58c1b7412db2cd44a08e57366349e8aae1c6015c5b078d3fd1b0c8f4ffb718cc81c0c462cecdf97f816c949621587cd635caefe56457cf1", + "tags": [ + [ + "e", + "15280e46bcba956ac0be0ebb5de1c19d25beae8db5223951e16ecdd24b524519", + "", + "root" + ], + [ + "e", + "107ea3c6074b2be4096c5d0233553db7ac326ede4678ba551498c13c80f0794e", + "wss://nostr.bitcoiner.social/", + "reply" + ], + [ + "p", + "8e567e90f3214bb221a726c53c0b901dd23bdc4281e4dfe425014e33f1dd217b" + ], + [ + "p", + "8e567e90f3214bb221a726c53c0b901dd23bdc4281e4dfe425014e33f1dd217b" + ] + ] + }, + { + "content": "They should store everything on Nostr. We have better infrastructure. 😃 ", + "created_at": 1689898211, + "id": "0b4cea57de5eadcf57efc6d1b44511c944085086410f3d400f13554d5c3eb132", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "732cf27c63e6fbcc4e7af2d7fbe2525af2aafe35f6effa270231f38393b13ae161cd9f58acf42ab3e7bbaebe15cab90b8fa4946484480d434e50d8dd36f6169d", + "tags": [ + [ + "e", + "3c4a16878ca8285dc65803a239b9ef7c6b01badeaed9b41b6e5af88a580c76a6", + "", + "reply" + ], + [ + "p", + "ee11a5dff40c19a555f41fe42b48f00e618c91225622ae37b6c2bb67b76c4e49" + ] + ] + }, + { + "content": "g5U/iOElAmZg1czy4FWXjbRuy3QG8LsGmW7QbwEYHjUEslUXqGNvG1P67+kt2IB6UnXUfUy0CCVTTHZ3UhXqJsfYfYNsME3JqRV3WOqDU/7Hb4zShj5YgbQHkai8tIhe?iv=aaWZ7SvNudW3QrZR+w7Ifg==", + "created_at": 1689898075, + "id": "1b0562bceb74fe5a051c0b23a1c76682268cf9857bafe3c7df15ad386623f797", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "fa4fb247f84456b731e82fe511d806909df64c4c0a1f407f78dd97c5c65152b970ca4c204adaa1304dd2985ef7bb59da8b7c684d1528a214fc973783cb99fd1c", + "tags": [ + [ + "p", + "fa47eab76aedb2895442da765a3a11d8a5a9a679884ebef8b977e0f36c912f0c" + ] + ] + }, + { + "content": "Just go back to the previous version. \n\nI am not sure what's crashing for you, but there is a bug fix coming up in a few minutes as well. ", + "created_at": 1689898027, + "id": "48cb09f199294e25bc884fad3253c92dcbbe5b3b03ade1e9c4f079c97d0803a1", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "3b09c5b8d314d35b6302203557bc7e01fdd4c94e2264e9cd895a16a31b14a0f7c106444ad84b137c3f34079b19aeeb05dc281b9bb4128a95c31c4877feee2c52", + "tags": [ + [ + "e", + "15280e46bcba956ac0be0ebb5de1c19d25beae8db5223951e16ecdd24b524519", + "", + "root" + ], + [ + "e", + "10443395bebea840ff883d98379f814eb694486a0f616efa8e53e07ef3b1dc92", + "wss://nostr.bitcoiner.social/", + "reply" + ], + [ + "p", + "8e567e90f3214bb221a726c53c0b901dd23bdc4281e4dfe425014e33f1dd217b" + ] + ] + }, + { + "content": "rAjdaIbE8aQNV4wl26DYoZtpy41jbPK60zFJ3eysPzo=?iv=Ef4GQxwtqFbfJ7iA10Halg==", + "created_at": 1689897433, + "id": "87702fa85d8d3b792be82275ba1c0763467b9c51c1b01970c238dbe601dc8e3e", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "f8f4d672666d2856c6ab2a6b323610da9e13b1839413f4258ba6d479dd8d6266ba25df019eef35ac84e5160f5b66edc828deb6f26e9205a01f02b16d82780f25", + "tags": [ + [ + "p", + "fa47eab76aedb2895442da765a3a11d8a5a9a679884ebef8b977e0f36c912f0c" + ] + ] + }, + { + "content": "WTFQjqBoYqgRFXnqnGwfd0pNaeoL3pkbZxmCjuP6DSU=?iv=HrCg46zasY2X8fcVsqsMgQ==", + "created_at": 1689896526, + "id": "cadccbd35fa4e3719612a5441ae5165cc6d3ee083ed940184bf392e5fe3142d9", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "72004a76b723ef7bd5fbb3093279a77546764840665bd5ac92849f284b5a7f12f489346ce251385c9af39da3b8e6bfdd15672b2dd940aaf33ae473b5a58d897a", + "tags": [ + [ + "p", + "fa47eab76aedb2895442da765a3a11d8a5a9a679884ebef8b977e0f36c912f0c" + ] + ] + }, + { + "content": "QLzMfgQsc7ODjSrJrLxP6DUl+yCHFlLGmMINyYmp6xoi42+qLO7Ucssh4GqWCyY9?iv=niAXV5K/KMasL+eNCr2/DQ==", + "created_at": 1689896516, + "id": "fcdf61a01298305920b318c693f71b5f9ac322225a065fd4fd70d97bd69cdcce", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "4606e2fd335552dffbf33bd6f619f2b8253f07d25ed38c2a26b3fb490800bc23c551d435da5839f1d7541c8bd4867fc5c6228cbe4355bda95f83e6c485d787de", + "tags": [ + [ + "p", + "fa47eab76aedb2895442da765a3a11d8a5a9a679884ebef8b977e0f36c912f0c" + ] + ] + }, + { + "content": "Which android phone do you use again? Is it a memory issue ? If so it gets slow before crashing. ", + "created_at": 1689895792, + "id": "2e94de4d2a46d61aa549f9e83545f5dfe4bcc404d49bdaae9a42dd202b24dc16", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "8ecc5eb799f021c715be69345b8209211203e65318248dbf071cd2ed24b1479a217354e192ac19fc50ac9ba20c9431d10f11a140377b4521d196fd240ecbcdbb", + "tags": [ + [ + "e", + "d8b836d465e495d4aba08c1ec2ad934009824c0bcf4274cd5a36828b25138503", + "", + "root" + ], + [ + "e", + "a0db5f1affbe065a92b0909ac480d17ea517d9ae03cc28f268468e7c82e7fe41", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "ccc0c31d1067eac417d2cf562e09df0bfb8f6724addfcb01be9600a75116446a" + ] + ] + }, + { + "content": "Isn't that automated for Android APKs? The phone doesn't install the app if it doesn't match the previous version's signing keys. ", + "created_at": 1689895740, + "id": "83a06ca57bfdab4f635221e67f05a5827ddd0e91f75756b05692138b5c055e12", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "a74648c78086553bf3572e86c2bea55421fa510f1a7804da1952b4d095fd2c1280890e54643bf78b5402c3565e8ffaecfd5cfad509498f208a7550471c264dcf", + "tags": [ + [ + "e", + "15280e46bcba956ac0be0ebb5de1c19d25beae8db5223951e16ecdd24b524519", + "", + "root" + ], + [ + "e", + "3eb596232de49ba67b1f47873d388cb389f93eb6b3a0449889588b3099402ff0", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "b45aca09dce5a9d8af39f5b116f306ba5b9cf175d54b99ef7fe44b14e176dfee" + ] + ] + }, + { + "content": "### #Amethyst v0.70.0: Background Video Playback (alpha)\n\nNow you can \"pin\" streams and videos to the background and keep using the app/the phone while watching/listening to it. \n\nhttps://cdn.nostr.build/i/04b00315f81c574afa45ae9c5632952e9bd7bd472bebb45b6e83aa97a692546b.jpg\n\nKeep an eye out for bugs, this is a massive restructuring of how the video playback system used to work\n\n- Moves Video/Audio player to a foreground service.\n- Migrates Feed, Stories, and Live Stream screens to use that service\n- Blocks screen from going to sleep if a video is playing.\n- Blocks WIFI from going to sleep if an online video is playing.\n- Allows the app to pause while listening to media and continue playing\n- Manages cache for up to 30 videos in parallel for each of the 3 categories: local, streaming, progressive content\n- Activates the use of popups with artwork that points to the screen with the video\n- Creates a button to allow any video to play while browsing the app/phone\n- Moves app to SingleTop mode.\n- Keeps viewed position cached for up to 100 videos.\n- Restructures the starting screen from App Navigation\n\nDownload:\n- [Play Edition](https://github.com/vitorpamplona/amethyst/releases/download/v0.70.0/amethyst-googleplay-universal-v0.70.0.apk)\n- [F-Droid Edition](https://github.com/vitorpamplona/amethyst/releases/download/v0.70.0/amethyst-fdroid-universal-v0.70.0.apk)", + "created_at": 1689894483, + "id": "15280e46bcba956ac0be0ebb5de1c19d25beae8db5223951e16ecdd24b524519", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "d1a1bcad4fcae1592e27ddc086d8e9f656e790536038a82a7560705348c964093c89c6058e4180a67f423a34e91157dfd48168a3db3c05e5d33aa261d5ebdf29", + "tags": [ + [ + "t", + "Amethyst" + ], + [ + "t", + "amethyst" + ], + [ + "r", + "https://cdn.nostr.build/i/04b00315f81c574afa45ae9c5632952e9bd7bd472bebb45b6e83aa97a692546b.jpg" + ], + [ + "r", + "https://github.com/vitorpamplona/amethyst/releases/download/v0.70.0/amethyst-googleplay-universal-v0.70.0.apk)" + ], + [ + "r", + "https://github.com/vitorpamplona/amethyst/releases/download/v0.70.0/amethyst-fdroid-universal-v0.70.0.apk)" + ] + ] + }, + { + "content": "kyZ2J/PX5HjuuY6Fnw4Wwbb7aigSPVVL5nEieJ2rxeKOtIxKkdk/rMuo03JVuKOFgV3+TmyUQS8KEEI0TCv1zu8mBvrQ66gk8SFcVFRlDHINWO4gqMV3hQub1+kbgO/YZv/ez4aM90+TAH+gLqb1Is4gAOOJ+aLCpeT5mAkmpwx4WPA99Q1jgqUix6Hhq9vAZWfbB+YnoCkkePlMYdM6iqhdMAPrPwTj6sauatmQCkBFTiPD5kCro750tKS63cvkx3AyYGDJWxkC8yURnqp8j9MPzXsGoNRTdVyimoJXFZyY/v/iRzeWQwFL2sHa1PIqKrqwEE/9mZY8YAqtrMx+5WB8tco0Aj5QnCJpocJ5XEB9M23Hl4/fMDrRGUrf0KCSmiSd5oljW5ruasb5VEEMgwO6RudG28Qafk/Z2cZ2s+nx9fjkOHkOaorOhCotPq9d2bd6VpqXc27BnKU/LyxRzFqXI2bVl7Gzl15nTobELgfjSYFIeUWYhbzr6n9MhCe2dqgHIt4FR5NUnHbLMHylo5zVBBQTkOQ5TX4BiE/55BbDqmudqNuQN1ZaFmKvRIaoIutFhopNwYRVe+Lj8NGcZ6jvR1sw+AcngJBdYYsAPkRisMELbeUkVNkmUcWbQIRNPsuTSKM8M/HSDAA9SBH2V5Rzd+8G9SrNoCGJoueABfJqjz0JHg9fc5X5qfa9/Ly5S0bgHhWU2wueMX85+UiD5G8yJF26Gd/wEr4YQrMnXT9xmTJQ/YusKmygOxcZ4yuC15stNV6hPnx1Dwr4KhISbw5+i76f/GFgbY7iX6nfKLsl+A6UxNGHkVUt1QJWRP/BxcXjVY/1ynQMmUlyIDu8E/ZbHCGvZuOnYow7+BDfTmKzgwKRoO8HcbijxsPG/nKF4QUIP6177l+wL/46E0EZGxroyT+w7a4QcD9lhqD8Bm4+6qFvBt1Ihl3RVlVzN6WzaKHVzs/WUhRYXNm4qzyYwjtCPR8jJ7MnfgFqFqDYye8Ac7CdIZvU/j2B3Xqk0ROLpcigFw/53sHJzfPz64QeE+Iq0Ikm52Vd9NqBCzQWJpMpi2mDPEL39P6AqE17sEFrEiEz5Ul6sl9gI0UywPSgf7grY3Thl/LmmRVl7LtDqWJxQ6/0BI05pUtFo9PF6ZfbA2gqt21gB6kRx3FXpxiHN+1KB+eBkyTUa/GwyAFwO+1noID2c17HlBYwrxikxCH8WD0qCjXmy2rzAUopDTbLmtrREfDTDSqm3Wy/3bDLYcB6rKcVVZUGQWp7heAbhk1i2LLouBQ4aCBE+Q8NoyFct7WWNZ788s2gBwA9xYx6haCnWu8x/72Fq8EayH8pakEWqNsAb9Ig7oxUZUbUFVlURp/4hFA6ypVEsVxPSikJ/iS9g1f9hO3vQ451jKWmVboq9ViRNSvIwI4xzB8/iYi1/R1NVanEZLovOP591TcDs+rCRL6xBpeZPM8NFWiqMo0K2Hr5/SLpYR2SFTcVG5x5OGCvAQO1CsrK6YxXEkRI7uy1oo7bYZm/LgzPzGcbESRhZrA2VmwtdE6LC/vTt7PlW8zxPAzja8ZeLkuKSZPlo9ahYHNtuHAVTHh5JojspOMJlGIjOrnZaSPZF4kjtOfhevF8b15YuE/EDLnv2EAyGR7U0zGm1ZSUgecOW6D9dBX1DrMLXbnSydaDxq76bmMIXzynqlQNkTHLPrj+leiB95gNaAc8NnMJoLeK7E9FiFxD?iv=0wUJgJRH2qM6M22nQWTtzg==", + "created_at": 1689894398, + "id": "ad2118124d93a34e78de1868a03b5db77269de9bd847008aa56d234ac435d911", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "a32e5d31c055b090fe60ba719c8691c8500eaa9f0239e9b3ca823c8af7ef0251c470facd766d0915bf495d8414037a16692da9c487bc260cdb43f272a4aa2c22", + "tags": [ + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ] + ] + }, + { + "content": "gXTNhA9dmULS6RWEeUnGpJeK8jO62z9IXGTKEeZkFyLPyzR5cwhIyVDCPZra7fDs?iv=S/+MHIRTOC3YvN5SRg544A==", + "created_at": 1689894312, + "id": "9fddd6ed3006a4b02a4f61106f93422a875d9104e18ba17d44b41eb0d29118ba", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "3332078b36bcff14ed9b4079c4615bf2a73d07d5982dbc0c3c225ad768d400f1d152de5912119a122c7366465a193bfe47817c2a03c575664074fb47dc5a56de", + "tags": [ + [ + "p", + "672196e844d54702dc5933bf339d53e1b2641a767264384323957f424fd57b04" + ] + ] + }, + { + "content": "SVapbPIcn2mKwCD8+0X/ssrakEARyfHdunFpBqKHJXCwahK9G4A5+wT8Tn6HcmK+qALX/eCIEeotD9jQfT/yFw==?iv=V3qBEP8xd7627UWztQb/1Q==", + "created_at": 1689894286, + "id": "ad0a2b77c0575b49e3f05412a09abbd7575e76547e9565fde0315a89c16a5c26", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "8fa4798a22452bffe5c56eeb0fabfc3cbb9b9ebe1ddf861fae41321befa3d67354fc588f3e664c004b5d5450df27dcb6687dc5261bcb24c986fae40d81114f0c", + "tags": [ + [ + "p", + "672196e844d54702dc5933bf339d53e1b2641a767264384323957f424fd57b04" + ] + ] + }, + { + "content": "We could use another update from the user to identify that the stream is still live so that zap.stream doesn't need to keep updating the event to sustain its status. ", + "created_at": 1689893549, + "id": "6ce9b93a4fb5967d2f70225d0d8c7777c1f86d3fefa135229f8efcae338d783f", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "6126b61b95f23e5364f13a7f75899e582641398ad66aa77277182c839243f503e03fb36f5445366336ec6532dd03a3aa90951aa41ad2a153ffb114be9438d096", + "tags": [ + [ + "e", + "173eb29e7402ef1750db662d06b88a187ea9c0b31d4ceff1df5d048fe79be3fa", + "", + "root" + ], + [ + "e", + "4bee2e762c7d296bd66dd5b4a0e84dc7e0a98355ad5f18277ac65c06da9ab25d", + "wss://nostr.bitcoiner.social/", + "reply" + ], + [ + "p", + "63fe6318dc58583cfe16810f86dd09e18bfd76aabc24a0081ce2856f330504ed" + ], + [ + "p", + "00000000827ffaa94bfea288c3dfce4422c794fbb96625b6b31e9049f729d700" + ], + [ + "p", + "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d" + ], + [ + "p", + "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245" + ], + [ + "p", + "ee6ea13ab9fe5c4a68eaf9b1a34fe014a66b40117c50ee2a614f4cda959b6e74" + ], + [ + "p", + "5c508c34f58866ec7341aaf10cc1af52e9232bb9f859c8103ca5ecf2aa93bf78" + ] + ] + }, + { + "content": "This could help in the updates to the LiveStream as well. ", + "created_at": 1689893064, + "id": "bf3bb95525800c504cb74c0c60a5e532fd1bc9d774613af6b6cf8125900a33b7", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "dcc36fde64e0b483114cec6ddf5f72b9f53a7deb9bf06475a4f36aed81b2d41d0b2982e77dee6d1a015c219db7bbe8672c5c43abd49646956d7a1ac669a6ee04", + "tags": [ + [ + "e", + "173eb29e7402ef1750db662d06b88a187ea9c0b31d4ceff1df5d048fe79be3fa", + "", + "root" + ], + [ + "e", + "fb6f8c9055d34b3fd2eca32f96a5193f9a491a623a57819b8c904e0504477190", + "wss://nostr.bitcoiner.social/", + "reply" + ], + [ + "p", + "63fe6318dc58583cfe16810f86dd09e18bfd76aabc24a0081ce2856f330504ed" + ], + [ + "p", + "00000000827ffaa94bfea288c3dfce4422c794fbb96625b6b31e9049f729d700" + ], + [ + "p", + "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d" + ], + [ + "p", + "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245" + ], + [ + "p", + "ee6ea13ab9fe5c4a68eaf9b1a34fe014a66b40117c50ee2a614f4cda959b6e74" + ], + [ + "p", + "5c508c34f58866ec7341aaf10cc1af52e9232bb9f859c8103ca5ecf2aa93bf78" + ] + ] + }, + { + "content": "To the best of my understanding, that is only true if you use a different IP for each contact of yours. Otherwise, the server can easily bundle your queues and map out who you are. They call re-using IP an \"opt-it\" security issue. Even though most people are reusing the same IP for everything. ", + "created_at": 1689891763, + "id": "48735c6e1caa54c82015c1a11d86c9c3ff8e7e6102992bc32b78f6c5c4294f43", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "b5e3b53de8cb327f7da73d2c9a09bf409d484e3dbca8ec7c844baf9b11ae9e3cef535b82d6c716260eff36bb672c1ab2a5ec85f445a539dba4cc919af0e8e0e1", + "tags": [ + [ + "e", + "dba7825c157548cb16be88cb771db063862ce2adb1969193cadcb29a164c536a", + "", + "root" + ], + [ + "e", + "0bf10092a54fee81dbd3ba2100eb80766276e93a30bf752961ae890be2993617", + "wss://nostr.bitcoiner.social/", + "reply" + ], + [ + "p", + "9110fe860a5e40a41e03d52d306a7b337ecf32d1090812ceaf423ec9b94954c8" + ], + [ + "p", + "04ea59bf576b9c41ad8d2137c538d4f499717bb3df14f5a20d9489dcc457774d" + ], + [ + "p", + "c998a5739f04f7fff202c54962aa5782b34ecb10d6f915bdfdd7582963bf9171" + ] + ] + }, + { + "content": "+", + "created_at": 1689875139, + "id": "7ae6e200034e48f561c22648e41f677cfb71a7713bcba6bec683c74727ef9619", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "7d73b8fe475b99b11e8041728e32f55b505fa57f141fe9a301d7112336fc2cc09829734d27100168ce3a20894b8321965c3479f544346ec4e2828ad313e36178", + "tags": [ + [ + "e", + "39d9dae2bbd253e85c78c55ab89588a245a9c40ad03373fc355153d35119c80a" + ], + [ + "p", + "bf2376e17ba4ec269d10fcc996a4746b451152be9031fa48e74553dde5526bce" + ] + ] + }, + { + "content": "Same issue. The metadata is always somewhere. On Signal, the servers at the company know the destination user and the time of the message. They claim to not be saving it, but who knows... For SimpleX, it's similar, but on their relays instead. ", + "created_at": 1689874092, + "id": "06756e30fb3a5a5adcf0ce8953e428dedb6511b03cd5d219cb3f394e58dc1657", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "6a26f8fd80c2ffef7ab5c0e505e2223ab57f4b4b049e7a5135afcf03c2fae44b71eca7a457f406c4fdbf3cf74c52a832eb354d303fa236c431ee0638680fc219", + "tags": [ + [ + "e", + "dba7825c157548cb16be88cb771db063862ce2adb1969193cadcb29a164c536a", + "", + "root" + ], + [ + "e", + "fc7fd52ed1a79e8f7a1dd6a84e38a04a73a38b92a7a43e4c76df9708adf70946", + "wss://nostr.bitcoiner.social/", + "reply" + ], + [ + "p", + "04ea59bf576b9c41ad8d2137c538d4f499717bb3df14f5a20d9489dcc457774d" + ], + [ + "p", + "04ea59bf576b9c41ad8d2137c538d4f499717bb3df14f5a20d9489dcc457774d" + ] + ] + }, + { + "content": "Clients generally filter by date, so you might not see some messages if you do this today. ", + "created_at": 1689873381, + "id": "cf1b4e3048fd829ba241bc84b850937cf8ad256208309fff0ffb92c6ad20cc00", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "8463639628afe7493e61931e6613da239d489d2c9c3212e0c58ac622a166c6664cb13cb33b80531f4037da99d2bf53548ad4553104ce55e161aa5cfe11e53584", + "tags": [ + [ + "e", + "dba7825c157548cb16be88cb771db063862ce2adb1969193cadcb29a164c536a", + "", + "root" + ], + [ + "e", + "d8d90496d54ebf856ecb5624e4b9e07950dd5afb1c57ff2b1a25fddbef98185c" + ], + [ + "e", + "adc0937780518b6a35c3ac44e36b2c48d0e6643d3609847652c8a4c245bca2c3" + ], + [ + "e", + "c98d7ec7858ff362a45b60c8a6dcd03c9b66f30ad65e89755b66d0c38320c858", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "04ea59bf576b9c41ad8d2137c538d4f499717bb3df14f5a20d9489dcc457774d" + ] + ] + }, + { + "content": "🤔", + "created_at": 1689873007, + "id": "0900a6bf9d2ef4b4765074b26e277bd8ae573e8dd697fd2a2a2626f2e6deffc3", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "d0a69e056d477f73ad70ad00ffab45cf33d685bae46a674552871eaf47f131ce2e063fe2064a4710f0393869a96712d0ae85e626b895e1f979e4478bdef8e56a", + "tags": [ + [ + "e", + "1a3cf67ecc40a0861fd39830417671a62c98ad35de0ee0ad9a78ff2b0170e1f7" + ], + [ + "p", + "21b419102da8fc0ba90484aec934bf55b7abcf75eedb39124e8d75e491f41a5e" + ] + ] + }, + { + "content": "🤔", + "created_at": 1689873006, + "id": "330f32a6c42c2f555cc1b2def25e521ea35823a81bb9fe36d08cab65bc5bfaba", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "c1dd416e6ba387ce6b74a5e8e7040e2f3e01b0a3ccf95660ffa8383da9f0e7cfbed1e9294416c3f386a9cd071a30b9767801bb2cd47dc3026e6d3116e7c8f6d5", + "tags": [ + [ + "e", + "7f4c1bd91549cef6c1e960bb3beda056f559097cee1fc957c131b4029595d6f7" + ], + [ + "p", + "d0aa74cd95a651d3d2ab4fb18b58fe71b447d78d40f8dd46f1dbaed5603d35cd" + ] + ] + }, + { + "content": "Nah, governments can ask operators for their data", + "created_at": 1689872829, + "id": "deac3db2b74976056d8f5a4543aaffd9ddabe2209323861605bbbacbb1a2309d", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "f827a824cc259fdd1b222d29ca59c63afc5d5926039457cad968d9461787f4d6757dccfebf9c60cbf2d47c9cdd3388d2aca713326530bccc3bd8c33066e4db7d", + "tags": [ + [ + "e", + "dba7825c157548cb16be88cb771db063862ce2adb1969193cadcb29a164c536a", + "", + "root" + ], + [ + "e", + "60de51c3eedf47496b23b5bb16c9b0513d776d9eab4326255adfc9df791f5eb1", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "2ef0fccfd5a55e36bc8be3a525c1ce97f20eabaa94e69d82febfd641d9480c35" + ] + ] + }, + { + "content": "Governments establishing a stronger evidence based on a time collusion of separate evidences. ", + "created_at": 1689872769, + "id": "adc0937780518b6a35c3ac44e36b2c48d0e6643d3609847652c8a4c245bca2c3", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "b46c04c7a396461959a0da797d2efb9ce1cf59fd00bb48bcb3f5b8985b7eae1168636119fdc982914acf5f5419b852d78a1a78f3453e6b1b0c561cb5bb57a441", + "tags": [ + [ + "e", + "dba7825c157548cb16be88cb771db063862ce2adb1969193cadcb29a164c536a", + "", + "root" + ], + [ + "e", + "d8d90496d54ebf856ecb5624e4b9e07950dd5afb1c57ff2b1a25fddbef98185c", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "04ea59bf576b9c41ad8d2137c538d4f499717bb3df14f5a20d9489dcc457774d" + ] + ] + }, + { + "content": "How do we hide the date/time of a DM message? ", + "created_at": 1689872583, + "id": "dba7825c157548cb16be88cb771db063862ce2adb1969193cadcb29a164c536a", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "69870943756995ebd822c0d56cd2ffe451fd8713bcddf7e8828dbe3f833823005f3e4a34170eaf4020fef416c66af03ddf00755eda42452c0b53c8079771a403", + "tags": [] + }, + { + "content": "O2u7Hl+o63AeQNONtyIXjDI/2Xi0WckHVWZ8aGJnO8hrT1XILWJ49X11Tz8eM25sW5vxceKR2gnYUh+paux3ZMkfhTYdcm63f9AYsyQBS8k=?iv=/iMP4rhqmyQXGU8+7llTuQ==", + "created_at": 1689872451, + "id": "175fc151ab6ba3d8c567e8bb372827ec94b875290068d4601251401042027edf", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "4a3e683e8a5073f191de3d49cbd5dfd4688382ceff1050addb5f5f6495bc7780d9d225ce346c23551141cb36442fedc2848f09db68d27f25fe2150200d1614ff", + "tags": [ + [ + "p", + "8083df6081d91b42bcf1042215e4bfc894af893cd07ea472e801bc0794da3934" + ] + ] + }, + { + "content": "e2dv5uyGynDKSN73wEsul1qw9v6Lns/jEYGcZud+u9Yh5gO6cuHHjVcwlZvIysfiEEL/UkcM1LSkpsrzrk55z5Ruy4f3CJsacb4DTFX7eI0=?iv=rCyLaRVvDh5PyMR4rZrIUQ==", + "created_at": 1689872401, + "id": "b3fece9b46c5cd3a5243d2bb4d23db4ab8648ad7b0fa6348a519c3da895c3ede", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "1ebeb7474c7a58a87d9738119fd692a7aa19ab65e231f43deb46c2d51814fa217194224871a7a8570e93eaeade1b7517e9cd13c54166d57c18aaf3a2fd0ce778", + "tags": [ + [ + "p", + "8083df6081d91b42bcf1042215e4bfc894af893cd07ea472e801bc0794da3934" + ] + ] + }, + { + "content": "It's sad, but true. However, we have a bunch of new non-twitter apps to balance it off. \n\nnostr:nevent1qqspadh2506xtrpjtld0mu0e5ly29cdseu2u7vrx5thsxp88t4uy6dqppemhxue69uhkummn9ekx7mp0qgsph3c2q9yt8uckmgelu0yf7glruudvfluesqn7cuftjpwdynm2gygrqsqqqqqpz67xy5", + "created_at": 1689869163, + "id": "e35dd1efdb8d688b2dd82d8e87c10891c2c15e0bfa85d75302366397abffff6f", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "16fa751c379b5107f0a8f7c975daacc95806f7d50a0b9f1fc58fbb8008c32278581f0937e3aae646e01d6bdb34a4f9eed8b783fe756378c8c20463e875b9dbc0", + "tags": [ + [ + "e", + "1eb6eaa3f4658c325fdafdf1f9a7c8a2e1b0cf15cf3066a2ef0304e75d784d34", + "", + "mention" + ], + [ + "p", + "1bc70a0148b3f316da33fe3c89f23e3e71ac4ff998027ec712b905cd24f6a411", + "", + "mention" + ] + ] + }, + { + "content": "+", + "created_at": 1689868629, + "id": "7f13a40f500a511d643ee6115877753a788f00c2b00d342a5c3cfbc99190b16b", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "22d6b5deedb017d291ae94d1e638a479397ae76c8eca229b193555bc436afc30e8f795a27224417b68a2b0a41e96414a14d203193facdc9ea2d0760ea7a4bf5c", + "tags": [ + [ + "e", + "9c27822da347c0083c2908d51f2429917e079e0fd1d623e334cc2946395dd123" + ], + [ + "p", + "ee6ea13ab9fe5c4a68eaf9b1a34fe014a66b40117c50ee2a614f4cda959b6e74" + ] + ] + }, + { + "content": "I can see that you like good UX. I just wished you just asked for... say... to increase the space between the text and the image directly... instead of this snarky post: \n\nnostr:nevent1qqspxnxmq8gvh2zf64ktvqt6ahhme7qy86cpvzqgnmszj5dc2stsrpgprdmhxue69uhhyetvv9ujummjv9hxwetsd9kxctnyv4mz7qg3waehxw309ahx7um5wgh8w6twv5hszxnhwden5te0dehhxarj9ecxcetzvd5xz6tw9ehhyee0mrzlhx\n\nAnd since you like good UX, you should know that this is not how you ask for improvements from anyone, anywhere. You ask for empathy, but you didn't offer any of it to those building the product. \n\nThat post could have simply been: \"Hey Vitor, can we increase the distance here between the text and the image?\". That would have created a more productive conversation. But no, your wording wanted to shame me and the \"product\". Basically a \"look how bad this is!\". Maybe I deserve it, maybe I don't. But that language goes against what you are preaching all along. \n\nOn a last note, Amethyst is here it push for everything, all at once, and move forward as fast as we can. That comes at some UX expense, as you realized, and that's ok. With more help, we can probably offer more UX improvements, but at this time, the majority of the development is still on new features. We are still on version 0.x for a reason. We are not even half the way of an actual product yet. ", + "created_at": 1689868224, + "id": "209fbae56844f5d16e64fdb4026ffd966864de649062c30146f8e588bb5eb452", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "fc3e11ca74034193f5c7044e80f6c5a4b035b7daa82147584c91fb8b931638daa43c5e7d576c4ca7bb295d4ca955a7e7f63658dce6e9ebe489b3a0473efaf3d8", + "tags": [ + [ + "e", + "134cdb01d0cba849d56cb6017aedefbcf8043eb01608089ee02951b854170185", + "", + "root" + ], + [ + "e", + "7aeb2f3ccca028aa33a3ffc287e6538e492d61c0ccae70627275730fcc354ac6", + "wss://nostr.bitcoiner.social/", + "reply" + ], + [ + "p", + "ee6ea13ab9fe5c4a68eaf9b1a34fe014a66b40117c50ee2a614f4cda959b6e74" + ] + ] + }, + { + "content": "Dude... I am here listening to you. I am not bothered at all. Why are you so angry at me all the time? ", + "created_at": 1689865738, + "id": "7edef713c3d24ea0271368c68e844ec1360c026f21c045c7b517a872de094259", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "7ef93ac8f1bb45c1b8b11a8c7f168c82c7deeb3d3b31221c60fd0ec21a0f7a11ed4443f194bed7cfabdaa90e912d6cf25bb7e2ca85dfd813e9d74611ac469b36", + "tags": [ + [ + "e", + "134cdb01d0cba849d56cb6017aedefbcf8043eb01608089ee02951b854170185", + "", + "root" + ], + [ + "e", + "cebe888ef52d02e679c32b0259e441095576bf9ca5a4508f69deb2a924c9f926", + "wss://relay.orangepill.dev/", + "reply" + ], + [ + "p", + "ee6ea13ab9fe5c4a68eaf9b1a34fe014a66b40117c50ee2a614f4cda959b6e74" + ] + ] + }, + { + "content": "Yep, that's the thing I was trying to avoid. I don't like disregarding what authors do, even in these small details. If people add a line, there should be a line there. But I will do some research to see how to improve it. ", + "created_at": 1689865669, + "id": "4b771bbff33a16eb80f6568a5473c1415d8db077884b8135b105c661c64c0af7", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "9517d5805d660b34e2574d7d95b3bcb25537dca821df8188d7367ce2b2189aeaf1eb53da84010e0d248054a3f9c8d6e616f0ef5eaa0e50d306eaeaef5bbd7474", + "tags": [ + [ + "e", + "134cdb01d0cba849d56cb6017aedefbcf8043eb01608089ee02951b854170185", + "", + "root" + ], + [ + "e", + "9a8ddc77b81891173936d4d3c44501ec5873c1ac6a246e34f89425e4bc4d33bc", + "wss://relay.nostrati.com/", + "reply" + ], + [ + "p", + "ee6ea13ab9fe5c4a68eaf9b1a34fe014a66b40117c50ee2a614f4cda959b6e74" + ] + ] + }, + { + "content": "I was just asking because you seem to care about this detail more than everyone else. But if you are offended by it, I am sorry. I won't ask you anything anymore. ", + "created_at": 1689865536, + "id": "72af445176b583364787978c772c929a550202cfb588da2e2a97bdef3601c93e", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "ede069883773114b2303a9981db6d6f72125aa423ff1a58acf0aa01af0ba498240bf60cd2a6a8350f0a58c972754ffde1a267fdcaa967fb7200d6a5605249193", + "tags": [ + [ + "e", + "134cdb01d0cba849d56cb6017aedefbcf8043eb01608089ee02951b854170185", + "", + "root" + ], + [ + "e", + "f49066620597bf34152ec79fdd44f4647016f9f519610bd2b470127915593a13", + "wss://nostr.bitcoiner.social/", + "reply" + ], + [ + "p", + "ee6ea13ab9fe5c4a68eaf9b1a34fe014a66b40117c50ee2a614f4cda959b6e74" + ] + ] + }, + { + "content": "If there is a new line before the url, do they show an empty space, then? Or do they just disregard how the author wrote? ", + "created_at": 1689864705, + "id": "c469379a1f15f7bbcc2a5da7a8b5eb3cbaf1a90c9c1e28c2b424ba88114fa496", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "914cb11c0f23568631c72b41ebe14b5d12f665a7785e5cc28c2e77b8d959c1e62d9af1b4d5b056783f7534f605d4e462750ea34c9cdc44a938764fe1b35eb1a0", + "tags": [ + [ + "e", + "134cdb01d0cba849d56cb6017aedefbcf8043eb01608089ee02951b854170185", + "", + "root" + ], + [ + "e", + "a4947c5d9a71d2d944e0cd1edcafaf25375ef1d4eefdc495d8ef58c38cfe6d48", + "wss://filter.nostr.wine/", + "reply" + ], + [ + "p", + "ee6ea13ab9fe5c4a68eaf9b1a34fe014a66b40117c50ee2a614f4cda959b6e74" + ] + ] + }, + { + "content": "+", + "created_at": 1689862624, + "id": "79d66d3f15bea48b6d0ac94f1a940ea7a0ec936527f56b7296df12f127560999", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "5e1749add3f9f02d3044c2d2919313f8e616a7ff4bbd7dd0735ce475425dcf1d65f388f4705e4a18224ffe86e69a194037ebe21f749a515d18e537e75eab2080", + "tags": [ + [ + "e", + "7c3b8478c7fae8943356cbc72fffb91d0972402226da9d84a3f63d3a77bb44c9" + ], + [ + "p", + "7fa56f5d6962ab1e3cd424e758c3002b8665f7b0d8dcee9fe9e288d7751ac194" + ] + ] + }, + { + "content": "+", + "created_at": 1689862150, + "id": "dd53ef21c2183dd451d8282291c54ffe30aa4a737b2111621f1a02beef772af4", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "fec7169c25bd4c995794b079f1acbf4212ce27555d4e20a57b5ed10be85e0a53c950db078c9c4460a2590baec3f0c88762e212411799b76da6ce529e886568ed", + "tags": [ + [ + "e", + "c0012d024315e94af4a3b78d88b5764b3db502689cc40e59f82051e57d69cffa" + ], + [ + "p", + "50c5c98ccc31ca9f1ef56a547afc4cb48195fe5603d4f7874a221db965867c8e" + ] + ] + }, + { + "content": "Do you count just anyone in any list you follow or do you want to break it down per list? ", + "created_at": 1689862073, + "id": "5836b1b6d60d819f7cdb9db7b723734ed46a43ee3905c712c379fe8430bea635", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "a5e34cb72dec3b80098a9d092c122628e192020c9d96437c63729f9c2fa892d5cb73b43bc08f7b18ea9048db5938abf0e3cf5688d615dfc879f956154cdb2467", + "tags": [ + [ + "e", + "134cdb01d0cba849d56cb6017aedefbcf8043eb01608089ee02951b854170185", + "", + "root" + ], + [ + "e", + "3a16231d3ae0dbd75a99c7d6038acef7ea2c510b123c566436965f813a638bf5", + "wss://relay.orangepill.dev/", + "reply" + ], + [ + "p", + "5fd693e61a7969ecf5c11dbf5ce20aedac1cea71721755b037955994bf6061bb" + ], + [ + "p", + "ee6ea13ab9fe5c4a68eaf9b1a34fe014a66b40117c50ee2a614f4cda959b6e74" + ], + [ + "p", + "7bdef7be22dd8e59f4600e044aa53a1cf975a9dc7d27df5833bc77db784a5805" + ] + ] + }, + { + "content": "+", + "created_at": 1689861399, + "id": "72c71b828d4ba31fd341a35bc2ca90e24dae437cfe8d1b4aea48354154222d09", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "1d78e9b3459e05b3fe269ec8ef4351bf86d54783d14585bbb2c0a370b3e9e47f81998c0b47168e16f568208ab7e55c4db33e1375b5f1b840105926a0efa5cb0f", + "tags": [ + [ + "e", + "0c1560b408c5fd5fba808d72506faf0de36b684beb39ae130b625ff48ac78e76" + ], + [ + "p", + "f4db5270bd991b17bea1e6d035f45dee392919c29474bbac10342d223c74e0d0" + ] + ] + }, + { + "content": "+", + "created_at": 1689861396, + "id": "43a89e40238a6eb9cbf43bd5df47879e6952b4bb7f4cadf93ce57de2a16087f3", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "07801393346d8264c7833d4926c6daa456630be169f61b504e73c86e5976cf1dcc283bf9334238457523ab0f6feddd9ca4f9d4c005e077851654c8070b10b27d", + "tags": [ + [ + "e", + "f4bc628a982288fae1e8e49b4858a64943e6cf9bbf25cf04faba489ec26355aa" + ], + [ + "p", + "f4db5270bd991b17bea1e6d035f45dee392919c29474bbac10342d223c74e0d0" + ] + ] + }, + { + "content": "Ohhh... Community tabs for different kinds. Very smart. 🚀\n\nnostr:nevent1qqs2auwg7glxpsqg5nvwqyuvpnzx6vgjvw40v2kyg8ptrr5dj6rg6zcprdmhxue69uhhyetvv9ujumn0wd68y6trdpjhxtn0wfnj7q3qalpha9l6f7kk08jxfdaxrpqqnd7vwcz6e6cvtattgexjhxr2vrcqxpqqqqqqz4hge7g", + "created_at": 1689861199, + "id": "998372074cee04fc8b89bb385dd6eb0ceba8cf5012446222ebef7fcc33662f04", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "39ac7eda70f0fe0711db4bc00bc2bc1cec8e7a45fd27daff370660fcc074a75b1057956a2186a4ce5dd8617048b79e0770e09b80a57fa187e3025a169ac3deae", + "tags": [ + [ + "e", + "aef1c8f23e60c008a4d8e0138c0cc46d311263aaf62ac441c2b18e8d96868d0b", + "", + "mention" + ], + [ + "p", + "efc37e97fa4fad679e464b7a6184009b7cc7605aceb0c5f56b464d2b986a60f0", + "", + "mention" + ] + ] + }, + { + "content": "I think the issue is on how to link the list choice and the relay choice. Does each list have their relays? Or maybe each list have relay list options? Or maybe the relay list is global and works for all lists? \nMaking that make sense in the UI is a challenge. ", + "created_at": 1689860877, + "id": "81911e85a3c7de2db65564853d4914a244ead918c2a9d2a17ab9a4f707bc63ec", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "9a2caf4c047ef61a84e5c1d54e5297707eeac4b6e839cd696336e3d55101fb77924689fbbe167e9d60460f48cb755e27805c0b478b6d98a96fd05e2264e9554b", + "tags": [ + [ + "e", + "d8b836d465e495d4aba08c1ec2ad934009824c0bcf4274cd5a36828b25138503", + "", + "root" + ], + [ + "e", + "4f26cec8a0e10ebd1be60ab8debaefd2de1a3f4e2f6c05910cbaa0d825c9439b", + "wss://nostr.bitcoiner.social/", + "reply" + ], + [ + "p", + "e2ccf7cf20403f3f2a4a55b328f0de3be38558a7d5f33632fdaaefc726c1c8eb" + ], + [ + "p", + "e2ccf7cf20403f3f2a4a55b328f0de3be38558a7d5f33632fdaaefc726c1c8eb" + ] + ] + }, + { + "content": "oJ8doMpCQ6ZfFxbyPiaH1Omq+QlT00sigyEEdmF0CqE93YpfSkTaawk69Y4G3RKet0JBbRZgwPlhtdhU2KBiRpQ8Ggf/W3cHayb5NeeaYB466R4GPeGfeAP2yV18ASnoUURqKH9j7kCazec6s38BKofrrlr/O2uARqTAZz+aff4MqMRqkjBwJXkUqwGQNgjZ7KXcSSi4R8g6eUfChTZaBEryxQh00zK+skAGhZFbvilgCSZ+PjDAohC/4Nz9kxK9jlRJZ48cjbZJlhSpcNv8Z4q5x7l4CWjZhomBjFgrbyXOXsdMUXb2Zy0ZaBkd27uk/O4SlWdT7oui+LC+sYd8CkfFln3Ho5kgFp7nnzi8emFowPKVVv3sU0J2Sc9Rw1nNnZT0ZKeOhqZq5MaRBPX2gDMhJf61n/JMImAKN7ZITgA1QJaw1mDplV+CdZ8kXHfn2gtOz+u+rGa9mJR/fsfgz30klfcixBUlKrQu43jorkU=?iv=wlPb/Dk80+TDdCjEVj1zxA==", + "created_at": 1689860762, + "id": "3082d8546d083e4c02e513e31fc7e8fa86d86d760958619a62fa9328df0592cf", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "26f8d38baa4b62826b067cea227fc2c169c1055f632becc9c6dc2dc26e4807c296c9d97a41f83a75d63297dc67a2918d27c0f2d42e5a815075603ddfc9a7524b", + "tags": [ + [ + "p", + "63fe6318dc58583cfe16810f86dd09e18bfd76aabc24a0081ce2856f330504ed" + ] + ] + }, + { + "content": "NmGECBQokRbj25yC1GLM+0EQp4uDQnbCUMAGr6BkfNGTPyGRV9Wp+nSMxU+5QWa6tfPPuT53FhSairq9lGgFxA==?iv=LWNGgfl2ZxKJaOulvEt+nw==", + "created_at": 1689860574, + "id": "786ecdd73e40b5a8df20fcd26a792b49fef7ee599002afce4c1286984316db13", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "27ff060daa027c8945b0908c25ef216e5442ccf92fab897e604a3dadcc7348c6a9b7e027c26e6777f5fd17f9b73cf1f1b5220c8bf3036c00c8215e772870138c", + "tags": [ + [ + "p", + "63fe6318dc58583cfe16810f86dd09e18bfd76aabc24a0081ce2856f330504ed" + ] + ] + }, + { + "content": "EmytAFZloV1YnquNnF4dS/SMoenFynEDbYcWjQF95sQ=?iv=uADsN7t5Gac2HA+6X87Ung==", + "created_at": 1689860432, + "id": "23e2d47970dd18fc49cf39e0e1db5ee94d03f7370809cd4de9748fc77bff4a0b", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "282e43b702199690d8d62543a09d3d469ba8544350b022c24cd2bc6838a6169a471c7a1839a58bb6b6592e0bcf9687561ca91d118d90d01d729cfd383407e611", + "tags": [ + [ + "p", + "63fe6318dc58583cfe16810f86dd09e18bfd76aabc24a0081ce2856f330504ed" + ] + ] + }, + { + "content": "zpV5c64Gr25S63G3P21ulXKzd2pItJXtq8sE8P72wtY=?iv=Zq+BthTWRbtlYb8mKvdmhg==", + "created_at": 1689860314, + "id": "3633e70aaccfc32800d2d435aeed6f447c55e646a3e94f2251e5deb2fff926a1", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "c358edc8614575bf56b207452274de2800befa7d8905f306c66bbf4f8e44f5b1b2674fe5bfe1153ad3298a0f9281ec1135b2c1f57a05b006003c085eda755a24", + "tags": [ + [ + "p", + "63fe6318dc58583cfe16810f86dd09e18bfd76aabc24a0081ce2856f330504ed" + ] + ] + }, + { + "content": "For posting is ready to go: https://github.com/vitorpamplona/amethyst/pull/511\n\nFor viewing, I am not really sure where to put it yet in the UI. ", + "created_at": 1689860166, + "id": "b6fea7cc4087d399fb7b8b9e74cdca10c27d9756816665271737630db01d6326", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "361abef7aa4ece11a8cfa6371a3e2f5b5315ae0d31c3a10ac3d548940f62ba8982d1643d6c6228d84dda1aa9442872ca01fdc2830ba855d8494826a10f012f2b", + "tags": [ + [ + "e", + "d8b836d465e495d4aba08c1ec2ad934009824c0bcf4274cd5a36828b25138503", + "", + "root" + ], + [ + "e", + "b6aa079b9b7c174a42441857fcac737a1924229a7895e3cbfa74466256403fdb", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "e2ccf7cf20403f3f2a4a55b328f0de3be38558a7d5f33632fdaaefc726c1c8eb" + ], + [ + "r", + "https://github.com/vitorpamplona/amethyst/pull/511" + ] + ] + }, + { + "content": "Amethyst is the Swiss Army Knife of Nostr clients. \n\nGM.", + "created_at": 1689860006, + "id": "d8b836d465e495d4aba08c1ec2ad934009824c0bcf4274cd5a36828b25138503", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "f6a03ab1f6715956b000e40ac4e524ecd8112f6a985d387b671a5c8c96f74b5edaa75ad7364b2e0efe6e10cd61f28b76b6cfc16f31e6d0a98132c22852153660", + "tags": [] + }, + { + "content": "The off-place heart has been fixed, but I am in the middle of a massive refactoring to ship background media playback. I hope I can finish it today. ", + "created_at": 1689859895, + "id": "f0d79ad5e47832399d6e758c63e7ae6b3c4041abd60a6c3f2baf7bd3b5bec847", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "efc9be562ec6b9827408ab1343443226ef638b8b70ff7bd875ae4b12a9c6dc19c5eb10537dc09b8b19a321230e8441b0e88519d70a0fc464a1a22855570b6357", + "tags": [ + [ + "e", + "134cdb01d0cba849d56cb6017aedefbcf8043eb01608089ee02951b854170185", + "", + "root" + ], + [ + "e", + "d29521c859bce7262b1e1a988c9288d88466851c2baffc6f7578b0d9f2937347", + "wss://filter.nostr.wine/", + "reply" + ], + [ + "p", + "648c0f5302c75f38382a4d2c85a482b927cc61b2828a0794e36c6cc796de86a6" + ], + [ + "p", + "ee6ea13ab9fe5c4a68eaf9b1a34fe014a66b40117c50ee2a614f4cda959b6e74" + ] + ] + }, + { + "content": "Sorry, I just tried to provide feedback on why things are the way they are. ", + "created_at": 1689859533, + "id": "23aad9e03bbd73536e22e830f819868447211e8ef66953830df4b1797c50cf97", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "f33c542e002f2d788b76cf55ee3fe144aaddf993f5a5c7e786fdd9ada1d3f180ac3686f0b504444abe8cf050d503052f16cf07b169da0128a5612f9ca378add3", + "tags": [ + [ + "e", + "134cdb01d0cba849d56cb6017aedefbcf8043eb01608089ee02951b854170185", + "", + "root" + ], + [ + "e", + "c5d0cdba3717383bfdeafe50c1275c95de28b18d036df0a60699b9ca019522e2", + "wss://nostr.bitcoiner.social/", + "reply" + ], + [ + "p", + "ee6ea13ab9fe5c4a68eaf9b1a34fe014a66b40117c50ee2a614f4cda959b6e74" + ], + [ + "p", + "7bdef7be22dd8e59f4600e044aa53a1cf975a9dc7d27df5833bc77db784a5805" + ] + ] + }, + { + "content": "You can already do that with lists. Even if you have not created lists yet, you can pick between Global and Follow lists to see notifications from. If you want the feature right now, you can create a list of the people you care most and that list will appear in the Notification filter. \n\nThe only issue is that you need to make a list in a list client, like highlighter.com or listr.lol", + "created_at": 1689859394, + "id": "b4b1f87e23e0287022def5727e902c550fddab066777ea788e85202613a01876", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "161b8ff1c1bcf4b20d88d17a41dda3f28d937a5228c1db4d1922557c76cd16a710d836a8cec1639777882e676069df86225500bbb631096ed4c21112385b426d", + "tags": [ + [ + "e", + "2f93fdd2f638c4932deff5b2dfdeb8e0f3c464d837e579defc2f95e428574112", + "", + "reply" + ], + [ + "p", + "01ddee289b1a2e90874ca3428a7a414764a6cad1abfaa985c201e7aada16d38c" + ] + ] + }, + { + "content": "Yep, it's similar to how GitHub and Reddit do it. But in Nostr, reaction counts are less interesting because anyone can create an account, inflate numbers and change a reader's perception of how the post was received. \n\nIn Nostr, it is more important to know which person provided those reactions than in apps that centralize identity.", + "created_at": 1689859264, + "id": "98e44e39877beaae41a73c2ea0016087e1a933cff20978715b77abcbd15057ad", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "0b5ac8ac7a02c0afb50e4b1f65d1d72e5c69cb6b019ed61fb788f476ff35767c219e324ecf81298cb91dab3afd8a16c10f56beaa87b3b9b5ba1f28963f7ef94f", + "tags": [ + [ + "e", + "134cdb01d0cba849d56cb6017aedefbcf8043eb01608089ee02951b854170185", + "", + "root" + ], + [ + "e", + "ffdd0c0aa3242dfcde3a4dd2b40a8d7b72b1a35c59199b130936c311a6524fc1", + "wss://relay.orangepill.dev/", + "reply" + ], + [ + "p", + "5fd693e61a7969ecf5c11dbf5ce20aedac1cea71721755b037955994bf6061bb" + ], + [ + "p", + "ee6ea13ab9fe5c4a68eaf9b1a34fe014a66b40117c50ee2a614f4cda959b6e74" + ], + [ + "p", + "7bdef7be22dd8e59f4600e044aa53a1cf975a9dc7d27df5833bc77db784a5805" + ] + ] + }, + { + "content": "> I feel like the reactions take up a lot of unnecessary space \n\nThey are designed to be a little party about your post. In other apps, reactions are relegated as useless. And because of their UI choice, they definitely are useless. We are trying to bring meaningful reactions back. This means there should be an easy way to immediately extract meaning from the reaction set. The current interface is not perfect by any means (especially because this is mostly an old design updated constantly over the weeks), but that's what we are going for. \n\n> should maybe be collapsed into a consolidated view that can be expanded to see them all if the user wants to. \n\nThat already happens in the posts in the regular feed. When users come to notifications, they want to see everything that has nappened. Hiding things that happened because we couldn't find a nicer UI yet is not a good idea. \n\n> The stats would feel more natural below the post than above it.\n\nI agree. But this is \"new\". We changed some of the reaction design in the feed and also added inline replies at the top which should have inverted the reaction set look in notifications. We will get there some day. \n\n> there is no space between the pfp images so it just looks very busy and cluttered. \n\nI tested adding some spaces, but it made the experience in low-end phones (which already don't have much space) a lot worse. So, we reverted until we get a better idea. \n\n> The badge on the pfp has a lot going on and could be simplified. \n\nOn this image, it's just the profile picture and the badge uptop so you know which ones are the ones you follow. I am not sure why it is a \"lot\"\n\n> And there is also not enough space between the text and the image in the actual post.\n\nThat is a problem between clients. In your post, there is no new line between \"I’ve been missing you. \" and the image url. So, it should be as close to the text as possible to correctly represent what the author wanted. Adding space is not what the author wanted to do. ", + "created_at": 1689858675, + "id": "e8d93fb9fe8aad86af190d0c9780ca4c4e5019381914b8cb65fc521eba6036d0", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "b2836ab980831edbf8b7ebe4948f8e65e49a172a8c0bc583264069fb2253787533a64ce294d60b876324d4646788ba8588b8ddcf33f58266f83b6a87e812de35", + "tags": [ + [ + "e", + "134cdb01d0cba849d56cb6017aedefbcf8043eb01608089ee02951b854170185", + "", + "root" + ], + [ + "e", + "d300a620a29f9e09cca2f8c81270742729ce2593d1cbdcd2578a870c73e1355e", + "wss://relay.orangepill.dev/", + "reply" + ], + [ + "p", + "ee6ea13ab9fe5c4a68eaf9b1a34fe014a66b40117c50ee2a614f4cda959b6e74" + ], + [ + "p", + "7bdef7be22dd8e59f4600e044aa53a1cf975a9dc7d27df5833bc77db784a5805" + ] + ] + }, + { + "content": "It doesn't matter. Download counts are largely inflated, double counted, faked, etc. I can pay to get 1m download in my app. And Web apps are never downloaded. Since lots of people do use PWAs right now, there is no way to know, not even a ballpark number.", + "created_at": 1689854101, + "id": "1a930a4908d732e5b6956aba473cd6dc10344bdc0726ca384daf2c5621b4bd11", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "94ae3dfc434fa223c050fde595cd8f0e18943ad51b4c165eda129215adb250d1fbeff28a47b3969f4e04ea6213dfa3cc0d71eb6ba23e5ea4fe23ad7abdafba11", + "tags": [ + [ + "e", + "763c8078c7dd051a4a690001664b8dfe984070dd3efacd78846c4cdd2da3d068", + "", + "root" + ], + [ + "e", + "9dcca85455abf03edd6812c740d708370077922204a74933548b8c49a5a39f47" + ], + [ + "e", + "aa7fc08e620a6c44c409783356d866910df2247e5b0a4e8493f6d1611eb8ed1b", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "8dfbea712e6263402297a88613240948231dec9172bee9afe2c82b5af27a72cb" + ], + [ + "p", + "09ed4d0ef81d77ee634617e36c505bdd9a8a3b3030686dfac5f5e12a08becdab" + ] + ] + }, + { + "content": "No.. not at all. Any small relay operator and even clients are at the merci of the state. ", + "created_at": 1689853928, + "id": "c3675151e21f23455a36ec7611a45fc69e49da3ce6f7fbbb3aee7d696eee4533", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "fac6ed996c0b989fc7983340e8a683ee2b61f058bdc75cd88b5fd993af257072a7f6bb39e2ae8faa095f70f7c7ccbe27b40805e322b8dbb85b0d5d3f35e7e213", + "tags": [ + [ + "e", + "25025a9422e006903a8bc8b7370f16bc1aeeeb7714c872751f02d8546bd603e5", + "", + "root" + ], + [ + "e", + "3212c3bb3d6607241aa71eaf28ecc838873fdd83a051497cfae39d2e34fa7d2d", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "09ed4d0ef81d77ee634617e36c505bdd9a8a3b3030686dfac5f5e12a08becdab" + ] + ] + }, + { + "content": "🤙", + "created_at": 1689851999, + "id": "2a493246e80b3763dec1f04042607a3c53ddbaec602de94bcb61bb201a0f6994", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "b3bfa5173003ae8b9217f7cd88226738545b22cbed21fe83adb1e28162525e5a162991bfd09bf72c87d317d1fcf98deb0f71159d12bd20b3a0c86233d6999d47", + "tags": [ + [ + "e", + "40e4da7d99af6b74270f6a41403ad4ef6fc221c4d1311c2afb878468b2a31ba1" + ], + [ + "p", + "1b9d72d38b422a09cefed126e88f82361d4b1cc11cd19a2fc04e17b00b0c7d15" + ] + ] + }, + { + "content": "🤙", + "created_at": 1689851984, + "id": "98fa2f068d0993daace0d34916318fc08ba24e0c8d9b61474666104af24b008f", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "2a13e46d8488437d06000d1eae343a3cd36725badd4f6028b019f6ed8a32e285f7cb0abab8f04574b54f5bc73743cb5033b08e5815a2216d2973a5fe44091937", + "tags": [ + [ + "e", + "94f3156cb584696e9ed2559b7aebaa57465518b0493408dbf93c8a6b27d6ca04" + ], + [ + "p", + "49e3ca8a4e680a8914b8736f72470c9e91f609905b01650c75d3e189a49f2172" + ] + ] + }, + { + "content": "XZNuUUWuMuNLom0yTq38jzxZaR9WkSCsdQRjt4q7FAU=?iv=F1s/jYGrdc2i+SMPTqBFgQ==", + "created_at": 1689851679, + "id": "ef72e739b14aebfa57b6c5d42bbc65f4a413247809c592f3b52b4f4b16cd2963", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "d2b3bf56fc86a2d6f4274dc0d2fb46d47935e31bd952ae7753863dcdd0101d35978a027fd4f6da316bcfbf6aebbef323c460b6dcfc2e1e2cf35c8e9c52859dc8", + "tags": [ + [ + "p", + "672196e844d54702dc5933bf339d53e1b2641a767264384323957f424fd57b04" + ] + ] + }, + { + "content": "E5diFaZYD9BL2VnxsPbFhszv7gPnULv+CqfY1mo7kNo=?iv=XFp9d80vSOYbIrs9e6H8rg==", + "created_at": 1689851672, + "id": "061c473461f3a4c067d8438630874451c43082695756c774b8f2bdfbbc8a94c4", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "ad8d277e27dde2f1ff3389a47e744625f1e672413e33b8f6fe0b1e7a597e8627d6db6883c1cb23643ebcb40c281e9a57f25296b4455aca24283cc0cf342494e1", + "tags": [ + [ + "p", + "672196e844d54702dc5933bf339d53e1b2641a767264384323957f424fd57b04" + ] + ] + }, + { + "content": "", + "created_at": 1689821830, + "id": "a2a0b38cca7cd77861264b47e27439180d9e8ec0c07257c824e29b7ae6cd7807", + "kind": 1063, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "30f4a24336bf1f0e422770d4ac83b6fc9a14d8e5ccb925c25802ce8fe50e9684f6d32324d0a5702d0fceec85f1f38e8c96b62d405a2e150d4da572900a86ebc2", + "tags": [ + [ + "url", + "http://nostrcheck.me/media/vitorpamplona/nostrcheck.me_0e75717e2422fcae74a5728783dcab922aa26dced8dc16ac.mp4" + ], + [ + "m", + "video/mp4" + ], + [ + "x", + "efd7a96c5095ea679d4019a3eda955c430b021a917a350b022bb3c169e67d499" + ], + [ + "size", + "2720953" + ] + ] + }, + { + "content": "", + "created_at": 1689820944, + "id": "7d4d4011107a1728880da56b0f470a0304cbb05e3ea0cdb810ed3eb861e410f5", + "kind": 1065, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "0af6a6f8b8e0933691c1644345a63fc1f91e2696faf592790b295e4b903b4c5e4f54a08a6a2911d6c06960df9a3d8cd36f21998161af3f24a37bc9b214996b89", + "tags": [ + [ + "e", + "2d4d14bb122911d7843a934355475528571f34d478d940db3079d9af58d3c448" + ], + [ + "m", + "image/jpeg" + ], + [ + "x", + "6e225189e0ca6deaac822e3f48fcc44d6132067bab26e59b1dd8f96e55e30969" + ], + [ + "size", + "45775" + ], + [ + "dim", + "495x669" + ], + [ + "blurhash", + "_7G*WnqG}Z9GO@IUEg.9Os9ZaftQ9tni^:%jM^KQRPNbV@03n3s?$~xCWBR*RfTKob,Xo$r;R+0QwaD$-;ogspW=%yR#Ef%3V@tRe.4oNgkDRijZo2Rj-iS5WaS0obV@oz" + ] + ] + }, + { + "content": "9m1+vEUF9wuhiBexLna0SA5wtRJOE5nP1iu5SpzO7II=?iv=Stum2j5gFWdgSUkATftsMw==", + "created_at": 1689818614, + "id": "e3848ec5ab89b4b4a90f1578e695fd5551f8396291ea4b11dbdf6b6a4c065d42", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "57a0bec436faa420590a50fa870e1de583e2615c6878d882c5bf117e4110e4aea9aa70c0b948110fe4d27123fd40d9ef9e4902b0dbbffcc76fc986c59bdb95de", + "tags": [ + [ + "p", + "8083df6081d91b42bcf1042215e4bfc894af893cd07ea472e801bc0794da3934" + ] + ] + }, + { + "content": "IgoBo0FWxSXhIfE4fpowHM7HKTcC8H+O+xTVsIeLYpA=?iv=7mzzIDMSU4G+9pi4cNUnXg==", + "created_at": 1689818605, + "id": "b08b843073ef035a485162714c3df63f049d831cdf9925683507eb6b4c040ed4", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "51db96a77a2a85ea0c6b4d50defa60c569614640c83a4aff933e02d103a88b7b59ad67aed9f23129f4f4c85c3c1fc522172d4ed7842945b739343abb4a3879ef", + "tags": [ + [ + "p", + "8083df6081d91b42bcf1042215e4bfc894af893cd07ea472e801bc0794da3934" + ] + ] + }, + { + "content": "🤙", + "created_at": 1689817063, + "id": "d7fbbcef0a1ba76404891938c72589557b10f032cf3338e0a518b2285b5bc956", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "e91283c33eb2525038cb88bb749cc58de7f7c527a63e336b8236a0ae198c812b69ea81e27f9ba4df4399fa75213b3b07a1b4518dbf1f5bc724c9b03081760b73", + "tags": [ + [ + "e", + "d4960970b0fcce6a8e19e9eaf88519d54df616e3dadcd260fa584cc3181711f9" + ], + [ + "p", + "f5f98ba54045a2fa8df2a97c35fc30299b9e0d51a701795c040ca80cedaf39b4" + ] + ] + }, + { + "content": "🤙", + "created_at": 1689817021, + "id": "fb97468b31105ca6af4937048cae0eeaffb01576c79f6b06aed84131b0bdf188", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "485e37b048849165ac76e177d546da3ef5606cb4e4641260ad0660f20e52d0bdd53f7d8b4a87cd9584e1a63ffd0b183557c85258f41f3ca8c28d5ded697b8779", + "tags": [ + [ + "e", + "c87e225890d3d6d429663f4cab9057221088c484805b9ef2da0573aa558b9e91" + ], + [ + "p", + "f5f98ba54045a2fa8df2a97c35fc30299b9e0d51a701795c040ca80cedaf39b4" + ] + ] + }, + { + "content": "🤙", + "created_at": 1689817012, + "id": "fa72f4d3ca47d559b0b5e627347aad6630c202fdd4000b0cdd70085f051f820e", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "9c6a4e063706ec03bbf99b1f839ad95b4b5e98b527bb3102d0b5d83f629ccd89294bda01f8d50c238d2e0e96c5967ce41f649e8a73a4686e349256ca8bc41193", + "tags": [ + [ + "e", + "0190e4e11059dcf124eea8387529429c4fc24b7151b0c098edefd364ffd80274" + ], + [ + "p", + "b2833792cd5c95662538e620fed371728e90671b9d6bdefebe8f706c1f1a04da" + ] + ] + }, + { + "content": "🤙", + "created_at": 1689817011, + "id": "b083690af84d9c7f1b7eb4da844e9132d0e9e20f94dc17dcf43e17ec1c285470", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "e2adf0fc81bc1601da5b28835c946762479a3fda09d7bf3b0888b0e7df8cd3f5d7b731ec4254b588426b9376e67caa777c8e8df5d7cfeac5699af33e57977662", + "tags": [ + [ + "e", + "ceb3b15d4564ba20c8ffc2d7753059028ceb5c3679d2229081c62eee84782a3a" + ], + [ + "p", + "b2833792cd5c95662538e620fed371728e90671b9d6bdefebe8f706c1f1a04da" + ] + ] + }, + { + "content": "🤙", + "created_at": 1689817009, + "id": "76ba23b7a75d204849ed6104a1c7b35b81b54aefdc90448ae97285d2908bf6b1", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "8d8d5a2d851199943a1d3a87e93954ce6d90acd55d294ad76015e2583fabb95d39288953697a9eb184a74447d9bdd38e8a4435c736defd3237578ec8aa522291", + "tags": [ + [ + "e", + "9c289fe421d434b5f8800fdb6a5f064412b809218d11571beec7fc7fa5bb8877" + ], + [ + "p", + "7ab1d3867722b4cbabb6c8503ab3f9265daa4f82e228cefe302621f4e5ee1f1c" + ] + ] + }, + { + "content": "Let's go! Nostr Calendars are up. 🚀\n\nnostr:nevent1qqsgyhxkj9etqared6eg2c9d8zjndnpr8qyc37l9cuelk02zyccn2sgppemhxue69uhkummn9ekx7mp0qgsf03c2gsmx5ef4c9zmxvlew04gdh7u94afnknp33qvv3c94kvwxgsrqsqqqqqpp5cakn", + "created_at": 1689816781, + "id": "ac64c67c3dc8b6d43a7c15b94c0d5c382e235f65cae783ed13abe4bff6084163", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "6d2c7e78d751c1f175ca559bea9da61b9c8b3dbdb916c2a15754b2d510642a2a27c176aea9e94f985c9a10d7e47b49443a164365fe9757a7ac2456ecd308587f", + "tags": [ + [ + "e", + "825cd69172b074796eb28560ad38a536cc23380988fbe5c733fb3d4226313541", + "", + "mention" + ], + [ + "p", + "97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322", + "", + "mention" + ] + ] + }, + { + "content": "How do we get subtitles in multiple languages for Nostr videos? ", + "created_at": 1689801767, + "id": "276064d45865bfb223b1c7156ce555ee291c51b82e3096711c7fc9048bef014e", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "93dbfa2a47499ed5d9567fce061399a636af7ec8fe2b3d9e02d6db67dd2024fd0db7ea0c696f925633c9b929ca0f1f83b1617372af182f7cf2a9d26ccc4c8e2f", + "tags": [] + }, + { + "content": "AxnOIG1qFS+PKCRIDl/vOfhNlZpMWWxgFCfMAmXR5VR0WyuHgq51owAycbQMDTneEr1fdCQvUvij0VzAhtsWMQ==?iv=fkuPtAZC0sB3f5z95Q5OOA==", + "created_at": 1689796668, + "id": "fe3050a24ef6f71bc7c6f300161e963bd93d8e35b46d6896a679a24bc234def6", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "63e0e21357ccd969d00d8b8e3391212a21b99d37eaee66086bce4a75a580f1edb403010a9554e93735eb496199fc1d9dad8a5fb8c6a562ce15b081d8c8400283", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "seyXteTXE7xcuLVoJFxOxrioedOcMZZA2kHO7D5czLW7qIG9djYZmotp8/4AKUvW0ML9/Zg+cMB/l98T1+mFgS+j0LG0v5MYBH1EzQDZpyLlPIZSu+U6FjVX+mQ5xP/1VYbw6bYeN724EJE8A5uR/CeR5ba+7mU/lESmMSQbcG+81nVbauESmwN0/CtfameLcvWQksSclKUVUoK1T8xPdg==?iv=OhXj3Pdt/MWXB2vLQGKQ1A==", + "created_at": 1689796648, + "id": "bd4a822b08a4c60fff4e9643bb524bc10a15ef413f05b54e6d2c06c8f93d175d", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "330156d1bf8dcbbfde9a9690b9a2c470476599275a949d1a57b07904e1cb34d6832a4b0f48eae64bf9d990d2a75ec371057ac4e213780874288319173b9c021a", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "dOTrkPCovcomFiLrZaT5PHkdhIjUBA19y1/AI7i05h30rg3KFHNcAWAoKGIDXdVYd9zwp4614oaB5OwU8v50Vg==?iv=zYLVydZOtyn4esxHM2POUw==", + "created_at": 1689796524, + "id": "8a72bd5d8d93e511bc4b90f9c06db9a835533a41244b7ab8dc603dd8204c4848", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "2e8930dcdacd7932c447652f8da5d2638fa64bcff4e4c04d0806472d7ac3b378ce8ed41dc7b5c32000d4117d217e6837438557964c24d55659fb9c415b0c6119", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "afy+lH9UsXeMDOXOIDcGWIbqGluAAOC9+Ou+hfz8YtJozeATNVXONKW9vywhW4uf/ug0daIa14ua+Htjru3k/4ZsSt4Lf5s3HL89JVvY8dNM4RQWY3ujCojCibipkHT3?iv=5ZpYFy/C0/lkBA0jUDitWw==", + "created_at": 1689796215, + "id": "1d4b12c76b6b59161c8167e4de7ffb9e6f8bda61abcc24f1352e37acfac5302a", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "6be01d493cb564657b75b4a3f46a2e8c2f66c08e3c16266b4a39e2e377632f007e2c878971f01ffa1755b744fc71054a5ca7285993a3d6d5b9117f47d5fe18c1", + "tags": [ + [ + "p", + "8083df6081d91b42bcf1042215e4bfc894af893cd07ea472e801bc0794da3934" + ] + ] + }, + { + "content": "hTpYWaI0Y2FGBRnAPWXblTqdiCrzqrlFlLfqCmDwjBYpa63jiCE2pS7bVcqSWMitjWVIyKhCN9fgVBYBFPvefamqJT9z0IZzKebvvs4BqB7Nd+Iz2nokOo4jOPeJqIu+?iv=OqPz5bYdh0+b4haP2XQKdA==", + "created_at": 1689796190, + "id": "3e2dbe64f489fb36298b6d9bebfcc6aeb0ed813a9743d64393eeaeede12d3bbf", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "3cff6a0cfcac3221b028cff5dac1c5ff6db6237680c0c6b30b73ef1196300709671f1865c50e0f7146d69e9a7fedd320959ed777d66fb04776ca4be32c5faea8", + "tags": [ + [ + "p", + "8083df6081d91b42bcf1042215e4bfc894af893cd07ea472e801bc0794da3934" + ] + ] + }, + { + "content": "fK7K+JZQjd+pGDqqY7iITMHhXNeqtbYM4yoRniviW3YAgOH3KW5htMwL4iE7BP22kbRCGD+KAugKCQS82eaADG0H4UzcQwRzDkcWfKkOBJZN4hyc+k2h/O73SCT2hjj3?iv=41MU3ZirxPhr7+5FRKko3g==", + "created_at": 1689796155, + "id": "a9cb0ef636892cf0a4c22d29da2b418d2668b94c75966550f8bca4be4b54f4f0", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "40da153bc8d11be451edb175ec9e5d896fd6415f1b288ddc83f84775bc990c930faf6061ed01152a8b69f0858a7f10025155e707e426bab08a1e57d13fef100d", + "tags": [ + [ + "p", + "8083df6081d91b42bcf1042215e4bfc894af893cd07ea472e801bc0794da3934" + ] + ] + }, + { + "content": "6XrKnpAX88V6Htj3dRFhYJIrpvoQygXbFRHQ7U6Lvulf2w+Wi8ObX0duVSPhbTdx?iv=1pKalTwNvr/773dNsYxrsQ==", + "created_at": 1689795660, + "id": "c7423761b1b250f98795e26c52aaff8fe85bb28c23ed30bd206bfc4d84ce9580", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "26bab236f84777a5f7478744aa689795f1dcdff523f2f4e3f801d6a73f6b221f5d1f55e664ee4b9880566eedc5acdc3ff8fd39e85aae27b04a2f4022c0a71a65", + "tags": [ + [ + "p", + "8083df6081d91b42bcf1042215e4bfc894af893cd07ea472e801bc0794da3934" + ] + ] + }, + { + "content": "d+fEU20cosND2HbmwFIJauroNtSmj+0vjS7JFTuSpVRZVlqsBYAudVHjIoBUoVhoZ6nRf1mYcf/DxCVwn08ZMvJAXqVgT5WPhylmKYm+6Y0=?iv=eJW6o5wA77YxIOLVyr08ow==", + "created_at": 1689795615, + "id": "f0d66292c0478c5876b12b330d5f8bb87ccce54249203d87440110c1e1e3f358", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "f5e9328dd7f581af984fb02f41b62bfd0b14961586b612f668a8f9a1a237e1d47a5f7e7ecef4cfe6988c18b8ac7c58701e858c27d747510e3dccaa16a8235e99", + "tags": [ + [ + "p", + "8083df6081d91b42bcf1042215e4bfc894af893cd07ea472e801bc0794da3934" + ] + ] + }, + { + "content": "jYW8dxVeSx76co1IsQTpqw==?iv=9TpMslZaeGk/Qc0kn6d0Lg==", + "created_at": 1689795614, + "id": "f4232c1aef99cf09ddf794392f4c37c4eca0d9d85bb2d1ae3ddf72da7632bc0b", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "bf5d8458087408d3a652d26c162fc405d31743a5f3de2c12fbca593ba3b3662e9052c2b3d7c9086dd79e4387a36762b55873544c4c762f104e3727d734365c83", + "tags": [ + [ + "p", + "8083df6081d91b42bcf1042215e4bfc894af893cd07ea472e801bc0794da3934" + ] + ] + }, + { + "content": "wJqpUSs9Tqc+LJMiwF2Tl1d11sl7y85iM4qutodWeBNn3UMTpyA731WmTMxtwo59HwgDx7Y2wi/B5oLY7oBZUA==?iv=0stWUqHs9xD34aJcRP0Z9A==", + "created_at": 1689795571, + "id": "df846e0e2628a0102dc5b5839e151dbd483cf5e6ac29b7c5212a20a058a9aa33", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "b65d1f339c88793dbfc0a0e46b91e53cd506732a6ece9d585041d8d1e0288b9cfd8b81d02a0efe4e6835d2b51258b2a2291af42f311dd1571977bbb22d1188e7", + "tags": [ + [ + "p", + "8083df6081d91b42bcf1042215e4bfc894af893cd07ea472e801bc0794da3934" + ] + ] + }, + { + "content": "ol3R5HKU2HN5/6TlsnqPEw==?iv=0y+mRP8iHhHiIHlIb/Njqg==", + "created_at": 1689795555, + "id": "de8f70191affee06d10e83abf8a8000d5af3b6726f636dcb204631672551d206", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "c98a7d07063f1f1f69a93838348123d6a6dd321cb8f720d876958e002e413e0dc95b9716f36ce1dfcfb51240c8ce7e0d8e835fe2e3fb209f3940a4fde582e0f3", + "tags": [ + [ + "p", + "8083df6081d91b42bcf1042215e4bfc894af893cd07ea472e801bc0794da3934" + ] + ] + }, + { + "content": "+", + "created_at": 1689793683, + "id": "ba35efe39f4d25ef3f79f578c618456a04d27115333a8ad4b5558a70b6ba20d0", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "193233755ae8283a7e0bbafcea1656d21a68f90912a4e58afa491a11590d262ee9f7cc57ad625f8b7a5969d6266968783037282c7171413cfdb3308d1c739da4", + "tags": [ + [ + "e", + "ca1d6d0979a9892cdc6bb6c9f6f0ad752abf91a59e2ab047c8dc40ba864d94fa" + ], + [ + "p", + "ff27d01cb1e56fb58580306c7ba76bb037bf211c5b573c56e4e70ca858755af0" + ] + ] + }, + { + "content": "WW1FqQbpCQpDxsJeX/w3qSMNW6OMRN1FoWU6pE0fxVl2dsisbuts+pZplL8S/0AcQ+WrBcGIxd5O8w5ky8Wz6zWyge0VQ63fr07NWuitHr4=?iv=ZehOo9LmLkLSt42WdXYnFg==", + "created_at": 1689793047, + "id": "fde523a39bf03736ae928db7d709e6d50193e7a6c20747cc529656db012a6f6b", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "4a72e902dede3d8ebbcf1f662f8194573d0bd2cc26a66d66ff11a67d11471d24444329c4a3f75dadd7ffc51740394ba83f54ff6337882b5b7ee332e65f468d41", + "tags": [ + [ + "p", + "8083df6081d91b42bcf1042215e4bfc894af893cd07ea472e801bc0794da3934" + ] + ] + }, + { + "content": "11d5n+hT39BBDvhG6kwgs3QtITRCilwvu2t1EyfnbW9zQDvhGImaVwcNSBJogPUWND81PxxSevsnRunX9IlpkE+NlxFvoRJETnjB7K7SYJgEm1AJS0gvOOZoJay6YgV+?iv=5O4lPYjvIlFJhZtbcOqBNg==", + "created_at": 1689793029, + "id": "617562fd855d45c2f4ee08f87c4f8cce815b4d2e94a51cf6c6d25b50789c6cb9", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "504ac9d67669273fbcc6d92535c7a01cd50915393baa190cac7d913b50fcd3606e2945b67370e37366327b70ed24fe2f45bd9be29c26342fd5fd9f5ad1db5c40", + "tags": [ + [ + "p", + "8083df6081d91b42bcf1042215e4bfc894af893cd07ea472e801bc0794da3934" + ] + ] + }, + { + "content": "+", + "created_at": 1689792227, + "id": "4afd3e5db2ec5e356e2b734978f0c142d46dd547e2a74bc23d3a0a01c15273f4", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "1439d24fa6b4b40ad66ef01799d7196fdf70f9fd7f8cdf8d114e99235af0a0d994c28bde2f665dceda0cc31694ded3534e1e8d55e316dd6605c84eddae875eed", + "tags": [ + [ + "e", + "794fb8ee8d06f5961c40a11f6cbda46819ef87d6907c0d9fb05038ca13aa7a4e" + ], + [ + "p", + "876e724d762be346b89f47070758da679cdb969a2a17d3c5df93da832bb71acd" + ] + ] + }, + { + "content": "juGxq6AXk3XCL4JEp5A+BJ4A7hwL1n5AZjD55zC7+EI3PjXiYZcGDta1c0CUH4qVcxmTLSqUFOcs/Dwtd5Qea/hemj9/nIu3GJYMh6Ch0+SPDo0sfXaVecSCAaAmcObl?iv=l+1TL3C3hwFh+Izzz9MVVA==", + "created_at": 1689792194, + "id": "5425f9eeab69bedf79ca59cd730aae076b04b33cabf709e78560929680164294", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "ba56b1630ad6dc18ff9d3169a5947011623281fd73dac87272bb6cb0b2cf316b0108171689728d49680f1b6da47169ff0cef2aa420d86326da2ed11ea7ec0394", + "tags": [ + [ + "p", + "8083df6081d91b42bcf1042215e4bfc894af893cd07ea472e801bc0794da3934" + ] + ] + }, + { + "content": "For sure.", + "created_at": 1689792082, + "id": "ad71d5164ffd119c21f1386f5ebaa23faf93b0860bb2a8af6d2af63b5143a43f", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "e466cd8f8c06b0acbc66bd4f59cb0852ab4df16b8d70e63de280b39750c44a58f49972b06563fe9b4f74760a3a8be835111a12e874015b8b32016fa78d22ff90", + "tags": [ + [ + "e", + "25025a9422e006903a8bc8b7370f16bc1aeeeb7714c872751f02d8546bd603e5", + "", + "root" + ], + [ + "e", + "4c37c971eb747bb8952650778094269d48047e470b392129967e412ac80fb604", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "876e724d762be346b89f47070758da679cdb969a2a17d3c5df93da832bb71acd" + ] + ] + }, + { + "content": "peJPIP0HJSqAp5QnclIiewPTW6D8ABE5XFjsRLNExq1+m0ofqGlK+p6eUYTtXEkVY708OLjsn4n1BwzZ3VvBrRhAFTW1qiBgot9Mh3g14bwzwe0qTVIMFJX0Zh/Xt0eu?iv=nMfwVItwt7/FJ8wPd/Eqhw==", + "created_at": 1689792036, + "id": "2a129c01330a59c5e517af6fe0fc3e5c2c2ca1514a19df5351d07502efc220f8", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "23a492d737219cacf65b085a17a2db72ddfc3410616b297b59eaaee9bd10522754832cbbf35c7e422434300b50909d2ce7ad2e3a95017686621d2126634b199a", + "tags": [ + [ + "p", + "8083df6081d91b42bcf1042215e4bfc894af893cd07ea472e801bc0794da3934" + ] + ] + }, + { + "content": "7yKCNmFIkil1iodXHUNPGg==?iv=QhwQSNtrZXzi4jw/06XOaQ==", + "created_at": 1689791999, + "id": "f7108bc890bdd5bd37ae38f7d11a02a8da5f02042b0b77423a74658fcddc9934", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "e20c98f26702482353a7982cf48665a7fe9f6bacfe05af338339a70dea82d2575235ddb1b6ddcd752579d6a83171c47e0df5fa282992c4aac099730900b91d64", + "tags": [ + [ + "p", + "8083df6081d91b42bcf1042215e4bfc894af893cd07ea472e801bc0794da3934" + ] + ] + }, + { + "content": "40VWtBtcLP3YFFX1QTw709kpQB0pTfY0UleW7S2iOJU=?iv=m7BNPpW5hyYeV/BuNR19AQ==", + "created_at": 1689791992, + "id": "19d8ee5db99a5631f71d4f4711bae78b5cc93c0c3552ab78fdff0df1c674979a", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "f416f0a88ea4de2b2487fb5b07b353516ad5ca4c17bcacf2315d7ef612b312281f1e087a14ebade82e91f6cd4c27395bcc88af61f51cbfeac4c2ff2c6d7e6378", + "tags": [ + [ + "p", + "8083df6081d91b42bcf1042215e4bfc894af893cd07ea472e801bc0794da3934" + ] + ] + }, + { + "content": "5p2yM2M5i3h7H0nuTsP5RrsvWmKbUpucyHzxMZJ1wsf//jObdREH5wLvqPQ2w6i2WKD/T/808UTk+rb8ZPzlqLNUgYBMlD8bjz1IEVY7Hn8=?iv=3749TEgAq+mmP68ICxcakA==", + "created_at": 1689791923, + "id": "341bc18bbcb90e8dd6736376d179a137e42ab2d33b9a9d9af60f82b2069be88c", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "c89bfc23afd50a4b669c5000a244bff10b114991983627c3da64b03de38f220792d14c75528cfd89b2ecefdb8093086d2ffa3b2b109ddb2a4be0b6b4dfe53bcc", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "n/Zh7u6uaozj+2mCIYhXuT2Oqn7uyYwYkqaBWPBOwsgO1dSqxHPLWwR5ZoiCPij9EWhtSI2BHEEy5OeYxqlLr51Cli4gzNpq03zxbEb+vulcrC0mXRBJXd3SIo/Cu/um?iv=putWwaSfX+fajySLJXgBeA==", + "created_at": 1689791780, + "id": "18d4f7440a02c83680b2a5744c0359fc088a80b6ca0dfe922c3e13103746926c", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "8dcad60b4faa5727302a3e3f2fdca3ecbddb85d3e87724d0e8d7053f647960d5174482a22957776ef8f84a33b9af5d19c45971b5cbb43428ed754c3839c25459", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "T7+/09ia5+pzY0WDwzhGhQ==?iv=iAV94k1Vl1X1OYpekGbgLg==", + "created_at": 1689791735, + "id": "a044df6a86bb24b2468609f74a3fb639ad599d6bf14293efd6b257148d1df8c0", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "ecfcb8838d80dfb943ee0d8fee094402484057ce6a85d35754a818707bf04becd299d41cc89519c378e545a461263f44d3e6adb6c201c2fdbae5cb7cb6c627a8", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "What's wrong with the image? ", + "created_at": 1689791634, + "id": "1a32a1345dab56de57b1d0e5e3e0f82197e782541cabd4d4ecd1b1ce55d495c8", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "0e893b5c1c6adadc6d61868ea542d8320924234f8e6a8df75eb845e06abbbd386f2cc8717692bf18927bd52b58f936ea5bf0fcaf66c03b1bc7219c33f1508620", + "tags": [ + [ + "e", + "134cdb01d0cba849d56cb6017aedefbcf8043eb01608089ee02951b854170185", + "", + "reply" + ], + [ + "p", + "ee6ea13ab9fe5c4a68eaf9b1a34fe014a66b40117c50ee2a614f4cda959b6e74" + ] + ] + }, + { + "content": "We haven't unlocked the power of communities yet. Amethyst will have a few UI changes to make the feeling of joining a community a little bit better. ", + "created_at": 1689791536, + "id": "5f74955acd83df8b9ef6031f19956685172beca93a4b03dfb56954a66782e9e8", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "9d277d454cefe5e6313d8c10820321ef2a6d91ff2ff305f3ed7639869321ca78d3d7aff5205f5d02b2884499e16171d29d1959fca185e35f73f34de79f6966b7", + "tags": [ + [ + "e", + "eb612971888141cd5abeaaab8b7472028574f26155074f57598ca9eb237080af", + "", + "root" + ], + [ + "e", + "39c1e289861226f800d915a60484b498a531d4cade8cb3caed3dafcdb4ee891a", + "wss://nostr.bitcoiner.social/", + "reply" + ], + [ + "p", + "ff27d01cb1e56fb58580306c7ba76bb037bf211c5b573c56e4e70ca858755af0" + ], + [ + "p", + "ff27d01cb1e56fb58580306c7ba76bb037bf211c5b573c56e4e70ca858755af0" + ], + [ + "p", + "efc37e97fa4fad679e464b7a6184009b7cc7605aceb0c5f56b464d2b986a60f0" + ], + [ + "p", + "d0a1ffb8761b974cec4a3be8cbcb2e96a7090dcf465ffeac839aa4ca20c9a59e" + ], + [ + "p", + "f4db5270bd991b17bea1e6d035f45dee392919c29474bbac10342d223c74e0d0" + ] + ] + }, + { + "content": "D2c4aPXsJCcwJ9z6NGsQALQ/i1+bbhIHgOsdloA7mMyLqxWkCXNtiSa0wvJN8Bi9fYhjlOa1zT1tj8GWUYVbkH7gsgLnboTwCLr48JjKNZRHY2ske/sFpF+V3OMYCtkDRRh74p6yKv5x4b3KSvAdZmuGApkP37wf4tA9QSYj7Fg=?iv=E+UwaN6Acc5VuYlhJo2wrA==", + "created_at": 1689791426, + "id": "4c65727b37d96f7937024be773f048cf291569682a6ec93d1f2677eb872900eb", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "17494231e1e2ac82f6f5c0ed39bfda56e76687ec29fb45ca6eb56c2621fea1f1612b47247c0a1d9f52fa2f2502c838ea5401cbfa414adcabbafad38be49c17d3", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "hturKi69ZiXh/zuDehkuYisaZulgLhQweuejTUC/NgkSY726pRvx2eMaeeMp/GyXLIiXJmHBbGHN3WcriT1eWg==?iv=145wzmomdE0AgjYK90KDHA==", + "created_at": 1689791397, + "id": "4145c43d088936140a0d03f78fe65d075c09560118a1d10eb9a61f754ac0c3ba", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "28dd7c2ddcf93091f5e24afea68410f5b77c505a271e6eeb17396aa8e7acd47da4ae65f2c7f8fd7b416be2d72955e81cddd884b0e6b2d041cd269c17158907de", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "UGNJsE4FdyJR6HsTJKRZiZ2SjVC+Rur8wg++uOTi8iLdnDTdVhv4hEA41MbHYCjZnCZQO50fFsBICzFnziC1DA==?iv=GpYALl36b8bHbqAL14NZWg==", + "created_at": 1689789316, + "id": "881bccdc3e7ea2e211282406d8a24f9d8b13730be7f7e4aa20cb2a87c3a813ef", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "c36ea50e7ad612a1e377851882b2db9f878d591115c769f83bd59344d24c45f4639a9e7b7e281bf2443b57612df932afc3f53f567218683c3b28077f2359c37c", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "Of course. But the question is how are they technically going to do it. There are many possibilities.", + "created_at": 1689788786, + "id": "bf39c47e2e5af5751dd5265744185df3d8205ab76a467331ef0bb97d288224af", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "c035c989ecb3a567bd0b7d09339276f93d2973d99bed28ec7aaf8a653a27a3f80674804abe0b2eca980060709147431ca910cb7da795648becf72014be0cef1f", + "tags": [ + [ + "e", + "25025a9422e006903a8bc8b7370f16bc1aeeeb7714c872751f02d8546bd603e5", + "", + "root" + ], + [ + "e", + "69601e47112484a0fc1f173d0bceef8ee33ed56c5831a3d30d12693dda4fdf28", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "206e580157eae3395cdf954ff30501e16902074656a4b9493f36f896167496b2" + ] + ] + }, + { + "content": "fRxYgGAPTXND3ruRL3wx/w==?iv=jsuZZX/FaK2XciQ2Wir7yg==", + "created_at": 1689788740, + "id": "81c6f03692855f0e36a4b80d864aaacfecb549d39e390a5f44813e6df5c9f8f4", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "ea0b345f1d05f62314c6d68a2938b888ccb1a3c0ebebe8848b3df72dc130711042f0144d9e3041c3521bd61ba2845a56bfe3bf745dcb8ebd9e01bd1e77710e53", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "LKXDKYSKDCjyq+6MkQgfGo5esbtZDs6yNBoY2WOiFHxBqa7Jywg556XC4eD/xaM1xh1S2Bd3eHRm3UT9sYJdk1ubyxDdiuKXSEPyhGuLBri76at3UgWfSs0wQknFS+cgnX8V9LhGGGpzMb+8kNZR36k3AEZfcjrbOvOVp0BLKIg=?iv=Glj5CCIi8+1zDbxw+2SeMg==", + "created_at": 1689788734, + "id": "d7f01cdc157a28c915e6077a14820cfb6535321e17d3199420f05d875353d1ae", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "b7036aa95b6e68d34089897e1f8edf6263ef52848396894b2b619092fdb2f59ac13f68fb5666a56a65deb04409de0e4fc1e94afe0c3c09098e8b2edd3e04ad42", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "YcjKnGE+tJH/cds7X/vOroR6NVYYpRh0otIc/ZgeZvA=?iv=xsJsUMr3It1EXfc5ZRHPLA==", + "created_at": 1689788612, + "id": "18a06699806b3202f7eba5736d89f8d30302539f7e306bfb7623c1a21c600092", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "c8e3241e90b60fac97c4457589816a56b22995be2ec2e2317d51e1d66fb897efb387b6cbeacbf261dda0804c9283211fbf1af1ac5bc9e9c5fdc78a2b2060014b", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "q/kqbaK7wnyDvJ4ORsOwfg==?iv=6rToBnTYx2KUnRTxPEHthA==", + "created_at": 1689788601, + "id": "ae37ff6bf243668b58d3b12a11123912a2e6f71ed1e60206d4e2234df6b9b6a3", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "eb5593f481e1d67d9e6faf18c17b59e5ec06dd8e6c5026b4d076cb3320e1c3ef8115de470005e7afdaacf1e0f1cebecfe8e9d5fdd73510b6fcbb71aad51b8494", + "tags": [ + [ + "p", + "99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64" + ] + ] + }, + { + "content": "No yet. ", + "created_at": 1689780075, + "id": "8df02766da387d6dc3bfc283c6b9c2e99650006fb5b1c88884b8d5014c25854d", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "1040be4fa70fb028dfb8bd622ef37407b7246db688e0e6ad942d8cf3cdba86b635a7f5f1a33feb4046ab77fd1f52ea28ffe98517070b942b1273e670a0f8603b", + "tags": [ + [ + "e", + "e5f11e003dfb5ed948bdd67525adef44c6534df4b529ea881337307810c3e6a8", + "", + "root" + ], + [ + "e", + "45e52aac94688eadc432a5ba9e81a213309c289c86618ce660617239cb7b7d9b", + "wss://nos.lol/", + "reply" + ], + [ + "p", + "63fe6318dc58583cfe16810f86dd09e18bfd76aabc24a0081ce2856f330504ed" + ] + ] + }, + { + "content": "Yep :)", + "created_at": 1689779927, + "id": "de53bc355935d7f20927b9cd580f8351263a0e78664678898267a70769e33573", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "a45551d3f326875ccf410c546d770fd1b87af47022ed6125cf0c4b58cb66251efd0089daab8e19563c25c44690b314c227724ff9bb9fcc39c16727152cbbd119", + "tags": [ + [ + "e", + "e5f11e003dfb5ed948bdd67525adef44c6534df4b529ea881337307810c3e6a8", + "", + "root" + ], + [ + "e", + "6fc9fe5427f818be975d11a5647aeee0d669bd417a5422e669a679114313b42a", + "wss://nostr.bitcoiner.social/", + "reply" + ], + [ + "p", + "63fe6318dc58583cfe16810f86dd09e18bfd76aabc24a0081ce2856f330504ed" + ] + ] + }, + { + "content": "Sorry nostr:npub1v0lxxxxutpvrelsksy8cdhgfux9l6a42hsj2qzquu2zk7vc9qnkszrqj49 \n\nhttps://cdn.nostr.build/i/e1c9f560acf3e3fbc147d83792313bca299010e5a259b00a8e7ee9724eaa6946.jpg", + "created_at": 1689779837, + "id": "e5f11e003dfb5ed948bdd67525adef44c6534df4b529ea881337307810c3e6a8", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "64516164405895e616f16240ee6e0b2aafeea2e78f93d19dd68c22b17e8dd6723adff8508edd20e23c3e9fcabc2f04c86d2fc35d50918169c9dd207aa9f4c873", + "tags": [ + [ + "p", + "63fe6318dc58583cfe16810f86dd09e18bfd76aabc24a0081ce2856f330504ed" + ] + ] + }, + { + "content": "I am waiting for them to start tagging content I am required by law to filter out... ", + "created_at": 1689779811, + "id": "385078f5c6f4d466900e5267755a1a2db58ff0cb9519cf695c5a69391eba29cf", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "f1890c97830f613abea4ab6f6958bab0d2afeb0bfc91261f0a9c517aa85c8007094bd6beaab44dbb85084952fff2c0207bb58e509176aa15c4cc5a99475410ea", + "tags": [ + [ + "e", + "25025a9422e006903a8bc8b7370f16bc1aeeeb7714c872751f02d8546bd603e5", + "", + "root" + ], + [ + "e", + "e19338dadac50e080bccc1457d5923aff9aaf88012401e9bc353c4c4b3c28839", + "wss://nostr.bitcoiner.social/", + "reply" + ], + [ + "p", + "c43bbb58e2e6bc2f9455758257f6ba5329107bd4e8274068c2936c69d9980b7d" + ] + ] + }, + { + "content": "We don't know what's going to happen when the state starts using Nostr.\n\nBut they will. ", + "created_at": 1689779396, + "id": "25025a9422e006903a8bc8b7370f16bc1aeeeb7714c872751f02d8546bd603e5", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "9a4740dbfb4894634fc40d6c34151a4e5c2771daa9af119bac96e36fcf0b65a938ea1a8224ddbfbc70034e81dc0f9ab86033c7425488359392d604e1f8257765", + "tags": [] + }, + { + "content": "We are using kind 30,000 mostly because I think it is a good idea to create a feed of the muted folks. Since Amethyst shows all kind 30,000 as feeds, it's an easy trick to show the \"blocked\" feed as well. \n\nBut we can go either way. ", + "created_at": 1689779276, + "id": "24e3fab99020ab31228b2ed48eb63fa7800be963d5503c5c2598ee61990ebeba", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "fdf665f4df27fcb7d407e43b888b9f25d96ad77fc95c9114ee3f50b5477e6cc8303f3966a031cff71ca0a9ab492152ebbbfcde597b62c22611d77a3628167e13", + "tags": [ + [ + "e", + "bab81750570876585535c8ac4a4d5f983ea4cb0675c94882af25b256d60f5a7e", + "", + "root" + ], + [ + "e", + "b9d1689cb4c5c3220fc2d8a3ef0731f6bdb2fb7cb2593a085c57488616932dfa", + "wss://filter.nostr.wine/", + "reply" + ], + [ + "p", + "d0a1ffb8761b974cec4a3be8cbcb2e96a7090dcf465ffeac839aa4ca20c9a59e" + ] + ] + }, + { + "content": "Not only relays will have to deal with this but clients as well. Agencies can tag Nostr content and write in law that clients operating in the jurisdiction must filter that content out. And agencies can easily enforce this via the PlayStore and the F-Droid store. \n\nWe don't know what's going to happen when the state starts using Nostr. ", + "created_at": 1689779139, + "id": "6d592b4cf06a528138af967f69e425c4175c7dd149776ead72718ca06c7c10a0", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "aa5d16975ac357fde1c7814e73ebfef5c326f98cf622ee5150c530c476f545d2db97e94a0278e1cbce7fef4e4546379083b71bf277351df57aea15a54e3e4fc8", + "tags": [ + [ + "e", + "810412a20e676fac2119d0401830601ad2b9bf640d39c5709ae047570476e06f", + "", + "reply" + ], + [ + "p", + "8dfbea712e6263402297a88613240948231dec9172bee9afe2c82b5af27a72cb" + ] + ] + }, + { + "content": "+", + "created_at": 1689778259, + "id": "218d0bcda05431434e82da0689cebd0f29edd9880dba67bed6dbd7106aa21402", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "ba1c0b1bc595450196b982d8fde84751ce16b4e2da577a9ecb44c16f1c8fe0c2716edec606ff3cefc0569836f9507ca34c6a9411d9a463004fe5521255ba54d6", + "tags": [ + [ + "e", + "5a7eac5ce4ec6ffad268fb6bbd5450e2361a1ee20efc2aba3f94f41c49ac6d64" + ], + [ + "p", + "564e2192d2c4df33224c15d787cd0172fc8c7e6a7afd67bcc3f8e3447d765981" + ] + ] + }, + { + "content": "🤙", + "created_at": 1689773079, + "id": "f2bae9c9b2c5b1db90828c1cbdd5892485a1a239303a7e7425922ec2757705c4", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "a64442be4bd5d5d7248f120a966e5d995f8958cad3242f05b145e08ca859c2602d88508f9d8bedab29ad0027349fe5cbfd8e12832208f7ccbb7f0f4419197a2d", + "tags": [ + [ + "e", + "ceade31f339b0d1ef64d951e49153c08d33b995ea73f419cb9d65501438857f9" + ], + [ + "p", + "f5f98ba54045a2fa8df2a97c35fc30299b9e0d51a701795c040ca80cedaf39b4" + ] + ] + }, + { + "content": "+", + "created_at": 1689770561, + "id": "bbf5451dfa185bec87f2e274e451792d8d203d4f257649c7a54b699d159aebce", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "2a74f27d5914cef15399d1a4b52f17c1825755b8a7b70e6d05dce67db7696272387dabc4b6f27cf76c62708b0ea167379ee17db00451a91020cc7a734c967df2", + "tags": [ + [ + "e", + "9fc46ca0fbdee0f4436f1d0b48d1303ea6b10bc6c5d47fad13bd96a6a1968ba6" + ], + [ + "p", + "7f5c2b4e48a0e9feca63a46b13cdb82489f4020398d60a2070a968caa818d75d" + ] + ] + }, + { + "content": "Qju4ICVAki2Ead6iINTA5GaOnJSwZy00Gilvyhm/LmjdnNEcQdQPXifheYc/1eMchN6VUxJDabiafPe1OjX+RD2iciBUlABOgpy+y+weUd8=?iv=BaIQNwhp6g4PiJu+MWdiuQ==", + "created_at": 1689770428, + "id": "389386ae9cbc4b1d5e4fefa464136b4f5eff12ad0e030b15076976a08c9b40c6", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "1e14b2d38f73f965f987c05c909eafefd97bdb29c04b3cc6d78aad708c0106559282286f9073a45f6f7d4f840b94249de21d5a6e964708cf0fb800401932068e", + "tags": [ + [ + "p", + "63fe6318dc58583cfe16810f86dd09e18bfd76aabc24a0081ce2856f330504ed" + ] + ] + }, + { + "content": "D+mvo+RodsQgWegn9RjuWHyawp7sHFBpLgHW5+2yQLw84TKrY5svyR2NfEUmJcl3?iv=BkB0cjrode2kmi5foZf/qA==", + "created_at": 1689770406, + "id": "bef8d4b6c114ca46c03093577e72ae1aea26b1102242ed1c9d0220c78f31d707", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "87cb9e2c165d9bb931c73a6c8899363ffa975f423989363580090919219406a13c5be2932e0df676931583d8a2be86def4b56bc0f8021543dd1aa584efda08ad", + "tags": [ + [ + "p", + "63fe6318dc58583cfe16810f86dd09e18bfd76aabc24a0081ce2856f330504ed" + ] + ] + }, + { + "content": "Sd4jDtAA1cp5RPs3vlXKgKEcnnwyBCX/6gAI8iFUj+vlFhblJc7UCQ0E+FtgPeeK8GYB1lrmll9Z+Xcy8S8yAQ==?iv=YJ/u5liYySfupmcXDjGu/w==", + "created_at": 1689770387, + "id": "f75b58ebfaca4a9697397fe8d2b6f848d3d01908bbfaad613e37b995e0fe0629", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "59bace0ecd181d2a29c13eee6cf238ac70a22a45b6e0ef6d9df39a46a7f5f6243c26b223fc085027cf326fdaf1e8f63028071560abd48fd24f2d912be12bc0a2", + "tags": [ + [ + "p", + "63fe6318dc58583cfe16810f86dd09e18bfd76aabc24a0081ce2856f330504ed" + ] + ] + }, + { + "content": "V+RxWXXhMHFF9yQQmbWK6Q==?iv=QrXWO3cMXO6+rntdblFulw==", + "created_at": 1689770372, + "id": "331ec02999a4ae6aaf33eeb738dc4c9e8535f077b9573f92c78aa75b1c0caa00", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "edc43ce3d7ddcbcb5b72e9c8e869250ccebd76244cfd883f7a4ba0833c7a2d19a0052a6aafdfd0cab1ed7a3d31a58c3b976f5a16c3499e0ddd769849d027699e", + "tags": [ + [ + "p", + "63fe6318dc58583cfe16810f86dd09e18bfd76aabc24a0081ce2856f330504ed" + ] + ] + }, + { + "content": "I will repeat myself: It is utterly embarrassing that YouTube creators have more monetization tools for their creations than developers. \n\nThis starts to fix it: \n\nnostr:nevent1qqsdcan9s3j2pvhgugnfz5vkfsv6ehumxeqzl6lhgkx7vh3h6hg7hegpz4mhxue69uhhyetvv9ujuerpd46hxtnfduhszrnhwden5te0dehhxtnvdakz7kzntv4", + "created_at": 1689770176, + "id": "2526d5ce37b700d416fea47721d3260a605b3a3edbb916adddd8f547cccdb6cc", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "f5d7339fa2d1be538e33d67e7cb7c267c54eb79a555719f245eae431471e50ead7735892395bf1bfc876d37c8849b0ff006188e22ceaec322d867f960699cd48", + "tags": [] + }, + { + "content": "An external service for larger purchases is great. But I think it is extremely important to also be able to one-click buy things from any Nostr interface without navigating away. I have explored a few options with Amethyst but it's not good yet. ", + "created_at": 1689769859, + "id": "f0bf7d248e55683e008eea97ad017f87b49e724539148bdfa937cb57caa588a4", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "ffddf687fc80146e53901dc55547ef00dc010453efa337eaac7c84768daab445bd0b4d1187ca97b35e6d47c7440dc9a995fac7226bf79f60b14cc8784dfc8279", + "tags": [ + [ + "e", + "1a1be57cf73c27aefab4f0b733fe8ba433dbccc7ba2dc8c53c9764d077f79add", + "", + "root" + ], + [ + "e", + "3b24ba5bf6026fa7b210db0895df602084817c5521bccccf80a7bbf64607cff9", + "wss://relay.orangepill.dev/", + "reply" + ], + [ + "p", + "f4db5270bd991b17bea1e6d035f45dee392919c29474bbac10342d223c74e0d0" + ], + [ + "p", + "fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52" + ], + [ + "p", + "3f770d65d3a764a9c5cb503ae123e62ec7598ad035d836e2a810f3877a745b24" + ], + [ + "p", + "f4db5270bd991b17bea1e6d035f45dee392919c29474bbac10342d223c74e0d0" + ] + ] + }, + { + "content": "Strange. Isn't it a relay issue? I noticed that the post is only in 5 relays. ", + "created_at": 1689768641, + "id": "aa82841f3da7f04319e9b5b0ef0d6a934da15fd575ba9ba2055bc7e542fb005a", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "6eece2f872bbfb9459c7bb3e6d8b73328d3d40b300b8ec31c47165dabf69d30a039103f32c7acd4620e03a1f2a3a4f764bf6c8687524ab117e677c7c74eb0107", + "tags": [ + [ + "e", + "bbcc50d1d1487dca1ae3791ac651c709d5a0b91b139ed5a54f4a1aa2f077c465", + "", + "root" + ], + [ + "e", + "4289c7852d03444b1075f3ca4dd5cf79ad324ec0cd464144470c9db796918604" + ], + [ + "e", + "3c4f2cd1fd77b5f00b946b58a71fc1bc0dd3ba74eb70d6e89d1a1dc025036b44", + "", + "reply" + ], + [ + "p", + "74dcec31fd3b8cfd960bc5a35ecbeeb8b9cee8eb81f6e8da4c8067553709248d" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "532d830dffe09c13e75e8b145c825718fc12b0003f61d61e9077721c7fff93cb" + ], + [ + "p", + "564e2192d2c4df33224c15d787cd0172fc8c7e6a7afd67bcc3f8e3447d765981" + ] + ] + }, + { + "content": "LnYgC0RLdzVdatNVXo/iD6UN+dP4xDT/9sw2E95T958=?iv=rikKQozxy/jFNMVIDjqTlg==", + "created_at": 1689768433, + "id": "6e22cc856c25dc8154959147f4c71ac9ad687385135390bba42df621b0daa1fb", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "ced9ab7e521432aa54d433b32869c21b402d9fb7e009eee6e70e6b0b2100edc4d78a3571dc79279c05ad11214e1d2429e5c764ac366b932bde2493beb71deee1", + "tags": [ + [ + "p", + "672196e844d54702dc5933bf339d53e1b2641a767264384323957f424fd57b04" + ] + ] + }, + { + "content": "84qIV+GtKNOE6pCikWXafQ==?iv=IH/gXx+bmRGJz6SoM5pkVA==", + "created_at": 1689768426, + "id": "20ccf572dc67d15526c6a2d39115769a37d3a8dfabab54dec30307e2e137d634", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "34409de0e4e1c707d11d352bdbbbfd45eb5be266302ee5b701cd6f3df97ebf88958b011f41f7e1814c70d7716960d9ff611712c1f261c450ea46d084af43ae76", + "tags": [ + [ + "p", + "672196e844d54702dc5933bf339d53e1b2641a767264384323957f424fd57b04" + ] + ] + }, + { + "content": "5w39JZPqwCg2wYp3fZi5DxJOfGS3ILijznewkli0xa8=?iv=3rXD8vh3AtHVd0RbFVlyRA==", + "created_at": 1689768408, + "id": "d67ff8794bf1e427c29c978a277e547bb8783799d8ba558a789636639fa64d5d", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "cf6ef7ca24fcceeca9095de854e0046098f508d5c4e13e05f283f98ef8b915da1300f6ca3e5929025151b128243980f7c7ed7a3ae958c8c3badb287fba2c0ec9", + "tags": [ + [ + "p", + "672196e844d54702dc5933bf339d53e1b2641a767264384323957f424fd57b04" + ] + ] + }, + { + "content": "Block the app? I am not sure what you mean", + "created_at": 1689766554, + "id": "95709faa74b8a044c55155344768f868035f4a2efaba9fdcafd91620a83c7ad7", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "d9348bc5a286dfd6bcabf2e778f85b9aa85a2ce53892951232900dfa964734e9ba4ee6177b4def01c4b8d29478fa228ecee19f474ddbeacee5b5ec80c82787e5", + "tags": [ + [ + "e", + "ab53ded32616980073fc2c9c6ee2e8056ecc5bbd6d46c10a925fd96077a0a574", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "b75b9a3131f4263add94ba20beb352a11032684f2dac07a7e1af827c6f3c1505" + ] + ] + }, + { + "content": "Yep, since February.", + "created_at": 1689766494, + "id": "67f9aefdac7e17525dcb9b9a8a4b62e8df734765c71df1b5a653b7e4e871b246", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "02d792d0446f213e8d0624ae50d376552baaeea7be6714aa186b5e2299546cd3e6227ec9e89692963e0ba50b680f7f2e3aa7a663b69e53ec48f96e9977ac7859", + "tags": [ + [ + "e", + "5fbedd48a63ed0a4c8c411b7c4eff4cca22b4430d0c2eabcfa1fdbef25dea8c5", + "", + "root" + ], + [ + "e", + "1b3898f53abd0fa5ad782f8d6175a441e14128d54d65a8ef008468cc5f9123a1", + "", + "reply" + ], + [ + "p", + "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "331dcd701d4785c9ed7f2cbc0d37e72448c810186c9066f16b9c6c69d454df6c" + ] + ] + }, + { + "content": "Over 100k, but downloads is not a good metric to follow. Daily active users from Nostr.band is way better. ", + "created_at": 1689766394, + "id": "9dcca85455abf03edd6812c740d708370077922204a74933548b8c49a5a39f47", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "4e22986a80e3fe0d76f06e70f19be3a1e26b3ad5bb918a750744033c6d7add144ab08532bec52c5edd8f010cc9c114b35ed973ca7f98daf5337c83e8a70c8fa4", + "tags": [ + [ + "e", + "763c8078c7dd051a4a690001664b8dfe984070dd3efacd78846c4cdd2da3d068", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "8dfbea712e6263402297a88613240948231dec9172bee9afe2c82b5af27a72cb" + ], + [ + "r", + "Nostr.band" + ] + ] + }, + { + "content": "What do you mean? I see this note on amethyst just fine. You don't see it? ", + "created_at": 1689765862, + "id": "4289c7852d03444b1075f3ca4dd5cf79ad324ec0cd464144470c9db796918604", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "605e4e0f4389037a02f6dbf16d72b9d616637d5ccf360c1fb40721febe76ac367839816263c20c99c3c4c381c2cb36789784888b7ee1ef780fcbac2e0eda9964", + "tags": [ + [ + "e", + "bbcc50d1d1487dca1ae3791ac651c709d5a0b91b139ed5a54f4a1aa2f077c465", + "", + "reply" + ], + [ + "p", + "74dcec31fd3b8cfd960bc5a35ecbeeb8b9cee8eb81f6e8da4c8067553709248d" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "532d830dffe09c13e75e8b145c825718fc12b0003f61d61e9077721c7fff93cb" + ], + [ + "p", + "564e2192d2c4df33224c15d787cd0172fc8c7e6a7afd67bcc3f8e3447d765981" + ] + ] + }, + { + "content": "", + "created_at": 1689735264, + "id": "568aa3a8feb50e84be9e4eb23e67a1c6caf64477a3f5beed397fd813fb341c51", + "kind": 1065, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "c17f12eb3978813697517020585f79ec8f3fb0d40e304d96f04fa187534c9726644782aa2efb38b88cb096f0bdc982836d1d8088ef5a4330deb56f661aca7eae", + "tags": [ + [ + "e", + "2091531f8196ac2334bf5249f0593d25a47516d7b0f05b72f75898a4767105d4" + ], + [ + "m", + "image/jpeg" + ], + [ + "x", + "44746cee88a03743d35757aaf5b3ba178d527b71831387fb6df6b7ff1c1dfed5" + ], + [ + "size", + "70744" + ], + [ + "dim", + "700x787" + ], + [ + "blurhash", + "{bJQs1xtx[M|aKt6bGkB~qkC%MaeM{ozkCj[_3R-xuWBoIofbHay%gxZWWfQj[juWCayJCR+jbj@WVa}kBWBaeWBV@a#kCf6ofayRij?WBj[kCjsj[WBslWBWAj[j]j?bHWBR+fPRjoLWCWCoLWV" + ] + ] + }, + { + "content": "", + "created_at": 1689735142, + "id": "8baf7f4f57b2ccc2959d4013d8ce8984f23ac63fa501fc4779081183a8d1e607", + "kind": 1063, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "2e7ff6a7d5e66d20ebcc295965f5a3819d8b0756f100b3fb2a174a6988b8f989d8abfd81afacb607406019144a19830dee5ec0e81d621d93c825b632db2c152b", + "tags": [ + [ + "url", + "http://nostrcheck.me/media/vitorpamplona/nostrcheck.me_22f927d3b7728cd4a5e4a346fdde6dc8a5572072ffbc25b4.mp4" + ], + [ + "m", + "video/mp4" + ], + [ + "x", + "b9f569c3cc11bf0bafc96acd2ecbbb947a291ed28c04a109194122ecb16b96ab" + ], + [ + "size", + "4552970" + ] + ] + }, + { + "content": "", + "created_at": 1689734960, + "id": "257b87c845792f00af0850ec6c1c2c303c03c7de5ced8809d18886e731da4e8f", + "kind": 1063, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "08949cd2e8c188fbc65879163fc62b449037a4540c9bdd918a5e0cd505810d61db0a221d84582a24c699f364db7439cb52bea21788370997f666ea580270ff3d", + "tags": [ + [ + "url", + "http://nostrcheck.me/media/vitorpamplona/nostrcheck.me_8e7b035017ec1de33d2b8566de0f29efa9bca2410efbbe49.mp4" + ], + [ + "m", + "video/mp4" + ], + [ + "x", + "c660cce3f512e9264baabc00b86f886b1a765507c318604695c2485843ee5568" + ], + [ + "size", + "1534508" + ] + ] + }, + { + "content": "", + "created_at": 1689733717, + "id": "523c5afe1411641ffe583c81e838fb5760ac86f933e731eeed1608ed6e469f2a", + "kind": 1063, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "f7eccf6879cd24054f088a317c65fec271c06b7c688ab03524321f02699a92a64384c343b14b4300eb21d04925dbb954b4d5fd929f7edfb2739964670f6ba276", + "tags": [ + [ + "url", + "http://nostrcheck.me/media/vitorpamplona/nostrcheck.me_16541715a9bcd12306d4f61bd5e039284128edcaafe3043f.mp4" + ], + [ + "m", + "video/mp4" + ], + [ + "x", + "f383c5b2f585a6a986f062ffc658afab97d3e12496037b336820c2aaedc21708" + ], + [ + "size", + "6121702" + ] + ] + }, + { + "content": "Reviewing a NIP vs writing a NIP.\nhttp://nostrcheck.me/media/vitorpamplona/nostrcheck.me_d1d268a25e132f26352546760b8f0fb22fc3c932760edd18.webp", + "created_at": 1689733437, + "id": "de7fa61fdd2072ad8d6b9e3c90cf970268de48290d24e67c0692c394eca466bf", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "7f88ffb115a2ad74d347a336b85f858ba6daeee05262332bfb9eaa0502ffe8bb5631909a6a16a2ff0a70e513c640aef3c4eed8545448fc534dddae5dd374a026", + "tags": [ + [ + "r", + "http://nostrcheck.me/media/vitorpamplona/nostrcheck.me_d1d268a25e132f26352546760b8f0fb22fc3c932760edd18.webp" + ] + ] + }, + { + "content": "", + "created_at": 1689733322, + "id": "f36e5d3ecbb914f4861ff170b8377d571e6395a02d5d5ac7c17bd99e2df78e3b", + "kind": 1063, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "de6ee5365d0e84255bfef9dca800c94c022ed7569d97069c7ef7d562556d3e9a20a852fa86579931f7370e9f85bcd4d24a64e78e64b1348493acfa6c519311df", + "tags": [ + [ + "url", + "https://nostr.build/i/457757ddef7ccc7c4306282d3442f9cc9a977a58773cee39c1d220055ddd07d8.jpg" + ], + [ + "m", + "image/jpeg" + ], + [ + "x", + "5fa74a9024ee9cfff829a4750929591f542fff4d45262bee6e22a241a2f77731" + ], + [ + "size", + "189954" + ], + [ + "dim", + "1170x1524" + ], + [ + "blurhash", + "_7ECI9+t-p%L%2~Bofy=Mx0z9sIoNan*%z~CM~E2NHIWX8%c?Z^%?aawsk%2TeJ9%0-:R-E1ae=|xa%2-pM}Nen$TIkoNYxrxYNHfj-owgxbxbxas:bcNFS1NbE2SgsSIW" + ] + ] + }, + { + "content": "Also, this is a tentative go solidify a single API for all service providers. \n\nhttps://github.com/nostr-protocol/nips/pull/547", + "created_at": 1689729262, + "id": "c3b4f7a5fb5b73b48acd49c00097bd48b334c506f7ba60f7e2f784e3ef6f86ad", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "6724905af656ff6a3fce1a4e1003c03283b4a9b34ace65915d55431f84edff612ba7bf1a0bd7eaa301fc11372b8ac14bc94d0950d0c793cd3efc7ad372d6aac3", + "tags": [ + [ + "e", + "0fb88d12f3852b003ab2ef21a0d4be2fa5b1471a347fb979d93ae381014b740a", + "", + "reply" + ], + [ + "p", + "0f22c06eac1002684efcc68f568540e8342d1609d508bcd4312c038e6194f8b6" + ], + [ + "p", + "76c71aae3a491f1d9eec47cba17e229cda4113a0bbb6e6ae1776d7643e29cafa" + ], + [ + "r", + "https://github.com/nostr-protocol/nips/pull/547" + ] + ] + }, + { + "content": "🚀", + "created_at": 1689724634, + "id": "e9c257a0586daf0767e313bb9ba569e432ecf17e3a9a8a7beb81254e29957020", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "a66d4cac9ff56f55ff998a665a347485c8e985a6ddbed24dd1405aa3a21291d1ff91ca01b7d2659bf774e5fdf59ad38f17869e1426ed8fe74e53ead866fe25ff", + "tags": [ + [ + "e", + "83a23b4f0584bd4a34c210cbbb5d4dafd03f25b886d0f5f7e5f638139e69d8f7" + ], + [ + "p", + "89d1ce9164f1f172daaa9c784153178cb1dec7912bf55f5dc07e0f1dabe40e6c" + ] + ] + }, + { + "content": "🚀", + "created_at": 1689724333, + "id": "a64c025b82d09bb1fb7d2eeaf810793d880cdd7f3cbb2c4cd30ea13582ca4afa", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "e6f16f6dd109d84c54077a705d9e912d1cb2c15fab6b6d12ac434902dffe5dd36cacbb57c760686dd6097c828d93a3ac979b95ef239cb0d42a9041d0cc187234", + "tags": [ + [ + "e", + "473007f975b7e612910adcdb9979e81cc9e3a8a37066c4d03685cc1a8a33928b" + ], + [ + "p", + "9267545d2917b80f707ffdb44a8ff979182568ef7baa04ee756b1f01d4e3688a" + ] + ] + }, + { + "content": "W don't display all notifications. The app only displays it when you are directly cited or when it's a reply to a post you are the author. ", + "created_at": 1689724319, + "id": "c220414cf423280cb3e8f88174a6ee9b8df1b3ede4febe24fbcc1dfdcd0e2208", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "9974f8f47a6479bdbf4f2e05bec747a43387a0d9752481ce80a0295c34e96df41b7523ad87ee78e30955f01951ee928ab3fc03a3a586e003932eecd5d8a3c543", + "tags": [ + [ + "e", + "6fd5fce21e31c71d7d27f5cf740f3570b296bde46894eccd5958f234e0e5a820", + "", + "root" + ], + [ + "e", + "bb271e57c3b96c9f7bfbb0e03964c3820d7dc629b46c30899dd11be7af4d4691" + ], + [ + "e", + "497eab572a2cd0716e92e63415b923e7c38f73a1dff0d1cd3216fe1bd51c8787" + ], + [ + "e", + "5e9aa9876a730974ecebef4f52742bd4a9877143146eddc4168424517667307f", + "", + "reply" + ], + [ + "p", + "89d1ce9164f1f172daaa9c784153178cb1dec7912bf55f5dc07e0f1dabe40e6c" + ], + [ + "p", + "180a6d42c7d64f8c3958d9d10dd5a4117eaaacea8e7f980781e9a53136cf5693" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ] + ] + }, + { + "content": "That's because another client is erasing it. We have always saved hashtags in the contact list. It's was never local.", + "created_at": 1689724277, + "id": "eeae5dde847dec45663970e4fc8423ab4c2a372de0badc1730029bcbbaa39f84", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "a8be54bde3be1b9170a3df82823822dffd1159a6561a2e2e84619528e212f0bf606c6a2527194506fb0536a598d0681109d63cac9394fd66943bde06392387fe", + "tags": [ + [ + "e", + "2485f76b226cc2489b20509d1042e4e6a7d1e4e1c0b540d1c8da86fc18804937", + "", + "root" + ], + [ + "e", + "46a660a9a9b87f8bcdc8471a61c53e2111537285a78f28ee62c495b539a7bd36" + ], + [ + "e", + "5057914f8a3c8425d6c2160c130a256c343dcd4943eaeb94c3f9bb83f03c19be" + ], + [ + "e", + "c67fe72ec0895e4e5c698ad669bd7b5e13ca936ad120a1dd574a86fc20e618ec", + "", + "reply" + ], + [ + "p", + "9267545d2917b80f707ffdb44a8ff979182568ef7baa04ee756b1f01d4e3688a" + ], + [ + "p", + "9267545d2917b80f707ffdb44a8ff979182568ef7baa04ee756b1f01d4e3688a" + ], + [ + "p", + "3f770d65d3a764a9c5cb503ae123e62ec7598ad035d836e2a810f3877a745b24" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "f0fb31d1810a9f95df3d178fcd67ca0b09879ad11e8689e56962cd839fb8ead4" + ] + ] + }, + { + "content": "Nostr devs are like: I am going to spend 2 hours and make a new app.. why not? ", + "created_at": 1689721709, + "id": "dd4375c77daa2335d53318fa39276b0840651e1e77fce1ed61465698e3af3fb1", + "kind": 1311, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "6c109ac0f321b61060241790d85acdfb223b6143038aba381f4eed27a20bf175dd44c779981aa0b1d2897e42d0d145fce4557bcb710726252cfba8054c11072a", + "tags": [ + [ + "a", + "30311:97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322:1689719669", + "", + "root" + ] + ] + }, + { + "content": "🚀", + "created_at": 1689721672, + "id": "cbbc2beb927c61a157f748d993d87c52fa0f097b5e468f3aa20b5029f5c08dc7", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "9e8106799c6812d6ada4ea8db38ab58d978e33d14347cf6b38335a9594de6dfd95bfeea0a447e016c4689ac2528a01c5e79639643026ba41564260d1f69634c5", + "tags": [ + [ + "e", + "c9911b6d35b4c87c53feae668005604ee0e620274322dfec6570dde6fdd68aa0" + ], + [ + "p", + "97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322" + ], + [ + "a", + "30311:97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322:1689719669" + ] + ] + }, + { + "content": "Because everything already is. ", + "created_at": 1689721283, + "id": "173122f70b71b0a057ed6bde5094abbda41540d68c5b1cccbbea5fd428578505", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "e82e5064d89be686f02d55ddf6dd7f3ccc206c154db3f18c9a89cdeb9ab399f15e2551f195db839b67c747ca32fd6362a3e6570dd5acdee4486cdffc992cd0c1", + "tags": [ + [ + "e", + "2485f76b226cc2489b20509d1042e4e6a7d1e4e1c0b540d1c8da86fc18804937", + "", + "root" + ], + [ + "e", + "19aa577d11b0dab38635548fb830f7f3eeb7f4de8c987d2d70d3526e23537c79" + ], + [ + "e", + "f03d390a0416e822a965d83d17ef61c0439979404eb0b0a79080053f64fe16f3", + "", + "reply" + ], + [ + "p", + "9267545d2917b80f707ffdb44a8ff979182568ef7baa04ee756b1f01d4e3688a" + ], + [ + "p", + "3f770d65d3a764a9c5cb503ae123e62ec7598ad035d836e2a810f3877a745b24" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "8e432ad14d3955d0863b975778f0c8817ef88c9f119d626da1a3face584bda73" + ] + ] + }, + { + "content": "https://github.com/nostr-protocol/nips/pull/673", + "created_at": 1689721195, + "id": "baf9d389c6b1e18a1676efd8904e52270198129c1f61dcc3db97e0c8cc49a000", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "73e5b4f28b8989e3aae1e7c31ddbcc43a392ac945186cb98719c9fb05d93e7bb90a5033b2fea99f5b3b9ab19128089b8f85ca0d0865ffda8daad5c81ade8e4a4", + "tags": [ + [ + "e", + "2485f76b226cc2489b20509d1042e4e6a7d1e4e1c0b540d1c8da86fc18804937", + "", + "root" + ], + [ + "e", + "46a660a9a9b87f8bcdc8471a61c53e2111537285a78f28ee62c495b539a7bd36" + ], + [ + "e", + "5057914f8a3c8425d6c2160c130a256c343dcd4943eaeb94c3f9bb83f03c19be" + ], + [ + "e", + "f8881207bfdca139717745ced0e86e0ee20d2e73417f21bb813c6ed151e920dc", + "", + "reply" + ], + [ + "p", + "9267545d2917b80f707ffdb44a8ff979182568ef7baa04ee756b1f01d4e3688a" + ], + [ + "p", + "9267545d2917b80f707ffdb44a8ff979182568ef7baa04ee756b1f01d4e3688a" + ], + [ + "p", + "3f770d65d3a764a9c5cb503ae123e62ec7598ad035d836e2a810f3877a745b24" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "r", + "https://github.com/nostr-protocol/nips/pull/673" + ] + ] + }, + { + "content": "I want to stop doing local settings. Everything should be on Nostr, on relays. ", + "created_at": 1689719485, + "id": "5057914f8a3c8425d6c2160c130a256c343dcd4943eaeb94c3f9bb83f03c19be", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "44a2c6edda25b215cd5187f309d0292bc188607384413bae08625ed6915d73bb95a348119f4a58f991e9bb97a19569c0678eee8599d9339f1e1e21d6d84923e3", + "tags": [ + [ + "e", + "2485f76b226cc2489b20509d1042e4e6a7d1e4e1c0b540d1c8da86fc18804937", + "", + "root" + ], + [ + "e", + "46a660a9a9b87f8bcdc8471a61c53e2111537285a78f28ee62c495b539a7bd36", + "wss://nostr.bitcoiner.social/", + "reply" + ], + [ + "p", + "9267545d2917b80f707ffdb44a8ff979182568ef7baa04ee756b1f01d4e3688a" + ], + [ + "p", + "9267545d2917b80f707ffdb44a8ff979182568ef7baa04ee756b1f01d4e3688a" + ], + [ + "p", + "3f770d65d3a764a9c5cb503ae123e62ec7598ad035d836e2a810f3877a745b24" + ] + ] + }, + { + "content": "Devs, who is using kind:10000 for Mute List instead of a kind:30000 with d tag=\"mute\"? \n\nWe should focus on just one way to do Mute Lists.", + "created_at": 1689719265, + "id": "bab81750570876585535c8ac4a4d5f983ea4cb0675c94882af25b256d60f5a7e", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "646f33f7f4c005d31c73b9687e041e6b49080606a71d789611a5129f9f1025ed6ada39d2ecb31f4f7c8fb50e33f3946ad11aae23d37c0388d964684772f89098", + "tags": [] + }, + { + "content": "Is this a global setup or each list will have their own keywords? ", + "created_at": 1689719025, + "id": "4738396f74638dca62d58a88764ededd2d89748e20f81f4fba574fb1af1a9b40", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "323a7cc7373289a83eca16c3696d37c05d0860539188eec90b931f54f29ae5e1ca7b6b561dffd4d1b65f5038dd0adab5af21063047667def894e72e9d0d35dcd", + "tags": [ + [ + "e", + "2485f76b226cc2489b20509d1042e4e6a7d1e4e1c0b540d1c8da86fc18804937", + "", + "root" + ], + [ + "e", + "25c76135357f79245f401168ee01aecb748c7434d8f12c3627a02fa41dd2d15f", + "wss://nostr.bitcoiner.social/", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "d0aa74cd95a651d3d2ab4fb18b58fe71b447d78d40f8dd46f1dbaed5603d35cd" + ], + [ + "p", + "9267545d2917b80f707ffdb44a8ff979182568ef7baa04ee756b1f01d4e3688a" + ] + ] + }, + { + "content": "I meant on Nostr. Which NIP? ", + "created_at": 1689718940, + "id": "25c76135357f79245f401168ee01aecb748c7434d8f12c3627a02fa41dd2d15f", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "a39d29dd625e2af0a636a09fca8047ea6abbeee9258713db413a9f975953ca625448878cd0db49db15bc6aa54e2df67aa8a72ba2b0f2dbdf44229bd4a3e7bdd6", + "tags": [ + [ + "e", + "2485f76b226cc2489b20509d1042e4e6a7d1e4e1c0b540d1c8da86fc18804937", + "", + "root" + ], + [ + "e", + "6e8e7ab0fc769cf059fbc93c40d7007bd8847a80433cd8e68c15be45bf1594bd", + "wss://nostr.bitcoiner.social/", + "reply" + ], + [ + "p", + "d0aa74cd95a651d3d2ab4fb18b58fe71b447d78d40f8dd46f1dbaed5603d35cd" + ], + [ + "p", + "9267545d2917b80f707ffdb44a8ff979182568ef7baa04ee756b1f01d4e3688a" + ], + [ + "p", + "d0aa74cd95a651d3d2ab4fb18b58fe71b447d78d40f8dd46f1dbaed5603d35cd" + ] + ] + }, + { + "content": "NIP-53 doesn't have direct invites though. I am very confused about what the invites are doing. Is this like join me now if you can, kind of invite? What happens if they reply yes? ", + "created_at": 1689718906, + "id": "6aae65ba6f84596984069e914b441bb2e29fd031c63a1e3647754c70a49576ad", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "680e70e6d5a2786349fd566cebb3f5678545854e7cb890bfe5ff68c8b374640acc04989e1285b27eb152ca765e938e8b0b39e8d3fb745857fcaf3c125da0ed68", + "tags": [ + [ + "e", + "8a7780984986beef1406caf4139a338349f8d194725eff881157cdc6e69cb983", + "", + "root" + ], + [ + "e", + "573cb50aa1485d3c41ae7324b6c5d469a979bed956417e6bc3d95825c61fe5ff", + "wss://nostr.bitcoiner.social/", + "reply" + ], + [ + "p", + "b8beebaac1fea45e8907a52b6d6a57707328276f2f000719de1cbe20b3b9fe80" + ], + [ + "p", + "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245" + ], + [ + "p", + "deab79dafa1c2be4b4a6d3aca1357b6caa0b744bf46ad529a5ae464288579e68" + ], + [ + "p", + "2779f3d9f42c7dee17f0e6bcdcf89a8f9d592d19e3b1bbd27ef1cffd1a7f98d1" + ] + ] + }, + { + "content": "nostr:npub1zuuajd7u3sx8xu92yav9jwxpr839cs0kc3q6t56vd5u9q033xmhsk6c2uc 's Facebook Marketplace NIP was merged! 🚀\n\nhttps://github.com/nostr-protocol/nips/blob/master/99.md\n", + "created_at": 1689715846, + "id": "d7c2b6093d9dfa3f452b871da8b3290a42159db6cd084ff17bcd6c6e25fc2a06", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "90b8a3d9f17ba803b7b2e188a6acad31cda7179dbd9ba6fd13cc9a600d32b9330999d5718c5d34f7823457c2dba964ee46ba7dc34615b4820544d753283ea7d4", + "tags": [ + [ + "p", + "1739d937dc8c0c7370aa27585938c119e25c41f6c441a5d34c6d38503e3136ef" + ] + ] + }, + { + "content": "It has been on my todo-list for ages. I am not sure where to save it thought. ", + "created_at": 1689710487, + "id": "67cf4b517fb8cf8cde6ff822500fcfa7fde11d0677e8096b7f98f38b6c1dcd1e", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "a6689c8dab94bf784a18ecaad285c74ef4332cf098eae040c092a1c05054b1479afe5bf066ec76d9eb0f8c86b2274d1688196ed9d7e5c01c68f89b6bd0b5ed84", + "tags": [ + [ + "e", + "2485f76b226cc2489b20509d1042e4e6a7d1e4e1c0b540d1c8da86fc18804937", + "", + "reply" + ], + [ + "p", + "9267545d2917b80f707ffdb44a8ff979182568ef7baa04ee756b1f01d4e3688a" + ] + ] + }, + { + "content": "I would guess they are requiring users to have a 'user' attribute such as a contact list or a user metadata kind set up. ", + "created_at": 1689710282, + "id": "69aa2f252f0d51e76147257b84866c237f4d05b6eeff41c12e22f717906268dc", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "461eb497159cc49ed2e44fe524e7f3658aa4ea561d9f74c13187f4fb2efa9ce4852c717cc057b85d1060044e69de294f5b8d4e174f1935d4d931d96344b07445", + "tags": [ + [ + "e", + "08f4c8cbe5cba4bc0c68863eabf8aa7c6ad22be19398cfd6ae137f541454a9b8", + "", + "root" + ], + [ + "e", + "fb96d54dcf8128f0ddd8994d53b81fff998e80043b45f15db257265df4d5dc23", + "wss://nostr.bitcoiner.social/", + "reply" + ], + [ + "p", + "43a22be283a77d24a3fa218e063e782da195d1adb0edd528b88ac9ba1bebcdfe" + ], + [ + "p", + "8a9402c71384dd0a387d3def483b8f89736fdfe26bc28276671820af942cca7e" + ], + [ + "p", + "532d830dffe09c13e75e8b145c825718fc12b0003f61d61e9077721c7fff93cb" + ] + ] + }, + { + "content": "https://github.com/nostr-protocol/nips/pull/597", + "created_at": 1689699142, + "id": "5571cc3a41f0cc0a36c38711307cefdb30504cf851e1328a2b4f852c29a0fa7d", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "2ce8c864668bb4c1b63a88727e796a870cb8498b20307a40a735fcc30e2759f93d73a96cddf95d9599316e9fcbc060938f87868a972f00fcc6bd24c2494bf44c", + "tags": [ + [ + "e", + "8a7780984986beef1406caf4139a338349f8d194725eff881157cdc6e69cb983", + "", + "root" + ], + [ + "e", + "3c4c22b112912148bfcb2e65ba02a200cb3363d4be8d1bdd77c5e2bf43b9a065" + ], + [ + "e", + "2c592975b96913fe5a856a67b41dff42e70fdfdb72922c86fdc59f31704e9c0b", + "", + "reply" + ], + [ + "p", + "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "deab79dafa1c2be4b4a6d3aca1357b6caa0b744bf46ad529a5ae464288579e68" + ], + [ + "p", + "b8beebaac1fea45e8907a52b6d6a57707328276f2f000719de1cbe20b3b9fe80" + ], + [ + "r", + "https://github.com/nostr-protocol/nips/pull/597" + ] + ] + }, + { + "content": "🤙", + "created_at": 1689699060, + "id": "c43ff35ea35d8d58089e68ed52cf9fd6dfaf5f9e25f475aeb88a807818d58812", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "fd8b3a15b4dabbde2dbbce1b1dbf3fa81bbc52c653b4473afee0498e1253379c094086a13d2c0e0a3c074b33a752c8faa22caf8faf0e403e64dd027a07228a4f", + "tags": [ + [ + "e", + "9909236b03e8581c67fa93a0409efa71638bda585943b0a1abad59a6196d3255" + ], + [ + "p", + "7ab1d3867722b4cbabb6c8503ab3f9265daa4f82e228cefe302621f4e5ee1f1c" + ] + ] + }, + { + "content": "🤙", + "created_at": 1689699028, + "id": "20a5feb4699b42f94c0ef86f698d4b39dba306ffaf1a296de086185b21bc008e", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "f6856444b7ca2df1d3f8b20791b2068ed670c925f0be05c01444d4cd56a60925a35f0114a26ad54fc9799a4c0ec6390cae58755e56fafd47e923e75a6c84e720", + "tags": [ + [ + "e", + "f1dbc22d6c52e9ab63cdbd7ae563b317f00c6206aa7e378965e432b1928ae36c" + ], + [ + "p", + "3493a605e9c26c31ebe1d86a20f96082c4f584d6fde3cf98b9afc2d783ffc952" + ] + ] + }, + { + "content": "2 possible issues: \n- if you were using private bookmarks, some clients do not support it and might have erased that info. \n- if your relays failed to provide a bookmark record before you decided to add another post into it, the app will start a fresh list for you, erasing what was done before. ", + "created_at": 1689698818, + "id": "f50b94d7b1c87b7c9a022a6ea8815f5ae94aace648f1b8f154606d011e14e3a9", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "6054a616397ebb2331804aad0eefd7763354bc2a3900d33a6325bd23d38f5d53d30c1b6f244c4935e232302f5a542df2f9a3b41b0bc36d091081ae386a3810e9", + "tags": [ + [ + "e", + "a43fdf0ef52cb242995bf8d173fb5a8c4f308cb07dd2a6b627a5816e929b1f23", + "", + "root" + ], + [ + "e", + "9de05c2edd1d5221dc8428cde09467dda4dfb84a0431015b65cf8ceb347a3d7a", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "880b21ccbe2e079c9ac5a5d14314ce5d47adbfe6cd5c00116e75f472d9a3f910" + ] + ] + }, + { + "content": "Groups of people? Use highlighter.com or listr.lol for now", + "created_at": 1689683437, + "id": "51868a97d597d756d01f3bd54d73946783b6cc217faca7ab288cd0b2769146e7", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "8bbfe64b5b37a07415f20b90703e7973578ae7213ed8b8eca6b080160ce426d1e6c3abd9c8d5f9440f3cbb9ee6456f6fda0f239c5c01002dfe777108c5b4106e", + "tags": [ + [ + "e", + "b220fa47738212e6935be76b73fb6a6124948113cda700c04dd349641e86c3fa", + "", + "reply" + ], + [ + "p", + "0d97beae567fcec9c6574f1c6ef6126ea969d4992c3198e51c0fac52c5274a14" + ], + [ + "r", + "highlighter.com" + ], + [ + "r", + "listr.lol" + ] + ] + }, + { + "content": "🤙", + "created_at": 1689677043, + "id": "f5b58d047aef44426bd06c0862b0258668ba9ff48f007269c24ee955d9d927e3", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "93f58aaf7438b0e630fdbcbfce5df066a2ab8a7fee3351a10fce01b9b100fc48f03d9111337491fe917a96ee677e76930d59e42828c6598244be0a990d6cc10b", + "tags": [ + [ + "e", + "8c1360284291b9602f1ed196fc221b7b4349f8be31795f7161c931fbc4c0b264" + ], + [ + "p", + "18affadacb471657941485d8e3053e2be0daa95aa42f9c6f8680d62c758a9ab3" + ] + ] + }, + { + "content": "170,000 lines of code for a video player alone is the answer 😁😅", + "created_at": 1689676994, + "id": "8c05e5903746a676c53f5951af60b204aa74f7ac034bf0f042624c34d4fba0d3", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "ffa6d381a1f5a5b578bf031feb5421ab2c5c9922b13b53a4a28a78e36ec022647ea8584431fdeb1b50872284226b9e1875ff566920096153e2771871d64fa1be", + "tags": [ + [ + "e", + "b3bcf12483811024e77cb1575b4345b88549fe0ee6a26df942c16547b34d7f36", + "", + "root" + ], + [ + "e", + "edf021fc9290fc7f7fe3bcd5c33904536a1710b6a525a33e696723fffb887627" + ], + [ + "e", + "2dce8555ed1824e129910aa57301771a0c1aba3d0f6b5529efcecd0a3f031e2a" + ], + [ + "e", + "8b4b4b56bb850a32efe4f45e68fd84d0ae2d5183062f507c6c68aecbaab29d28", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "b8ef68a3073dae2a78a02e1d5921013bffbc82aa5039f77b6f7434512cc65de7" + ] + ] + }, + { + "content": "The relay architecture is terrible for curation. That's why relay-centric browsing is broken. ", + "created_at": 1689676644, + "id": "96f7ebeec77ef2945527c777c9eb0143cdee0a634461a0b52131396c0635650d", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "7b75d01573bfee59f38469f410ec13f24155d87f913b26a88824af57f5f8b4b6fc87202558d167facc818a73f9286644075fd9474b84ea78382322085d23b04d", + "tags": [ + [ + "e", + "0133b5466212bcf7200ac43448cd44c996d09ec89eec785061637987f9e423de", + "", + "reply" + ], + [ + "p", + "1bc70a0148b3f316da33fe3c89f23e3e71ac4ff998027ec712b905cd24f6a411" + ] + ] + }, + { + "content": "No idea", + "created_at": 1689676119, + "id": "2dce8555ed1824e129910aa57301771a0c1aba3d0f6b5529efcecd0a3f031e2a", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "1af2fb3bc6acc1a56ba42a6c0a6db9c4921ac399552de26d03128c69bd7e99b22b769cc2e309c95f7553282715dd2c8640fed3f04f160a1fb68feef83d3c3cbc", + "tags": [ + [ + "e", + "b3bcf12483811024e77cb1575b4345b88549fe0ee6a26df942c16547b34d7f36", + "", + "root" + ], + [ + "e", + "edf021fc9290fc7f7fe3bcd5c33904536a1710b6a525a33e696723fffb887627", + "", + "reply" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "b8ef68a3073dae2a78a02e1d5921013bffbc82aa5039f77b6f7434512cc65de7" + ] + ] + }, + { + "content": "{\"content\":\"Introducing Minibits Wallet for Android – a new Cashu mobile wallet with focus on performance and usability! \\n\\nMinibits aims to make ecash UX less technical.\\n\\nSign up for testing at https://minibits.cash or get one of the alpha releases on the GitHub repository! \\n\\nThis is still at a research stage, read the warnings before use. Please provide feedback and report bugs!\\n\\nhttps://github.com/minibits-cash/minibits_wallet\\nhttps://void.cat/d/SzRmh2jNzHKgKvKQb7bETV.webp\",\"created_at\":1689675049,\"id\":\"eff1e425d2790ec703bacb0373b067499edf24174b845ac1fb9172987552945b\",\"kind\":1,\"pubkey\":\"50d94fc2d8580c682b071a542f8b1e31a200b0508bab95a33bef0855df281d63\",\"sig\":\"1d868c7ec460c110b6861dadfcc6506e3edf9887bd1c5d3e40f35acbed10b9c6f6ca868c69cd6c9582665ffc05c73bd70905a92e26143c77f1a7ef121ccbfb1e\",\"tags\":[]}", + "created_at": 1689676096, + "id": "c2c56a4f0afb483d2e6d9bcacf5662a8b3de06db891a30c1da2f6e91114aa256", + "kind": 6, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "2da6d302cc4d8a0072573dc1ab4919d0e79c747b45f52b41f67e001a3e865aab0ada32348324adf490ef86e541b3497857d44eb8c74c2ff8212e8e3299b84438", + "tags": [ + [ + "e", + "eff1e425d2790ec703bacb0373b067499edf24174b845ac1fb9172987552945b" + ], + [ + "p", + "50d94fc2d8580c682b071a542f8b1e31a200b0508bab95a33bef0855df281d63" + ] + ] + }, + { + "content": "Possible? Sure. I am not sure if it's desirable. No one likes these translations services that require all your messages to get sent to a server. It would be a lot better if they created a local model to translate in-device like the Play version does. ", + "created_at": 1689676003, + "id": "855a4de95fc1bce83a4da7c28fe823365162a1413503cfbca9cbe322269b07ba", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "16566000229b6a4cb882f5337d0f6ac5513f80345c72f165739f6e058bdec9e9a34d24755f85111ae76f6e5b71c65b4adc669314ed8d1ac7d3af7868eafc6e66", + "tags": [ + [ + "e", + "305284085aa2e647f5f8ac0da34a3898674c10087c4d7a9653d5292d97585a4c", + "", + "root" + ], + [ + "e", + "4d1ce28ed36892e1c3892c05c36a49fadc00a628f194c99e88dd4f2d54e89024" + ], + [ + "e", + "f7f0a6cd0833758383e74399a6f92cef9cc0ffab1243562125d27a283a369b22" + ], + [ + "e", + "996566ec7df1d641e8842673c0b798626e31b8a60c6045e83d07e8c48d4ef948", + "", + "reply" + ], + [ + "p", + "b6e13999da09d9fb2bea6ddf5ac65693d66ffa43738e009aac6d547be5fd3c80" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "ba31f050a66d6aee73fb258405a44fcffa662e24784e6650944f8fc2d3089427" + ] + ] + }, + { + "content": "🤙", + "created_at": 1689675731, + "id": "808dd71e183d66fbb206ba02bd8f7167e3192851091e70daa4fb691c69a7d4d6", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "94b58286c108e74b1c3428d7a1c6453c2f27e76a34400af9dcc4afd5f8af863d066e4e6bad885499cfd72c6fc6f10f19bbbb683e8ab4caf8cd2d9dd3524509a1", + "tags": [ + [ + "e", + "f75a1684c2982ce450bbfd1c6e6eeee3aac0d9c57e3a542e2d038f28e54fd2da" + ], + [ + "p", + "18affadacb471657941485d8e3053e2be0daa95aa42f9c6f8680d62c758a9ab3" + ] + ] + }, + { + "content": "🤙", + "created_at": 1689675726, + "id": "7bd385d259bbf9d331eb4e1ca9ca78ef0d7ea1bb43d44daf2e2029d4c575014e", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "d5801e6e34971ef41ae34dd1e714823ce8096dcc84f88ad566fd4abf9ffb5eeca82ef8152a88945cb7ec3ba9ffe50a7e21595b2d04daa6b88b586a3bdb790b6f", + "tags": [ + [ + "e", + "536959c20e829ddd2516afa9774c22c332cdb335770d363201f547b9918e1cf7" + ], + [ + "p", + "18affadacb471657941485d8e3053e2be0daa95aa42f9c6f8680d62c758a9ab3" + ] + ] + }, + { + "content": "GM, freaks. \n\nnostr:nevent1qqsy9u6jkzy4pa4ktcmrnhwa33uqqkyk6yugjgrkqcrefwlsewxly2cpz4mhxue69uhhyetvv9ujuerpd46hxtnfduhsygytpg474ahta7f9arnclrc2mfql0zvt3knj4zt3hzvc30mc2lfknupsgqqqqqqss5qlwl", + "created_at": 1689675330, + "id": "a6c102acb21bc9229f23722b4f1d55232c91901b1710be8a4a7c71c9ea128c16", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "a6444849124e0bd3479620c2102c1d6defb81852ef3c2118296452b5370901591b02102f5c148005ac8b69ba4fd86d106cc8673306c3a89150a09ca8b4feb790", + "tags": [ + [ + "e", + "42f352b08950f6b65e3639dddd8c78005896d138892076060794bbf0cb8df22b", + "", + "mention" + ], + [ + "p", + "8b0a2beaf6ebef925e8e78f8f0ada41f7898b8da72a8971b89988bf7857d369f", + "", + "mention" + ] + ] + }, + { + "content": "No, only on the Play version ", + "created_at": 1689674872, + "id": "f7f0a6cd0833758383e74399a6f92cef9cc0ffab1243562125d27a283a369b22", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "1ba2852e22e55b216ab87c5e2e2b3edc62accf811b033a51d2e4ce79bd015e517d909785db81220d9825c88e976e47498053c9d2995d26a09c9d3e82e6e0a944", + "tags": [ + [ + "e", + "305284085aa2e647f5f8ac0da34a3898674c10087c4d7a9653d5292d97585a4c", + "", + "root" + ], + [ + "e", + "4d1ce28ed36892e1c3892c05c36a49fadc00a628f194c99e88dd4f2d54e89024", + "", + "reply" + ], + [ + "p", + "b6e13999da09d9fb2bea6ddf5ac65693d66ffa43738e009aac6d547be5fd3c80" + ], + [ + "p", + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + ], + [ + "p", + "ba31f050a66d6aee73fb258405a44fcffa662e24784e6650944f8fc2d3089427" + ] + ] + }, + { + "content": "🤙", + "created_at": 1689674801, + "id": "b79a18aecbb705999848e430aa48ca8e4a02f205baf0abf1893ad78be5bd097a", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "8ff23133abaea20df1a6bb81e4d0c17184b10ef4a61c1d9420409b05a155b1765aba40ed409dafca1f1404a70d13f47b8c17b7192c361dd3552f80c3fb40117c", + "tags": [ + [ + "e", + "70526f1c71a579e9a7d0ca60f0c32ddcaa2fb0588e5ccc854ffd5eb706913c1c" + ], + [ + "p", + "d651b0cc52fe150819266fd62efb79e3f859161b33fc054ba98e43537e4a9601" + ] + ] + }, + { + "content": "🤙", + "created_at": 1689674786, + "id": "9e44d17fb36c23f8122dcd1a052db0df8b77e67524efab0500b3bfee490fb150", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "52ea3aad9c774be769bd6129aaadba7cff8cf06a573887d2c64f6f4c1c04c7ffa54e2d2dfa60a2323d06cd57b9034a2db1991fbbaad331b8981542ef739ca8a6", + "tags": [ + [ + "e", + "88377d4a0fb02c73c8c9a9ec0c90d29ebe80c30e7e0dd357bd9fdc34719b467f" + ], + [ + "p", + "b2833792cd5c95662538e620fed371728e90671b9d6bdefebe8f706c1f1a04da" + ] + ] + }, + { + "content": "🤙", + "created_at": 1689674730, + "id": "9cdd27028fa23568917ccee7fe7f1de15b43504e006515f7a0cb124075263b18", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "b6261ca964542f01cb714f5089147e316cb30ae016bfa76462840f41c645f6f8e115998b4221a33ee78c025c78f0a3b3dc2961713640e561dce76e7bcea388c4", + "tags": [ + [ + "e", + "f637d77cf787a9f772b7926f9752fa5c2eed3e21e10c41f2e8ca0f7addf08821" + ], + [ + "p", + "b2833792cd5c95662538e620fed371728e90671b9d6bdefebe8f706c1f1a04da" + ] + ] + }, + { + "content": "🚀", + "created_at": 1689674506, + "id": "6714667912c344a403c50998ee0c3dcdc66b03174625525a838acf4ba99610e8", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "0394f188cb33d3c177e384a639deb8992cc8d0fb94600b9176439b7e02ca4dd77f6e1e706bb18e03d542a2b02db6309c2f09bcce194de2342c1108196134ae88", + "tags": [ + [ + "e", + "2744bfaea2c88d8e1337f635f0e57e14d4ee44d69c67e630c9d15f1eeb86c822" + ], + [ + "p", + "98d3b91eb93faad55a2a43ee21d71262f793f4de3db9a5d7710970ba8a251881" + ] + ] + }, + { + "content": "🤙", + "created_at": 1689674497, + "id": "d9af4d5f22a2989278ab2a5e8eb4310bfc8cf3ebb2331d5df74dadedd1beddcb", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "989b263e6f46c5b55cd56a78d3c38b6fb7d66033826d89b61696965e6ac584f7a487ea294612ca0ec256e64c22790e1c7b47e75ad1e6651c54bbe9122eea21e9", + "tags": [ + [ + "e", + "cdc0cd6cdf63c223ba85ddd0612ee3aa6b8a6e222d901c6389e54a9af7d72eb3" + ], + [ + "p", + "7635328aeba6447da86a1b6cd0608232718c045454861fc9e98f432eed66e812" + ] + ] + }, + { + "content": "🤙", + "created_at": 1689674432, + "id": "3069edc36af6612cf734f943ae1fde2dda8bfd6c9ae90e92655fd4f6502280c6", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "0503f95c23a2aa99d0bc3bae631767ea08d64d161ec2a4609c6a0cc3f27b10b2c663442095458e9c59ad90942cf841f37018a33b44dbfc089a85db2397cf5996", + "tags": [ + [ + "e", + "c576696bb51e39aa44e3ca8ecc089ac760f5771961b5d689870f355876c0a12c" + ], + [ + "p", + "31da8e96a0d372f657280a3b678c5c8398b053d0891d458b7c8b0a752737a9e0" + ] + ] + }, + { + "content": "🤙", + "created_at": 1689674426, + "id": "0bff08abd0c2d42180c7ab81b4605c46dd425d9a6aaa46796bae9e52b196d929", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "3df849993210969fe921274e42bc85dc7401993095bb6ddaa4441f85c08b29220e9851f5cb65c023f5163d55b3c142ec15a0b5464b68f618a73ac9e9fdb6804c", + "tags": [ + [ + "e", + "641ddd94ba362703b7d62819b0188d548837740eb7448a05390da2829c7ba11d" + ], + [ + "p", + "180a6d42c7d64f8c3958d9d10dd5a4117eaaacea8e7f980781e9a53136cf5693" + ] + ] + }, + { + "content": "🤙", + "created_at": 1689674423, + "id": "0daf05f8c55e150201937e621cdec9405b9e81f2305165ed36a5558321a581ad", + "kind": 7, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "ef61781ea0683789dadbe55c8448069ad3b95dd7fce6b174b91e0461d29a2d8c83dbc26e17d0ab686e389cf6850d5dc696a344da374861d84a66cf33a29fff2f", + "tags": [ + [ + "e", + "31ccd562c205061d6052946e7125a48c24a371a9459403d3b8fbb58c4c2d52bb" + ], + [ + "p", + "1b9d72d38b422a09cefed126e88f82361d4b1cc11cd19a2fc04e17b00b0c7d15" + ] + ] + }, + { + "content": "", + "created_at": 1689671952, + "id": "29f243eded2b46d7e96facb9bdd51e1a01a759ff5bf80f816e22c34b8fc6d89a", + "kind": 1984, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "082154083f66095ec70b8ae15ebd113e6ee57011b5e1c2d3adaad4fcc9612859e173c364eaf7ba2167387669555497b567b21ddc355cc4105f03f7ed67a0bcf5", + "tags": [ + [ + "p", + "5c070d057298297ff0dd72779a4126efd30c743907371cc9e44bb54861dc3fc9", + "nudity" + ] + ] + }, + { + "content": "", + "created_at": 1689647540, + "id": "01f9c880cff98ef2bbc3348f904be5817bc00a64ee4afb90ed357e3232ff75eb", + "kind": 1063, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "df6eff31de9fb678dee844ce1334802e4578b049b7e4f3a5abf187303ab7acacd0de63f9e6c8ed5cd70a42b43a30c29aeee7fda28377b50677c702e58e156fa1", + "tags": [ + [ + "url", + "https://nostr.build/av/01b69af390dac66fab819c17d93de7b2c9e070f13f444d3a1a4db6cb785222d9.mp4" + ], + [ + "m", + "video/mp4" + ], + [ + "x", + "01b69af390dac66fab819c17d93de7b2c9e070f13f444d3a1a4db6cb785222d9" + ], + [ + "size", + "1099399" + ] + ] + }, + { + "content": "", + "created_at": 1689647463, + "id": "846a0bd2419f5faf68587a544dd8ad1302675f28c3643938e51377b855581739", + "kind": 1063, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "9dd403c8f62393c03a3194cfb25ff444197ee2fc1de46e0c0c8664f65a939846add90d768e6bc0380147d39b44e5600f68cd7102910bd96313df10ccec3b4f13", + "tags": [ + [ + "url", + "https://nostr.build/av/a921fefb2485ca7a2f93121b6eef1f868133eff1931a99e3c847bec96bb45df0.mp4" + ], + [ + "m", + "video/mp4" + ], + [ + "x", + "a921fefb2485ca7a2f93121b6eef1f868133eff1931a99e3c847bec96bb45df0" + ], + [ + "size", + "189820" + ] + ] + }, + { + "content": "", + "created_at": 1689647421, + "id": "e2a3d9b37e0d6d98bbd8b36a26e8825aa67a5328ebf745dd9f7239fea69d97f5", + "kind": 1063, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "7502e7527cf42b647dfc936e399f44e8ca97943cf659b4d98ce541328b90520e28084fd62e13044478845de9b1f45af1b1c813e434dbaa692004f7f3a9cc1196", + "tags": [ + [ + "url", + "https://nostr.build/av/c32f2572a8f23053590a69cbdfa0cb1463a9c6d874dfbc745c2929d69da62ddf.mp4" + ], + [ + "m", + "video/mp4" + ], + [ + "x", + "c32f2572a8f23053590a69cbdfa0cb1463a9c6d874dfbc745c2929d69da62ddf" + ], + [ + "size", + "999370" + ] + ] + }, + { + "content": "", + "created_at": 1689646963, + "id": "3c7e59dcf0b5b682d1983306c92e6173b1247fca0419d837cf912933f670a148", + "kind": 1065, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "129cdc94b7cfc8b034731c0c93fb28cad71f96c489358ea63be5431ebbd0d5b78f813ea9430dfffa46e848ae2f524289d149951c9ad47188200d8da54f759aca", + "tags": [ + [ + "e", + "ad8095ae59d8202718df0cea762210513957e56ca13896b19793f167c2252494" + ], + [ + "m", + "image/jpeg" + ], + [ + "x", + "27685303c3efe890e7995959baa3c9c3fd46146801a61fec5039100dba0f659f" + ], + [ + "size", + "99764" + ], + [ + "dim", + "700x700" + ], + [ + "blurhash", + "U8RC[6-;~q-;-;j[WBWB-;ayWBay-:WBj[ay" + ] + ] + }, + { + "content": "One of our most important features. \n\nnostr:nevent1qqsqkc2nessaxmj3ak7jcvx8c3wa9h0xd34m6zctt4gg5cflyaa3afsprdmhxue69uhhyetvv9ujummjv9hxwetsd9kxctnyv4mz7q3qkmsnnxw6p8vlk2l2dh0443jkj0txl7jrww8qpx4vd428he0a8jqqxpqqqqqqz344mdr", + "created_at": 1689646713, + "id": "305284085aa2e647f5f8ac0da34a3898674c10087c4d7a9653d5292d97585a4c", + "kind": 1, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "cb0c8d9d2a800b445fd0091ac8e0d90eec909c626447b54357a66db89a4e68a2786e81fa69afe0b3c6ef1d32b42134d8acc3d0c3dc3b4aa4554931dbf2d4fcd8", + "tags": [ + [ + "e", + "0b6153cc21d36e51edbd2c30c7c45dd2dde66c6bbd0b0b5d508a613f277b1ea6", + "", + "mention" + ], + [ + "p", + "b6e13999da09d9fb2bea6ddf5ac65693d66ffa43738e009aac6d547be5fd3c80", + "", + "mention" + ] + ] + }, + { + "content": "", + "created_at": 1689645973, + "id": "fcfbcc09a29bccfacc30648f2896e98a743fe53b9575c2b74e22ef27132b418f", + "kind": 1063, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "9afb7d2d297b056c6ee3ec07640158d89b736e98711caf65d9af0c102d5edae9f967d9138e9318c1ab5e26640527b0826bee942c631990e41cb303401317e440", + "tags": [ + [ + "url", + "http://nostrcheck.me/media/vitorpamplona/nostrcheck.me_037bcb8edf70a9558ac91aa3fe682d52629fc5d104a560a4.mp4" + ], + [ + "m", + "video/mp4" + ], + [ + "x", + "c213bc58d4976a10ad979803510c0354b35bbb4388c127513179862f513bc49c" + ], + [ + "size", + "634647" + ] + ] + }, + { + "content": "", + "created_at": 1689645460, + "id": "fe0e0f2ee6955b49c6b669e7a837a89c8f62bacb3c965659acfa2cc62a1aa432", + "kind": 1065, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "11225b4d9c32b97ab6be603f424304e022c92b1ecc8fc2398b93f8e1e1b407c7fc43fa02662d1d992dfff73801df36aca8c0f855bded7e409df6306acfdb6865", + "tags": [ + [ + "e", + "763298a22775bf8dcc7bd53a680c013772ca89684ebd7bcefc7893ccfae55418" + ], + [ + "m", + "image/jpeg" + ], + [ + "x", + "aa0c52d9b8a1ea1d8f13a8a7ce5347d54ae9498d4596720cc9a6a2d107a384ef" + ], + [ + "size", + "19585" + ], + [ + "dim", + "700x439" + ], + [ + "blurhash", + "rcQJ$X=]$~M}xXNHj@NHt59dt6%1s:fPRka}WXoexsRlj[t6WDfkazoeWC%0t6RlNHoes:oeayj[~9IqIpocRlt6fRt5R+^hIWM|ocRkoea|s.R+" + ] + ] + }, + { + "content": "", + "created_at": 1689644892, + "id": "cf1c11434611087cf4067cecac3d3cbf3a4c9cb3ab7d0d2ecda568f09922446c", + "kind": 1063, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "d9fe14a564778961e829343e5532af5d02ee22c74229ccb162252a1f22819d13ebf3c71911acbc9dba42a1cba53d83c4bf5cb7b47967ed20fb1db0b988b4a314", + "tags": [ + [ + "url", + "http://nostrcheck.me/media/vitorpamplona/nostrcheck.me_23d68bdbf34b80739e049afca249e8b1657865d97add8530.mp4" + ], + [ + "m", + "video/mp4" + ], + [ + "x", + "aabd46855472a53dbf4b53fe1a635e21866846a13f4dc3f64db1ea9f753994fb" + ], + [ + "size", + "1839932" + ] + ] + }, + { + "content": "FdG8mzOV58zqAkp7Qxv0WLTmWFvQloax9jYy974bV40=?iv=d4w5JdfkhAMEl41xUDZx7w==", + "created_at": 1689637676, + "id": "663d4a5985e3cad8f67eb65ad0e00d173caf765175cb55603694bb423a4cdfe2", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "fbc5da1ce36dcd903874429230297028ae7864dadf0c709a1308a837e14e8a79663646189f9a6448d7d27af318fcc2b7fdd51d252240935cdcdff301a179570d", + "tags": [ + [ + "p", + "8fb140b4e8ddef97ce4b821d247278a1a4353362623f64021484b372f948000c" + ] + ] + }, + { + "content": "o2Mg9Aje0jyl7nuUseRxsg==?iv=to7+pWNFngqM+mwIPy5AdQ==", + "created_at": 1689637614, + "id": "db71590c17eecf3119d78cbb5859dc3406be14854f65cdbb8bdccaa3d2a5df0f", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "b19739ccf233092f79aa739deb09cbce4c3657f709692c9c8ab95f354dcfbace3f6e3e6aec440902b6bb1aec0f77dbb9b39733159ebc9feee3999b588488e91c", + "tags": [ + [ + "p", + "8fb140b4e8ddef97ce4b821d247278a1a4353362623f64021484b372f948000c" + ] + ] + }, + { + "content": "3uVnxDkGt4xxFs7zdSPpdxDR33Q2FJWqsnPPu4IDoP0thesChUq4DsYBidQ9iIh7?iv=KnNpoML3YnkaGI/DnD6CxQ==", + "created_at": 1689637180, + "id": "28f3ddb0d16d4a752c73dc7531c2d221d3689035e8695fdde111cd122edf5831", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "c1b26f20a66f2cf91caa9159fabf9ee17f1b98d98a250e6c67971763e38690ef013b1a81eceee504e85e99b8ea9747e89a35fa3a7207daef51a0d768df8f9458", + "tags": [ + [ + "p", + "8fb140b4e8ddef97ce4b821d247278a1a4353362623f64021484b372f948000c" + ] + ] + }, + { + "content": "Cwn68+FXCmX4W6qSl1eNiTbmn1vTeAHF25GpMBMid5Mg9x1BazZvpbT/k3/TgHS8W502zcYqCeyVhVPfPU87fQ==?iv=5/HJRrixXfJtO7/n8bDYZw==", + "created_at": 1689637166, + "id": "fa1b6d36c3194a2d7779f9d52c00f534fb0f389955da59edd1f5f9bac99c97d0", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "b48844f9754c36ab4e9469fcd70350a165ab631c740a2f285f62790a1cda8804f2b87da09c3ff9df755234a8bf3e12aae60c0b0461057680a3620531e499171e", + "tags": [ + [ + "p", + "8fb140b4e8ddef97ce4b821d247278a1a4353362623f64021484b372f948000c" + ] + ] + }, + { + "content": "+q5Stn5eAtTfm/ULw2SkApBV1gqztggFhMwa0OjCBx3syNt/asVFpoPqxguGd9QQErTTDIFDoHAiCX5vEIh6YQ==?iv=Cj00Q8hQLpbHfVh1hQb1oA==", + "created_at": 1689637117, + "id": "30d057504b23277b8b9d8654e46f2a66a3adcbd194706c9c37ce4864763b3d74", + "kind": 4, + "pubkey": "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "sig": "dcf3aec8217171253ab614be7cffc239f5767a0d9cd6bd396af6665016c7ed77263f446e1c8f5e10ed60cc81bc78c8ff4b908a2908df5a90ed210bd69784469a", + "tags": [ + [ + "p", + "8fb140b4e8ddef97ce4b821d247278a1a4353362623f64021484b372f948000c" + ] + ] + } +] \ No newline at end of file diff --git a/app/src/androidTest/java/com/vitorpamplona/amethyst/ChatroomKeyTest.kt b/quartz/src/androidTest/java/com/vitorpamplona/quartz/ChatroomKeyTest.kt similarity index 85% rename from app/src/androidTest/java/com/vitorpamplona/amethyst/ChatroomKeyTest.kt rename to quartz/src/androidTest/java/com/vitorpamplona/quartz/ChatroomKeyTest.kt index a2a36bbc9..8b234a64f 100644 --- a/app/src/androidTest/java/com/vitorpamplona/amethyst/ChatroomKeyTest.kt +++ b/quartz/src/androidTest/java/com/vitorpamplona/quartz/ChatroomKeyTest.kt @@ -1,7 +1,7 @@ -package com.vitorpamplona.amethyst +package com.vitorpamplona.quartz import androidx.test.ext.junit.runners.AndroidJUnit4 -import com.vitorpamplona.amethyst.model.ChatroomKey +import com.vitorpamplona.quartz.events.ChatroomKey import kotlinx.collections.immutable.persistentSetOf import org.junit.Assert.assertEquals import org.junit.Test diff --git a/app/src/androidTest/java/com/vitorpamplona/amethyst/CitationTests.kt b/quartz/src/androidTest/java/com/vitorpamplona/quartz/CitationTests.kt similarity index 92% rename from app/src/androidTest/java/com/vitorpamplona/amethyst/CitationTests.kt rename to quartz/src/androidTest/java/com/vitorpamplona/quartz/CitationTests.kt index 450f300a3..0ecd801bc 100644 --- a/app/src/androidTest/java/com/vitorpamplona/amethyst/CitationTests.kt +++ b/quartz/src/androidTest/java/com/vitorpamplona/quartz/CitationTests.kt @@ -1,8 +1,8 @@ -package com.vitorpamplona.amethyst +package com.vitorpamplona.quartz import androidx.test.ext.junit.runners.AndroidJUnit4 -import com.vitorpamplona.amethyst.service.model.Event -import com.vitorpamplona.amethyst.service.model.TextNoteEvent +import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.events.TextNoteEvent import junit.framework.TestCase.assertEquals import org.junit.Test import org.junit.runner.RunWith @@ -75,7 +75,7 @@ class CitationTests { @Test fun parseEvent() { - val event = Event.fromJson(json, true) as TextNoteEvent + val event = Event.fromJson(json) as TextNoteEvent val expectedCitations = setOf( "8c0da4862130283ff9e67d889df264177a508974e2feb96de139804ea66d6168", diff --git a/app/src/androidTest/java/com/vitorpamplona/amethyst/CryptoUtilsTest.kt b/quartz/src/androidTest/java/com/vitorpamplona/quartz/CryptoUtilsTest.kt similarity index 93% rename from app/src/androidTest/java/com/vitorpamplona/amethyst/CryptoUtilsTest.kt rename to quartz/src/androidTest/java/com/vitorpamplona/quartz/CryptoUtilsTest.kt index 1a10c08be..15810d3fb 100644 --- a/app/src/androidTest/java/com/vitorpamplona/amethyst/CryptoUtilsTest.kt +++ b/quartz/src/androidTest/java/com/vitorpamplona/quartz/CryptoUtilsTest.kt @@ -1,10 +1,10 @@ -package com.vitorpamplona.amethyst +package com.vitorpamplona.quartz import androidx.test.ext.junit.runners.AndroidJUnit4 -import com.vitorpamplona.amethyst.model.hexToByteArray -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils -import com.vitorpamplona.amethyst.service.KeyPair +import com.vitorpamplona.quartz.encoders.hexToByteArray +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.crypto.KeyPair import org.junit.Assert.assertEquals import org.junit.Test import org.junit.runner.RunWith diff --git a/app/src/androidTest/java/com/vitorpamplona/amethyst/EventSigCheck.kt b/quartz/src/androidTest/java/com/vitorpamplona/quartz/EventSigCheck.kt similarity index 87% rename from app/src/androidTest/java/com/vitorpamplona/amethyst/EventSigCheck.kt rename to quartz/src/androidTest/java/com/vitorpamplona/quartz/EventSigCheck.kt index 944e4239c..7794c4509 100644 --- a/app/src/androidTest/java/com/vitorpamplona/amethyst/EventSigCheck.kt +++ b/quartz/src/androidTest/java/com/vitorpamplona/quartz/EventSigCheck.kt @@ -1,9 +1,7 @@ -package com.vitorpamplona.amethyst +package com.vitorpamplona.quartz import androidx.test.ext.junit.runners.AndroidJUnit4 -import com.google.gson.JsonElement -import com.vitorpamplona.amethyst.service.model.Event -import com.vitorpamplona.amethyst.service.relays.Client +import com.vitorpamplona.quartz.events.Event import org.junit.Test import org.junit.runner.RunWith @@ -14,10 +12,11 @@ class EventSigCheck { @Test fun testUnicode2028and2029ShouldNotBeEscaped() { - val msg = Event.gson.fromJson(payload1, JsonElement::class.java).asJsonArray - val event = Event.fromJson(msg[2], Client.lenient) + val msg = Event.mapper.readTree(payload1) + val event = Event.fromJson(msg[2]) // Should pass event.checkSignature() } + } diff --git a/app/src/androidTest/java/com/vitorpamplona/amethyst/GiftWrapEventTest.kt b/quartz/src/androidTest/java/com/vitorpamplona/quartz/GiftWrapEventTest.kt similarity index 97% rename from app/src/androidTest/java/com/vitorpamplona/amethyst/GiftWrapEventTest.kt rename to quartz/src/androidTest/java/com/vitorpamplona/quartz/GiftWrapEventTest.kt index e349e0339..8536549f5 100644 --- a/app/src/androidTest/java/com/vitorpamplona/amethyst/GiftWrapEventTest.kt +++ b/quartz/src/androidTest/java/com/vitorpamplona/quartz/GiftWrapEventTest.kt @@ -1,18 +1,17 @@ -package com.vitorpamplona.amethyst +package com.vitorpamplona.quartz import androidx.test.ext.junit.runners.AndroidJUnit4 -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.hexToByteArray -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils -import com.vitorpamplona.amethyst.service.KeyPair -import com.vitorpamplona.amethyst.service.model.ChatMessageEvent -import com.vitorpamplona.amethyst.service.model.Event -import com.vitorpamplona.amethyst.service.model.GiftWrapEvent -import com.vitorpamplona.amethyst.service.model.Gossip -import com.vitorpamplona.amethyst.service.model.NIP24Factory -import com.vitorpamplona.amethyst.service.model.SealedGossipEvent -import com.vitorpamplona.amethyst.service.relays.Client +import com.vitorpamplona.quartz.encoders.hexToByteArray +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.crypto.KeyPair +import com.vitorpamplona.quartz.encoders.HexKey +import com.vitorpamplona.quartz.events.ChatMessageEvent +import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.events.GiftWrapEvent +import com.vitorpamplona.quartz.events.Gossip +import com.vitorpamplona.quartz.events.NIP24Factory +import com.vitorpamplona.quartz.events.SealedGossipEvent import org.junit.Assert.assertEquals import org.junit.Assert.assertNotEquals import org.junit.Assert.assertNotNull @@ -542,7 +541,7 @@ class GiftWrapEventTest { fun unwrapUnsealGossip(json: String, privateKey: HexKey): Gossip? { val pkBytes = privateKey.hexToByteArray() - val wrap = Event.fromJson(json, Client.lenient) as GiftWrapEvent + val wrap = Event.fromJson(json) as GiftWrapEvent wrap.checkSignature() assertEquals(CryptoUtils.pubkeyCreate(pkBytes).toHexKey(), wrap.recipientPubKey()) diff --git a/quartz/src/androidTest/java/com/vitorpamplona/quartz/HexEncodingTest.kt b/quartz/src/androidTest/java/com/vitorpamplona/quartz/HexEncodingTest.kt new file mode 100644 index 000000000..eb9164a81 --- /dev/null +++ b/quartz/src/androidTest/java/com/vitorpamplona/quartz/HexEncodingTest.kt @@ -0,0 +1,47 @@ +package com.vitorpamplona.quartz + +import com.vitorpamplona.quartz.crypto.CryptoUtils +import org.junit.Assert.assertEquals +import org.junit.Test + +class HexEncodingTest { + + val TestHex = "48a72b485d38338627ec9d427583551f9af4f016c739b8ec0d6313540a8b12cf" + + @Test + fun testHexEncodeDecodeOurs() { + assertEquals( + TestHex, + com.vitorpamplona.quartz.encoders.Hex.encode( + com.vitorpamplona.quartz.encoders.Hex.decode(TestHex) + ) + ) + } + + @Test + fun testHexEncodeDecodeSecp256k1() { + assertEquals( + TestHex, + fr.acinq.secp256k1.Hex.encode( + fr.acinq.secp256k1.Hex.decode(TestHex) + ) + ) + } + + @Test + fun testRandoms() { + for (i in 0..1000) { + val bytes = CryptoUtils.privkeyCreate() + val hex = fr.acinq.secp256k1.Hex.encode(bytes) + assertEquals( + fr.acinq.secp256k1.Hex.encode(bytes), + com.vitorpamplona.quartz.encoders.Hex.encode(bytes) + ) + assertEquals( + bytes.toList(), + com.vitorpamplona.quartz.encoders.Hex.decode(hex).toList() + ) + } + } + +} \ No newline at end of file diff --git a/quartz/src/androidTest/java/com/vitorpamplona/quartz/LargeDBSignatureCheck.kt b/quartz/src/androidTest/java/com/vitorpamplona/quartz/LargeDBSignatureCheck.kt new file mode 100644 index 000000000..a52cf5172 --- /dev/null +++ b/quartz/src/androidTest/java/com/vitorpamplona/quartz/LargeDBSignatureCheck.kt @@ -0,0 +1,34 @@ +package com.vitorpamplona.quartz + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation +import com.fasterxml.jackson.module.kotlin.readValue +import com.vitorpamplona.quartz.events.Event +import junit.framework.TestCase.assertEquals +import junit.framework.TestCase.assertTrue +import kotlinx.coroutines.runBlocking +import org.junit.Test +import org.junit.runner.RunWith +import java.io.InputStreamReader + +@RunWith(AndroidJUnit4::class) +class LargeDBSignatureCheck { + + @Test + fun insertDatabaseSample() = runBlocking { + val fullDBInputStream = getInstrumentation().context.assets.open("nostr_vitor_short.json") + + val eventArray = Event.mapper.readValue>( + InputStreamReader(fullDBInputStream) + ) as List + + var counter = 0 + eventArray.forEach { + assertTrue(it.hasValidSignature()) + counter ++ + } + + assertEquals(eventArray.size, counter) + } + +} \ No newline at end of file diff --git a/app/src/androidTest/java/com/vitorpamplona/amethyst/LnInvoiceUtilTest.kt b/quartz/src/androidTest/java/com/vitorpamplona/quartz/LnInvoiceUtilTest.kt similarity index 93% rename from app/src/androidTest/java/com/vitorpamplona/amethyst/LnInvoiceUtilTest.kt rename to quartz/src/androidTest/java/com/vitorpamplona/quartz/LnInvoiceUtilTest.kt index 77f92b1a8..2f76c5fc4 100644 --- a/app/src/androidTest/java/com/vitorpamplona/amethyst/LnInvoiceUtilTest.kt +++ b/quartz/src/androidTest/java/com/vitorpamplona/quartz/LnInvoiceUtilTest.kt @@ -1,7 +1,7 @@ -package com.vitorpamplona.amethyst +package com.vitorpamplona.quartz import androidx.test.ext.junit.runners.AndroidJUnit4 -import com.vitorpamplona.amethyst.service.lnurl.LnInvoiceUtil +import com.vitorpamplona.quartz.encoders.LnInvoiceUtil import org.junit.Assert import org.junit.Test import org.junit.runner.RunWith diff --git a/app/src/androidTest/java/com/vitorpamplona/amethyst/PrivateZapTests.kt b/quartz/src/androidTest/java/com/vitorpamplona/quartz/PrivateZapTests.kt similarity index 86% rename from app/src/androidTest/java/com/vitorpamplona/amethyst/PrivateZapTests.kt rename to quartz/src/androidTest/java/com/vitorpamplona/quartz/PrivateZapTests.kt index 3b35cdad1..212caab4b 100644 --- a/app/src/androidTest/java/com/vitorpamplona/amethyst/PrivateZapTests.kt +++ b/quartz/src/androidTest/java/com/vitorpamplona/quartz/PrivateZapTests.kt @@ -1,12 +1,12 @@ -package com.vitorpamplona.amethyst +package com.vitorpamplona.quartz import androidx.test.ext.junit.runners.AndroidJUnit4 -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.model.Event -import com.vitorpamplona.amethyst.service.model.LnZapEvent -import com.vitorpamplona.amethyst.service.model.LnZapRequestEvent -import com.vitorpamplona.amethyst.service.model.LnZapRequestEvent.Companion.createEncryptionPrivateKey -import fr.acinq.secp256k1.Hex +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.events.LnZapEvent +import com.vitorpamplona.quartz.events.LnZapRequestEvent +import com.vitorpamplona.quartz.events.LnZapRequestEvent.Companion.createEncryptionPrivateKey +import com.vitorpamplona.quartz.encoders.Hex import junit.framework.TestCase.assertNotNull import junit.framework.TestCase.fail import org.junit.Test @@ -17,7 +17,7 @@ class PrivateZapTests { @Test fun testPollZap() { - val poll = Event.Companion.fromJson( + val poll = Event.fromJson( """{ "content": "New poll \n\n #zappoll", "created_at": 1682440713, @@ -57,9 +57,7 @@ class PrivateZapTests { "wss://relay.damus.io/" ] } -""", - true - ) +""") val loggedIn = Hex.decode("e8e7197ccc53c9ed4cf9b1c8dce085475fa1ffdd71f2c14e44fe23d0bdf77598") @@ -89,7 +87,7 @@ class PrivateZapTests { @Test fun testKind1PrivateZap() { - val textNote = Event.Companion.fromJson( + val textNote = Event.fromJson( """{ "content": "Testing copied author. \n\nnostr:npub1gcxzte5zlkncx26j68ez60fzkvtkm9e0vrwdcvsjakxf9mu9qewqlfnj5z", "created_at": 1682369982, @@ -107,9 +105,7 @@ class PrivateZapTests { "wss://relay.damus.io/" ] } -""", - true - ) +""") val loggedIn = Hex.decode("e8e7197ccc53c9ed4cf9b1c8dce085475fa1ffdd71f2c14e44fe23d0bdf77598") diff --git a/quartz/src/main/AndroidManifest.xml b/quartz/src/main/AndroidManifest.xml new file mode 100644 index 000000000..a5918e68a --- /dev/null +++ b/quartz/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/CryptoUtils.kt b/quartz/src/main/java/com/vitorpamplona/quartz/crypto/CryptoUtils.kt similarity index 51% rename from app/src/main/java/com/vitorpamplona/amethyst/service/CryptoUtils.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/crypto/CryptoUtils.kt index b2aac5c36..0817c059b 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/CryptoUtils.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/crypto/CryptoUtils.kt @@ -1,8 +1,10 @@ -package com.vitorpamplona.amethyst.service +package com.vitorpamplona.quartz.crypto +import android.util.Log import com.goterl.lazysodium.SodiumAndroid import com.goterl.lazysodium.utils.Key -import fr.acinq.secp256k1.Hex +import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.encoders.Hex import fr.acinq.secp256k1.Secp256k1 import java.security.MessageDigest import java.security.SecureRandom @@ -11,10 +13,12 @@ import javax.crypto.Cipher import javax.crypto.spec.IvParameterSpec import javax.crypto.spec.SecretKeySpec + object CryptoUtils { private val secp256k1 = Secp256k1.get() private val libSodium = SodiumAndroid() private val random = SecureRandom() + private val h02 = Hex.decode("02") fun randomInt(bound: Int): Int { return random.nextInt(bound) @@ -52,10 +56,15 @@ object CryptoUtils { * @return 32B shared secret */ fun getSharedSecretNIP04(privateKey: ByteArray, pubKey: ByteArray): ByteArray = - secp256k1.pubKeyTweakMul(Hex.decode("02") + pubKey, privateKey).copyOfRange(1, 33) + secp256k1.pubKeyTweakMul(h02 + pubKey, privateKey).copyOfRange(1, 33) fun encryptNIP04(msg: String, privateKey: ByteArray, pubKey: ByteArray): String { - val encryptionInfo = encryptNIP04(msg, getSharedSecretNIP04(privateKey, pubKey)) + val info = encryptNIP04(msg, getSharedSecretNIP04(privateKey, pubKey)) + val encryptionInfo = EncryptedInfoString( + v = info.v, + nonce = Base64.getEncoder().encodeToString(info.nonce), + ciphertext = Base64.getEncoder().encodeToString(info.ciphertext) + ) return "${encryptionInfo.ciphertext}?iv=${encryptionInfo.nonce}" } @@ -68,10 +77,10 @@ object CryptoUtils { random.nextBytes(iv) val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding") cipher.init(Cipher.ENCRYPT_MODE, SecretKeySpec(sharedSecret, "AES"), IvParameterSpec(iv)) - val ivBase64 = Base64.getEncoder().encodeToString(iv) + //val ivBase64 = Base64.getEncoder().encodeToString(iv) val encryptedMsg = cipher.doFinal(msg.toByteArray()) - val encryptedMsgBase64 = Base64.getEncoder().encodeToString(encryptedMsg) - return EncryptedInfo(encryptedMsgBase64, ivBase64, Nip44Version.NIP04.versionCode) + //val encryptedMsgBase64 = Base64.getEncoder().encodeToString(encryptedMsg) + return EncryptedInfo(encryptedMsg, iv, Nip44Version.NIP04.versionCode) } fun decryptNIP04(msg: String, privateKey: ByteArray, pubKey: ByteArray): String { @@ -92,6 +101,10 @@ object CryptoUtils { private fun decryptNIP04(cipher: String, nonce: String, sharedSecret: ByteArray): String { val iv = Base64.getDecoder().decode(nonce) val encryptedMsg = Base64.getDecoder().decode(cipher) + return decryptNIP04(encryptedMsg, iv, sharedSecret) + } + + private fun decryptNIP04(encryptedMsg: ByteArray, iv: ByteArray, sharedSecret: ByteArray): String { val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding") cipher.init(Cipher.DECRYPT_MODE, SecretKeySpec(sharedSecret, "AES"), IvParameterSpec(iv)) return String(cipher.doFinal(encryptedMsg)) @@ -108,17 +121,14 @@ object CryptoUtils { val cipher = cryptoStreamXChaCha20Xor( libSodium = libSodium, - messageBytes = msg.toByteArray(), + messageBytes = msg.toByteArray(),//compress(msg), nonce = nonce, key = Key.fromBytes(sharedSecret) ) - val cipherBase64 = Base64.getEncoder().encodeToString(cipher) - val nonceBase64 = Base64.getEncoder().encodeToString(nonce) - return EncryptedInfo( - ciphertext = cipherBase64, - nonce = nonceBase64, + ciphertext = cipher ?: ByteArray(0), + nonce = nonce, v = Nip44Version.NIP24.versionCode ) } @@ -131,22 +141,120 @@ object CryptoUtils { fun decryptNIP24(encryptedInfo: EncryptedInfo, sharedSecret: ByteArray): String? { return cryptoStreamXChaCha20Xor( libSodium = libSodium, - messageBytes = Base64.getDecoder().decode(encryptedInfo.ciphertext), - nonce = Base64.getDecoder().decode(encryptedInfo.nonce), + messageBytes = encryptedInfo.ciphertext, + nonce = encryptedInfo.nonce, key = Key.fromBytes(sharedSecret) - )?.decodeToString() + )?.decodeToString() //?.let { decompress(it) } } /** * @return 32B shared secret */ fun getSharedSecretNIP24(privateKey: ByteArray, pubKey: ByteArray): ByteArray = - sha256(secp256k1.pubKeyTweakMul(Hex.decode("02") + pubKey, privateKey).copyOfRange(1, 33)) + sha256(secp256k1.pubKeyTweakMul(h02 + pubKey, privateKey).copyOfRange(1, 33)) } -data class EncryptedInfo(val ciphertext: String, val nonce: String, val v: Int) +data class EncryptedInfo(val ciphertext: ByteArray, val nonce: ByteArray, val v: Int) +data class EncryptedInfoString(val ciphertext: String, val nonce: String, val v: Int) enum class Nip44Version(val versionCode: Int) { NIP04(0), NIP24(1) } + + +fun encodeNIP44(info: EncryptedInfo): String { + return encodeByteArray(info) +} + +fun decodeNIP44(str: String): EncryptedInfo? { + if (str.isEmpty()) return null + return if (str[0] == '{') { + decodeJackson(str) + } else { + decodeByteArray(str) + } +} + +fun encodeByteArray(info: EncryptedInfo): String { + return Base64.getEncoder().encodeToString(byteArrayOf(info.v.toByte()) + info.nonce + info.ciphertext) +} + +fun decodeByteArray(base64: String): EncryptedInfo? { + return try { + val byteArray = Base64.getDecoder().decode(base64) + return EncryptedInfo( + v = byteArray[0].toInt(), + nonce = byteArray.copyOfRange(1, 25), + ciphertext = byteArray.copyOfRange(25, byteArray.size) + ) + } catch (e: Exception) { + Log.w("CryptoUtils", "Unable to Parse encrypted payload: ${base64}") + null + } +} + +fun encodeJackson(info: EncryptedInfo): String { + return Event.mapper.writeValueAsString( + EncryptedInfoString( + v = info.v, + nonce = Base64.getEncoder().encodeToString(info.nonce), + ciphertext = Base64.getEncoder().encodeToString(info.ciphertext) + ) + ) +} + +fun decodeJackson(json: String): EncryptedInfo { + val info = Event.mapper.readValue(json, EncryptedInfoString::class.java) + return EncryptedInfo( + v = info.v, + nonce = Base64.getDecoder().decode(info.nonce), + ciphertext = Base64.getDecoder().decode(info.ciphertext) + ) +} + +/* +OLD Versions used for the Benchmark + +fun encodeKotlin(info: EncryptedInfo): String { + return Json.encodeToString( + EncryptedInfoString( + v = info.v, + nonce = Base64.getEncoder().encodeToString(info.nonce), + ciphertext = Base64.getEncoder().encodeToString(info.ciphertext) + ) + ) +} + +fun decodeKotlin(json: String): EncryptedInfo { + val info = Json.decodeFromString(json) + return EncryptedInfo( + v = info.v, + nonce = Base64.getDecoder().decode(info.nonce), + ciphertext = Base64.getDecoder().decode(info.ciphertext) + ) +} + +fun encodeCSV(info: EncryptedInfo): String { + return "${info.v},${Base64.getEncoder().encodeToString(info.nonce)},${Base64.getEncoder().encodeToString(info.ciphertext)}" +} + +fun decodeCSV(base64: String): EncryptedInfo { + val parts = base64.split(",") + return EncryptedInfo( + v = parts[0].toInt(), + nonce = Base64.getDecoder().decode(parts[1]), + ciphertext = Base64.getDecoder().decode(parts[2]) + ) +} + + +fun compress(input: String): ByteArray { + return DeflaterInputStream(input.toByteArray().inputStream()).readBytes() +} + +fun decompress(inputBytes: ByteArray): String { + return InflaterInputStream(inputBytes.inputStream()).bufferedReader().use { it.readText() } +} + +*/ \ No newline at end of file diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/KeyPair.kt b/quartz/src/main/java/com/vitorpamplona/quartz/crypto/KeyPair.kt similarity index 91% rename from app/src/main/java/com/vitorpamplona/amethyst/service/KeyPair.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/crypto/KeyPair.kt index ae1eaab99..adb67b990 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/KeyPair.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/crypto/KeyPair.kt @@ -1,6 +1,6 @@ -package com.vitorpamplona.amethyst.service +package com.vitorpamplona.quartz.crypto -import com.vitorpamplona.amethyst.model.toHexKey +import com.vitorpamplona.quartz.encoders.toHexKey class KeyPair( privKey: ByteArray? = null, diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/SodiumUtils.kt b/quartz/src/main/java/com/vitorpamplona/quartz/crypto/SodiumUtils.kt similarity index 98% rename from app/src/main/java/com/vitorpamplona/amethyst/service/SodiumUtils.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/crypto/SodiumUtils.kt index 0c16f058b..17b4e7a9e 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/SodiumUtils.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/crypto/SodiumUtils.kt @@ -1,4 +1,4 @@ -package com.vitorpamplona.amethyst.service +package com.vitorpamplona.quartz.crypto import com.goterl.lazysodium.SodiumAndroid import com.goterl.lazysodium.utils.Key diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/ATag.kt b/quartz/src/main/java/com/vitorpamplona/quartz/encoders/ATag.kt similarity index 69% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/ATag.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/encoders/ATag.kt index 9c66b8729..8d0c78c79 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/ATag.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/encoders/ATag.kt @@ -1,12 +1,8 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.encoders import android.util.Log import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.service.bechToBytes -import com.vitorpamplona.amethyst.service.nip19.Tlv -import com.vitorpamplona.amethyst.service.nip19.TlvBuilder -import com.vitorpamplona.amethyst.service.toNAddress -import fr.acinq.secp256k1.Hex +import com.vitorpamplona.quartz.encoders.Hex @Immutable data class ATag(val kind: Int, val pubKeyHex: String, val dTag: String, val relay: String?) { @@ -14,10 +10,10 @@ data class ATag(val kind: Int, val pubKeyHex: String, val dTag: String, val rela fun toNAddr(): String { return TlvBuilder().apply { - addString(Tlv.Type.SPECIAL, dTag) - addStringIfNotNull(Tlv.Type.RELAY, relay) - addHex(Tlv.Type.AUTHOR, pubKeyHex) - addInt(Tlv.Type.KIND, kind) + addString(Nip19.TlvTypes.SPECIAL, dTag) + addStringIfNotNull(Nip19.TlvTypes.RELAY, relay) + addHex(Nip19.TlvTypes.AUTHOR, pubKeyHex) + addInt(Nip19.TlvTypes.KIND, kind) }.build().toNAddress() } @@ -52,10 +48,10 @@ data class ATag(val kind: Int, val pubKeyHex: String, val dTag: String, val rela if (key.startsWith("naddr")) { val tlv = Tlv.parse(key.bechToBytes()) - val d = tlv.firstAsString(Tlv.Type.SPECIAL) ?: "" - val relay = tlv.firstAsString(Tlv.Type.RELAY) - val author = tlv.firstAsHex(Tlv.Type.AUTHOR) - val kind = tlv.firstAsInt(Tlv.Type.KIND) + val d = tlv.firstAsString(Nip19.TlvTypes.SPECIAL) ?: "" + val relay = tlv.firstAsString(Nip19.TlvTypes.RELAY) + val author = tlv.firstAsHex(Nip19.TlvTypes.AUTHOR) + val kind = tlv.firstAsInt(Nip19.TlvTypes.KIND) if (kind != null && author != null) { return ATag(kind, author, d, relay) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/Bech32Util.kt b/quartz/src/main/java/com/vitorpamplona/quartz/encoders/Bech32Util.kt similarity index 99% rename from app/src/main/java/com/vitorpamplona/amethyst/service/Bech32Util.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/encoders/Bech32Util.kt index 62cb91e3d..0a27bfa24 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/Bech32Util.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/encoders/Bech32Util.kt @@ -1,4 +1,4 @@ -package com.vitorpamplona.amethyst.service +package com.vitorpamplona.quartz.encoders /* * Copyright 2020 ACINQ SAS diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/HexUtils.kt b/quartz/src/main/java/com/vitorpamplona/quartz/encoders/HexUtils.kt new file mode 100644 index 000000000..11ccbfdeb --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/encoders/HexUtils.kt @@ -0,0 +1,70 @@ +package com.vitorpamplona.quartz.encoders + +/** Makes the distinction between String and Hex **/ +typealias HexKey = String + +fun ByteArray.toHexKey(): HexKey { + return Hex.encode(this) +} + +fun HexKey.hexToByteArray(): ByteArray { + return Hex.decode(this) +} + +object HexValidator { + private fun isHex2(c: Char): Boolean { + return when (c) { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'A', 'B', 'C', 'D', 'E', 'F', ' ' -> true + else -> false + } + } + + fun isHex(hex: String?): Boolean { + if (hex == null) return false + var isHex = true + for (c in hex.toCharArray()) { + if (!isHex2(c)) { + isHex = false + break + } + } + return isHex + } +} + +object Hex { + private val hexCode = arrayOf('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f') + + // Faster if no calculations are needed. + private fun hexToBin(ch: Char): Int = when (ch) { + in '0'..'9' -> ch - '0' + in 'a'..'f' -> ch - 'a' + 10 + in 'A'..'F' -> ch - 'A' + 10 + else -> throw IllegalArgumentException("illegal hex character: $ch") + } + + @JvmStatic + fun decode(hex: String): ByteArray { + // faster version of hex decoder + require(hex.length % 2 == 0) + val outSize = hex.length / 2 + val out = ByteArray(outSize) + + for (i in 0 until outSize) { + out[i] = (hexToBin(hex[2 * i]) * 16 + hexToBin(hex[2 * i + 1])).toByte() + } + + return out + } + + @JvmStatic + fun encode(input: ByteArray): String { + val len = input.size + val out = CharArray(len * 2) + for (i in 0 until len) { + out[i*2] = hexCode[(input[i].toInt() shr 4) and 0xF] + out[i*2+1] = hexCode[input[i].toInt() and 0xF] + } + return String(out) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/lnurl/LnInvoiceUtil.kt b/quartz/src/main/java/com/vitorpamplona/quartz/encoders/LnInvoiceUtil.kt similarity index 97% rename from app/src/main/java/com/vitorpamplona/amethyst/service/lnurl/LnInvoiceUtil.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/encoders/LnInvoiceUtil.kt index d134a1038..80d0f0f94 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/lnurl/LnInvoiceUtil.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/encoders/LnInvoiceUtil.kt @@ -1,6 +1,5 @@ -package com.vitorpamplona.amethyst.service.lnurl +package com.vitorpamplona.quartz.encoders -import com.vitorpamplona.amethyst.service.checkNotInMainThread import java.math.BigDecimal import java.util.Locale import java.util.regex.Pattern @@ -122,8 +121,6 @@ object LnInvoiceUtil { } fun getAmountInSats(invoice: String): BigDecimal { - checkNotInMainThread() - return getAmount(invoice).multiply(BigDecimal(100000000)) } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/lnurl/LnWithdrawalUtil.kt b/quartz/src/main/java/com/vitorpamplona/quartz/encoders/LnWithdrawalUtil.kt similarity index 94% rename from app/src/main/java/com/vitorpamplona/amethyst/service/lnurl/LnWithdrawalUtil.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/encoders/LnWithdrawalUtil.kt index 47183238e..bedf72d65 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/lnurl/LnWithdrawalUtil.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/encoders/LnWithdrawalUtil.kt @@ -1,4 +1,4 @@ -package com.vitorpamplona.amethyst.service.lnurl +package com.vitorpamplona.quartz.encoders import java.util.regex.Pattern diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/nip19/Nip19.kt b/quartz/src/main/java/com/vitorpamplona/quartz/encoders/Nip19.kt similarity index 50% rename from app/src/main/java/com/vitorpamplona/amethyst/service/nip19/Nip19.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/encoders/Nip19.kt index 937e99b01..229a4f84e 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/nip19/Nip19.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/encoders/Nip19.kt @@ -1,10 +1,9 @@ -package com.vitorpamplona.amethyst.service.nip19 +package com.vitorpamplona.quartz.encoders import android.util.Log import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.bechToBytes -import com.vitorpamplona.amethyst.service.toNEvent +import com.vitorpamplona.quartz.crypto.KeyPair +import com.vitorpamplona.quartz.encoders.Hex import java.util.regex.Pattern object Nip19 { @@ -12,7 +11,17 @@ object Nip19 { USER, NOTE, EVENT, RELAY, ADDRESS } - val nip19regex = Pattern.compile("(nostr:)?@?(nsec1|npub1|nevent1|naddr1|note1|nprofile1|nrelay1)([qpzry9x8gf2tvdw0s3jn54khce6mua7l]+)([\\S]*)", Pattern.CASE_INSENSITIVE) + enum class TlvTypes(val id: Byte) { + SPECIAL(0), + RELAY(1), + AUTHOR(2), + KIND(3); + } + + val nip19regex = Pattern.compile( + "(nostr:)?@?(nsec1|npub1|nevent1|naddr1|note1|nprofile1|nrelay1)([qpzry9x8gf2tvdw0s3jn54khce6mua7l]+)([\\S]*)", + Pattern.CASE_INSENSITIVE + ) @Immutable data class Return( @@ -81,8 +90,8 @@ object Nip19 { private fun nprofile(bytes: ByteArray): Return? { val tlv = Tlv.parse(bytes) - val hex = tlv.firstAsHex(Tlv.Type.SPECIAL) ?: return null - val relay = tlv.firstAsString(Tlv.Type.RELAY) + val hex = tlv.firstAsHex(TlvTypes.SPECIAL) ?: return null + val relay = tlv.firstAsString(TlvTypes.RELAY) return Return(Type.USER, hex, relay) } @@ -90,16 +99,16 @@ object Nip19 { private fun nevent(bytes: ByteArray): Return? { val tlv = Tlv.parse(bytes) - val hex = tlv.firstAsHex(Tlv.Type.SPECIAL) ?: return null - val relay = tlv.firstAsString(Tlv.Type.RELAY) - val author = tlv.firstAsHex(Tlv.Type.AUTHOR) - val kind = tlv.firstAsInt(Tlv.Type.KIND.id) + val hex = tlv.firstAsHex(TlvTypes.SPECIAL) ?: return null + val relay = tlv.firstAsString(TlvTypes.RELAY) + val author = tlv.firstAsHex(TlvTypes.AUTHOR) + val kind = tlv.firstAsInt(TlvTypes.KIND.id) return Return(Type.EVENT, hex, relay, author, kind) } private fun nrelay(bytes: ByteArray): Return? { - val relayUrl = Tlv.parse(bytes).firstAsString(Tlv.Type.SPECIAL.id) ?: return null + val relayUrl = Tlv.parse(bytes).firstAsString(TlvTypes.SPECIAL.id) ?: return null return Return(Type.RELAY, relayUrl) } @@ -107,20 +116,63 @@ object Nip19 { private fun naddr(bytes: ByteArray): Return? { val tlv = Tlv.parse(bytes) - val d = tlv.firstAsString(Tlv.Type.SPECIAL.id) ?: "" - val relay = tlv.firstAsString(Tlv.Type.RELAY.id) - val author = tlv.firstAsHex(Tlv.Type.AUTHOR.id) ?: return null - val kind = tlv.firstAsInt(Tlv.Type.KIND.id) ?: return null + val d = tlv.firstAsString(TlvTypes.SPECIAL.id) ?: "" + val relay = tlv.firstAsString(TlvTypes.RELAY.id) + val author = tlv.firstAsHex(TlvTypes.AUTHOR.id) ?: return null + val kind = tlv.firstAsInt(TlvTypes.KIND.id) ?: return null return Return(Type.ADDRESS, "$kind:$author:$d", relay, author, kind) } public fun createNEvent(idHex: String, author: String?, kind: Int?, relay: String?): String { return TlvBuilder().apply { - addHex(Tlv.Type.SPECIAL, idHex) - addStringIfNotNull(Tlv.Type.RELAY, relay) - addHexIfNotNull(Tlv.Type.AUTHOR, author) - addIntIfNotNull(Tlv.Type.KIND, kind) + addHex(TlvTypes.SPECIAL, idHex) + addStringIfNotNull(TlvTypes.RELAY, relay) + addHexIfNotNull(TlvTypes.AUTHOR, author) + addIntIfNotNull(TlvTypes.KIND, kind) }.build().toNEvent() } } + +fun decodePublicKey(key: String): ByteArray { + val parsed = Nip19.uriToRoute(key) + val pubKeyParsed = parsed?.hex?.hexToByteArray() + + return if (key.startsWith("nsec")) { + KeyPair(privKey = key.bechToBytes()).pubKey + } else if (pubKeyParsed != null) { + pubKeyParsed + } else { + Hex.decode(key) + } +} + +fun decodePublicKeyAsHexOrNull(key: String): HexKey? { + return try { + val parsed = Nip19.uriToRoute(key) + val pubKeyParsed = parsed?.hex + + if (key.startsWith("nsec")) { + KeyPair(privKey = key.bechToBytes()).pubKey.toHexKey() + } else if (pubKeyParsed != null) { + pubKeyParsed + } else { + Hex.decode(key).toHexKey() + } + } catch (e: Exception) { + null + } +} + + +fun TlvBuilder.addString(type: Nip19.TlvTypes, string: String) = addString(type.id, string) +fun TlvBuilder.addHex(type: Nip19.TlvTypes, key: HexKey) = addHex(type.id, key) +fun TlvBuilder.addInt(type: Nip19.TlvTypes, data: Int) = addInt(type.id, data) + +fun TlvBuilder.addStringIfNotNull(type: Nip19.TlvTypes, data: String?) = addStringIfNotNull(type.id, data) +fun TlvBuilder.addHexIfNotNull(type: Nip19.TlvTypes, data: HexKey?) = addHexIfNotNull(type.id, data) +fun TlvBuilder.addIntIfNotNull(type: Nip19.TlvTypes, data: Int?) = addIntIfNotNull(type.id, data) + +fun Tlv.firstAsInt(type: Nip19.TlvTypes) = firstAsInt(type.id) +fun Tlv.firstAsHex(type: Nip19.TlvTypes) = firstAsHex(type.id) +fun Tlv.firstAsString(type: Nip19.TlvTypes) = firstAsString(type.id) \ No newline at end of file diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/nip19/Tlv.kt b/quartz/src/main/java/com/vitorpamplona/quartz/encoders/Tlv.kt similarity index 68% rename from app/src/main/java/com/vitorpamplona/amethyst/service/nip19/Tlv.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/encoders/Tlv.kt index eca8ad968..02e4d80de 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/nip19/Tlv.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/encoders/Tlv.kt @@ -1,8 +1,5 @@ -package com.vitorpamplona.amethyst.service.nip19 +package com.vitorpamplona.quartz.encoders -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.hexToByteArray -import com.vitorpamplona.amethyst.model.toHexKey import java.io.ByteArrayOutputStream import java.nio.ByteBuffer import java.nio.ByteOrder @@ -17,26 +14,18 @@ class TlvBuilder() { fun addString(type: Byte, string: String) = add(type, string.toByteArray(Charsets.UTF_8)) fun addHex(type: Byte, key: HexKey) = add(type, key.hexToByteArray()) - fun addInt(type: Byte, data: Int) = add(type, data.toByteArray()) + fun addInt(type: Byte, data: Int) = add(type, data.to32BitByteArray()) fun addStringIfNotNull(type: Byte, data: String?) = data?.let { addString(type, it) } fun addHexIfNotNull(type: Byte, data: HexKey?) = data?.let { addHex(type, it) } fun addIntIfNotNull(type: Byte, data: Int?) = data?.let { addInt(type, it) } - fun addString(type: Tlv.Type, string: String) = addString(type.id, string) - fun addHex(type: Tlv.Type, key: HexKey) = addHex(type.id, key) - fun addInt(type: Tlv.Type, data: Int) = addInt(type.id, data) - - fun addStringIfNotNull(type: Tlv.Type, data: String?) = addStringIfNotNull(type.id, data) - fun addHexIfNotNull(type: Tlv.Type, data: HexKey?) = addHexIfNotNull(type.id, data) - fun addIntIfNotNull(type: Tlv.Type, data: Int?) = addIntIfNotNull(type.id, data) - fun build(): ByteArray { return outputStream.toByteArray() } } -fun Int.toByteArray(): ByteArray { +fun Int.to32BitByteArray(): ByteArray { val bytes = ByteArray(4) (0..3).forEach { bytes[3 - it] = ((this ushr (8 * it)) and 0xFFFF).toByte() @@ -58,19 +47,7 @@ class Tlv(val data: Map>) { fun firstAsHex(type: Byte) = data[type]?.firstOrNull()?.toHexKey()?.intern() fun firstAsString(type: Byte) = data[type]?.firstOrNull()?.toString(Charsets.UTF_8) - fun firstAsInt(type: Type) = firstAsInt(type.id) - fun firstAsHex(type: Type) = firstAsHex(type.id) - fun firstAsString(type: Type) = firstAsString(type.id) - - enum class Type(val id: Byte) { - SPECIAL(0), - RELAY(1), - AUTHOR(2), - KIND(3); - } - companion object { - fun parse(data: ByteArray): Tlv { val result = mutableMapOf>() var rest = data diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/AdvertisedRelayListEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/AdvertisedRelayListEvent.kt similarity index 87% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/AdvertisedRelayListEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/AdvertisedRelayListEvent.kt index 5403809fc..d9c76162d 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/AdvertisedRelayListEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/AdvertisedRelayListEvent.kt @@ -1,10 +1,11 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils +import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.ATag +import com.vitorpamplona.quartz.encoders.HexKey @Immutable class AdvertisedRelayListEvent( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/AppDefinitionEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/AppDefinitionEvent.kt similarity index 84% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/AppDefinitionEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/AppDefinitionEvent.kt index 6a19c6d8a..9c27d3bfc 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/AppDefinitionEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/AppDefinitionEvent.kt @@ -1,9 +1,9 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import android.util.Log import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.UserMetadata +import com.vitorpamplona.quartz.encoders.ATag +import com.vitorpamplona.quartz.encoders.HexKey import java.io.ByteArrayInputStream @Immutable @@ -19,7 +19,7 @@ class AppDefinitionEvent( override fun address() = ATag(kind, pubKey, dTag(), null) fun appMetaData() = try { - MetadataEvent.metadataParser.readValue( + mapper.readValue( ByteArrayInputStream(content.toByteArray(Charsets.UTF_8)), UserMetadata::class.java ) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/AppRecommendationEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/AppRecommendationEvent.kt similarity index 83% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/AppRecommendationEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/AppRecommendationEvent.kt index 6baa518cc..eb6c895d6 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/AppRecommendationEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/AppRecommendationEvent.kt @@ -1,7 +1,8 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.HexKey +import com.vitorpamplona.quartz.encoders.ATag +import com.vitorpamplona.quartz.encoders.HexKey @Immutable class AppRecommendationEvent( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/AudioTrackEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/AudioTrackEvent.kt similarity index 88% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/AudioTrackEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/AudioTrackEvent.kt index aca414b89..19346daf8 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/AudioTrackEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/AudioTrackEvent.kt @@ -1,10 +1,11 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils +import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.ATag +import com.vitorpamplona.quartz.encoders.HexKey @Immutable class AudioTrackEvent( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/BadgeAwardEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/BadgeAwardEvent.kt similarity index 80% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/BadgeAwardEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/BadgeAwardEvent.kt index 082322b11..d956d23dc 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/BadgeAwardEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/BadgeAwardEvent.kt @@ -1,7 +1,7 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.HexKey +import com.vitorpamplona.quartz.encoders.HexKey @Immutable class BadgeAwardEvent( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/BadgeDefinitionEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/BadgeDefinitionEvent.kt similarity index 86% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/BadgeDefinitionEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/BadgeDefinitionEvent.kt index 5a4d25c16..2ed6823d1 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/BadgeDefinitionEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/BadgeDefinitionEvent.kt @@ -1,7 +1,8 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.HexKey +import com.vitorpamplona.quartz.encoders.ATag +import com.vitorpamplona.quartz.encoders.HexKey @Immutable class BadgeDefinitionEvent( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/BadgeProfilesEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/BadgeProfilesEvent.kt similarity index 87% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/BadgeProfilesEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/BadgeProfilesEvent.kt index 60f7adb71..30b704652 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/BadgeProfilesEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/BadgeProfilesEvent.kt @@ -1,7 +1,8 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.HexKey +import com.vitorpamplona.quartz.encoders.ATag +import com.vitorpamplona.quartz.encoders.HexKey @Immutable class BadgeProfilesEvent( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/BaseTextNoteEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/BaseTextNoteEvent.kt similarity index 83% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/BaseTextNoteEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/BaseTextNoteEvent.kt index 0c11ca525..167833264 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/BaseTextNoteEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/BaseTextNoteEvent.kt @@ -1,11 +1,14 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import android.util.Log import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.tagSearch -import com.vitorpamplona.amethyst.service.nip19.Nip19 -import com.vitorpamplona.amethyst.service.nip19.Nip19.nip19regex +import com.vitorpamplona.quartz.encoders.HexKey +import com.vitorpamplona.quartz.encoders.Nip19 +import com.vitorpamplona.quartz.encoders.Nip19.nip19regex +import java.util.regex.Pattern + +val tagSearch = Pattern.compile("(?:\\s|\\A)\\#\\[([0-9]+)\\]") +val hashtagSearch = Pattern.compile("(?:\\s|\\A)#([^\\s!@#\$%^&*()=+./,\\[{\\]};:'\"?><]+)") @Immutable open class BaseTextNoteEvent( @@ -128,3 +131,18 @@ open class BaseTextNoteEvent( } } } + +fun findHashtags(content: String): List { + val matcher = hashtagSearch.matcher(content) + val returningList = mutableSetOf() + while (matcher.find()) { + try { + val tag = matcher.group(1) + if (tag != null && tag.isNotBlank()) { + returningList.add(tag) + } + } catch (e: Exception) { + } + } + return returningList.toList() +} \ No newline at end of file diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/BookmarkListEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/BookmarkListEvent.kt similarity index 84% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/BookmarkListEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/BookmarkListEvent.kt index 012b918fc..f9d161baa 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/BookmarkListEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/BookmarkListEvent.kt @@ -1,10 +1,11 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils +import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.ATag +import com.vitorpamplona.quartz.encoders.HexKey @Immutable class BookmarkListEvent( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/ChannelCreateEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/ChannelCreateEvent.kt similarity index 78% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/ChannelCreateEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/ChannelCreateEvent.kt index f35523a69..5bf523f4c 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/ChannelCreateEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/ChannelCreateEvent.kt @@ -1,11 +1,12 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import android.util.Log import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils +import com.fasterxml.jackson.module.kotlin.readValue +import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.HexKey @Immutable class ChannelCreateEvent( @@ -17,7 +18,7 @@ class ChannelCreateEvent( sig: HexKey ) : Event(id, pubKey, createdAt, kind, tags, content, sig) { fun channelInfo(): ChannelData = try { - MetadataEvent.gson.fromJson(content, ChannelData::class.java) + mapper.readValue(content) } catch (e: Exception) { Log.e("ChannelMetadataEvent", "Can't parse channel info $content", e) ChannelData(null, null, null) @@ -29,7 +30,7 @@ class ChannelCreateEvent( fun create(channelInfo: ChannelData?, privateKey: ByteArray, createdAt: Long = TimeUtils.now()): ChannelCreateEvent { val content = try { if (channelInfo != null) { - gson.toJson(channelInfo) + mapper.writeValueAsString(channelInfo) } else { "" } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/ChannelHideMessageEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/ChannelHideMessageEvent.kt similarity index 83% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/ChannelHideMessageEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/ChannelHideMessageEvent.kt index 27c322373..7e8b24136 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/ChannelHideMessageEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/ChannelHideMessageEvent.kt @@ -1,10 +1,10 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils +import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.HexKey @Immutable class ChannelHideMessageEvent( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/ChannelMessageEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/ChannelMessageEvent.kt similarity index 89% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/ChannelMessageEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/ChannelMessageEvent.kt index 583350cb2..286736677 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/ChannelMessageEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/ChannelMessageEvent.kt @@ -1,10 +1,10 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils +import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.HexKey @Immutable class ChannelMessageEvent( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/ChannelMetadataEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/ChannelMetadataEvent.kt similarity index 78% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/ChannelMetadataEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/ChannelMetadataEvent.kt index a7091b074..19067905d 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/ChannelMetadataEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/ChannelMetadataEvent.kt @@ -1,11 +1,11 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import android.util.Log import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils +import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.HexKey @Immutable class ChannelMetadataEvent( @@ -20,7 +20,7 @@ class ChannelMetadataEvent( override fun channel() = tags.firstOrNull { it.size > 1 && it[0] == "e" }?.get(1) fun channelInfo() = try { - MetadataEvent.gson.fromJson(content, ChannelCreateEvent.ChannelData::class.java) + mapper.readValue(content, ChannelCreateEvent.ChannelData::class.java) } catch (e: Exception) { Log.e("ChannelMetadataEvent", "Can't parse channel info $content", e) ChannelCreateEvent.ChannelData(null, null, null) @@ -32,7 +32,7 @@ class ChannelMetadataEvent( fun create(newChannelInfo: ChannelCreateEvent.ChannelData?, originalChannelIdHex: String, privateKey: ByteArray, createdAt: Long = TimeUtils.now()): ChannelMetadataEvent { val content = if (newChannelInfo != null) { - gson.toJson(newChannelInfo) + mapper.writeValueAsString(newChannelInfo) } else { "" } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/ChannelMuteUserEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/ChannelMuteUserEvent.kt similarity index 83% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/ChannelMuteUserEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/ChannelMuteUserEvent.kt index 97c1c074d..74702aa28 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/ChannelMuteUserEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/ChannelMuteUserEvent.kt @@ -1,10 +1,10 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils +import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.HexKey @Immutable class ChannelMuteUserEvent( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/ChatMessageEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/ChatMessageEvent.kt similarity index 84% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/ChatMessageEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/ChatMessageEvent.kt index 23b6c7a4c..47a552f18 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/ChatMessageEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/ChatMessageEvent.kt @@ -1,11 +1,12 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.ChatroomKey -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils +import androidx.compose.runtime.Stable +import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.HexKey +import kotlinx.collections.immutable.ImmutableSet import kotlinx.collections.immutable.toImmutableSet @Immutable @@ -30,9 +31,9 @@ class ChatMessageEvent( val listedPubKeys = recipientsPubKey() val result = if (pubKey == oneSideHex) { - listedPubKeys.minus(oneSideHex).toSet() + listedPubKeys.toSet().minus(oneSideHex) } else { - listedPubKeys.plus(pubKey).minus(oneSideHex).toSet() + listedPubKeys.plus(pubKey).toSet().minus(oneSideHex) } if (result.isEmpty()) { @@ -101,3 +102,8 @@ class ChatMessageEvent( interface ChatroomKeyable { fun chatroomKey(toRemove: HexKey): ChatroomKey } + +@Stable +data class ChatroomKey( + val users: ImmutableSet +) \ No newline at end of file diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/ClassifiedsEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/ClassifiedsEvent.kt similarity index 90% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/ClassifiedsEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/ClassifiedsEvent.kt index 3506d409c..f215430cd 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/ClassifiedsEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/ClassifiedsEvent.kt @@ -1,10 +1,11 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils +import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.ATag +import com.vitorpamplona.quartz.encoders.HexKey @Immutable class ClassifiedsEvent( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/CommunityDefinitionEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/CommunityDefinitionEvent.kt similarity index 82% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/CommunityDefinitionEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/CommunityDefinitionEvent.kt index e03cf2cad..8e8bb4e1c 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/CommunityDefinitionEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/CommunityDefinitionEvent.kt @@ -1,10 +1,11 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils +import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.ATag +import com.vitorpamplona.quartz.encoders.HexKey @Immutable class CommunityDefinitionEvent( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/CommunityPostApprovalEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/CommunityPostApprovalEvent.kt similarity index 85% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/CommunityPostApprovalEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/CommunityPostApprovalEvent.kt index dc22071d7..8089e8bfa 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/CommunityPostApprovalEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/CommunityPostApprovalEvent.kt @@ -1,12 +1,12 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import android.util.Log import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils -import com.vitorpamplona.amethyst.service.relays.Client +import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.ATag +import com.vitorpamplona.quartz.encoders.HexKey @Immutable class CommunityPostApprovalEvent( @@ -19,7 +19,7 @@ class CommunityPostApprovalEvent( ) : Event(id, pubKey, createdAt, kind, tags, content, sig) { fun containedPost(): Event? = try { content.ifBlank { null }?.let { - fromJson(it, Client.lenient) + fromJson(it) } } catch (e: Exception) { Log.w("CommunityPostEvent", "Failed to Parse Community Approval Contained Post of $id with $content") diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/ContactListEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/ContactListEvent.kt similarity index 87% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/ContactListEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/ContactListEvent.kt index ccee19640..ea9e15ca9 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/ContactListEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/ContactListEvent.kt @@ -1,14 +1,15 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import android.util.Log import androidx.compose.runtime.Immutable import androidx.compose.runtime.Stable -import com.google.gson.reflect.TypeToken -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.model.decodePublicKey -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils +import com.fasterxml.jackson.module.kotlin.readValue +import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.ATag +import com.vitorpamplona.quartz.encoders.HexKey +import com.vitorpamplona.quartz.encoders.decodePublicKey @Immutable data class Contact(val pubKeyHex: String, val relayUri: String?) @@ -78,7 +79,7 @@ class ContactListEvent( fun relays(): Map? = try { if (content.isNotEmpty()) { - gson.fromJson(content, object : TypeToken>() {}.type) as Map + mapper.readValue>(content) } else { null } @@ -102,7 +103,7 @@ class ContactListEvent( publicKey: ByteArray? = null ): ContactListEvent { val content = if (relayUse != null) { - gson.toJson(relayUse) + mapper.writeValueAsString(relayUse) } else { "" } @@ -357,7 +358,7 @@ class ContactListEvent( fun updateRelayList(earlierVersion: ContactListEvent, relayUse: Map?, pubKey: HexKey, privateKey: ByteArray?, createdAt: Long = TimeUtils.now()): ContactListEvent { val content = if (relayUse != null) { - gson.toJson(relayUse) + mapper.writeValueAsString(relayUse) } else { "" } @@ -394,3 +395,66 @@ class ContactListEvent( data class ReadWrite(val read: Boolean, val write: Boolean) } + +@Stable +class UserMetadata { + var name: String? = null + var username: String? = null + var display_name: String? = null + var displayName: String? = null + var picture: String? = null + var banner: String? = null + var website: String? = null + var about: String? = null + + var nip05: String? = null + var nip05Verified: Boolean = false + var nip05LastVerificationTime: Long? = 0 + + var domain: String? = null + var lud06: String? = null + var lud16: String? = null + + var twitter: String? = null + + var updatedMetadataAt: Long = 0 + var latestMetadata: MetadataEvent? = null + var tags: ImmutableListOfLists? = null + + fun anyName(): String? { + return display_name ?: displayName ?: name ?: username + } + + fun anyNameStartsWith(prefix: String): Boolean { + return listOfNotNull(name, username, display_name, displayName, nip05, lud06, lud16) + .any { it.contains(prefix, true) } + } + + fun lnAddress(): String? { + return (lud16?.trim() ?: lud06?.trim())?.ifBlank { null } + } + + fun bestUsername(): String? { + return name?.ifBlank { null } ?: username?.ifBlank { null } + } + + fun bestDisplayName(): String? { + return displayName?.ifBlank { null } ?: display_name?.ifBlank { null } + } + + fun nip05(): String? { + return nip05?.ifBlank { null } + } + + fun profilePicture(): String? { + if (picture.isNullOrBlank()) picture = null + return picture + } +} + +@Stable +data class ImmutableListOfLists(val lists: List> = emptyList()) + +fun List>.toImmutableListOfLists(): ImmutableListOfLists { + return ImmutableListOfLists(this) +} \ No newline at end of file diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/DeletionEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/DeletionEvent.kt similarity index 83% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/DeletionEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/DeletionEvent.kt index a82410481..57ef1cf36 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/DeletionEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/DeletionEvent.kt @@ -1,10 +1,10 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils +import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.HexKey @Immutable class DeletionEvent( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/EmojiPackEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/EmojiPackEvent.kt similarity index 84% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/EmojiPackEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/EmojiPackEvent.kt index f07b40e19..8e41d5d94 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/EmojiPackEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/EmojiPackEvent.kt @@ -1,10 +1,10 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils +import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.HexKey @Immutable class EmojiPackEvent( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/EmojiPackSelectionEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/EmojiPackSelectionEvent.kt similarity index 79% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/EmojiPackSelectionEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/EmojiPackSelectionEvent.kt index b56d095b0..78ff9e030 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/EmojiPackSelectionEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/EmojiPackSelectionEvent.kt @@ -1,10 +1,11 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils +import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.ATag +import com.vitorpamplona.quartz.encoders.HexKey @Immutable class EmojiPackSelectionEvent( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/Event.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/Event.kt similarity index 50% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/Event.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/Event.kt index a8a20ae8d..594e17e47 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/Event.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/Event.kt @@ -1,25 +1,36 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import android.util.Log import androidx.compose.runtime.Immutable -import com.google.gson.* -import com.google.gson.annotations.SerializedName -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils -import com.vitorpamplona.amethyst.service.nip19.Nip19 -import com.vitorpamplona.amethyst.service.relays.bytesUsedInMemory -import fr.acinq.secp256k1.Hex -import java.lang.reflect.Type +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.core.JsonParser +import com.fasterxml.jackson.databind.DeserializationContext +import com.fasterxml.jackson.databind.DeserializationFeature +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.SerializerProvider +import com.fasterxml.jackson.databind.deser.std.StdDeserializer +import com.fasterxml.jackson.databind.module.SimpleModule +import com.fasterxml.jackson.databind.ser.std.StdSerializer +import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.ATag +import com.vitorpamplona.quartz.encoders.Hex +import com.vitorpamplona.quartz.encoders.HexKey +import com.vitorpamplona.quartz.encoders.Nip19 +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.utils.TimeUtils import java.math.BigDecimal import java.util.* + @Immutable open class Event( val id: HexKey, - @SerializedName("pubkey") val pubKey: HexKey, - @SerializedName("created_at") val createdAt: Long, + @JsonProperty("pubkey") + val pubKey: HexKey, + @JsonProperty("created_at") + val createdAt: Long, val kind: Int, val tags: List>, val content: String, @@ -49,7 +60,7 @@ open class Event( override fun sig(): HexKey = sig - override fun toJson(): String = gson.toJson(this) + override fun toJson(): String = mapper.writeValueAsString(toJsonObject()) fun hasAnyTaggedUser() = tags.any { it.size > 1 && it[0] == "p" } @@ -163,11 +174,14 @@ open class Event( return "nostr:${toNIP19()}" } + fun hasCorrectIDHash() = id.equals(generateId()) + fun hasVerifedSignature() = CryptoUtils.verifySignature(Hex.decode(sig), Hex.decode(id), Hex.decode(pubKey)) + /** * Checks if the ID is correct and then if the pubKey's secret key signed the event. */ override fun checkSignature() { - if (!id.contentEquals(generateId())) { + if (!hasCorrectIDHash()) { throw Exception( """|Unexpected ID. | Event: ${toJson()} @@ -176,194 +190,167 @@ open class Event( """.trimIndent() ) } - if (!CryptoUtils.verifySignature(Hex.decode(sig), Hex.decode(id), Hex.decode(pubKey))) { + if (!hasVerifedSignature()) { throw Exception("""Bad signature!""") } } override fun hasValidSignature(): Boolean { return try { - id.contentEquals(generateId()) && CryptoUtils.verifySignature(Hex.decode(sig), Hex.decode(id), Hex.decode(pubKey)) + hasCorrectIDHash() && hasVerifedSignature() } catch (e: Exception) { Log.e("Event", "Fail checking if event $id has a valid signature", e) false } } + fun makeJsonForId(): String { + return makeJsonForId(pubKey, createdAt, kind, tags, content) + } + private fun generateId(): String { - val rawEvent = listOf(0, pubKey, createdAt, kind, tags, content) - - // GSON decided to hardcode these replacements. - // They break Nostr's hash check. - // These lines revert their code. - // https://github.com/google/gson/issues/2295 - val rawEventJson = gson.toJson(rawEvent) - .replace("\\u2028", "\u2028") - .replace("\\u2029", "\u2029") - - return CryptoUtils.sha256(rawEventJson.toByteArray()).toHexKey() + return CryptoUtils.sha256(makeJsonForId().toByteArray()).toHexKey() } - private class EventDeserializer : JsonDeserializer { - override fun deserialize( - json: JsonElement, - typeOfT: Type?, - context: JsonDeserializationContext? - ): Event { - val jsonObject = json.asJsonObject - return Event( - id = jsonObject.get("id").asString.intern(), - pubKey = jsonObject.get("pubkey").asString.intern(), - createdAt = jsonObject.get("created_at").asLong, - kind = jsonObject.get("kind").asInt, - tags = jsonObject.get("tags").asJsonArray.map { - it.asJsonArray.mapNotNull { s -> if (s.isJsonNull) null else s.asString.intern() } - }, - content = jsonObject.get("content").asString, - sig = jsonObject.get("sig").asString - ) + private class EventDeserializer : StdDeserializer(Event::class.java) { + override fun deserialize(jp: JsonParser, ctxt: DeserializationContext): Event { + return fromJson(jp.codec.readTree(jp)) } } - private class GossipDeserializer : JsonDeserializer { - override fun deserialize( - json: JsonElement, - typeOfT: Type?, - context: JsonDeserializationContext? - ): Gossip { - val jsonObject = json.asJsonObject + private class GossipDeserializer : StdDeserializer(Gossip::class.java) { + override fun deserialize(jp: JsonParser, ctxt: DeserializationContext): Gossip { + val jsonObject: JsonNode = jp.codec.readTree(jp) return Gossip( - id = jsonObject.get("id")?.asString?.intern(), - pubKey = jsonObject.get("pubkey")?.asString?.intern(), - createdAt = jsonObject.get("created_at")?.asLong, - kind = jsonObject.get("kind")?.asInt, - tags = jsonObject.get("tags")?.asJsonArray?.mapNotNull { - it?.asJsonArray?.mapNotNull { s -> if (s?.isJsonNull != false) null else s.asString.intern() } + id = jsonObject.get("id")?.asText()?.intern(), + pubKey = jsonObject.get("pubkey")?.asText()?.intern(), + createdAt = jsonObject.get("created_at")?.asLong(), + kind = jsonObject.get("kind")?.asInt(), + tags = jsonObject.get("tags")?.map { + it.mapNotNull { s -> if (s?.isNull ?: true) null else s.asText().intern() } }, - content = jsonObject.get("content")?.asString + content = jsonObject.get("content")?.asText() ) } } - private class EventSerializer : JsonSerializer { - override fun serialize( - src: Event, - typeOfSrc: Type?, - context: JsonSerializationContext? - ): JsonElement { - return JsonObject().apply { - addProperty("id", src.id) - addProperty("pubkey", src.pubKey) - addProperty("created_at", src.createdAt) - addProperty("kind", src.kind) + private class EventSerializer: StdSerializer(Event::class.java) { + override fun serialize(event: Event, gen: JsonGenerator, provider: SerializerProvider) { + gen.writeStartObject() + gen.writeStringField("id", event.id) + gen.writeStringField("pubkey", event.pubKey) + gen.writeNumberField("created_at", event.createdAt) + gen.writeNumberField("kind", event.kind) + gen.writeArrayFieldStart("tags") + event.tags.forEach { tag -> + gen.writeArray(tag.toTypedArray(), 0, tag.size) + } + gen.writeEndArray() + gen.writeStringField("content", event.content) + gen.writeStringField("sig", event.sig) + gen.writeEndObject() + } + } + + private class GossipSerializer: StdSerializer(Gossip::class.java) { + override fun serialize(event: Gossip, gen: JsonGenerator, provider: SerializerProvider) { + gen.writeStartObject() + event.id?.let { gen.writeStringField("id", it) } + event.pubKey?.let { gen.writeStringField("pubkey", it) } + event.createdAt?.let { gen.writeNumberField("created_at", it) } + event.kind?.let { gen.writeNumberField("kind", it) } + event.tags?.let { + gen.writeArrayFieldStart("tags") + event.tags.forEach { tag -> + gen.writeArray(tag.toTypedArray(), 0, tag.size) + } + gen.writeEndArray() + } + event.content?.let { gen.writeStringField("content", it) } + gen.writeEndObject() + } + } + + fun toJsonObject(): JsonNode { + val factory = mapper.nodeFactory + + return factory.objectNode().apply { + put("id", id) + put("pubkey", pubKey) + put("created_at", createdAt) + put("kind", kind) + put( + "tags", + factory.arrayNode(tags.size).apply { + tags.forEach { tag -> + add( + factory.arrayNode(tag.size).apply { + tag.forEach { add(it) } + } + ) + } + } + ) + put("content", content) + put("sig", sig) + } + } + + companion object { + val mapper = jacksonObjectMapper() + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + .registerModule(SimpleModule() + .addSerializer(Event::class.java, EventSerializer()) + .addDeserializer(Event::class.java, EventDeserializer()) + .addSerializer(Gossip::class.java, GossipSerializer()) + .addDeserializer(Gossip::class.java, GossipDeserializer()) + .addDeserializer(Response::class.java, ResponseDeserializer()) + .addDeserializer(Request::class.java, RequestDeserializer()) + ) + + fun fromJson(jsonObject: JsonNode): Event { + return EventFactory.create( + id = jsonObject.get("id").asText().intern(), + pubKey = jsonObject.get("pubkey").asText().intern(), + createdAt = jsonObject.get("created_at").asLong(), + kind = jsonObject.get("kind").asInt(), + tags = jsonObject.get("tags").map { + it.mapNotNull { s -> if (s.isNull) null else s.asText().intern() } + }, + content = jsonObject.get("content").asText(), + sig = jsonObject.get("sig").asText() + ) + } + + fun fromJson(json: String): Event = mapper.readValue(json, Event::class.java) + fun toJson(event: Event): String = mapper.writeValueAsString(event) + + fun makeJsonForId(pubKey: HexKey, createdAt: Long, kind: Int, tags: List>, content: String): String { + val factory = mapper.nodeFactory + val rawEvent = factory.arrayNode(6).apply { + add(0) + add(pubKey) + add(createdAt) + add(kind) add( - "tags", - JsonArray().also { jsonTags -> - src.tags.forEach { tag -> - jsonTags.add( - JsonArray().also { jsonTagElement -> - tag.forEach { tagElement -> - jsonTagElement.add(tagElement) - } + factory.arrayNode(tags.size).apply { + tags.forEach { tag -> + add( + factory.arrayNode(tag.size).apply { + tag.forEach { add(it) } } ) } } ) - addProperty("content", src.content) - addProperty("sig", src.sig) + add(content) } - } - } - private class GossipSerializer : JsonSerializer { - override fun serialize( - src: Gossip, - typeOfSrc: Type?, - context: JsonSerializationContext? - ): JsonElement { - return JsonObject().apply { - src.id?.let { addProperty("id", it) } - src.pubKey?.let { addProperty("pubkey", it) } - src.createdAt?.let { addProperty("created_at", it) } - src.kind?.let { addProperty("kind", it) } - src.tags?.let { - add( - "tags", - JsonArray().also { jsonTags -> - it.forEach { tag -> - jsonTags.add( - JsonArray().also { jsonTagElement -> - tag.forEach { tagElement -> - jsonTagElement.add(tagElement) - } - } - ) - } - } - ) - } - src.content?.let { addProperty("content", it) } - } - } - } - - private class ByteArrayDeserializer : JsonDeserializer { - override fun deserialize( - json: JsonElement, - typeOfT: Type?, - context: JsonDeserializationContext? - ): ByteArray = Hex.decode(json.asString) - } - - private class ByteArraySerializer : JsonSerializer { - override fun serialize( - src: ByteArray, - typeOfSrc: Type?, - context: JsonSerializationContext? - ) = JsonPrimitive(src.toHexKey()) - } - - companion object { - val gson: Gson = GsonBuilder() - .disableHtmlEscaping() - .registerTypeAdapter(Event::class.java, EventSerializer()) - .registerTypeAdapter(Event::class.java, EventDeserializer()) - .registerTypeAdapter(Gossip::class.java, GossipSerializer()) - .registerTypeAdapter(Gossip::class.java, GossipDeserializer()) - .registerTypeAdapter(ByteArray::class.java, ByteArraySerializer()) - .registerTypeAdapter(ByteArray::class.java, ByteArrayDeserializer()) - .registerTypeAdapter(Response::class.java, ResponseDeserializer()) - .registerTypeAdapter(Request::class.java, RequestDeserializer()) - .create() - - fun fromJson(json: String, lenient: Boolean = false): Event = gson.fromJson(json, Event::class.java).getRefinedEvent(lenient) - - fun fromJson(json: JsonElement, lenient: Boolean = false): Event = gson.fromJson(json, Event::class.java).getRefinedEvent(lenient) - - fun Event.getRefinedEvent(lenient: Boolean = false): Event { - return EventFactory.create(id, pubKey, createdAt, kind, tags, content, sig, lenient) + return mapper.writeValueAsString(rawEvent) } fun generateId(pubKey: HexKey, createdAt: Long, kind: Int, tags: List>, content: String): ByteArray { - val rawEvent = listOf( - 0, - pubKey, - createdAt, - kind, - tags, - content - ) - - // GSON decided to hardcode these replacements. - // They break Nostr's hash check. - // These lines revert their code. - // https://github.com/google/gson/issues/2295 - val rawEventJson = gson.toJson(rawEvent) - .replace("\\u2028", "\u2028") - .replace("\\u2029", "\u2029") - - return CryptoUtils.sha256(rawEventJson.toByteArray()) + return CryptoUtils.sha256(makeJsonForId(pubKey, createdAt, kind, tags, content).toByteArray()) } fun create(privateKey: ByteArray, kind: Int, tags: List> = emptyList(), content: String = "", createdAt: Long = TimeUtils.now()): Event { @@ -380,3 +367,8 @@ interface AddressableEvent { fun dTag(): String fun address(): ATag } + +fun String.bytesUsedInMemory(): Int { + return (8 * ((((this.length) * 2) + 45) / 8)) +} + diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/EventFactory.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/EventFactory.kt similarity index 96% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/EventFactory.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/EventFactory.kt index 0e8d6d69b..f2c2043a9 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/EventFactory.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/EventFactory.kt @@ -1,6 +1,6 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events -import com.vitorpamplona.amethyst.model.toHexKey +import com.vitorpamplona.quartz.encoders.toHexKey class EventFactory { companion object { @@ -11,8 +11,7 @@ class EventFactory { kind: Int, tags: List>, content: String, - sig: String, - lenient: Boolean + sig: String ) = when (kind) { AdvertisedRelayListEvent.kind -> AdvertisedRelayListEvent(id, pubKey, createdAt, tags, content, sig) AppDefinitionEvent.kind -> AppDefinitionEvent(id, pubKey, createdAt, tags, content, sig) @@ -68,7 +67,7 @@ class EventFactory { PollNoteEvent.kind -> PollNoteEvent(id, pubKey, createdAt, tags, content, sig) PrivateDmEvent.kind -> PrivateDmEvent(id, pubKey, createdAt, tags, content, sig) ReactionEvent.kind -> ReactionEvent(id, pubKey, createdAt, tags, content, sig) - RecommendRelayEvent.kind -> RecommendRelayEvent(id, pubKey, createdAt, tags, content, sig, lenient) + RecommendRelayEvent.kind -> RecommendRelayEvent(id, pubKey, createdAt, tags, content, sig) RelaySetEvent.kind -> RelaySetEvent(id, pubKey, createdAt, tags, content, sig) ReportEvent.kind -> ReportEvent(id, pubKey, createdAt, tags, content, sig) RepostEvent.kind -> RepostEvent(id, pubKey, createdAt, tags, content, sig) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/EventInterface.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/EventInterface.kt similarity index 92% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/EventInterface.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/EventInterface.kt index a4c178abd..777b1cffa 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/EventInterface.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/EventInterface.kt @@ -1,7 +1,8 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.HexKey +import com.vitorpamplona.quartz.encoders.ATag +import com.vitorpamplona.quartz.encoders.HexKey import java.math.BigDecimal @Immutable diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/FileHeaderEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/FileHeaderEvent.kt similarity index 93% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/FileHeaderEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/FileHeaderEvent.kt index 8ae6115ee..9c55f3d4d 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/FileHeaderEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/FileHeaderEvent.kt @@ -1,10 +1,10 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils +import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.HexKey @Immutable class FileHeaderEvent( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/FileStorageEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/FileStorageEvent.kt similarity index 86% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/FileStorageEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/FileStorageEvent.kt index 8d8f580d7..68de6b62a 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/FileStorageEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/FileStorageEvent.kt @@ -1,11 +1,11 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import android.util.Log import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils +import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.HexKey import java.util.Base64 @Immutable diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/FileStorageHeaderEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/FileStorageHeaderEvent.kt similarity index 92% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/FileStorageHeaderEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/FileStorageHeaderEvent.kt index 6193849b3..6f4644240 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/FileStorageHeaderEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/FileStorageHeaderEvent.kt @@ -1,10 +1,10 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils +import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.HexKey @Immutable class FileStorageHeaderEvent( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/GeneralListEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/GeneralListEvent.kt similarity index 87% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/GeneralListEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/GeneralListEvent.kt index 17713ac8d..ba0f39fd8 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/GeneralListEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/GeneralListEvent.kt @@ -1,11 +1,12 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import android.util.Log import androidx.compose.runtime.Immutable -import com.google.gson.reflect.TypeToken -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.hexToByteArray -import com.vitorpamplona.amethyst.service.CryptoUtils +import com.fasterxml.jackson.module.kotlin.readValue +import com.vitorpamplona.quartz.encoders.hexToByteArray +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.ATag +import com.vitorpamplona.quartz.encoders.HexKey @Immutable abstract class GeneralListEvent( @@ -46,7 +47,7 @@ abstract class GeneralListEvent( } privateTagsCache = try { - gson.fromJson(plainContent(privKey), object : TypeToken>>() {}.type) + plainContent(privKey)?.let { mapper.readValue>>(it) } } catch (e: Throwable) { Log.w("GeneralList", "Error parsing the JSON ${e.message}") null @@ -89,7 +90,7 @@ abstract class GeneralListEvent( privAddresses?.forEach { privTags.add(listOf("a", it.toTag())) } - val msg = gson.toJson(privTags) + val msg = mapper.writeValueAsString(privTags) return CryptoUtils.encryptNIP04( msg, @@ -103,7 +104,7 @@ abstract class GeneralListEvent( privateKey: ByteArray ): String { return CryptoUtils.encryptNIP04( - msg = gson.toJson(privateTags), + msg = mapper.writeValueAsString(privateTags), privateKey = privateKey, pubKey = CryptoUtils.pubkeyCreate(privateKey) ) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/GenericRepostEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/GenericRepostEvent.kt similarity index 86% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/GenericRepostEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/GenericRepostEvent.kt index c76fee35e..51f1a7354 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/GenericRepostEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/GenericRepostEvent.kt @@ -1,11 +1,10 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils -import com.vitorpamplona.amethyst.service.relays.Client +import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.HexKey @Immutable class GenericRepostEvent( @@ -21,7 +20,7 @@ class GenericRepostEvent( fun originalAuthor() = tags.filter { it.firstOrNull() == "p" }.mapNotNull { it.getOrNull(1) } fun containedPost() = try { - fromJson(content, Client.lenient) + fromJson(content) } catch (e: Exception) { null } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/GiftWrapEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/GiftWrapEvent.kt similarity index 76% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/GiftWrapEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/GiftWrapEvent.kt index e48828b04..84ab92e36 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/GiftWrapEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/GiftWrapEvent.kt @@ -1,15 +1,15 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import android.util.Log import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.model.hexToByteArray -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils -import com.vitorpamplona.amethyst.service.EncryptedInfo -import com.vitorpamplona.amethyst.service.Nip44Version -import com.vitorpamplona.amethyst.service.relays.Client +import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.encoders.hexToByteArray +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.crypto.Nip44Version +import com.vitorpamplona.quartz.crypto.decodeNIP44 +import com.vitorpamplona.quartz.crypto.encodeNIP44 +import com.vitorpamplona.quartz.encoders.HexKey @Immutable class GiftWrapEvent( @@ -33,17 +33,17 @@ class GiftWrapEvent( } fun unwrap(privKey: ByteArray) = try { - plainContent(privKey)?.let { fromJson(it, Client.lenient) } + plainContent(privKey)?.let { fromJson(it) } } catch (e: Exception) { // Log.e("UnwrapError", "Couldn't Decrypt the content", e) null } private fun plainContent(privKey: ByteArray): String? { - if (content.isBlank()) return null + if (content.isEmpty()) return null return try { - val toDecrypt = gson.fromJson(content, EncryptedInfo::class.java) + val toDecrypt = decodeNIP44(content) ?: return null return when (toDecrypt.v) { Nip44Version.NIP04.versionCode -> CryptoUtils.decryptNIP04(toDecrypt, privKey, pubKey.hexToByteArray()) @@ -69,9 +69,9 @@ class GiftWrapEvent( val privateKey = CryptoUtils.privkeyCreate() // GiftWrap is always a random key val sharedSecret = CryptoUtils.getSharedSecretNIP24(privateKey, recipientPubKey.hexToByteArray()) - val content = gson.toJson( + val content = encodeNIP44( CryptoUtils.encryptNIP24( - gson.toJson(event), + toJson(event), sharedSecret ) ) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/HTTPAuthorizationEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/HTTPAuthorizationEvent.kt similarity index 82% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/HTTPAuthorizationEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/HTTPAuthorizationEvent.kt index e2f9f6018..ea9896e18 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/HTTPAuthorizationEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/HTTPAuthorizationEvent.kt @@ -1,10 +1,10 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils +import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.HexKey @Immutable class HTTPAuthorizationEvent( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/HighlightEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/HighlightEvent.kt similarity index 80% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/HighlightEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/HighlightEvent.kt index 4222be0d8..330783580 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/HighlightEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/HighlightEvent.kt @@ -1,10 +1,10 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils +import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.HexKey @Immutable class HighlightEvent( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/LiveActivitiesChatMessageEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/LiveActivitiesChatMessageEvent.kt similarity index 89% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/LiveActivitiesChatMessageEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/LiveActivitiesChatMessageEvent.kt index dc4031159..1160dd6ca 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/LiveActivitiesChatMessageEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/LiveActivitiesChatMessageEvent.kt @@ -1,10 +1,11 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils +import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.ATag +import com.vitorpamplona.quartz.encoders.HexKey @Immutable class LiveActivitiesChatMessageEvent( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/LiveActivitiesEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/LiveActivitiesEvent.kt similarity index 88% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/LiveActivitiesEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/LiveActivitiesEvent.kt index ef9cfa0b7..43e4a25ae 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/LiveActivitiesEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/LiveActivitiesEvent.kt @@ -1,10 +1,11 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils +import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.ATag +import com.vitorpamplona.quartz.encoders.HexKey @Immutable class LiveActivitiesEvent( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/LnZapEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/LnZapEvent.kt similarity index 85% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/LnZapEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/LnZapEvent.kt index 59e61c309..c4502cf69 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/LnZapEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/LnZapEvent.kt @@ -1,10 +1,9 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import android.util.Log import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.service.lnurl.LnInvoiceUtil -import com.vitorpamplona.amethyst.service.relays.Client +import com.vitorpamplona.quartz.encoders.HexKey +import com.vitorpamplona.quartz.encoders.LnInvoiceUtil @Immutable class LnZapEvent( @@ -17,10 +16,9 @@ class LnZapEvent( ) : LnZapEventInterface, Event(id, pubKey, createdAt, kind, tags, content, sig) { // This event is also kept in LocalCache (same object) @Transient val zapRequest: LnZapRequestEvent? - override fun containedPost(): LnZapRequestEvent? = try { description()?.ifBlank { null }?.let { - fromJson(it, Client.lenient) + fromJson(it) } as? LnZapRequestEvent } catch (e: Exception) { Log.e("LnZapEvent", "Failed to Parse Contained Post ${description()}", e) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/LnZapEventInterface.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/LnZapEventInterface.kt similarity index 87% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/LnZapEventInterface.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/LnZapEventInterface.kt index 56c382894..e65ac6946 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/LnZapEventInterface.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/LnZapEventInterface.kt @@ -1,4 +1,4 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import androidx.compose.runtime.Immutable import java.math.BigDecimal diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/LnZapPaymentRequestEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/LnZapPaymentRequestEvent.kt similarity index 69% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/LnZapPaymentRequestEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/LnZapPaymentRequestEvent.kt index 726a355a1..2f46d58f9 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/LnZapPaymentRequestEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/LnZapPaymentRequestEvent.kt @@ -1,17 +1,16 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import android.util.Log import androidx.compose.runtime.Immutable -import com.google.gson.JsonDeserializationContext -import com.google.gson.JsonDeserializer -import com.google.gson.JsonElement -import com.google.gson.JsonParseException -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.model.hexToByteArray -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils -import java.lang.reflect.Type +import com.fasterxml.jackson.core.JsonParser +import com.fasterxml.jackson.databind.DeserializationContext +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.deser.std.StdDeserializer +import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.encoders.hexToByteArray +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.HexKey @Immutable class LnZapPaymentRequestEvent( @@ -39,7 +38,7 @@ class LnZapPaymentRequestEvent( val jsonText = CryptoUtils.decryptNIP04(content, sharedSecret) - val payInvoiceMethod = gson.fromJson(jsonText, Request::class.java) + val payInvoiceMethod = mapper.readValue(jsonText, Request::class.java) lnInvoice = (payInvoiceMethod as? PayInvoiceMethod)?.params?.invoice @@ -60,7 +59,7 @@ class LnZapPaymentRequestEvent( createdAt: Long = TimeUtils.now() ): LnZapPaymentRequestEvent { val pubKey = CryptoUtils.pubkeyCreate(privateKey) - val serializedRequest = gson.toJson(PayInvoiceMethod.create(lnInvoice)) + val serializedRequest = mapper.writeValueAsString(PayInvoiceMethod.create(lnInvoice)) val content = CryptoUtils.encryptNIP04( serializedRequest, @@ -94,23 +93,15 @@ class PayInvoiceMethod(var params: PayInvoiceParams? = null) : Request("pay_invo } } -class RequestDeserializer : - JsonDeserializer { - @Throws(JsonParseException::class) - override fun deserialize( - json: JsonElement, - typeOfT: Type, - context: JsonDeserializationContext - ): Request? { - val jsonObject = json.asJsonObject - val method = jsonObject.get("method")?.asString + +class RequestDeserializer : StdDeserializer(Request::class.java) { + override fun deserialize(jp: JsonParser, ctxt: DeserializationContext): Request? { + val jsonObject: JsonNode = jp.codec.readTree(jp) + val method = jsonObject.get("method")?.asText() if (method == "pay_invoice") { - return context.deserialize(jsonObject, PayInvoiceMethod::class.java) + return jp.codec.treeToValue(jsonObject, PayInvoiceMethod::class.java) } return null } - - companion object { - } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/LnZapPaymentResponseEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/LnZapPaymentResponseEvent.kt similarity index 57% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/LnZapPaymentResponseEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/LnZapPaymentResponseEvent.kt index fe6e5cc6e..9055bbebd 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/LnZapPaymentResponseEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/LnZapPaymentResponseEvent.kt @@ -1,15 +1,14 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import android.util.Log import androidx.compose.runtime.Immutable -import com.google.gson.JsonDeserializationContext -import com.google.gson.JsonDeserializer -import com.google.gson.JsonElement -import com.google.gson.JsonParseException -import com.google.gson.annotations.SerializedName -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.service.CryptoUtils -import java.lang.reflect.Type +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.core.JsonParser +import com.fasterxml.jackson.databind.DeserializationContext +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.deser.std.StdDeserializer +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.HexKey @Immutable class LnZapPaymentResponseEvent( @@ -51,7 +50,7 @@ class LnZapPaymentResponseEvent( return try { if (content.isNotEmpty()) { val decrypted = decrypt(privKey, pubKey) - response = gson.fromJson(decrypted, Response::class.java) + response = mapper.readValue(decrypted, Response::class.java) response } else { null @@ -69,7 +68,7 @@ class LnZapPaymentResponseEvent( // RESPONSE OBJECTS abstract class Response( - @SerializedName("result_type") + @JsonProperty("result_type") val resultType: String ) @@ -85,57 +84,49 @@ class PayInvoiceErrorResponse(val error: PayInvoiceErrorParams? = null) : class PayInvoiceErrorParams(val code: ErrorType?, val message: String?) enum class ErrorType { - @SerializedName(value = "rate_limited", alternate = ["RATE_LIMITED"]) + @JsonProperty(value = "RATE_LIMITED") RATE_LIMITED, // The client is sending commands too fast. It should retry in a few seconds. - @SerializedName(value = "not_implemented", alternate = ["NOT_IMPLEMENTED"]) + @JsonProperty(value = "NOT_IMPLEMENTED") NOT_IMPLEMENTED, // The command is not known or is intentionally not implemented. - @SerializedName(value = "insufficient_balance", alternate = ["INSUFFICIENT_BALANCE"]) + @JsonProperty(value = "INSUFFICIENT_BALANCE") INSUFFICIENT_BALANCE, // The wallet does not have enough funds to cover a fee reserve or the payment amount. - @SerializedName(value = "quota_exceeded", alternate = ["QUOTA_EXCEEDED"]) + @JsonProperty(value = "QUOTA_EXCEEDED") QUOTA_EXCEEDED, // The wallet has exceeded its spending quota. - @SerializedName(value = "restricted", alternate = ["RESTRICTED"]) + @JsonProperty(value = "RESTRICTED") RESTRICTED, // This public key is not allowed to do this operation. - @SerializedName(value = "unauthorized", alternate = ["UNAUTHORIZED"]) + @JsonProperty(value = "UNAUTHORIZED") UNAUTHORIZED, // This public key has no wallet connected. - @SerializedName(value = "internal", alternate = ["INTERNAL"]) + @JsonProperty(value = "INTERNAL") INTERNAL, // An internal error. - @SerializedName(value = "other", alternate = ["OTHER"]) + @JsonProperty(value = "OTHER") OTHER // Other error. } } -class ResponseDeserializer : - JsonDeserializer { - @Throws(JsonParseException::class) - override fun deserialize( - json: JsonElement, - typeOfT: Type, - context: JsonDeserializationContext - ): Response? { - val jsonObject = json.asJsonObject - val resultType = jsonObject.get("result_type")?.asString + +class ResponseDeserializer : StdDeserializer(Response::class.java) { + override fun deserialize(jp: JsonParser, ctxt: DeserializationContext): Response? { + val jsonObject: JsonNode = jp.codec.readTree(jp) + val resultType = jsonObject.get("result_type")?.asText() if (resultType == "pay_invoice") { - val result = jsonObject.get("result")?.asJsonObject - val error = jsonObject.get("error")?.asJsonObject + val result = jsonObject.get("result") + val error = jsonObject.get("error") if (result != null) { - return context.deserialize(jsonObject, PayInvoiceSuccessResponse::class.java) + return jp.codec.treeToValue(jsonObject, PayInvoiceSuccessResponse::class.java) } if (error != null) { - return context.deserialize(jsonObject, PayInvoiceErrorResponse::class.java) + return jp.codec.treeToValue(jsonObject, PayInvoiceErrorResponse::class.java) } } else { // tries to guess - if (jsonObject.get("result")?.asJsonObject?.get("preimage") != null) { - return context.deserialize(jsonObject, PayInvoiceSuccessResponse::class.java) + if (jsonObject.get("result")?.get("preimage") != null) { + return jp.codec.treeToValue(jsonObject, PayInvoiceSuccessResponse::class.java) } - if (jsonObject.get("error")?.asJsonObject?.get("code") != null) { - return context.deserialize(jsonObject, PayInvoiceErrorResponse::class.java) + if (jsonObject.get("error")?.get("code") != null) { + return jp.codec.treeToValue(jsonObject, PayInvoiceErrorResponse::class.java) } } return null } - - companion object { - } -} +} \ No newline at end of file diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/LnZapRequestEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/LnZapRequestEvent.kt similarity index 93% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/LnZapRequestEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/LnZapRequestEvent.kt index ab60da265..c318ca669 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/LnZapRequestEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/LnZapRequestEvent.kt @@ -1,9 +1,12 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.* -import com.vitorpamplona.amethyst.service.Bech32 -import com.vitorpamplona.amethyst.service.CryptoUtils +import com.vitorpamplona.quartz.utils.* +import com.vitorpamplona.quartz.encoders.Bech32 +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.HexKey +import com.vitorpamplona.quartz.encoders.hexToByteArray +import com.vitorpamplona.quartz.encoders.toHexKey import java.nio.charset.Charset import java.security.SecureRandom import javax.crypto.BadPaddingException @@ -167,7 +170,8 @@ class LnZapRequestEvent( val encryptedMsg = parts.first().run { Bech32.decode(this).second } val encryptedBytes = Bech32.five2eight(encryptedMsg, 0) val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding") - cipher.init(Cipher.DECRYPT_MODE, SecretKeySpec(sharedSecret, "AES"), IvParameterSpec(Bech32.five2eight(iv, 0))) + cipher.init(Cipher.DECRYPT_MODE, SecretKeySpec(sharedSecret, "AES"), IvParameterSpec( + Bech32.five2eight(iv, 0))) try { val decryptedMsgBytes = cipher.doFinal(encryptedBytes) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/LongTextNoteEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/LongTextNoteEvent.kt similarity index 86% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/LongTextNoteEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/LongTextNoteEvent.kt index e5bf88ded..09184f2a5 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/LongTextNoteEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/LongTextNoteEvent.kt @@ -1,10 +1,11 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils +import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.ATag +import com.vitorpamplona.quartz.encoders.HexKey @Immutable class LongTextNoteEvent( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/MetadataEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/MetadataEvent.kt similarity index 79% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/MetadataEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/MetadataEvent.kt index 732ad457d..490cb826f 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/MetadataEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/MetadataEvent.kt @@ -1,16 +1,11 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import android.util.Log import androidx.compose.runtime.Stable -import com.fasterxml.jackson.databind.DeserializationFeature -import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper -import com.google.gson.Gson -import com.vitorpamplona.amethyst.R -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.model.UserMetadata -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils +import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.HexKey import java.io.ByteArrayInputStream @Stable @@ -19,8 +14,6 @@ abstract class IdentityClaim( val proof: String ) { abstract fun toProofUrl(): String - abstract fun toIcon(): Int - abstract fun toDescriptor(): Int abstract fun platform(): String fun platformIdentity() = "${platform()}:$identity" @@ -47,8 +40,6 @@ class GitHubIdentity( override fun toProofUrl() = "https://gist.github.com/$identity/$proof" override fun platform() = platform - override fun toIcon() = R.drawable.github - override fun toDescriptor() = R.string.github companion object { val platform = "github" @@ -73,8 +64,6 @@ class TwitterIdentity( override fun toProofUrl() = "https://twitter.com/$identity/status/$proof" override fun platform() = platform - override fun toIcon() = R.drawable.twitter - override fun toDescriptor() = R.string.twitter companion object { val platform = "twitter" @@ -99,8 +88,6 @@ class TelegramIdentity( override fun toProofUrl() = "https://t.me/$proof" override fun platform() = platform - override fun toIcon() = R.drawable.telegram - override fun toDescriptor() = R.string.telegram companion object { val platform = "telegram" @@ -114,8 +101,6 @@ class MastodonIdentity( override fun toProofUrl() = "https://$identity/$proof" override fun platform() = platform - override fun toIcon() = R.drawable.mastodon - override fun toDescriptor() = R.string.mastodon companion object { val platform = "mastodon" @@ -142,7 +127,7 @@ class MetadataEvent( sig: HexKey ) : Event(id, pubKey, createdAt, kind, tags, content, sig) { fun contactMetaData() = try { - metadataParser.readValue( + mapper.readValue( ByteArrayInputStream(content.toByteArray(Charsets.UTF_8)), UserMetadata::class.java ) @@ -163,13 +148,6 @@ class MetadataEvent( companion object { const val kind = 0 - val gson = Gson() - - val metadataParser by lazy { - jacksonObjectMapper() - .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) - .readerFor(UserMetadata::class.java) - } fun create(contactMetaData: String, identities: List, pubKey: HexKey, privateKey: ByteArray?, createdAt: Long = TimeUtils.now()): MetadataEvent { val tags = mutableListOf>() diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/MuteListEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/MuteListEvent.kt similarity index 86% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/MuteListEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/MuteListEvent.kt index cdcd0b366..cc8eea424 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/MuteListEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/MuteListEvent.kt @@ -1,13 +1,14 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import android.util.Log import androidx.compose.runtime.Immutable -import com.google.gson.reflect.TypeToken -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.model.hexToByteArray -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils +import com.fasterxml.jackson.module.kotlin.readValue +import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.encoders.hexToByteArray +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.ATag +import com.vitorpamplona.quartz.encoders.HexKey @Immutable class MuteListEvent( @@ -41,7 +42,7 @@ class MuteListEvent( } privateTagsCache = try { - gson.fromJson(plainContent(privKey), object : TypeToken>>() {}.type) + plainContent(privKey)?.let { mapper.readValue>>(it) } } catch (e: Throwable) { Log.w("BookmarkList", "Error parsing the JSON ${e.message}") null @@ -85,7 +86,7 @@ class MuteListEvent( privAddresses?.forEach { privTags.add(listOf("a", it.toTag())) } - val msg = gson.toJson(privTags) + val msg = mapper.writeValueAsString(privTags) val content = CryptoUtils.encryptNIP04( msg, diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/NIP24Factory.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/NIP24Factory.kt similarity index 92% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/NIP24Factory.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/NIP24Factory.kt index d91627e10..cb7523351 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/NIP24Factory.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/NIP24Factory.kt @@ -1,8 +1,8 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.HexKey class NIP24Factory { fun createMsgNIP24( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/NNSEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/NNSEvent.kt similarity index 80% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/NNSEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/NNSEvent.kt index 37ed50f37..25a22e706 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/NNSEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/NNSEvent.kt @@ -1,10 +1,11 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils +import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.ATag +import com.vitorpamplona.quartz.encoders.HexKey @Immutable class NNSEvent( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/PeopleListEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/PeopleListEvent.kt similarity index 96% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/PeopleListEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/PeopleListEvent.kt index 45c4cc464..0e216c746 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/PeopleListEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/PeopleListEvent.kt @@ -1,10 +1,10 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils +import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.HexKey import kotlinx.collections.immutable.ImmutableSet import kotlinx.collections.immutable.persistentSetOf import kotlinx.collections.immutable.toImmutableSet diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/PinListEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/PinListEvent.kt similarity index 80% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/PinListEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/PinListEvent.kt index 990f51a10..fb33e998d 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/PinListEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/PinListEvent.kt @@ -1,10 +1,11 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils +import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.ATag +import com.vitorpamplona.quartz.encoders.HexKey @Immutable class PinListEvent( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/PollNoteEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/PollNoteEvent.kt similarity index 93% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/PollNoteEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/PollNoteEvent.kt index 5195df73e..4c926f1ba 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/PollNoteEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/PollNoteEvent.kt @@ -1,10 +1,11 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils +import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.ATag +import com.vitorpamplona.quartz.encoders.HexKey const val POLL_OPTION = "poll_option" const val VALUE_MAXIMUM = "value_maximum" diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/PrivateDmEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/PrivateDmEvent.kt similarity index 91% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/PrivateDmEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/PrivateDmEvent.kt index 3ca959e2c..5a0120ac4 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/PrivateDmEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/PrivateDmEvent.kt @@ -1,14 +1,13 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import android.util.Log import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.ChatroomKey -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils -import com.vitorpamplona.amethyst.service.HexValidator -import fr.acinq.secp256k1.Hex +import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.HexKey +import com.vitorpamplona.quartz.encoders.HexValidator +import com.vitorpamplona.quartz.encoders.Hex import kotlinx.collections.immutable.persistentSetOf @Immutable diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/ReactionEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/ReactionEvent.kt similarity index 93% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/ReactionEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/ReactionEvent.kt index 537fafc86..9f8ca146f 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/ReactionEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/ReactionEvent.kt @@ -1,10 +1,10 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils +import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.HexKey @Immutable class ReactionEvent( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/RecommendRelayEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/RecommendRelayEvent.kt similarity index 67% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/RecommendRelayEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/RecommendRelayEvent.kt index fb4130ac4..ec6dd23ed 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/RecommendRelayEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/RecommendRelayEvent.kt @@ -1,10 +1,10 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils +import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.HexKey import java.net.URI @Immutable @@ -14,15 +14,10 @@ class RecommendRelayEvent( createdAt: Long, tags: List>, content: String, - sig: HexKey, - val lenient: Boolean = false + sig: HexKey ) : Event(id, pubKey, createdAt, kind, tags, content, sig) { - fun relay() = if (lenient) { - URI.create(content.trim()) - } else { - URI.create(content) - } + fun relay() = URI.create(content.trim()) companion object { const val kind = 2 diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/RelayAuthEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/RelayAuthEvent.kt similarity index 81% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/RelayAuthEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/RelayAuthEvent.kt index d3586c426..a1675dd37 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/RelayAuthEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/RelayAuthEvent.kt @@ -1,10 +1,10 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils +import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.HexKey @Immutable class RelayAuthEvent( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/RelaySetEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/RelaySetEvent.kt similarity index 81% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/RelaySetEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/RelaySetEvent.kt index b286ce57a..555355b0e 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/RelaySetEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/RelaySetEvent.kt @@ -1,10 +1,11 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils +import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.ATag +import com.vitorpamplona.quartz.encoders.HexKey @Immutable class RelaySetEvent( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/ReportEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/ReportEvent.kt similarity index 92% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/ReportEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/ReportEvent.kt index d7931e8ba..6cdaf0ee9 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/ReportEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/ReportEvent.kt @@ -1,10 +1,10 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils +import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.HexKey @Immutable data class ReportedKey(val key: String, val reportType: ReportEvent.ReportType) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/RepostEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/RepostEvent.kt similarity index 85% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/RepostEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/RepostEvent.kt index 33697560e..5f9b542bd 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/RepostEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/RepostEvent.kt @@ -1,11 +1,10 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import androidx.compose.runtime.Immutable -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils -import com.vitorpamplona.amethyst.service.relays.Client +import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.HexKey @Immutable class RepostEvent( @@ -21,7 +20,7 @@ class RepostEvent( fun originalAuthor() = taggedUsers() fun containedPost() = try { - fromJson(content, Client.lenient) + fromJson(content) } catch (e: Exception) { null } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/SealedGossipEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/SealedGossipEvent.kt similarity index 77% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/SealedGossipEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/SealedGossipEvent.kt index 556404add..3bdf735d9 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/SealedGossipEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/SealedGossipEvent.kt @@ -1,16 +1,16 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import android.util.Log import androidx.compose.runtime.Immutable -import com.google.gson.annotations.SerializedName -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.model.hexToByteArray -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils -import com.vitorpamplona.amethyst.service.EncryptedInfo -import com.vitorpamplona.amethyst.service.Nip44Version -import com.vitorpamplona.amethyst.service.relays.Client +import com.fasterxml.jackson.annotation.JsonProperty +import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.encoders.hexToByteArray +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.crypto.Nip44Version +import com.vitorpamplona.quartz.crypto.decodeNIP44 +import com.vitorpamplona.quartz.crypto.encodeNIP44 +import com.vitorpamplona.quartz.encoders.HexKey @Immutable class SealedGossipEvent( @@ -35,17 +35,17 @@ class SealedGossipEvent( } fun unseal(privKey: ByteArray): Gossip? = try { - plainContent(privKey)?.let { gson.fromJson(it, Gossip::class.java) } + plainContent(privKey)?.let { Gossip.fromJson(it) } } catch (e: Exception) { Log.w("GossipEvent", "Fail to decrypt or parse Gossip", e) null } private fun plainContent(privKey: ByteArray): String? { - if (content.isBlank()) return null + if (content.isEmpty()) return null return try { - val toDecrypt = gson.fromJson(content, EncryptedInfo::class.java) + val toDecrypt = decodeNIP44(content) ?: return null return when (toDecrypt.v) { Nip44Version.NIP04.versionCode -> CryptoUtils.decryptNIP04(toDecrypt, privKey, pubKey.hexToByteArray()) @@ -79,9 +79,9 @@ class SealedGossipEvent( ): SealedGossipEvent { val sharedSecret = CryptoUtils.getSharedSecretNIP24(privateKey, encryptTo.hexToByteArray()) - val content = gson.toJson( + val content = encodeNIP44( CryptoUtils.encryptNIP24( - gson.toJson(gossip), + Gossip.toJson(gossip), sharedSecret ) ) @@ -96,9 +96,9 @@ class SealedGossipEvent( class Gossip( val id: HexKey?, - @SerializedName("pubkey") + @JsonProperty("pubkey") val pubKey: HexKey?, - @SerializedName("created_at") + @JsonProperty("created_at") val createdAt: Long?, val kind: Int?, val tags: List>?, @@ -113,10 +113,13 @@ class Gossip( val newID = id?.ifBlank { null } ?: Event.generateId(newPubKey, newCreatedAt, newKind, newTags, newContent).toHexKey() val sig = "" - return EventFactory.create(newID, newPubKey, newCreatedAt, newKind, newTags, newContent, sig, Client.lenient) + return EventFactory.create(newID, newPubKey, newCreatedAt, newKind, newTags, newContent, sig) } companion object { + fun fromJson(json: String): Gossip = Event.mapper.readValue(json, Gossip::class.java) + fun toJson(event: Gossip): String = Event.mapper.writeValueAsString(event) + fun create(event: Event): Gossip { return Gossip(event.id, event.pubKey, event.createdAt, event.kind, event.tags, event.content) } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/TextNoteEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/TextNoteEvent.kt similarity index 91% rename from app/src/main/java/com/vitorpamplona/amethyst/service/model/TextNoteEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/events/TextNoteEvent.kt index b0074adf2..ef27bbe4c 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/TextNoteEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/TextNoteEvent.kt @@ -1,13 +1,13 @@ -package com.vitorpamplona.amethyst.service.model +package com.vitorpamplona.quartz.events import androidx.compose.runtime.Immutable import com.linkedin.urls.detection.UrlDetector import com.linkedin.urls.detection.UrlDetectorOptions -import com.vitorpamplona.amethyst.model.HexKey -import com.vitorpamplona.amethyst.model.TimeUtils -import com.vitorpamplona.amethyst.model.toHexKey -import com.vitorpamplona.amethyst.service.CryptoUtils -import com.vitorpamplona.amethyst.ui.screen.loggedIn.findHashtags +import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.ATag +import com.vitorpamplona.quartz.encoders.HexKey @Immutable class TextNoteEvent( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/TimeUtils.kt b/quartz/src/main/java/com/vitorpamplona/quartz/utils/TimeUtils.kt similarity index 86% rename from app/src/main/java/com/vitorpamplona/amethyst/model/TimeUtils.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/utils/TimeUtils.kt index 8098bdfcc..140355dd6 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/TimeUtils.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/utils/TimeUtils.kt @@ -1,6 +1,6 @@ -package com.vitorpamplona.amethyst.model +package com.vitorpamplona.quartz.utils -import com.vitorpamplona.amethyst.service.CryptoUtils +import com.vitorpamplona.quartz.crypto.CryptoUtils object TimeUtils { const val oneMinute = 60 @@ -16,6 +16,5 @@ object TimeUtils { fun oneDayAgo() = now() - oneDay fun eightHoursAgo() = now() - eightHours fun oneWeekAgo() = now() - oneWeek - fun randomWithinAWeek() = System.currentTimeMillis() / 1000 - CryptoUtils.randomInt(oneWeek) } diff --git a/app/src/test/java/com/vitorpamplona/amethyst/NIP19ParserTest.kt b/quartz/src/test/java/com/vitorpamplona/quartz/encoders/NIP19ParserTest.kt similarity index 93% rename from app/src/test/java/com/vitorpamplona/amethyst/NIP19ParserTest.kt rename to quartz/src/test/java/com/vitorpamplona/quartz/encoders/NIP19ParserTest.kt index 9c023a1c8..b4578acda 100644 --- a/app/src/test/java/com/vitorpamplona/amethyst/NIP19ParserTest.kt +++ b/quartz/src/test/java/com/vitorpamplona/quartz/encoders/NIP19ParserTest.kt @@ -1,7 +1,5 @@ -package com.vitorpamplona.amethyst +package com.vitorpamplona.quartz.encoders -import com.vitorpamplona.amethyst.service.model.ATag -import com.vitorpamplona.amethyst.service.nip19.Nip19 import org.junit.Assert.assertEquals import org.junit.Test @@ -38,19 +36,34 @@ class NIP19ParserTest { @Test fun nAddrFormatter() { - val address = ATag(30023, "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", "", null) + val address = ATag( + 30023, + "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", + "", + null + ) assertEquals("naddr1qqqqygzxpsj7dqha57pjk5k37gkn6g4nzakewtmqmnwryyhd3jfwlpgxtspsgqqqw4rs3xyxus", address.toNAddr()) } @Test fun nAddrFormatter2() { - val address = ATag(30023, "d0debf9fb12def81f43d7c69429bb784812ac1e4d2d53a202db6aac7ea4b466c", "guide-wireguard", null) + val address = ATag( + 30023, + "d0debf9fb12def81f43d7c69429bb784812ac1e4d2d53a202db6aac7ea4b466c", + "guide-wireguard", + null + ) assertEquals("naddr1qq8kwatfv3jj6amfwfjkwatpwfjqygxsm6lelvfda7qlg0tud9pfhduysy4vrexj65azqtdk4tr75j6xdspsgqqqw4rsg32ag8", address.toNAddr()) } @Test fun nAddrFormatter3() { - val address = ATag(30023, "d1e60465c2b777325e9133f2100d2bb31416dca810f54a1d95665621c5dee193", "89de7920", "wss://relay.damus.io") + val address = ATag( + 30023, + "d1e60465c2b777325e9133f2100d2bb31416dca810f54a1d95665621c5dee193", + "89de7920", + "wss://relay.damus.io" + ) assertEquals("naddr1qqyrswtyv5mnjv3sqy28wumn8ghj7un9d3shjtnyv9kh2uewd9hsygx3uczxts4hwue9ayfn7ggq62anzstde2qs749pm9tx2csuthhpjvpsgqqqw4rs8pmj38", address.toNAddr()) } diff --git a/app/src/test/java/com/vitorpamplona/amethyst/service/Nip19Test.kt b/quartz/src/test/java/com/vitorpamplona/quartz/encoders/Nip19Test.kt similarity index 95% rename from app/src/test/java/com/vitorpamplona/amethyst/service/Nip19Test.kt rename to quartz/src/test/java/com/vitorpamplona/quartz/encoders/Nip19Test.kt index 0c9c3aa0a..6e11ece4f 100644 --- a/app/src/test/java/com/vitorpamplona/amethyst/service/Nip19Test.kt +++ b/quartz/src/test/java/com/vitorpamplona/quartz/encoders/Nip19Test.kt @@ -1,6 +1,5 @@ -package com.vitorpamplona.amethyst.service +package com.vitorpamplona.quartz.encoders -import com.vitorpamplona.amethyst.service.nip19.Nip19 import org.junit.Assert import org.junit.Ignore import org.junit.Test diff --git a/app/src/test/java/com/vitorpamplona/amethyst/service/TlvIntegerTest.kt b/quartz/src/test/java/com/vitorpamplona/quartz/encoders/TlvIntegerTest.kt similarity index 51% rename from app/src/test/java/com/vitorpamplona/amethyst/service/TlvIntegerTest.kt rename to quartz/src/test/java/com/vitorpamplona/quartz/encoders/TlvIntegerTest.kt index cf847a33d..83037aa8b 100644 --- a/app/src/test/java/com/vitorpamplona/amethyst/service/TlvIntegerTest.kt +++ b/quartz/src/test/java/com/vitorpamplona/quartz/encoders/TlvIntegerTest.kt @@ -1,7 +1,5 @@ -package com.vitorpamplona.amethyst.service +package com.vitorpamplona.quartz.encoders -import com.vitorpamplona.amethyst.service.nip19.toByteArray -import com.vitorpamplona.amethyst.service.nip19.toInt32 import org.junit.Assert import org.junit.Assert.assertEquals import org.junit.Test @@ -24,15 +22,15 @@ class TlvIntegerTest { @Test() fun backAndForth() { - assertEquals(234, 234.toByteArray().toInt32()) - assertEquals(1, 1.toByteArray().toInt32()) - assertEquals(0, 0.toByteArray().toInt32()) - assertEquals(1000, 1000.toByteArray().toInt32()) + assertEquals(234, 234.to32BitByteArray().toInt32()) + assertEquals(1, 1.to32BitByteArray().toInt32()) + assertEquals(0, 0.to32BitByteArray().toInt32()) + assertEquals(1000, 1000.to32BitByteArray().toInt32()) - assertEquals(-234, (-234).toByteArray().toInt32()) - assertEquals(-1, (-1).toByteArray().toInt32()) - assertEquals(-0, (-0).toByteArray().toInt32()) - assertEquals(-1000, (-1000).toByteArray().toInt32()) + assertEquals(-234, (-234).to32BitByteArray().toInt32()) + assertEquals(-1, (-1).to32BitByteArray().toInt32()) + assertEquals(-0, (-0).to32BitByteArray().toInt32()) + assertEquals(-1000, (-1000).to32BitByteArray().toInt32()) } private fun byteArrayOfInts(vararg ints: Int) = diff --git a/settings.gradle b/settings.gradle index a62027f5d..017aa10c6 100644 --- a/settings.gradle +++ b/settings.gradle @@ -16,3 +16,5 @@ dependencyResolutionManagement { } rootProject.name = "Amethyst" include ':app' +include ':benchmark' +include ':quartz'