diff --git a/amethyst/proguard-rules.pro b/amethyst/proguard-rules.pro index fc7d6cf0f..7790abd2b 100644 --- a/amethyst/proguard-rules.pro +++ b/amethyst/proguard-rules.pro @@ -58,9 +58,7 @@ } # JSON parsing --keep class com.vitorpamplona.quartz.crypto.** { *; } --keep class com.vitorpamplona.quartz.encoders.** { *; } --keep class com.vitorpamplona.quartz.events.** { *; } +-keep class com.vitorpamplona.quartz.** { *; } -keep class com.vitorpamplona.amethyst.model.** { *; } -keep class com.vitorpamplona.amethyst.service.** { *; } -keep class com.vitorpamplona.ammolite.service.** { *; } diff --git a/amethyst/src/androidTest/java/com/vitorpamplona/amethyst/ImageUploadTesting.kt b/amethyst/src/androidTest/java/com/vitorpamplona/amethyst/ImageUploadTesting.kt index 90f60eef8..1a5584eeb 100644 --- a/amethyst/src/androidTest/java/com/vitorpamplona/amethyst/ImageUploadTesting.kt +++ b/amethyst/src/androidTest/java/com/vitorpamplona/amethyst/ImageUploadTesting.kt @@ -36,7 +36,7 @@ import com.vitorpamplona.amethyst.ui.actions.mediaServers.ServerName import com.vitorpamplona.amethyst.ui.actions.mediaServers.ServerType import com.vitorpamplona.quartz.crypto.CryptoUtils import com.vitorpamplona.quartz.crypto.KeyPair -import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.nip01Core.toHexKey import junit.framework.TestCase.assertEquals import junit.framework.TestCase.fail import kotlinx.coroutines.CoroutineScope diff --git a/amethyst/src/androidTest/java/com/vitorpamplona/amethyst/OkHttpOtsTest.kt b/amethyst/src/androidTest/java/com/vitorpamplona/amethyst/OkHttpOtsTest.kt index b7dee3a7e..de46bb8dc 100644 --- a/amethyst/src/androidTest/java/com/vitorpamplona/amethyst/OkHttpOtsTest.kt +++ b/amethyst/src/androidTest/java/com/vitorpamplona/amethyst/OkHttpOtsTest.kt @@ -24,10 +24,10 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import com.vitorpamplona.amethyst.service.ots.OkHttpBlockstreamExplorer import com.vitorpamplona.amethyst.service.ots.OkHttpCalendarBuilder import com.vitorpamplona.quartz.crypto.KeyPair -import com.vitorpamplona.quartz.events.Event -import com.vitorpamplona.quartz.events.OtsEvent -import com.vitorpamplona.quartz.ots.OpenTimestamps -import com.vitorpamplona.quartz.signers.NostrSignerInternal +import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper +import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerInternal +import com.vitorpamplona.quartz.nip03Timestamp.OtsEvent +import com.vitorpamplona.quartz.nip03Timestamp.ots.OpenTimestamps import junit.framework.TestCase.assertEquals import org.junit.Assert import org.junit.Before @@ -51,21 +51,21 @@ class OkHttpOtsTest { @Test fun verifyNostrEvent() { - val ots = Event.fromJson(otsEvent) as OtsEvent + val ots = EventMapper.fromJson(otsEvent) as OtsEvent println(ots.info()) assertEquals(1707688818L, ots.verify()) } @Test fun verifyNostrEvent2() { - val ots = Event.fromJson(otsEvent2) as OtsEvent + val ots = EventMapper.fromJson(otsEvent2) as OtsEvent println(ots.info()) assertEquals(1706322179L, ots.verify()) } @Test fun verifyNostrPendingEvent() { - val ots = Event.fromJson(otsPendingEvent) as OtsEvent + val ots = EventMapper.fromJson(otsPendingEvent) as OtsEvent println(ots.info()) assertEquals(null, ots.verify()) } diff --git a/amethyst/src/androidTest/java/com/vitorpamplona/amethyst/ThreadAssemblerTest.kt b/amethyst/src/androidTest/java/com/vitorpamplona/amethyst/ThreadAssemblerTest.kt index acfb6bedf..29dab71cd 100644 --- a/amethyst/src/androidTest/java/com/vitorpamplona/amethyst/ThreadAssemblerTest.kt +++ b/amethyst/src/androidTest/java/com/vitorpamplona/amethyst/ThreadAssemblerTest.kt @@ -27,8 +27,10 @@ import com.vitorpamplona.amethyst.model.AccountSettings import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.ui.dal.ThreadFeedFilter import com.vitorpamplona.quartz.crypto.KeyPair -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.hasValidSignature +import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper import junit.framework.TestCase import junit.framework.TestCase.assertEquals import kotlinx.coroutines.CoroutineScope @@ -119,7 +121,7 @@ class ThreadAssemblerTest { fun threadOrderTest() = runBlocking { val eventArray = - Event.mapper.readValue>(db) as List + Event.fromJson(header) + EventMapper.mapper.readValue>(db) as List + Event.fromJson(header) var counter = 0 eventArray.forEach { diff --git a/amethyst/src/androidTest/java/com/vitorpamplona/amethyst/UrlUserTagTransformationTest.kt b/amethyst/src/androidTest/java/com/vitorpamplona/amethyst/UrlUserTagTransformationTest.kt index 7616ecabd..10374ac1d 100644 --- a/amethyst/src/androidTest/java/com/vitorpamplona/amethyst/UrlUserTagTransformationTest.kt +++ b/amethyst/src/androidTest/java/com/vitorpamplona/amethyst/UrlUserTagTransformationTest.kt @@ -27,9 +27,9 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.platform.app.InstrumentationRegistry import com.vitorpamplona.amethyst.model.LocalCache 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 com.vitorpamplona.quartz.nip01Core.UserMetadata +import com.vitorpamplona.quartz.nip01Core.toHexKey +import com.vitorpamplona.quartz.nip19Bech32Entities.decodePublicKey import org.junit.Assert.assertEquals import org.junit.Test import org.junit.runner.RunWith diff --git a/amethyst/src/fdroid/java/com/vitorpamplona/amethyst/service/notifications/PushMessageReceiver.kt b/amethyst/src/fdroid/java/com/vitorpamplona/amethyst/service/notifications/PushMessageReceiver.kt index 75f79ad84..01092dcf1 100644 --- a/amethyst/src/fdroid/java/com/vitorpamplona/amethyst/service/notifications/PushMessageReceiver.kt +++ b/amethyst/src/fdroid/java/com/vitorpamplona/amethyst/service/notifications/PushMessageReceiver.kt @@ -29,8 +29,8 @@ import com.vitorpamplona.amethyst.Amethyst import com.vitorpamplona.amethyst.LocalPreferences import com.vitorpamplona.amethyst.service.notifications.NotificationUtils.getOrCreateDMChannel import com.vitorpamplona.amethyst.service.notifications.NotificationUtils.getOrCreateZapChannel -import com.vitorpamplona.quartz.events.Event -import com.vitorpamplona.quartz.events.GiftWrapEvent +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip59Giftwrap.GiftWrapEvent import kotlinx.coroutines.CancellationException import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch diff --git a/amethyst/src/fdroid/java/com/vitorpamplona/amethyst/ui/components/TranslatableRichTextViewer.kt b/amethyst/src/fdroid/java/com/vitorpamplona/amethyst/ui/components/TranslatableRichTextViewer.kt index a434d1afb..387368c5c 100644 --- a/amethyst/src/fdroid/java/com/vitorpamplona/amethyst/ui/components/TranslatableRichTextViewer.kt +++ b/amethyst/src/fdroid/java/com/vitorpamplona/amethyst/ui/components/TranslatableRichTextViewer.kt @@ -26,7 +26,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import com.vitorpamplona.amethyst.ui.navigation.INav import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel -import com.vitorpamplona.quartz.events.ImmutableListOfLists +import com.vitorpamplona.quartz.nip02FollowList.ImmutableListOfLists @Composable fun TranslatableRichTextViewer( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/DebugUtils.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/DebugUtils.kt index 0c63f8b20..e075cb8e6 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/DebugUtils.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/DebugUtils.kt @@ -157,15 +157,15 @@ fun debugState(context: Context) { " MB", ) - val qttNotes = LocalCache.notes.countByGroup { _, it -> it.event?.kind() } - val qttAddressables = LocalCache.addressables.countByGroup { _, it -> it.event?.kind() } + val qttNotes = LocalCache.notes.countByGroup { _, it -> it.event?.kind } + val qttAddressables = LocalCache.addressables.countByGroup { _, it -> it.event?.kind } val bytesNotes = LocalCache.notes - .sumByGroup(groupMap = { _, it -> it.event?.kind() }, sumOf = { _, it -> it.event?.countMemory() ?: 0L }) + .sumByGroup(groupMap = { _, it -> it.event?.kind }, sumOf = { _, it -> it.event?.countMemory() ?: 0L }) val bytesAddressables = LocalCache.addressables - .sumByGroup(groupMap = { _, it -> it.event?.kind() }, sumOf = { _, it -> it.event?.countMemory() ?: 0L }) + .sumByGroup(groupMap = { _, it -> it.event?.kind }, sumOf = { _, it -> it.event?.countMemory() ?: 0L }) qttNotes.toList().sortedByDescending { bytesNotes.get(it.first) }.forEach { (kind, qtt) -> Log.d("STATE DUMP", "Kind ${kind.toString().padStart(5,' ')}:\t${qtt.toString().padStart(6,' ')} elements\t${bytesNotes.get(kind)?.div((1024 * 1024))}MB ") diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt index 7413c1a4b..49a689101 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt @@ -45,21 +45,22 @@ import com.vitorpamplona.amethyst.ui.tor.TorSettingsFlow import com.vitorpamplona.amethyst.ui.tor.TorType import com.vitorpamplona.ammolite.relays.RelaySetupInfo import com.vitorpamplona.quartz.crypto.KeyPair -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.Nip47WalletConnect -import com.vitorpamplona.quartz.encoders.hexToByteArray -import com.vitorpamplona.quartz.encoders.toHexKey -import com.vitorpamplona.quartz.encoders.toNpub -import com.vitorpamplona.quartz.events.AdvertisedRelayListEvent -import com.vitorpamplona.quartz.events.AppSpecificDataEvent -import com.vitorpamplona.quartz.events.ChatMessageRelayListEvent -import com.vitorpamplona.quartz.events.ContactListEvent -import com.vitorpamplona.quartz.events.Event -import com.vitorpamplona.quartz.events.LnZapEvent -import com.vitorpamplona.quartz.events.MetadataEvent -import com.vitorpamplona.quartz.events.MuteListEvent -import com.vitorpamplona.quartz.events.PrivateOutboxRelayListEvent -import com.vitorpamplona.quartz.events.SearchRelayListEvent +import com.vitorpamplona.quartz.experimental.edits.PrivateOutboxRelayListEvent +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.MetadataEvent +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.hexToByteArray +import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper +import com.vitorpamplona.quartz.nip01Core.toHexKey +import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent +import com.vitorpamplona.quartz.nip17Dm.ChatMessageRelayListEvent +import com.vitorpamplona.quartz.nip19Bech32Entities.toNpub +import com.vitorpamplona.quartz.nip47WalletConnect.Nip47WalletConnect +import com.vitorpamplona.quartz.nip50Search.SearchRelayListEvent +import com.vitorpamplona.quartz.nip51Lists.MuteListEvent +import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent +import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent +import com.vitorpamplona.quartz.nip78AppData.AppSpecificDataEvent import kotlinx.coroutines.CancellationException import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow @@ -168,7 +169,7 @@ object LocalPreferences { with(encryptedPreferences()) { val newSystemOfAccounts = getString(PrefKeys.ALL_ACCOUNT_INFO, "[]")?.let { - Event.mapper.readValue>(it) + EventMapper.mapper.readValue>(it) } if (!newSystemOfAccounts.isNullOrEmpty()) { @@ -188,7 +189,7 @@ object LocalPreferences { savedAccounts.emit(migrated) - edit().apply { putString(PrefKeys.ALL_ACCOUNT_INFO, Event.mapper.writeValueAsString(savedAccounts.value)) }.apply() + edit().apply { putString(PrefKeys.ALL_ACCOUNT_INFO, EventMapper.mapper.writeValueAsString(savedAccounts.value)) }.apply() } } } @@ -209,7 +210,7 @@ object LocalPreferences { .apply { putString( PrefKeys.ALL_ACCOUNT_INFO, - Event.mapper.writeValueAsString(accounts.filter { !it.isTransient }), + EventMapper.mapper.writeValueAsString(accounts.filter { !it.isTransient }), ) }.apply() } @@ -315,11 +316,11 @@ object LocalPreferences { settings.keyPair.privKey?.let { putString(PrefKeys.NOSTR_PRIVKEY, it.toHexKey()) } } settings.keyPair.pubKey.let { putString(PrefKeys.NOSTR_PUBKEY, it.toHexKey()) } - putString(PrefKeys.RELAYS, Event.mapper.writeValueAsString(settings.localRelays)) + putString(PrefKeys.RELAYS, EventMapper.mapper.writeValueAsString(settings.localRelays)) putString( PrefKeys.DEFAULT_FILE_SERVER, - Event.mapper.writeValueAsString(settings.defaultFileServer), + EventMapper.mapper.writeValueAsString(settings.defaultFileServer), ) putString(PrefKeys.DEFAULT_HOME_FOLLOW_LIST, settings.defaultHomeFollowList.value) putString(PrefKeys.DEFAULT_STORIES_FOLLOW_LIST, settings.defaultStoriesFollowList.value) @@ -333,12 +334,12 @@ object LocalPreferences { ) putString( PrefKeys.ZAP_PAYMENT_REQUEST_SERVER, - Event.mapper.writeValueAsString(settings.zapPaymentRequest), + EventMapper.mapper.writeValueAsString(settings.zapPaymentRequest), ) if (settings.backupContactList != null) { putString( PrefKeys.LATEST_CONTACT_LIST, - Event.mapper.writeValueAsString(settings.backupContactList), + EventMapper.mapper.writeValueAsString(settings.backupContactList), ) } else { remove(PrefKeys.LATEST_CONTACT_LIST) @@ -347,7 +348,7 @@ object LocalPreferences { if (settings.backupUserMetadata != null) { putString( PrefKeys.LATEST_USER_METADATA, - Event.mapper.writeValueAsString(settings.backupUserMetadata), + EventMapper.mapper.writeValueAsString(settings.backupUserMetadata), ) } else { remove(PrefKeys.LATEST_USER_METADATA) @@ -356,7 +357,7 @@ object LocalPreferences { if (settings.backupDMRelayList != null) { putString( PrefKeys.LATEST_DM_RELAY_LIST, - Event.mapper.writeValueAsString(settings.backupDMRelayList), + EventMapper.mapper.writeValueAsString(settings.backupDMRelayList), ) } else { remove(PrefKeys.LATEST_DM_RELAY_LIST) @@ -365,7 +366,7 @@ object LocalPreferences { if (settings.backupNIP65RelayList != null) { putString( PrefKeys.LATEST_NIP65_RELAY_LIST, - Event.mapper.writeValueAsString(settings.backupNIP65RelayList), + EventMapper.mapper.writeValueAsString(settings.backupNIP65RelayList), ) } else { remove(PrefKeys.LATEST_NIP65_RELAY_LIST) @@ -374,7 +375,7 @@ object LocalPreferences { if (settings.backupSearchRelayList != null) { putString( PrefKeys.LATEST_SEARCH_RELAY_LIST, - Event.mapper.writeValueAsString(settings.backupSearchRelayList), + EventMapper.mapper.writeValueAsString(settings.backupSearchRelayList), ) } else { remove(PrefKeys.LATEST_SEARCH_RELAY_LIST) @@ -389,7 +390,7 @@ object LocalPreferences { if (settings.backupMuteList != null) { putString( PrefKeys.LATEST_MUTE_LIST, - Event.mapper.writeValueAsString(settings.backupMuteList), + EventMapper.mapper.writeValueAsString(settings.backupMuteList), ) } else { remove(PrefKeys.LATEST_MUTE_LIST) @@ -398,7 +399,7 @@ object LocalPreferences { if (settings.backupPrivateHomeRelayList != null) { putString( PrefKeys.LATEST_PRIVATE_HOME_RELAY_LIST, - Event.mapper.writeValueAsString(settings.backupPrivateHomeRelayList), + EventMapper.mapper.writeValueAsString(settings.backupPrivateHomeRelayList), ) } else { remove(PrefKeys.LATEST_PRIVATE_HOME_RELAY_LIST) @@ -407,7 +408,7 @@ object LocalPreferences { if (settings.backupAppSpecificData != null) { putString( PrefKeys.LATEST_APP_SPECIFIC_DATA, - Event.mapper.writeValueAsString(settings.backupAppSpecificData), + EventMapper.mapper.writeValueAsString(settings.backupAppSpecificData), ) } else { remove(PrefKeys.LATEST_APP_SPECIFIC_DATA) @@ -421,7 +422,7 @@ object LocalPreferences { remove(PrefKeys.USE_PROXY) remove(PrefKeys.PROXY_PORT) - putString(PrefKeys.TOR_SETTINGS, Event.mapper.writeValueAsString(settings.torSettings.toSettings())) + putString(PrefKeys.TOR_SETTINGS, EventMapper.mapper.writeValueAsString(settings.torSettings.toSettings())) val regularMap = settings.lastReadPerRoute.value.mapValues { @@ -430,13 +431,13 @@ object LocalPreferences { putString( PrefKeys.LAST_READ_PER_ROUTE, - Event.mapper.writeValueAsString(regularMap), + EventMapper.mapper.writeValueAsString(regularMap), ) putStringSet(PrefKeys.HAS_DONATED_IN_VERSION, settings.hasDonatedInVersion.value) putString( PrefKeys.PENDING_ATTESTATIONS, - Event.mapper.writeValueAsString(settings.pendingAttestations.value), + EventMapper.mapper.writeValueAsString(settings.pendingAttestations.value), ) }.apply() } @@ -452,7 +453,7 @@ object LocalPreferences { ) { Log.d("LocalPreferences", "Saving to shared settings") with(prefs.edit()) { - putString(PrefKeys.SHARED_SETTINGS, Event.mapper.writeValueAsString(sharedSettings)) + putString(PrefKeys.SHARED_SETTINGS, EventMapper.mapper.writeValueAsString(sharedSettings)) apply() } } @@ -461,7 +462,7 @@ object LocalPreferences { Log.d("LocalPreferences", "Load shared settings") with(prefs) { return try { - getString(PrefKeys.SHARED_SETTINGS, "{}")?.let { Event.mapper.readValue(it) } + getString(PrefKeys.SHARED_SETTINGS, "{}")?.let { EventMapper.mapper.readValue(it) } } catch (e: Throwable) { if (e is CancellationException) throw e Log.w( @@ -666,7 +667,7 @@ object LocalPreferences { if (T::class.java.isInstance(Event::class.java)) { Event.fromJson(value) as T? } else { - Event.mapper.readValue(value) + EventMapper.mapper.readValue(value) } } catch (e: Throwable) { if (e is CancellationException) throw e diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ServiceManager.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ServiceManager.kt index 707b4089f..27b4ff455 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ServiceManager.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ServiceManager.kt @@ -57,11 +57,11 @@ import com.vitorpamplona.amethyst.service.ots.OkHttpCalendarBuilder import com.vitorpamplona.amethyst.ui.tor.TorManager import com.vitorpamplona.amethyst.ui.tor.TorType import com.vitorpamplona.ammolite.relays.NostrClient -import com.vitorpamplona.quartz.encoders.bechToBytes -import com.vitorpamplona.quartz.encoders.decodePublicKeyAsHexOrNull -import com.vitorpamplona.quartz.encoders.toHexKey -import com.vitorpamplona.quartz.events.OtsEvent -import com.vitorpamplona.quartz.ots.OpenTimestamps +import com.vitorpamplona.quartz.nip01Core.toHexKey +import com.vitorpamplona.quartz.nip03Timestamp.OtsEvent +import com.vitorpamplona.quartz.nip03Timestamp.ots.OpenTimestamps +import com.vitorpamplona.quartz.nip19Bech32Entities.bech32.bechToBytes +import com.vitorpamplona.quartz.nip19Bech32Entities.decodePublicKeyAsHexOrNull import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -116,7 +116,11 @@ class ServiceManager( OkHttpCalendarBuilder(myAccount::shouldUseTorForMoneyOperations), ) } else { - OtsEvent.otsInstance = OpenTimestamps(OkHttpBlockstreamExplorer { false }, OkHttpCalendarBuilder { false }) + OtsEvent.otsInstance = + OpenTimestamps( + OkHttpBlockstreamExplorer { false }, + OkHttpCalendarBuilder { false }, + ) HttpClientManager.setDefaultProxy(null) } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt index 85fac791a..96dc6f1a1 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt @@ -50,87 +50,94 @@ import com.vitorpamplona.ammolite.relays.RelaySetupInfo import com.vitorpamplona.ammolite.relays.RelaySetupInfoToConnect import com.vitorpamplona.ammolite.relays.TypedFilter import com.vitorpamplona.ammolite.relays.filters.SincePerRelayFilter +import com.vitorpamplona.quartz.blossom.BlossomAuthorizationEvent +import com.vitorpamplona.quartz.blossom.BlossomServersEvent import com.vitorpamplona.quartz.crypto.KeyPair -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.Dimension -import com.vitorpamplona.quartz.encoders.ETag -import com.vitorpamplona.quartz.encoders.EventHint -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.IMetaTag -import com.vitorpamplona.quartz.encoders.Nip47WalletConnect -import com.vitorpamplona.quartz.encoders.PTag -import com.vitorpamplona.quartz.encoders.RelayUrlFormatter -import com.vitorpamplona.quartz.encoders.hexToByteArray -import com.vitorpamplona.quartz.events.AdvertisedRelayListEvent -import com.vitorpamplona.quartz.events.AppSpecificDataEvent -import com.vitorpamplona.quartz.events.BlossomAuthorizationEvent -import com.vitorpamplona.quartz.events.BlossomServersEvent -import com.vitorpamplona.quartz.events.BookmarkListEvent -import com.vitorpamplona.quartz.events.ChannelCreateEvent -import com.vitorpamplona.quartz.events.ChannelMessageEvent -import com.vitorpamplona.quartz.events.ChannelMetadataEvent -import com.vitorpamplona.quartz.events.ChatMessageRelayListEvent -import com.vitorpamplona.quartz.events.ClassifiedsEvent -import com.vitorpamplona.quartz.events.CommentEvent -import com.vitorpamplona.quartz.events.Contact -import com.vitorpamplona.quartz.events.ContactListEvent -import com.vitorpamplona.quartz.events.DeletionEvent -import com.vitorpamplona.quartz.events.DraftEvent -import com.vitorpamplona.quartz.events.EmojiPackEvent -import com.vitorpamplona.quartz.events.EmojiPackSelectionEvent -import com.vitorpamplona.quartz.events.EmojiUrl -import com.vitorpamplona.quartz.events.Event -import com.vitorpamplona.quartz.events.EventInterface -import com.vitorpamplona.quartz.events.FileHeaderEvent -import com.vitorpamplona.quartz.events.FileServersEvent -import com.vitorpamplona.quartz.events.FileStorageEvent -import com.vitorpamplona.quartz.events.FileStorageHeaderEvent -import com.vitorpamplona.quartz.events.GeneralListEvent -import com.vitorpamplona.quartz.events.GenericRepostEvent -import com.vitorpamplona.quartz.events.GiftWrapEvent -import com.vitorpamplona.quartz.events.GitReplyEvent -import com.vitorpamplona.quartz.events.HTTPAuthorizationEvent -import com.vitorpamplona.quartz.events.InteractiveStoryBaseEvent -import com.vitorpamplona.quartz.events.InteractiveStoryPrologueEvent -import com.vitorpamplona.quartz.events.InteractiveStoryReadingStateEvent -import com.vitorpamplona.quartz.events.InteractiveStorySceneEvent -import com.vitorpamplona.quartz.events.LiveActivitiesChatMessageEvent -import com.vitorpamplona.quartz.events.LnZapEvent -import com.vitorpamplona.quartz.events.LnZapPaymentRequestEvent -import com.vitorpamplona.quartz.events.LnZapPaymentResponseEvent -import com.vitorpamplona.quartz.events.LnZapRequestEvent -import com.vitorpamplona.quartz.events.MetadataEvent -import com.vitorpamplona.quartz.events.MuteListEvent -import com.vitorpamplona.quartz.events.NIP17Factory -import com.vitorpamplona.quartz.events.NIP17Group -import com.vitorpamplona.quartz.events.NIP90ContentDiscoveryRequestEvent -import com.vitorpamplona.quartz.events.OtsEvent -import com.vitorpamplona.quartz.events.PeopleListEvent -import com.vitorpamplona.quartz.events.PictureEvent -import com.vitorpamplona.quartz.events.PictureMeta -import com.vitorpamplona.quartz.events.PollNoteEvent -import com.vitorpamplona.quartz.events.Price -import com.vitorpamplona.quartz.events.PrivateDmEvent -import com.vitorpamplona.quartz.events.PrivateOutboxRelayListEvent -import com.vitorpamplona.quartz.events.ProfileGalleryEntryEvent -import com.vitorpamplona.quartz.events.ReactionEvent -import com.vitorpamplona.quartz.events.RelayAuthEvent -import com.vitorpamplona.quartz.events.ReportEvent -import com.vitorpamplona.quartz.events.RepostEvent -import com.vitorpamplona.quartz.events.Response -import com.vitorpamplona.quartz.events.SealedGossipEvent -import com.vitorpamplona.quartz.events.SearchRelayListEvent -import com.vitorpamplona.quartz.events.StatusEvent -import com.vitorpamplona.quartz.events.StoryOption -import com.vitorpamplona.quartz.events.TextNoteEvent -import com.vitorpamplona.quartz.events.TextNoteModificationEvent -import com.vitorpamplona.quartz.events.TorrentCommentEvent -import com.vitorpamplona.quartz.events.VideoHorizontalEvent -import com.vitorpamplona.quartz.events.VideoVerticalEvent -import com.vitorpamplona.quartz.events.WrappedEvent -import com.vitorpamplona.quartz.events.ZapSplitSetup -import com.vitorpamplona.quartz.signers.NostrSigner -import com.vitorpamplona.quartz.signers.NostrSignerInternal +import com.vitorpamplona.quartz.experimental.edits.PrivateOutboxRelayListEvent +import com.vitorpamplona.quartz.experimental.edits.TextNoteModificationEvent +import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStoryBaseEvent +import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStoryPrologueEvent +import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStoryReadingStateEvent +import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStorySceneEvent +import com.vitorpamplona.quartz.experimental.interactiveStories.StoryOption +import com.vitorpamplona.quartz.experimental.nip95.FileStorageEvent +import com.vitorpamplona.quartz.experimental.nip95.FileStorageHeaderEvent +import com.vitorpamplona.quartz.experimental.profileGallery.ProfileGalleryEntryEvent +import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent +import com.vitorpamplona.quartz.nip01Core.EventHint +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.MetadataEvent +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.addressables.taggedAddresses +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.events.taggedEvents +import com.vitorpamplona.quartz.nip01Core.geohash.geohashes +import com.vitorpamplona.quartz.nip01Core.hashtags.hashtags +import com.vitorpamplona.quartz.nip01Core.hexToByteArray +import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper +import com.vitorpamplona.quartz.nip01Core.people.hasAnyTaggedUser +import com.vitorpamplona.quartz.nip01Core.people.isTaggedUser +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerInternal +import com.vitorpamplona.quartz.nip02FollowList.Contact +import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent +import com.vitorpamplona.quartz.nip03Timestamp.OtsEvent +import com.vitorpamplona.quartz.nip04Dm.PrivateDmEvent +import com.vitorpamplona.quartz.nip09Deletions.DeletionEvent +import com.vitorpamplona.quartz.nip10Notes.ETag +import com.vitorpamplona.quartz.nip10Notes.PTag +import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent +import com.vitorpamplona.quartz.nip17Dm.ChatMessageRelayListEvent +import com.vitorpamplona.quartz.nip17Dm.NIP17Factory +import com.vitorpamplona.quartz.nip17Dm.NIP17Group +import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent +import com.vitorpamplona.quartz.nip18Reposts.RepostEvent +import com.vitorpamplona.quartz.nip22Comments.CommentEvent +import com.vitorpamplona.quartz.nip25Reactions.ReactionEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelCreateEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelMessageEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelMetadataEvent +import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiPackEvent +import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiPackSelectionEvent +import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiUrl +import com.vitorpamplona.quartz.nip30CustomEmoji.taggedEmojis +import com.vitorpamplona.quartz.nip34Git.GitReplyEvent +import com.vitorpamplona.quartz.nip35Torrents.TorrentCommentEvent +import com.vitorpamplona.quartz.nip37Drafts.DraftEvent +import com.vitorpamplona.quartz.nip38UserStatus.StatusEvent +import com.vitorpamplona.quartz.nip42RelayAuth.RelayAuthEvent +import com.vitorpamplona.quartz.nip47WalletConnect.LnZapPaymentRequestEvent +import com.vitorpamplona.quartz.nip47WalletConnect.LnZapPaymentResponseEvent +import com.vitorpamplona.quartz.nip47WalletConnect.Nip47WalletConnect +import com.vitorpamplona.quartz.nip47WalletConnect.Response +import com.vitorpamplona.quartz.nip50Search.SearchRelayListEvent +import com.vitorpamplona.quartz.nip51Lists.BookmarkListEvent +import com.vitorpamplona.quartz.nip51Lists.GeneralListEvent +import com.vitorpamplona.quartz.nip51Lists.MuteListEvent +import com.vitorpamplona.quartz.nip51Lists.PeopleListEvent +import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesChatMessageEvent +import com.vitorpamplona.quartz.nip56Reports.ReportEvent +import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent +import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent +import com.vitorpamplona.quartz.nip57Zaps.ZapSplitSetup +import com.vitorpamplona.quartz.nip59Giftwrap.GiftWrapEvent +import com.vitorpamplona.quartz.nip59Giftwrap.SealedGossipEvent +import com.vitorpamplona.quartz.nip59Giftwrap.WrappedEvent +import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent +import com.vitorpamplona.quartz.nip65RelayList.RelayUrlFormatter +import com.vitorpamplona.quartz.nip68Picture.PictureEvent +import com.vitorpamplona.quartz.nip68Picture.PictureMeta +import com.vitorpamplona.quartz.nip71Video.VideoHorizontalEvent +import com.vitorpamplona.quartz.nip71Video.VideoVerticalEvent +import com.vitorpamplona.quartz.nip78AppData.AppSpecificDataEvent +import com.vitorpamplona.quartz.nip90Dvms.NIP90ContentDiscoveryRequestEvent +import com.vitorpamplona.quartz.nip92IMeta.IMetaTag +import com.vitorpamplona.quartz.nip94FileMetadata.Dimension +import com.vitorpamplona.quartz.nip94FileMetadata.FileHeaderEvent +import com.vitorpamplona.quartz.nip96FileStorage.FileServersEvent +import com.vitorpamplona.quartz.nip98HttpAuth.HTTPAuthorizationEvent +import com.vitorpamplona.quartz.nip99Classifieds.ClassifiedsEvent +import com.vitorpamplona.quartz.nip99Classifieds.Price import com.vitorpamplona.quartz.utils.DualCase import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.DelicateCoroutinesApi @@ -501,7 +508,7 @@ class Account( ?.toSet() ?: emptySet(), geotags = latestContactList - ?.unverifiedFollowGeohashSet() + ?.geohashes() ?.toSet() ?: emptySet(), addresses = latestContactList @@ -1230,7 +1237,7 @@ class Account( } private fun sendNewAppSpecificData(toInternal: AccountSyncedSettingsInternal) { - signer.nip44Encrypt(Event.mapper.writeValueAsString(toInternal), signer.pubKey) { encrypted -> + signer.nip44Encrypt(EventMapper.mapper.writeValueAsString(toInternal), signer.pubKey) { encrypted -> AppSpecificDataEvent.create( dTag = APP_SPECIFIC_DATA_D_TAG, description = encrypted, @@ -1650,7 +1657,7 @@ class Account( } note.event?.let { - if (it.kind() == 1) { + if (it.kind == 1) { RepostEvent.create(it, signer) { Amethyst.instance.client.send(it) LocalCache.justConsume(it, null) @@ -1709,7 +1716,7 @@ class Account( } fun hasPendingAttestations(note: Note): Boolean { - val id = note.event?.id() ?: note.idHex + val id = note.event?.id ?: note.idHex return settings.pendingAttestations.value[id] != null } @@ -1717,7 +1724,7 @@ class Account( if (!isWriteable()) return if (note.isDraft()) return - val id = note.event?.id() ?: note.idHex + val id = note.event?.id ?: note.idHex settings.addPendingAttestation(id, OtsEvent.stamp(id)) } @@ -2834,7 +2841,7 @@ class Account( ) { if (!isWriteable()) return - val idHex = originalNote.event?.id() ?: return + val idHex = originalNote.event?.id ?: return TextNoteModificationEvent.create( content = message, @@ -3746,7 +3753,7 @@ class Account( fun cachedDecryptContent(note: Note): String? = cachedDecryptContent(note.event) - fun cachedDecryptContent(event: EventInterface?): String? { + fun cachedDecryptContent(event: Event?): String? { if (event == null) return null return if (event is PrivateDmEvent && isWriteable()) { @@ -3754,7 +3761,7 @@ class Account( } else if (event is LnZapRequestEvent && event.isPrivateZap() && isWriteable()) { event.cachedPrivateZap()?.content } else { - event.content() + event.content } } @@ -3772,7 +3779,7 @@ class Account( onReady(it.content) } } else { - event?.content()?.let { onReady(it) } + event?.content?.let { onReady(it) } } } @@ -4315,7 +4322,7 @@ class Account( LocalCache.verifyAndConsume(event, null) signer.decrypt(event.content, event.pubKey) { decrypted -> try { - val syncedSettings = Event.mapper.readValue(decrypted) + val syncedSettings = EventMapper.mapper.readValue(decrypted) settings.syncedSettings.updateFrom(syncedSettings) } catch (e: Throwable) { if (e is CancellationException) throw e @@ -4408,7 +4415,7 @@ class Account( signer.decrypt(it.content, it.pubKey) { decrypted -> val syncedSettings = try { - Event.mapper.readValue(decrypted) + EventMapper.mapper.readValue(decrypted) } catch (e: Throwable) { if (e is CancellationException) throw e Log.w("LocalPreferences", "Error Decoding latestAppSpecificData from Preferences with value $decrypted", e) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/AccountSettings.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/AccountSettings.kt index ebc5044c1..753462920 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/AccountSettings.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/AccountSettings.kt @@ -30,22 +30,22 @@ import com.vitorpamplona.amethyst.ui.tor.TorSettingsFlow import com.vitorpamplona.ammolite.relays.Constants import com.vitorpamplona.ammolite.relays.RelaySetupInfo import com.vitorpamplona.quartz.crypto.KeyPair -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.Nip47WalletConnect -import com.vitorpamplona.quartz.encoders.RelayUrlFormatter -import com.vitorpamplona.quartz.encoders.toHexKey -import com.vitorpamplona.quartz.events.AdvertisedRelayListEvent -import com.vitorpamplona.quartz.events.AppSpecificDataEvent -import com.vitorpamplona.quartz.events.ChatMessageRelayListEvent -import com.vitorpamplona.quartz.events.ContactListEvent -import com.vitorpamplona.quartz.events.LnZapEvent -import com.vitorpamplona.quartz.events.MetadataEvent -import com.vitorpamplona.quartz.events.MuteListEvent -import com.vitorpamplona.quartz.events.PrivateOutboxRelayListEvent -import com.vitorpamplona.quartz.events.SearchRelayListEvent -import com.vitorpamplona.quartz.signers.ExternalSignerLauncher -import com.vitorpamplona.quartz.signers.NostrSignerExternal -import com.vitorpamplona.quartz.signers.NostrSignerInternal +import com.vitorpamplona.quartz.experimental.edits.PrivateOutboxRelayListEvent +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.MetadataEvent +import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerInternal +import com.vitorpamplona.quartz.nip01Core.toHexKey +import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent +import com.vitorpamplona.quartz.nip17Dm.ChatMessageRelayListEvent +import com.vitorpamplona.quartz.nip47WalletConnect.Nip47WalletConnect +import com.vitorpamplona.quartz.nip50Search.SearchRelayListEvent +import com.vitorpamplona.quartz.nip51Lists.MuteListEvent +import com.vitorpamplona.quartz.nip55AndroidSigner.ExternalSignerLauncher +import com.vitorpamplona.quartz.nip55AndroidSigner.NostrSignerExternal +import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent +import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent +import com.vitorpamplona.quartz.nip65RelayList.RelayUrlFormatter +import com.vitorpamplona.quartz.nip78AppData.AppSpecificDataEvent import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow @@ -371,7 +371,7 @@ class AccountSettings( appSettings: AppSpecificDataEvent?, newSyncedSettings: AccountSyncedSettingsInternal, ) { - if (appSettings == null || appSettings.content().isEmpty()) return + if (appSettings == null || appSettings.content.isEmpty()) return // Events might be different objects, we have to compare their ids. if (backupAppSpecificData?.id != appSettings.id) { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/AccountSyncedSettings.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/AccountSyncedSettings.kt index 4ea4baaae..511b8a6bc 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/AccountSyncedSettings.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/AccountSyncedSettings.kt @@ -22,7 +22,7 @@ package com.vitorpamplona.amethyst.model import androidx.compose.runtime.Stable import com.vitorpamplona.amethyst.ui.screen.loggedIn.notifications.equalImmutableLists -import com.vitorpamplona.quartz.events.LnZapEvent +import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.flow.MutableStateFlow diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/AccountSyncedSettingsInternal.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/AccountSyncedSettingsInternal.kt index 04296f5b2..83bc5e8b5 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/AccountSyncedSettingsInternal.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/AccountSyncedSettingsInternal.kt @@ -22,7 +22,7 @@ package com.vitorpamplona.amethyst.model import android.content.res.Resources import androidx.core.os.ConfigurationCompat -import com.vitorpamplona.quartz.events.LnZapEvent +import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent import java.util.Locale val DefaultReactions = diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/AntiSpamFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/AntiSpamFilter.kt index 84663723e..2571c35a9 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/AntiSpamFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/AntiSpamFilter.kt @@ -26,9 +26,10 @@ import com.vitorpamplona.amethyst.service.checkNotInMainThread import com.vitorpamplona.amethyst.ui.note.njumpLink import com.vitorpamplona.ammolite.relays.Relay import com.vitorpamplona.ammolite.relays.RelayStats -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.Nip19Bech32 -import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip19Bech32Entities.Nip19Parser +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NEvent import kotlinx.coroutines.flow.MutableStateFlow data class Spammer( @@ -60,7 +61,7 @@ class AntiSpamFilter { // really long, make it ok. // The idea here is to avoid considering repeated "@Bot, command" messages spam, while still // blocking repeated "lnbc..." invoices or fishing urls - if (event.content.length < 180 && Nip19Bech32.nip19regex.matcher(event.content).find()) return false + if (event.content.length < 180 && Nip19Parser.nip19regex.matcher(event.content).find()) return false // double list strategy: // if duplicated, it goes into spam. 1000 spam messages are saved into the spam list. @@ -80,7 +81,7 @@ class AntiSpamFilter { logOffender(hash, event) if (relay != null) { - RelayStats.newSpam(relay.url, njumpLink(Nip19Bech32.createNEvent(event.id, event.pubKey, event.kind, relay.url))) + RelayStats.newSpam(relay.url, njumpLink(NEvent.create(event.id, event.pubKey, event.kind, relay.url))) } flowSpam.tryEmit(AntiSpamState(this)) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Channel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Channel.kt index 7bc7ec22e..da9e1c4fa 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Channel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Channel.kt @@ -28,12 +28,13 @@ import com.vitorpamplona.amethyst.service.checkNotInMainThread import com.vitorpamplona.amethyst.ui.dal.DefaultFeedOrder import com.vitorpamplona.amethyst.ui.note.toShortenHex import com.vitorpamplona.ammolite.relays.BundledUpdate -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.Hex -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.toNEvent -import com.vitorpamplona.quartz.events.ChannelCreateEvent -import com.vitorpamplona.quartz.events.LiveActivitiesEvent +import com.vitorpamplona.quartz.crypto.Hex +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip19Bech32Entities.toNAddr +import com.vitorpamplona.quartz.nip19Bech32Entities.toNEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelCreateEvent +import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent import kotlinx.coroutines.Dispatchers @Stable diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Chatroom.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Chatroom.kt index d85571003..dc4e63648 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Chatroom.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Chatroom.kt @@ -23,8 +23,9 @@ package com.vitorpamplona.amethyst.model import androidx.compose.runtime.Stable import com.vitorpamplona.amethyst.service.checkNotInMainThread import com.vitorpamplona.amethyst.ui.dal.DefaultFeedOrder -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.events.PrivateDmEvent +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip04Dm.PrivateDmEvent +import com.vitorpamplona.quartz.nip14Subject.subject import com.vitorpamplona.quartz.utils.TimeUtils @Stable diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/HashtagIcon.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/HashtagIcon.kt index 11a5dc813..97cc8856e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/HashtagIcon.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/HashtagIcon.kt @@ -50,7 +50,7 @@ import com.vitorpamplona.amethyst.ui.components.HashTag import com.vitorpamplona.amethyst.ui.components.RenderRegular import com.vitorpamplona.amethyst.ui.navigation.EmptyNav import com.vitorpamplona.amethyst.ui.theme.ThemeComparisonColumn -import com.vitorpamplona.quartz.events.EmptyTagList +import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList @Preview @Composable diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt index 8918b0878..2abd3b340 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt @@ -31,106 +31,120 @@ import com.vitorpamplona.amethyst.model.observables.LatestByKindWithETag import com.vitorpamplona.amethyst.service.checkNotInMainThread import com.vitorpamplona.ammolite.relays.BundledInsert import com.vitorpamplona.ammolite.relays.Relay -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.HexValidator -import com.vitorpamplona.quartz.encoders.decodeEventIdAsHexOrNull -import com.vitorpamplona.quartz.encoders.decodePublicKeyAsHexOrNull -import com.vitorpamplona.quartz.events.AddressableEvent -import com.vitorpamplona.quartz.events.AdvertisedRelayListEvent -import com.vitorpamplona.quartz.events.AppDefinitionEvent -import com.vitorpamplona.quartz.events.AppRecommendationEvent -import com.vitorpamplona.quartz.events.AppSpecificDataEvent -import com.vitorpamplona.quartz.events.AudioHeaderEvent -import com.vitorpamplona.quartz.events.AudioTrackEvent -import com.vitorpamplona.quartz.events.BadgeAwardEvent -import com.vitorpamplona.quartz.events.BadgeDefinitionEvent -import com.vitorpamplona.quartz.events.BadgeProfilesEvent -import com.vitorpamplona.quartz.events.BaseAddressableEvent -import com.vitorpamplona.quartz.events.BaseTextNoteEvent -import com.vitorpamplona.quartz.events.BlossomServersEvent -import com.vitorpamplona.quartz.events.BookmarkListEvent -import com.vitorpamplona.quartz.events.CalendarDateSlotEvent -import com.vitorpamplona.quartz.events.CalendarEvent -import com.vitorpamplona.quartz.events.CalendarRSVPEvent -import com.vitorpamplona.quartz.events.CalendarTimeSlotEvent -import com.vitorpamplona.quartz.events.ChannelCreateEvent -import com.vitorpamplona.quartz.events.ChannelHideMessageEvent -import com.vitorpamplona.quartz.events.ChannelListEvent -import com.vitorpamplona.quartz.events.ChannelMessageEvent -import com.vitorpamplona.quartz.events.ChannelMetadataEvent -import com.vitorpamplona.quartz.events.ChannelMuteUserEvent -import com.vitorpamplona.quartz.events.ChatMessageEncryptedFileHeaderEvent -import com.vitorpamplona.quartz.events.ChatMessageEvent -import com.vitorpamplona.quartz.events.ChatMessageRelayListEvent -import com.vitorpamplona.quartz.events.ChatroomKey -import com.vitorpamplona.quartz.events.ClassifiedsEvent -import com.vitorpamplona.quartz.events.CommentEvent -import com.vitorpamplona.quartz.events.CommunityDefinitionEvent -import com.vitorpamplona.quartz.events.CommunityListEvent -import com.vitorpamplona.quartz.events.CommunityPostApprovalEvent -import com.vitorpamplona.quartz.events.ContactListEvent -import com.vitorpamplona.quartz.events.DeletionEvent -import com.vitorpamplona.quartz.events.DraftEvent -import com.vitorpamplona.quartz.events.EmojiPackEvent -import com.vitorpamplona.quartz.events.EmojiPackSelectionEvent -import com.vitorpamplona.quartz.events.Event -import com.vitorpamplona.quartz.events.FhirResourceEvent -import com.vitorpamplona.quartz.events.FileHeaderEvent -import com.vitorpamplona.quartz.events.FileServersEvent -import com.vitorpamplona.quartz.events.FileStorageEvent -import com.vitorpamplona.quartz.events.FileStorageHeaderEvent -import com.vitorpamplona.quartz.events.GenericRepostEvent -import com.vitorpamplona.quartz.events.GiftWrapEvent -import com.vitorpamplona.quartz.events.GitIssueEvent -import com.vitorpamplona.quartz.events.GitPatchEvent -import com.vitorpamplona.quartz.events.GitReplyEvent -import com.vitorpamplona.quartz.events.GitRepositoryEvent -import com.vitorpamplona.quartz.events.HighlightEvent -import com.vitorpamplona.quartz.events.InteractiveStoryPrologueEvent -import com.vitorpamplona.quartz.events.InteractiveStoryReadingStateEvent -import com.vitorpamplona.quartz.events.InteractiveStorySceneEvent -import com.vitorpamplona.quartz.events.LiveActivitiesChatMessageEvent -import com.vitorpamplona.quartz.events.LiveActivitiesEvent -import com.vitorpamplona.quartz.events.LnZapEvent -import com.vitorpamplona.quartz.events.LnZapPaymentRequestEvent -import com.vitorpamplona.quartz.events.LnZapPaymentResponseEvent -import com.vitorpamplona.quartz.events.LnZapRequestEvent -import com.vitorpamplona.quartz.events.LongTextNoteEvent -import com.vitorpamplona.quartz.events.MetadataEvent -import com.vitorpamplona.quartz.events.MuteListEvent -import com.vitorpamplona.quartz.events.NIP90ContentDiscoveryRequestEvent -import com.vitorpamplona.quartz.events.NIP90ContentDiscoveryResponseEvent -import com.vitorpamplona.quartz.events.NIP90StatusEvent -import com.vitorpamplona.quartz.events.NIP90UserDiscoveryRequestEvent -import com.vitorpamplona.quartz.events.NIP90UserDiscoveryResponseEvent -import com.vitorpamplona.quartz.events.NNSEvent -import com.vitorpamplona.quartz.events.OtsEvent -import com.vitorpamplona.quartz.events.PeopleListEvent -import com.vitorpamplona.quartz.events.PictureEvent -import com.vitorpamplona.quartz.events.PinListEvent -import com.vitorpamplona.quartz.events.PollNoteEvent -import com.vitorpamplona.quartz.events.PrivateDmEvent -import com.vitorpamplona.quartz.events.PrivateOutboxRelayListEvent -import com.vitorpamplona.quartz.events.ProfileGalleryEntryEvent -import com.vitorpamplona.quartz.events.ReactionEvent -import com.vitorpamplona.quartz.events.RecommendRelayEvent -import com.vitorpamplona.quartz.events.RelationshipStatusEvent -import com.vitorpamplona.quartz.events.RelaySetEvent -import com.vitorpamplona.quartz.events.ReportEvent -import com.vitorpamplona.quartz.events.RepostEvent -import com.vitorpamplona.quartz.events.SealedGossipEvent -import com.vitorpamplona.quartz.events.SearchRelayListEvent -import com.vitorpamplona.quartz.events.StatusEvent -import com.vitorpamplona.quartz.events.TextNoteEvent -import com.vitorpamplona.quartz.events.TextNoteModificationEvent -import com.vitorpamplona.quartz.events.TorrentCommentEvent -import com.vitorpamplona.quartz.events.TorrentEvent -import com.vitorpamplona.quartz.events.VerificationState -import com.vitorpamplona.quartz.events.VideoHorizontalEvent -import com.vitorpamplona.quartz.events.VideoVerticalEvent -import com.vitorpamplona.quartz.events.WikiNoteEvent -import com.vitorpamplona.quartz.events.WrappedEvent +import com.vitorpamplona.quartz.blossom.BlossomServersEvent +import com.vitorpamplona.quartz.crypto.Hex +import com.vitorpamplona.quartz.experimental.audio.AudioHeaderEvent +import com.vitorpamplona.quartz.experimental.audio.AudioTrackEvent +import com.vitorpamplona.quartz.experimental.edits.PrivateOutboxRelayListEvent +import com.vitorpamplona.quartz.experimental.edits.TextNoteModificationEvent +import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStoryPrologueEvent +import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStoryReadingStateEvent +import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStorySceneEvent +import com.vitorpamplona.quartz.experimental.medical.FhirResourceEvent +import com.vitorpamplona.quartz.experimental.nip95.FileStorageEvent +import com.vitorpamplona.quartz.experimental.nip95.FileStorageHeaderEvent +import com.vitorpamplona.quartz.experimental.nns.NNSEvent +import com.vitorpamplona.quartz.experimental.profileGallery.ProfileGalleryEntryEvent +import com.vitorpamplona.quartz.experimental.relationshipStatus.RelationshipStatusEvent +import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.MetadataEvent +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.addressables.AddressableEvent +import com.vitorpamplona.quartz.nip01Core.addressables.BaseAddressableEvent +import com.vitorpamplona.quartz.nip01Core.addressables.mapTaggedAddress +import com.vitorpamplona.quartz.nip01Core.addressables.taggedAddresses +import com.vitorpamplona.quartz.nip01Core.checkSignature +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.core.matchTag1With +import com.vitorpamplona.quartz.nip01Core.events.forEachTaggedEvent +import com.vitorpamplona.quartz.nip01Core.events.isTaggedEvent +import com.vitorpamplona.quartz.nip01Core.events.mapTaggedEvent +import com.vitorpamplona.quartz.nip01Core.events.taggedEvents +import com.vitorpamplona.quartz.nip01Core.hasValidSignature +import com.vitorpamplona.quartz.nip01Core.people.isTaggedUsers +import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent +import com.vitorpamplona.quartz.nip03Timestamp.OtsEvent +import com.vitorpamplona.quartz.nip03Timestamp.VerificationState +import com.vitorpamplona.quartz.nip04Dm.PrivateDmEvent +import com.vitorpamplona.quartz.nip09Deletions.DeletionEvent +import com.vitorpamplona.quartz.nip10Notes.BaseTextNoteEvent +import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent +import com.vitorpamplona.quartz.nip17Dm.ChatMessageEncryptedFileHeaderEvent +import com.vitorpamplona.quartz.nip17Dm.ChatMessageEvent +import com.vitorpamplona.quartz.nip17Dm.ChatMessageRelayListEvent +import com.vitorpamplona.quartz.nip17Dm.ChatroomKey +import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent +import com.vitorpamplona.quartz.nip18Reposts.RepostEvent +import com.vitorpamplona.quartz.nip19Bech32Entities.decodeEventIdAsHexOrNull +import com.vitorpamplona.quartz.nip19Bech32Entities.decodePublicKeyAsHexOrNull +import com.vitorpamplona.quartz.nip19Bech32Entities.isATag +import com.vitorpamplona.quartz.nip19Bech32Entities.parse +import com.vitorpamplona.quartz.nip22Comments.CommentEvent +import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent +import com.vitorpamplona.quartz.nip25Reactions.ReactionEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelCreateEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelHideMessageEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelListEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelMessageEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelMetadataEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelMuteUserEvent +import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiPackEvent +import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiPackSelectionEvent +import com.vitorpamplona.quartz.nip34Git.GitIssueEvent +import com.vitorpamplona.quartz.nip34Git.GitPatchEvent +import com.vitorpamplona.quartz.nip34Git.GitReplyEvent +import com.vitorpamplona.quartz.nip34Git.GitRepositoryEvent +import com.vitorpamplona.quartz.nip35Torrents.TorrentCommentEvent +import com.vitorpamplona.quartz.nip35Torrents.TorrentEvent +import com.vitorpamplona.quartz.nip37Drafts.DraftEvent +import com.vitorpamplona.quartz.nip38UserStatus.StatusEvent +import com.vitorpamplona.quartz.nip40Expiration.expiration +import com.vitorpamplona.quartz.nip40Expiration.isExpirationBefore +import com.vitorpamplona.quartz.nip40Expiration.isExpired +import com.vitorpamplona.quartz.nip47WalletConnect.LnZapPaymentRequestEvent +import com.vitorpamplona.quartz.nip47WalletConnect.LnZapPaymentResponseEvent +import com.vitorpamplona.quartz.nip50Search.SearchRelayListEvent +import com.vitorpamplona.quartz.nip51Lists.BookmarkListEvent +import com.vitorpamplona.quartz.nip51Lists.MuteListEvent +import com.vitorpamplona.quartz.nip51Lists.PeopleListEvent +import com.vitorpamplona.quartz.nip51Lists.PinListEvent +import com.vitorpamplona.quartz.nip51Lists.RelaySetEvent +import com.vitorpamplona.quartz.nip52Calendar.CalendarDateSlotEvent +import com.vitorpamplona.quartz.nip52Calendar.CalendarEvent +import com.vitorpamplona.quartz.nip52Calendar.CalendarRSVPEvent +import com.vitorpamplona.quartz.nip52Calendar.CalendarTimeSlotEvent +import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesChatMessageEvent +import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent +import com.vitorpamplona.quartz.nip54Wiki.WikiNoteEvent +import com.vitorpamplona.quartz.nip56Reports.ReportEvent +import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent +import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent +import com.vitorpamplona.quartz.nip58Badges.BadgeAwardEvent +import com.vitorpamplona.quartz.nip58Badges.BadgeDefinitionEvent +import com.vitorpamplona.quartz.nip58Badges.BadgeProfilesEvent +import com.vitorpamplona.quartz.nip59Giftwrap.GiftWrapEvent +import com.vitorpamplona.quartz.nip59Giftwrap.SealedGossipEvent +import com.vitorpamplona.quartz.nip59Giftwrap.WrappedEvent +import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent +import com.vitorpamplona.quartz.nip68Picture.PictureEvent +import com.vitorpamplona.quartz.nip71Video.VideoHorizontalEvent +import com.vitorpamplona.quartz.nip71Video.VideoVerticalEvent +import com.vitorpamplona.quartz.nip72ModCommunities.CommunityDefinitionEvent +import com.vitorpamplona.quartz.nip72ModCommunities.CommunityListEvent +import com.vitorpamplona.quartz.nip72ModCommunities.CommunityPostApprovalEvent +import com.vitorpamplona.quartz.nip78AppData.AppSpecificDataEvent +import com.vitorpamplona.quartz.nip84Highlights.HighlightEvent +import com.vitorpamplona.quartz.nip89AppHandlers.AppDefinitionEvent +import com.vitorpamplona.quartz.nip89AppHandlers.AppRecommendationEvent +import com.vitorpamplona.quartz.nip90Dvms.NIP90ContentDiscoveryRequestEvent +import com.vitorpamplona.quartz.nip90Dvms.NIP90ContentDiscoveryResponseEvent +import com.vitorpamplona.quartz.nip90Dvms.NIP90StatusEvent +import com.vitorpamplona.quartz.nip90Dvms.NIP90UserDiscoveryRequestEvent +import com.vitorpamplona.quartz.nip90Dvms.NIP90UserDiscoveryResponseEvent +import com.vitorpamplona.quartz.nip94FileMetadata.FileHeaderEvent +import com.vitorpamplona.quartz.nip96FileStorage.FileServersEvent +import com.vitorpamplona.quartz.nip99Classifieds.ClassifiedsEvent import com.vitorpamplona.quartz.utils.TimeUtils import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentSetOf @@ -289,7 +303,7 @@ object LocalCache { // upgrade to the latest val newNote = checkGetOrCreateAddressableNote(noteEvent.address().toTag()) - if (newNote != null && noteEvent is Event && newNote.event == null) { + if (newNote != null && newNote.event == null) { val author = note.author ?: getOrCreateUser(noteEvent.pubKey) newNote.loadEvent(noteEvent as Event, author, emptyList()) note.moveAllReferencesTo(newNote) @@ -352,7 +366,7 @@ object LocalCache { if (key.isBlank()) return false if (key.contains(":")) return false - return HexValidator.isHex(key) + return Hex.isHex(key) } fun checkGetOrCreateAddressableNote(key: String): AddressableNote? = @@ -567,7 +581,7 @@ object LocalCache { } // Already processed this event. - if (note.event?.id() == event.id()) return + if (note.event?.id == event.id) return if (antiSpam.isSpam(event, relay)) { return @@ -601,7 +615,7 @@ object LocalCache { } // Already processed this event. - if (note.event?.id() == event.id()) return + if (note.event?.id == event.id) return if (antiSpam.isSpam(event, relay)) { return @@ -691,7 +705,7 @@ object LocalCache { version.moveAllReferencesTo(note) } - if (note.event?.id() == event.id()) return + if (note.event?.id == event.id) return if (event.createdAt > (note.createdAt() ?: 0)) { note.loadEvent(event, author, emptyList()) @@ -862,7 +876,7 @@ object LocalCache { } // Already processed this event. - if (note.event?.id() == event.id()) return + if (note.event?.id == event.id) return if (event.createdAt > (note.createdAt() ?: 0)) { note.loadEvent(event, author, emptyList()) @@ -888,7 +902,7 @@ object LocalCache { val author = getOrCreateUser(event.pubKey) // Already processed this event. - if (version.event?.id() == event.id()) return + if (version.event?.id == event.id) return // makes sure the OTS has a valid certificate if (event.cacheVerify() is VerificationState.Error) return // no valid OTS @@ -919,7 +933,7 @@ object LocalCache { } // Already processed this event. - if (note.event?.id() == event.id()) return + if (note.event?.id == event.id) return val replyTo = computeReplyTo(event) @@ -998,7 +1012,7 @@ object LocalCache { } // Already processed this event. - if (note.event?.id() == event.id()) return + if (note.event?.id == event.id) return if (event.createdAt > (note.createdAt() ?: 0)) { note.loadEvent(event, author, replyTos) @@ -1021,11 +1035,6 @@ object LocalCache { consumeBaseReplaceable(event, relay) } - @Suppress("UNUSED_PARAMETER") - fun consume(event: RecommendRelayEvent) { - // // Log.d("RR", event.toJson()) - } - fun consume( event: PrivateDmEvent, relay: Relay?, @@ -1109,7 +1118,7 @@ object LocalCache { notes.forEach { key, note -> val noteEvent = note.event if (noteEvent is AddressableEvent && noteEvent.addressTag() in addressSet) { - if (noteEvent.pubKey() == event.pubKey && noteEvent.createdAt() <= event.createdAt) { + if (noteEvent.pubKey == event.pubKey && noteEvent.createdAt <= event.createdAt) { deleteNote(note) deletedAtLeastOne = true } @@ -1129,7 +1138,7 @@ object LocalCache { val mentions = deleteNote.event - ?.tags() + ?.tags ?.filter { it.firstOrNull() == "p" } ?.mapNotNull { it.getOrNull(1) } ?.mapNotNull { checkGetOrCreateUser(it) } @@ -1404,7 +1413,7 @@ object LocalCache { note.loadEvent(event, author, replyTo) - // Log.d("CM", "New Chat Note (${note.author?.toBestDisplayName()} ${note.event?.content()} + // Log.d("CM", "New Chat Note (${note.author?.toBestDisplayName()} ${note.event?.content} // ${formattedDateTime(event.createdAt)}") // Counts the replies @@ -1777,9 +1786,7 @@ object LocalCache { requestNote?.let { request -> zappedNote?.addZapPayment(request, note) } - if (responseCallback != null) { - responseCallback(event) - } + responseCallback(event) } fun findUsersStartingWith( @@ -1843,7 +1850,7 @@ object LocalCache { return@filter false } - if (note.event?.matchTag1With(text) == true || + if (note.event?.tags?.matchTag1With(text) == true || note.idHex.startsWith(text, true) ) { if (!note.isHiddenFor(forAccount.flowHiddenUsers.value)) { @@ -1855,7 +1862,7 @@ object LocalCache { if (note.event?.isContentEncoded() == false) { if (!note.isHiddenFor(forAccount.flowHiddenUsers.value)) { - return@filter note.event?.content()?.contains(text, true) ?: false + return@filter note.event?.content?.contains(text, true) ?: false } else { return@filter false } @@ -1874,7 +1881,7 @@ object LocalCache { return@filter false } - if (addressable.event?.matchTag1With(text) == true || + if (addressable.event?.tags?.matchTag1With(text) == true || addressable.idHex.startsWith(text, true) ) { if (!addressable.isHiddenFor(forAccount.flowHiddenUsers.value)) { @@ -1886,7 +1893,7 @@ object LocalCache { if (addressable.event?.isContentEncoded() == false) { if (!addressable.isHiddenFor(forAccount.flowHiddenUsers.value)) { - return@filter addressable.event?.content()?.contains(text, true) ?: false + return@filter addressable.event?.content?.contains(text, true) ?: false } else { return@filter false } @@ -1923,7 +1930,7 @@ object LocalCache { !noteEvent.isExpired() && noteEvent.content.isNotBlank() ) - }.sortedWith(compareBy({ it.event?.expiration() ?: it.event?.createdAt() }, { it.idHex })) + }.sortedWith(compareBy({ it.event?.expiration() ?: it.event?.createdAt }, { it.idHex })) .reversed() .toImmutableList() } @@ -2073,8 +2080,8 @@ object LocalCache { notes.filter { _, note -> val noteEvent = note.event if (noteEvent is AddressableEvent) { - noteEvent.createdAt() < - (addressables.get(noteEvent.address().toTag())?.event?.createdAt() ?: 0) + noteEvent.createdAt < + (addressables.get(noteEvent.address().toTag())?.event?.createdAt ?: 0) } else { false } @@ -2215,7 +2222,7 @@ object LocalCache { account.liveHiddenUsers.value ?.hiddenUsers ?.map { userHex -> - (notes.filter { _, it -> it.event?.pubKey() == userHex } + addressables.filter { _, it -> it.event?.pubKey() == userHex }).toSet() + (notes.filter { _, it -> it.event?.pubKey == userHex } + addressables.filter { _, it -> it.event?.pubKey == userHex }).toSet() }?.flatten() ?: emptyList() @@ -2451,7 +2458,7 @@ object LocalCache { // updates relay with a new event. getAddressableNoteIfExists(event.addressTag())?.let { it.event?.let { existingEvent -> - if (existingEvent.createdAt() > event.createdAt) { + if (existingEvent.createdAt > event.createdAt) { Log.d("LocalCache", "Updating ${relay.url} with a new version of ${event.toJson()} to ${existingEvent.toJson()}") relay.send(existingEvent) } @@ -2548,7 +2555,6 @@ object LocalCache { is PeopleListEvent -> consume(event, relay) is PollNoteEvent -> consume(event, relay) is ReactionEvent -> consume(event) - is RecommendRelayEvent -> consume(event) is RelationshipStatusEvent -> consume(event, relay) is RelaySetEvent -> consume(event, relay) is ReportEvent -> consume(event, relay) @@ -2580,7 +2586,7 @@ object LocalCache { if (notificationEvent is AddressableEvent) { val note = addressables.get(notificationEvent.addressTag()) val noteEvent = note?.event - noteEvent != null && notificationEvent.createdAt <= noteEvent.createdAt() + noteEvent != null && notificationEvent.createdAt <= noteEvent.createdAt } else { val note = notes.get(notificationEvent.id) note?.event != null diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Note.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Note.kt index 5e05d37dd..292ec7ded 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Note.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Note.kt @@ -37,33 +37,36 @@ import com.vitorpamplona.ammolite.relays.BundledUpdate import com.vitorpamplona.ammolite.relays.Relay import com.vitorpamplona.ammolite.relays.RelayBriefInfoCache import com.vitorpamplona.ammolite.relays.filters.EOSETime -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.Nip19Bech32 -import com.vitorpamplona.quartz.events.AddressableEvent -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.CommunityPostApprovalEvent -import com.vitorpamplona.quartz.events.DraftEvent -import com.vitorpamplona.quartz.events.Event -import com.vitorpamplona.quartz.events.EventInterface -import com.vitorpamplona.quartz.events.GenericRepostEvent -import com.vitorpamplona.quartz.events.ImmutableListOfLists -import com.vitorpamplona.quartz.events.LiveActivitiesChatMessageEvent -import com.vitorpamplona.quartz.events.LiveActivitiesEvent -import com.vitorpamplona.quartz.events.LnZapEvent -import com.vitorpamplona.quartz.events.LnZapPaymentRequestEvent -import com.vitorpamplona.quartz.events.LnZapPaymentResponseEvent -import com.vitorpamplona.quartz.events.LnZapRequestEvent -import com.vitorpamplona.quartz.events.LongTextNoteEvent -import com.vitorpamplona.quartz.events.PayInvoiceSuccessResponse -import com.vitorpamplona.quartz.events.RepostEvent -import com.vitorpamplona.quartz.events.WrappedEvent -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.crypto.Hex +import com.vitorpamplona.quartz.lightning.LnInvoiceUtil +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.addressables.AddressableEvent +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.hashtags.anyHashTag +import com.vitorpamplona.quartz.nip01Core.hashtags.isTaggedHash +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip02FollowList.ImmutableListOfLists +import com.vitorpamplona.quartz.nip10Notes.BaseTextNoteEvent +import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent +import com.vitorpamplona.quartz.nip18Reposts.RepostEvent +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NEvent +import com.vitorpamplona.quartz.nip19Bech32Entities.toNAddr +import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelCreateEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelMessageEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelMetadataEvent +import com.vitorpamplona.quartz.nip36SensitiveContent.isSensitiveOrNSFW +import com.vitorpamplona.quartz.nip37Drafts.DraftEvent +import com.vitorpamplona.quartz.nip47WalletConnect.LnZapPaymentRequestEvent +import com.vitorpamplona.quartz.nip47WalletConnect.LnZapPaymentResponseEvent +import com.vitorpamplona.quartz.nip47WalletConnect.PayInvoiceSuccessResponse +import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesChatMessageEvent +import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent +import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent +import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent +import com.vitorpamplona.quartz.nip59Giftwrap.WrappedEvent +import com.vitorpamplona.quartz.nip72ModCommunities.CommunityPostApprovalEvent import com.vitorpamplona.quartz.utils.TimeUtils import com.vitorpamplona.quartz.utils.containsAny import kotlinx.coroutines.CancellationException @@ -91,7 +94,7 @@ class AddressableNote( if (event == null) return null val publishedAt = (event as? LongTextNoteEvent)?.publishedAt() ?: Long.MAX_VALUE - val lastCreatedAt = event?.createdAt() ?: Long.MAX_VALUE + val lastCreatedAt = event?.createdAt ?: Long.MAX_VALUE return minOf(publishedAt, lastCreatedAt) } @@ -103,7 +106,7 @@ class AddressableNote( deletionAddressables: Set, ): Boolean { val thisEvent = event - return deletionAddressables.contains(address) || (thisEvent != null && deletionEvents.contains(thisEvent.id())) + return deletionAddressables.contains(address) || (thisEvent != null && deletionEvents.contains(thisEvent.id)) } } @@ -113,7 +116,7 @@ open class Note( ) { // These fields are only available after the Text Note event is received. // They are immutable after that. - var event: EventInterface? = null + var event: Event? = null var author: User? = null var replyTo: List? = null @@ -152,17 +155,17 @@ open class Note( return if (myEvent is WrappedEvent) { val host = myEvent.host if (host != null) { - Nip19Bech32.createNEvent( + NEvent.create( host.id, host.pubKey, host.kind, relayHintUrl(), ) } else { - Nip19Bech32.createNEvent(idHex, author?.pubkeyHex, event?.kind(), relayHintUrl()) + NEvent.create(idHex, author?.pubkeyHex, event?.kind, relayHintUrl()) } } else { - Nip19Bech32.createNEvent(idHex, author?.pubkeyHex, event?.kind(), relayHintUrl()) + NEvent.create(idHex, author?.pubkeyHex, event?.kind, relayHintUrl()) } } @@ -203,7 +206,7 @@ open class Note( open fun address(): ATag? = null - open fun createdAt() = event?.createdAt() + open fun createdAt() = event?.createdAt fun isDraft() = event is DraftEvent @@ -212,7 +215,7 @@ open class Note( author: User, replyTo: List, ) { - if (this.event?.id() != event.id()) { + if (this.event?.id != event.id) { this.event = event this.author = author this.replyTo = replyTo @@ -282,8 +285,8 @@ open class Note( } fun removeReaction(note: Note) { - val tags = note.event?.tags() ?: emptyArray() - val reaction = note.event?.content()?.firstFullCharOrEmoji(ImmutableListOfLists(tags)) ?: "+" + val tags = note.event?.tags ?: emptyArray() + val reaction = note.event?.content?.firstFullCharOrEmoji(ImmutableListOfLists(tags)) ?: "+" if (reactions[reaction]?.contains(note) == true) { reactions[reaction]?.let { @@ -396,8 +399,8 @@ open class Note( } fun addReaction(note: Note) { - val tags = note.event?.tags() ?: emptyArray() - val reaction = note.event?.content()?.firstFullCharOrEmoji(ImmutableListOfLists(tags)) ?: "+" + val tags = note.event?.tags ?: emptyArray() + val reaction = note.event?.content?.firstFullCharOrEmoji(ImmutableListOfLists(tags)) ?: "+" val listOfAuthors = reactions[reaction] if (listOfAuthors == null) { @@ -701,7 +704,7 @@ open class Note( .any { val pledgeValue = try { - BigDecimal(it.event?.content()) + BigDecimal(it.event?.content) } catch (e: Exception) { if (e is CancellationException) throw e null @@ -716,7 +719,7 @@ open class Note( .filter { it.event?.isTaggedHash("bounty-added-reward") ?: false } .mapNotNull { try { - BigDecimal(it.event?.content()) + BigDecimal(it.event?.content) } catch (e: Exception) { if (e is CancellationException) throw e null @@ -808,7 +811,7 @@ open class Note( fun isHiddenFor(accountChoices: Account.LiveHiddenUsers): Boolean { val thisEvent = event ?: return false - val hash = thisEvent.pubKey().hashCode() + val hash = thisEvent.pubKey.hashCode() // if the author is hidden by spam or blocked if (accountChoices.hiddenUsersHashCodes.contains(hash) || @@ -818,7 +821,7 @@ open class Note( } // if the post is sensitive and the user doesn't want to see sensitive content - if (accountChoices.showSensitiveContent == false && thisEvent.isSensitive()) { + if (accountChoices.showSensitiveContent == false && thisEvent.isSensitiveOrNSFW()) { return true } @@ -986,7 +989,7 @@ class NoteLiveSet( val boostCount = innerBoosts.map { it.note.boosts.size }.distinctUntilChanged() - val content = innerMetadata.map { it.note.event?.content() ?: "" } + val content = innerMetadata.map { it.note.event?.content ?: "" } fun isInUse(): Boolean = metadata.hasObservers() || diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/ParticipantListBuilder.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/ParticipantListBuilder.kt index bd1ead6a3..2ddcd534d 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/ParticipantListBuilder.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/ParticipantListBuilder.kt @@ -20,7 +20,7 @@ */ package com.vitorpamplona.amethyst.model -import com.vitorpamplona.quartz.encoders.HexKey +import com.vitorpamplona.quartz.nip01Core.HexKey class ParticipantListBuilder { private fun addFollowsThatDirectlyParticipateOnToSet( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/ThreadAssembler.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/ThreadAssembler.kt index dfad0c60b..29980d3e8 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/ThreadAssembler.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/ThreadAssembler.kt @@ -22,10 +22,10 @@ package com.vitorpamplona.amethyst.model import androidx.compose.runtime.Stable import com.vitorpamplona.amethyst.service.checkNotInMainThread -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.events.AddressableEvent -import com.vitorpamplona.quartz.events.GenericRepostEvent -import com.vitorpamplona.quartz.events.RepostEvent +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.addressables.AddressableEvent +import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent +import com.vitorpamplona.quartz.nip18Reposts.RepostEvent import kotlinx.collections.immutable.ImmutableSet import kotlinx.collections.immutable.toImmutableSet @@ -42,7 +42,7 @@ class ThreadAssembler { val markedAsRoot = note.event - ?.tags() + ?.tags ?.firstOrNull { it[0] == "e" && it.size > 3 && it[3] == "root" } ?.getOrNull(1) if (markedAsRoot != null) { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/ThreadLevelCalculator.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/ThreadLevelCalculator.kt index df804b071..f8d424e53 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/ThreadLevelCalculator.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/ThreadLevelCalculator.kt @@ -20,9 +20,9 @@ */ package com.vitorpamplona.amethyst.model -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.events.GenericRepostEvent -import com.vitorpamplona.quartz.events.RepostEvent +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent +import com.vitorpamplona.quartz.nip18Reposts.RepostEvent import java.lang.Long.min import java.time.Instant import java.time.ZoneId diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/User.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/User.kt index d531d0063..1bf34dda7 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/User.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/User.kt @@ -31,20 +31,23 @@ import com.vitorpamplona.amethyst.ui.note.toShortenHex import com.vitorpamplona.ammolite.relays.BundledUpdate import com.vitorpamplona.ammolite.relays.Relay import com.vitorpamplona.ammolite.relays.filters.EOSETime -import com.vitorpamplona.quartz.encoders.Hex -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.Lud06 -import com.vitorpamplona.quartz.encoders.Nip19Bech32 -import com.vitorpamplona.quartz.encoders.toNpub -import com.vitorpamplona.quartz.events.AdvertisedRelayListEvent -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.crypto.Hex +import com.vitorpamplona.quartz.lightning.Lud06 +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.MetadataEvent +import com.vitorpamplona.quartz.nip01Core.UserMetadata +import com.vitorpamplona.quartz.nip01Core.geohash.isTaggedGeoHash +import com.vitorpamplona.quartz.nip01Core.hashtags.isTaggedHash +import com.vitorpamplona.quartz.nip01Core.people.isTaggedUser +import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent +import com.vitorpamplona.quartz.nip02FollowList.toImmutableListOfLists +import com.vitorpamplona.quartz.nip17Dm.ChatroomKey +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NProfile +import com.vitorpamplona.quartz.nip19Bech32Entities.toNpub +import com.vitorpamplona.quartz.nip51Lists.BookmarkListEvent +import com.vitorpamplona.quartz.nip56Reports.ReportEvent +import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent +import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent import com.vitorpamplona.quartz.utils.DualCase import com.vitorpamplona.quartz.utils.containsAny import kotlinx.collections.immutable.persistentSetOf @@ -86,7 +89,7 @@ class User( fun toNProfile(): String { val relayList = (LocalCache.getAddressableNoteIfExists(AdvertisedRelayListEvent.createAddressTag(pubkeyHex))?.event as? AdvertisedRelayListEvent)?.writeRelays() - return Nip19Bech32.createNProfile( + return NProfile.create( pubkeyHex, relayList?.take(3) ?: listOfNotNull(latestMetadataRelay), ) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/observables/CreatedAtComparator.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/observables/CreatedAtComparator.kt index 1996f4585..1cd47498d 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/observables/CreatedAtComparator.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/observables/CreatedAtComparator.kt @@ -38,7 +38,7 @@ object CreatedAtComparator : Comparator { } else if (secondEvent == null) { -1 } else { - firstEvent.createdAt().compareTo(secondEvent.createdAt()) + firstEvent.createdAt.compareTo(secondEvent.createdAt) } } } @@ -58,7 +58,7 @@ object CreatedAtComparatorAddresses : Comparator { } else if (secondEvent == null) { -1 } else { - firstEvent.createdAt().compareTo(secondEvent.createdAt()) + firstEvent.createdAt.compareTo(secondEvent.createdAt) } } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/observables/LatestByKindAndAuthor.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/observables/LatestByKindAndAuthor.kt index 47459da9f..9598b435c 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/observables/LatestByKindAndAuthor.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/observables/LatestByKindAndAuthor.kt @@ -23,7 +23,7 @@ package com.vitorpamplona.amethyst.model.observables import com.vitorpamplona.amethyst.model.AddressableNote import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note -import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.nip01Core.core.Event import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow @@ -53,7 +53,7 @@ class LatestByKindAndAuthor( .maxOrNullOf( filter = { idHex: String, note: AddressableNote -> note.event?.let { - it.kind() == kind && it.pubKey() == pubkey + it.kind == kind && it.pubKey == pubkey } == true }, comparator = CreatedAtComparatorAddresses, @@ -63,7 +63,7 @@ class LatestByKindAndAuthor( .maxOrNullOf( filter = { idHex: String, note: Note -> note.event?.let { - it.kind() == kind && it.pubKey() == pubkey + it.kind == kind && it.pubKey == pubkey } == true }, comparator = CreatedAtComparator, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/observables/LatestByKindWithETag.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/observables/LatestByKindWithETag.kt index ad2fc4fd2..b501c2117 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/observables/LatestByKindWithETag.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/observables/LatestByKindWithETag.kt @@ -22,7 +22,8 @@ package com.vitorpamplona.amethyst.model.observables import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note -import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.events.isTaggedEvent import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow @@ -51,7 +52,7 @@ class LatestByKindWithETag( .maxOrNullOf( filter = { idHex: String, note: Note -> note.event?.let { - it.kind() == kind && it.isTaggedEvent(eTag) + it.kind == kind && it.isTaggedEvent(eTag) } == true }, comparator = CreatedAtComparator, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/AmethystNostrDataSource.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/AmethystNostrDataSource.kt index e9fbdb558..41347e1db 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/AmethystNostrDataSource.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/AmethystNostrDataSource.kt @@ -24,8 +24,8 @@ import com.vitorpamplona.amethyst.Amethyst import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.ammolite.relays.NostrDataSource import com.vitorpamplona.ammolite.relays.Relay -import com.vitorpamplona.quartz.events.AddressableEvent -import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.nip01Core.addressables.AddressableEvent +import com.vitorpamplona.quartz.nip01Core.core.Event abstract class AmethystNostrDataSource( debugName: String, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/Base64Image.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/Base64Image.kt index eea91d393..820400199 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/Base64Image.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/Base64Image.kt @@ -35,7 +35,7 @@ import coil3.request.ImageRequest import coil3.request.Options import com.vitorpamplona.amethyst.commons.richtext.RichTextParser.Companion.base64contentPattern import com.vitorpamplona.quartz.crypto.CryptoUtils -import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.nip01Core.toHexKey import java.util.Base64 @Stable diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/CachedRichTextParser.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/CachedRichTextParser.kt index 2ac35e33c..55a13f3b6 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/CachedRichTextParser.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/CachedRichTextParser.kt @@ -23,7 +23,7 @@ package com.vitorpamplona.amethyst.service import android.util.LruCache import com.vitorpamplona.amethyst.commons.richtext.RichTextParser import com.vitorpamplona.amethyst.commons.richtext.RichTextViewerState -import com.vitorpamplona.quartz.events.ImmutableListOfLists +import com.vitorpamplona.quartz.nip02FollowList.ImmutableListOfLists object CachedRichTextParser { private val richTextCache = LruCache(50) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/CashuProcessor.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/CashuProcessor.kt index 0189c1490..a2d20134a 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/CashuProcessor.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/CashuProcessor.kt @@ -23,6 +23,7 @@ package com.vitorpamplona.amethyst.service import android.content.Context import android.util.LruCache import androidx.compose.runtime.Immutable +import com.fasterxml.jackson.databind.node.JsonNodeFactory import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import com.fasterxml.jackson.module.kotlin.readValue import com.vitorpamplona.amethyst.R @@ -30,8 +31,7 @@ import com.vitorpamplona.amethyst.service.lnurl.LightningAddressResolver import com.vitorpamplona.amethyst.service.okhttp.HttpClientManager import com.vitorpamplona.amethyst.ui.components.GenericLoadable import com.vitorpamplona.amethyst.ui.stringRes -import com.vitorpamplona.quartz.encoders.toHexKey -import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.nip01Core.toHexKey import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList import kotlinx.serialization.ExperimentalSerializationApi @@ -279,7 +279,7 @@ class CashuProcessor { val url = "$mintAddress/checkfees" // Melt cashu tokens at Mint val client = HttpClientManager.getHttpClient(forceProxy(url)) - val factory = Event.mapper.nodeFactory + val factory = JsonNodeFactory.instance val jsonObject = factory.objectNode() jsonObject.put("pr", invoice) @@ -343,7 +343,7 @@ class CashuProcessor { val url = token.mint + "/melt" // Melt cashu tokens at Mint val client = HttpClientManager.getHttpClient(forceProxy(url)) - val factory = Event.mapper.nodeFactory + val factory = JsonNodeFactory.instance val jsonObject = factory.objectNode() diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/EmojiUtils.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/EmojiUtils.kt index c47a21b0d..001c0faea 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/EmojiUtils.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/EmojiUtils.kt @@ -20,7 +20,7 @@ */ package com.vitorpamplona.amethyst.service -import com.vitorpamplona.quartz.events.ImmutableListOfLists +import com.vitorpamplona.quartz.nip02FollowList.ImmutableListOfLists fun String.isUTF16Char(pos: Int): Boolean = Character.charCount(this.codePointAt(pos)) == 2 diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/Nip11RelayInfoRetriever.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/Nip11RelayInfoRetriever.kt index 3056edf9d..fea9d0a0b 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/Nip11RelayInfoRetriever.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/Nip11RelayInfoRetriever.kt @@ -23,8 +23,8 @@ package com.vitorpamplona.amethyst.service import android.util.Log import android.util.LruCache import com.vitorpamplona.amethyst.service.okhttp.HttpClientManager -import com.vitorpamplona.quartz.encoders.Nip11RelayInformation -import com.vitorpamplona.quartz.encoders.RelayUrlFormatter +import com.vitorpamplona.quartz.nip11RelayInfo.Nip11RelayInformation +import com.vitorpamplona.quartz.nip65RelayList.RelayUrlFormatter import com.vitorpamplona.quartz.utils.TimeUtils import kotlinx.coroutines.CancellationException import okhttp3.Call diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrAccountDataSource.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrAccountDataSource.kt index 57ca3c884..9a18ce848 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrAccountDataSource.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrAccountDataSource.kt @@ -30,47 +30,46 @@ import com.vitorpamplona.ammolite.relays.Relay import com.vitorpamplona.ammolite.relays.TypedFilter import com.vitorpamplona.ammolite.relays.filters.EOSETime import com.vitorpamplona.ammolite.relays.filters.SincePerRelayFilter -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.events.AdvertisedRelayListEvent -import com.vitorpamplona.quartz.events.AppSpecificDataEvent -import com.vitorpamplona.quartz.events.BadgeAwardEvent -import com.vitorpamplona.quartz.events.BadgeProfilesEvent -import com.vitorpamplona.quartz.events.BlossomServersEvent -import com.vitorpamplona.quartz.events.BookmarkListEvent -import com.vitorpamplona.quartz.events.CalendarDateSlotEvent -import com.vitorpamplona.quartz.events.CalendarRSVPEvent -import com.vitorpamplona.quartz.events.CalendarTimeSlotEvent -import com.vitorpamplona.quartz.events.ChannelMessageEvent -import com.vitorpamplona.quartz.events.ChatMessageRelayListEvent -import com.vitorpamplona.quartz.events.CommentEvent -import com.vitorpamplona.quartz.events.ContactListEvent -import com.vitorpamplona.quartz.events.DraftEvent -import com.vitorpamplona.quartz.events.EmojiPackSelectionEvent -import com.vitorpamplona.quartz.events.Event -import com.vitorpamplona.quartz.events.EventInterface -import com.vitorpamplona.quartz.events.FileServersEvent -import com.vitorpamplona.quartz.events.GenericRepostEvent -import com.vitorpamplona.quartz.events.GiftWrapEvent -import com.vitorpamplona.quartz.events.GitIssueEvent -import com.vitorpamplona.quartz.events.GitPatchEvent -import com.vitorpamplona.quartz.events.GitReplyEvent -import com.vitorpamplona.quartz.events.HighlightEvent -import com.vitorpamplona.quartz.events.InteractiveStoryPrologueEvent -import com.vitorpamplona.quartz.events.InteractiveStorySceneEvent -import com.vitorpamplona.quartz.events.LnZapEvent -import com.vitorpamplona.quartz.events.LnZapPaymentResponseEvent -import com.vitorpamplona.quartz.events.MetadataEvent -import com.vitorpamplona.quartz.events.MuteListEvent -import com.vitorpamplona.quartz.events.PeopleListEvent -import com.vitorpamplona.quartz.events.PollNoteEvent -import com.vitorpamplona.quartz.events.PrivateOutboxRelayListEvent -import com.vitorpamplona.quartz.events.ReactionEvent -import com.vitorpamplona.quartz.events.ReportEvent -import com.vitorpamplona.quartz.events.RepostEvent -import com.vitorpamplona.quartz.events.SealedGossipEvent -import com.vitorpamplona.quartz.events.SearchRelayListEvent -import com.vitorpamplona.quartz.events.StatusEvent -import com.vitorpamplona.quartz.events.TextNoteEvent +import com.vitorpamplona.quartz.blossom.BlossomServersEvent +import com.vitorpamplona.quartz.experimental.edits.PrivateOutboxRelayListEvent +import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStoryPrologueEvent +import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStorySceneEvent +import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.MetadataEvent +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent +import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent +import com.vitorpamplona.quartz.nip17Dm.ChatMessageRelayListEvent +import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent +import com.vitorpamplona.quartz.nip18Reposts.RepostEvent +import com.vitorpamplona.quartz.nip22Comments.CommentEvent +import com.vitorpamplona.quartz.nip25Reactions.ReactionEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelMessageEvent +import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiPackSelectionEvent +import com.vitorpamplona.quartz.nip34Git.GitIssueEvent +import com.vitorpamplona.quartz.nip34Git.GitPatchEvent +import com.vitorpamplona.quartz.nip34Git.GitReplyEvent +import com.vitorpamplona.quartz.nip37Drafts.DraftEvent +import com.vitorpamplona.quartz.nip38UserStatus.StatusEvent +import com.vitorpamplona.quartz.nip47WalletConnect.LnZapPaymentResponseEvent +import com.vitorpamplona.quartz.nip50Search.SearchRelayListEvent +import com.vitorpamplona.quartz.nip51Lists.BookmarkListEvent +import com.vitorpamplona.quartz.nip51Lists.MuteListEvent +import com.vitorpamplona.quartz.nip51Lists.PeopleListEvent +import com.vitorpamplona.quartz.nip52Calendar.CalendarDateSlotEvent +import com.vitorpamplona.quartz.nip52Calendar.CalendarRSVPEvent +import com.vitorpamplona.quartz.nip52Calendar.CalendarTimeSlotEvent +import com.vitorpamplona.quartz.nip56Reports.ReportEvent +import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent +import com.vitorpamplona.quartz.nip58Badges.BadgeAwardEvent +import com.vitorpamplona.quartz.nip58Badges.BadgeProfilesEvent +import com.vitorpamplona.quartz.nip59Giftwrap.GiftWrapEvent +import com.vitorpamplona.quartz.nip59Giftwrap.SealedGossipEvent +import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent +import com.vitorpamplona.quartz.nip78AppData.AppSpecificDataEvent +import com.vitorpamplona.quartz.nip84Highlights.HighlightEvent +import com.vitorpamplona.quartz.nip96FileStorage.FileServersEvent import com.vitorpamplona.quartz.utils.TimeUtils // TODO: Migrate this to a property of AccountVi @@ -315,7 +314,7 @@ object NostrAccountDataSource : AmethystNostrDataSource("AccountData") { is PrivateOutboxRelayListEvent -> { val note = LocalCache.getAddressableNoteIfExists(event.addressTag()) val noteEvent = note?.event - if (noteEvent == null || event.createdAt > noteEvent.createdAt()) { + if (noteEvent == null || event.createdAt > noteEvent.createdAt) { event.privateTags(account.signer) { LocalCache.justConsume(event, relay) } @@ -329,7 +328,7 @@ object NostrAccountDataSource : AmethystNostrDataSource("AccountData") { val note = LocalCache.getAddressableNoteIfExists(event.addressTag()) val noteEvent = note?.event if (noteEvent != null) { - if (event.createdAt > noteEvent.createdAt() || relay.brief !in note.relays) { + if (event.createdAt > noteEvent.createdAt || relay.brief !in note.relays) { LocalCache.consume(event, relay) } } else { @@ -431,10 +430,10 @@ object NostrAccountDataSource : AmethystNostrDataSource("AccountData") { } private fun markInnerAsSeenOnRelay( - newNoteEvent: EventInterface, + newNoteEvent: Event, relay: Relay, ) { - markInnerAsSeenOnRelay(newNoteEvent.id(), relay) + markInnerAsSeenOnRelay(newNoteEvent.id, relay) } private fun markInnerAsSeenOnRelay( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrChannelDataSource.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrChannelDataSource.kt index b8f279938..ec7320cbb 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrChannelDataSource.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrChannelDataSource.kt @@ -27,8 +27,8 @@ import com.vitorpamplona.amethyst.model.PublicChatChannel import com.vitorpamplona.ammolite.relays.FeedType import com.vitorpamplona.ammolite.relays.TypedFilter import com.vitorpamplona.ammolite.relays.filters.SincePerRelayFilter -import com.vitorpamplona.quartz.events.ChannelMessageEvent -import com.vitorpamplona.quartz.events.LiveActivitiesChatMessageEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelMessageEvent +import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesChatMessageEvent object NostrChannelDataSource : AmethystNostrDataSource("ChatroomFeed") { var account: Account? = null diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrChatroomDataSource.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrChatroomDataSource.kt index d05ea4cf6..0d2ca1d9e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrChatroomDataSource.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrChatroomDataSource.kt @@ -25,8 +25,8 @@ import com.vitorpamplona.amethyst.service.relays.EOSEAccount import com.vitorpamplona.ammolite.relays.FeedType import com.vitorpamplona.ammolite.relays.TypedFilter import com.vitorpamplona.ammolite.relays.filters.SincePerRelayFilter -import com.vitorpamplona.quartz.events.ChatroomKey -import com.vitorpamplona.quartz.events.PrivateDmEvent +import com.vitorpamplona.quartz.nip04Dm.PrivateDmEvent +import com.vitorpamplona.quartz.nip17Dm.ChatroomKey object NostrChatroomDataSource : AmethystNostrDataSource("ChatroomFeed") { lateinit var account: Account diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrChatroomListDataSource.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrChatroomListDataSource.kt index b3ef5a1a0..5e8f13eb0 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrChatroomListDataSource.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrChatroomListDataSource.kt @@ -26,10 +26,10 @@ import com.vitorpamplona.ammolite.relays.EVENT_FINDER_TYPES import com.vitorpamplona.ammolite.relays.FeedType import com.vitorpamplona.ammolite.relays.TypedFilter import com.vitorpamplona.ammolite.relays.filters.SincePerRelayFilter -import com.vitorpamplona.quartz.events.ChannelCreateEvent -import com.vitorpamplona.quartz.events.ChannelMessageEvent -import com.vitorpamplona.quartz.events.ChannelMetadataEvent -import com.vitorpamplona.quartz.events.PrivateDmEvent +import com.vitorpamplona.quartz.nip04Dm.PrivateDmEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelCreateEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelMessageEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelMetadataEvent object NostrChatroomListDataSource : AmethystNostrDataSource("MailBoxFeed") { lateinit var account: Account diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrCommunityDataSource.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrCommunityDataSource.kt index 50c822932..e57b4c3f9 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrCommunityDataSource.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrCommunityDataSource.kt @@ -24,8 +24,8 @@ import com.vitorpamplona.amethyst.model.AddressableNote import com.vitorpamplona.ammolite.relays.COMMON_FEED_TYPES import com.vitorpamplona.ammolite.relays.TypedFilter import com.vitorpamplona.ammolite.relays.filters.SincePerRelayFilter -import com.vitorpamplona.quartz.events.CommunityDefinitionEvent -import com.vitorpamplona.quartz.events.CommunityPostApprovalEvent +import com.vitorpamplona.quartz.nip72ModCommunities.CommunityDefinitionEvent +import com.vitorpamplona.quartz.nip72ModCommunities.CommunityPostApprovalEvent object NostrCommunityDataSource : AmethystNostrDataSource("SingleCommunityFeed") { private var communityToWatch: AddressableNote? = null diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrDiscoveryDataSource.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrDiscoveryDataSource.kt index c55222eef..0e14b62bf 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrDiscoveryDataSource.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrDiscoveryDataSource.kt @@ -27,15 +27,15 @@ import com.vitorpamplona.ammolite.relays.FeedType import com.vitorpamplona.ammolite.relays.TypedFilter import com.vitorpamplona.ammolite.relays.filters.SinceAuthorPerRelayFilter import com.vitorpamplona.ammolite.relays.filters.SincePerRelayFilter -import com.vitorpamplona.quartz.events.AppDefinitionEvent -import com.vitorpamplona.quartz.events.ChannelCreateEvent -import com.vitorpamplona.quartz.events.ChannelMessageEvent -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.LiveActivitiesChatMessageEvent -import com.vitorpamplona.quartz.events.LiveActivitiesEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelCreateEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelMessageEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelMetadataEvent +import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesChatMessageEvent +import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent +import com.vitorpamplona.quartz.nip72ModCommunities.CommunityDefinitionEvent +import com.vitorpamplona.quartz.nip72ModCommunities.CommunityPostApprovalEvent +import com.vitorpamplona.quartz.nip89AppHandlers.AppDefinitionEvent +import com.vitorpamplona.quartz.nip99Classifieds.ClassifiedsEvent import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlinx.coroutines.launch diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrGeohashDataSource.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrGeohashDataSource.kt index 4e017b6eb..413d9a4f7 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrGeohashDataSource.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrGeohashDataSource.kt @@ -23,16 +23,16 @@ package com.vitorpamplona.amethyst.service import com.vitorpamplona.ammolite.relays.COMMON_FEED_TYPES import com.vitorpamplona.ammolite.relays.TypedFilter import com.vitorpamplona.ammolite.relays.filters.SincePerRelayFilter -import com.vitorpamplona.quartz.events.AudioHeaderEvent -import com.vitorpamplona.quartz.events.AudioTrackEvent -import com.vitorpamplona.quartz.events.ChannelMessageEvent -import com.vitorpamplona.quartz.events.ClassifiedsEvent -import com.vitorpamplona.quartz.events.CommentEvent -import com.vitorpamplona.quartz.events.HighlightEvent -import com.vitorpamplona.quartz.events.LongTextNoteEvent -import com.vitorpamplona.quartz.events.PollNoteEvent -import com.vitorpamplona.quartz.events.TextNoteEvent -import com.vitorpamplona.quartz.events.WikiNoteEvent +import com.vitorpamplona.quartz.experimental.audio.AudioHeaderEvent +import com.vitorpamplona.quartz.experimental.audio.AudioTrackEvent +import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent +import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent +import com.vitorpamplona.quartz.nip22Comments.CommentEvent +import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelMessageEvent +import com.vitorpamplona.quartz.nip54Wiki.WikiNoteEvent +import com.vitorpamplona.quartz.nip84Highlights.HighlightEvent +import com.vitorpamplona.quartz.nip99Classifieds.ClassifiedsEvent object NostrGeohashDataSource : AmethystNostrDataSource("SingleGeoHashFeed") { private var geohashToWatch: String? = null diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrHashtagDataSource.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrHashtagDataSource.kt index b53b6389d..9f81afd36 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrHashtagDataSource.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrHashtagDataSource.kt @@ -23,18 +23,18 @@ package com.vitorpamplona.amethyst.service import com.vitorpamplona.ammolite.relays.COMMON_FEED_TYPES import com.vitorpamplona.ammolite.relays.TypedFilter import com.vitorpamplona.ammolite.relays.filters.SincePerRelayFilter -import com.vitorpamplona.quartz.events.AudioHeaderEvent -import com.vitorpamplona.quartz.events.AudioTrackEvent -import com.vitorpamplona.quartz.events.ChannelMessageEvent -import com.vitorpamplona.quartz.events.ClassifiedsEvent -import com.vitorpamplona.quartz.events.CommentEvent -import com.vitorpamplona.quartz.events.HighlightEvent -import com.vitorpamplona.quartz.events.InteractiveStorySceneEvent -import com.vitorpamplona.quartz.events.LiveActivitiesChatMessageEvent -import com.vitorpamplona.quartz.events.LongTextNoteEvent -import com.vitorpamplona.quartz.events.PollNoteEvent -import com.vitorpamplona.quartz.events.TextNoteEvent -import com.vitorpamplona.quartz.events.WikiNoteEvent +import com.vitorpamplona.quartz.experimental.audio.AudioHeaderEvent +import com.vitorpamplona.quartz.experimental.audio.AudioTrackEvent +import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStorySceneEvent +import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent +import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent +import com.vitorpamplona.quartz.nip22Comments.CommentEvent +import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelMessageEvent +import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesChatMessageEvent +import com.vitorpamplona.quartz.nip54Wiki.WikiNoteEvent +import com.vitorpamplona.quartz.nip84Highlights.HighlightEvent +import com.vitorpamplona.quartz.nip99Classifieds.ClassifiedsEvent object NostrHashtagDataSource : AmethystNostrDataSource("SingleHashtagFeed") { private var hashtagToWatch: String? = null diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrHomeDataSource.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrHomeDataSource.kt index 23e5cf206..ca6527a1f 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrHomeDataSource.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrHomeDataSource.kt @@ -27,24 +27,24 @@ import com.vitorpamplona.ammolite.relays.FeedType import com.vitorpamplona.ammolite.relays.TypedFilter import com.vitorpamplona.ammolite.relays.filters.SinceAuthorPerRelayFilter import com.vitorpamplona.ammolite.relays.filters.SincePerRelayFilter -import com.vitorpamplona.quartz.events.AdvertisedRelayListEvent -import com.vitorpamplona.quartz.events.AudioHeaderEvent -import com.vitorpamplona.quartz.events.AudioTrackEvent -import com.vitorpamplona.quartz.events.ClassifiedsEvent -import com.vitorpamplona.quartz.events.CommentEvent -import com.vitorpamplona.quartz.events.CommunityPostApprovalEvent -import com.vitorpamplona.quartz.events.GenericRepostEvent -import com.vitorpamplona.quartz.events.HighlightEvent -import com.vitorpamplona.quartz.events.InteractiveStoryPrologueEvent -import com.vitorpamplona.quartz.events.LiveActivitiesChatMessageEvent -import com.vitorpamplona.quartz.events.LiveActivitiesEvent -import com.vitorpamplona.quartz.events.LongTextNoteEvent -import com.vitorpamplona.quartz.events.MetadataEvent -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 com.vitorpamplona.quartz.events.WikiNoteEvent +import com.vitorpamplona.quartz.experimental.audio.AudioHeaderEvent +import com.vitorpamplona.quartz.experimental.audio.AudioTrackEvent +import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStoryPrologueEvent +import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent +import com.vitorpamplona.quartz.nip01Core.MetadataEvent +import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent +import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent +import com.vitorpamplona.quartz.nip18Reposts.RepostEvent +import com.vitorpamplona.quartz.nip22Comments.CommentEvent +import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent +import com.vitorpamplona.quartz.nip51Lists.PinListEvent +import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesChatMessageEvent +import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent +import com.vitorpamplona.quartz.nip54Wiki.WikiNoteEvent +import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent +import com.vitorpamplona.quartz.nip72ModCommunities.CommunityPostApprovalEvent +import com.vitorpamplona.quartz.nip84Highlights.HighlightEvent +import com.vitorpamplona.quartz.nip99Classifieds.ClassifiedsEvent import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlinx.coroutines.launch diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrLnZapPaymentResponseDataSource.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrLnZapPaymentResponseDataSource.kt index 8c1c93070..5ce56efb2 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrLnZapPaymentResponseDataSource.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrLnZapPaymentResponseDataSource.kt @@ -23,8 +23,8 @@ package com.vitorpamplona.amethyst.service import com.vitorpamplona.ammolite.relays.FeedType import com.vitorpamplona.ammolite.relays.TypedFilter import com.vitorpamplona.ammolite.relays.filters.SincePerRelayFilter -import com.vitorpamplona.quartz.events.LnZapPaymentResponseEvent -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip47WalletConnect.LnZapPaymentResponseEvent class NostrLnZapPaymentResponseDataSource( private val fromServiceHex: String, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrSearchEventOrUserDataSource.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrSearchEventOrUserDataSource.kt index d1091f03a..5d36fe3d4 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrSearchEventOrUserDataSource.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrSearchEventOrUserDataSource.kt @@ -24,35 +24,42 @@ import com.vitorpamplona.ammolite.relays.ALL_FEED_TYPES import com.vitorpamplona.ammolite.relays.FeedType import com.vitorpamplona.ammolite.relays.TypedFilter import com.vitorpamplona.ammolite.relays.filters.SincePerRelayFilter +import com.vitorpamplona.quartz.crypto.Hex import com.vitorpamplona.quartz.crypto.KeyPair -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.Hex -import com.vitorpamplona.quartz.encoders.HexValidator -import com.vitorpamplona.quartz.encoders.Nip19Bech32 -import com.vitorpamplona.quartz.encoders.bechToBytes -import com.vitorpamplona.quartz.encoders.toHexKey -import com.vitorpamplona.quartz.events.AudioHeaderEvent -import com.vitorpamplona.quartz.events.AudioTrackEvent -import com.vitorpamplona.quartz.events.BadgeDefinitionEvent -import com.vitorpamplona.quartz.events.BookmarkListEvent -import com.vitorpamplona.quartz.events.ChannelCreateEvent -import com.vitorpamplona.quartz.events.ChannelMetadataEvent -import com.vitorpamplona.quartz.events.ClassifiedsEvent -import com.vitorpamplona.quartz.events.CommentEvent -import com.vitorpamplona.quartz.events.CommunityDefinitionEvent -import com.vitorpamplona.quartz.events.EmojiPackEvent -import com.vitorpamplona.quartz.events.HighlightEvent -import com.vitorpamplona.quartz.events.InteractiveStoryPrologueEvent -import com.vitorpamplona.quartz.events.InteractiveStorySceneEvent -import com.vitorpamplona.quartz.events.LiveActivitiesEvent -import com.vitorpamplona.quartz.events.LongTextNoteEvent -import com.vitorpamplona.quartz.events.MetadataEvent -import com.vitorpamplona.quartz.events.NNSEvent -import com.vitorpamplona.quartz.events.PeopleListEvent -import com.vitorpamplona.quartz.events.PinListEvent -import com.vitorpamplona.quartz.events.PollNoteEvent -import com.vitorpamplona.quartz.events.TextNoteEvent -import com.vitorpamplona.quartz.events.WikiNoteEvent +import com.vitorpamplona.quartz.experimental.audio.AudioHeaderEvent +import com.vitorpamplona.quartz.experimental.audio.AudioTrackEvent +import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStoryPrologueEvent +import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStorySceneEvent +import com.vitorpamplona.quartz.experimental.nns.NNSEvent +import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent +import com.vitorpamplona.quartz.nip01Core.MetadataEvent +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.toHexKey +import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent +import com.vitorpamplona.quartz.nip19Bech32Entities.Nip19Parser +import com.vitorpamplona.quartz.nip19Bech32Entities.bech32.bechToBytes +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NAddress +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NEmbed +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NEvent +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NProfile +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NPub +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NRelay +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NSec +import com.vitorpamplona.quartz.nip19Bech32Entities.parse +import com.vitorpamplona.quartz.nip22Comments.CommentEvent +import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelCreateEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelMetadataEvent +import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiPackEvent +import com.vitorpamplona.quartz.nip51Lists.BookmarkListEvent +import com.vitorpamplona.quartz.nip51Lists.PeopleListEvent +import com.vitorpamplona.quartz.nip51Lists.PinListEvent +import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent +import com.vitorpamplona.quartz.nip54Wiki.WikiNoteEvent +import com.vitorpamplona.quartz.nip58Badges.BadgeDefinitionEvent +import com.vitorpamplona.quartz.nip72ModCommunities.CommunityDefinitionEvent +import com.vitorpamplona.quartz.nip84Highlights.HighlightEvent +import com.vitorpamplona.quartz.nip99Classifieds.ClassifiedsEvent import kotlin.coroutines.cancellation.CancellationException object NostrSearchEventOrUserDataSource : AmethystNostrDataSource("SearchEventFeed") { @@ -67,21 +74,21 @@ object NostrSearchEventOrUserDataSource : AmethystNostrDataSource("SearchEventFe val hexToWatch = try { val isAStraightHex = - if (HexValidator.isHex(mySearchString)) { + if (Hex.isHex(mySearchString)) { Hex.decode(mySearchString).toHexKey() } else { null } - when (val parsed = Nip19Bech32.uriToRoute(mySearchString)?.entity) { - is Nip19Bech32.NSec -> KeyPair(privKey = parsed.hex.bechToBytes()).pubKey.toHexKey() - is Nip19Bech32.NPub -> parsed.hex - is Nip19Bech32.NProfile -> parsed.hex - is Nip19Bech32.Note -> parsed.hex - is Nip19Bech32.NEvent -> parsed.hex - is Nip19Bech32.NEmbed -> parsed.event.id - is Nip19Bech32.NRelay -> null - is Nip19Bech32.NAddress -> parsed.atag + when (val parsed = Nip19Parser.uriToRoute(mySearchString)?.entity) { + is NSec -> KeyPair(privKey = parsed.hex.bechToBytes()).pubKey.toHexKey() + is NPub -> parsed.hex + is NProfile -> parsed.hex + is com.vitorpamplona.quartz.nip19Bech32Entities.entities.Note -> parsed.hex + is NEvent -> parsed.hex + is NEmbed -> parsed.event.id + is NRelay -> null + is NAddress -> parsed.aTag() else -> isAStraightHex } } catch (e: Exception) { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleChannelDataSource.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleChannelDataSource.kt index 4dc3f5c69..39bbf9355 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleChannelDataSource.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleChannelDataSource.kt @@ -27,8 +27,8 @@ import com.vitorpamplona.ammolite.relays.EVENT_FINDER_TYPES import com.vitorpamplona.ammolite.relays.FeedType import com.vitorpamplona.ammolite.relays.TypedFilter import com.vitorpamplona.ammolite.relays.filters.SincePerRelayFilter -import com.vitorpamplona.quartz.events.ChannelCreateEvent -import com.vitorpamplona.quartz.events.ChannelMetadataEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelCreateEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelMetadataEvent object NostrSingleChannelDataSource : AmethystNostrDataSource("SingleChannelFeed") { private var channelsToWatch = setOf() diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleEventDataSource.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleEventDataSource.kt index 016ad68f1..1cc9266f9 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleEventDataSource.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleEventDataSource.kt @@ -27,22 +27,22 @@ import com.vitorpamplona.ammolite.relays.EVENT_FINDER_TYPES import com.vitorpamplona.ammolite.relays.TypedFilter import com.vitorpamplona.ammolite.relays.filters.EOSETime import com.vitorpamplona.ammolite.relays.filters.SincePerRelayFilter -import com.vitorpamplona.quartz.events.CommunityPostApprovalEvent -import com.vitorpamplona.quartz.events.DeletionEvent -import com.vitorpamplona.quartz.events.GenericRepostEvent -import com.vitorpamplona.quartz.events.GitReplyEvent -import com.vitorpamplona.quartz.events.LiveActivitiesChatMessageEvent -import com.vitorpamplona.quartz.events.LnZapEvent -import com.vitorpamplona.quartz.events.NIP90ContentDiscoveryResponseEvent -import com.vitorpamplona.quartz.events.NIP90StatusEvent -import com.vitorpamplona.quartz.events.OtsEvent -import com.vitorpamplona.quartz.events.PollNoteEvent -import com.vitorpamplona.quartz.events.ReactionEvent -import com.vitorpamplona.quartz.events.ReportEvent -import com.vitorpamplona.quartz.events.RepostEvent -import com.vitorpamplona.quartz.events.TextNoteEvent -import com.vitorpamplona.quartz.events.TextNoteModificationEvent -import com.vitorpamplona.quartz.events.TorrentCommentEvent +import com.vitorpamplona.quartz.experimental.edits.TextNoteModificationEvent +import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent +import com.vitorpamplona.quartz.nip03Timestamp.OtsEvent +import com.vitorpamplona.quartz.nip09Deletions.DeletionEvent +import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent +import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent +import com.vitorpamplona.quartz.nip18Reposts.RepostEvent +import com.vitorpamplona.quartz.nip25Reactions.ReactionEvent +import com.vitorpamplona.quartz.nip34Git.GitReplyEvent +import com.vitorpamplona.quartz.nip35Torrents.TorrentCommentEvent +import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesChatMessageEvent +import com.vitorpamplona.quartz.nip56Reports.ReportEvent +import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent +import com.vitorpamplona.quartz.nip72ModCommunities.CommunityPostApprovalEvent +import com.vitorpamplona.quartz.nip90Dvms.NIP90ContentDiscoveryResponseEvent +import com.vitorpamplona.quartz.nip90Dvms.NIP90StatusEvent object NostrSingleEventDataSource : AmethystNostrDataSource("SingleEventFeed") { private var nextEventsToWatch = setOf() diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleUserDataSource.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleUserDataSource.kt index 404fd70ab..d79108c8a 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleUserDataSource.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleUserDataSource.kt @@ -25,12 +25,12 @@ import com.vitorpamplona.ammolite.relays.EVENT_FINDER_TYPES import com.vitorpamplona.ammolite.relays.TypedFilter import com.vitorpamplona.ammolite.relays.filters.EOSETime import com.vitorpamplona.ammolite.relays.filters.SincePerRelayFilter -import com.vitorpamplona.quartz.events.AdvertisedRelayListEvent -import com.vitorpamplona.quartz.events.ChatMessageRelayListEvent -import com.vitorpamplona.quartz.events.MetadataEvent -import com.vitorpamplona.quartz.events.RelationshipStatusEvent -import com.vitorpamplona.quartz.events.ReportEvent -import com.vitorpamplona.quartz.events.StatusEvent +import com.vitorpamplona.quartz.experimental.relationshipStatus.RelationshipStatusEvent +import com.vitorpamplona.quartz.nip01Core.MetadataEvent +import com.vitorpamplona.quartz.nip17Dm.ChatMessageRelayListEvent +import com.vitorpamplona.quartz.nip38UserStatus.StatusEvent +import com.vitorpamplona.quartz.nip56Reports.ReportEvent +import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent object NostrSingleUserDataSource : AmethystNostrDataSource("SingleUserFeed") { private var usersToWatch = setOf() diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrThreadDataSource.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrThreadDataSource.kt index 3e509ed3c..8a740c138 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrThreadDataSource.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrThreadDataSource.kt @@ -42,7 +42,7 @@ object NostrThreadDataSource : AmethystNostrDataSource("SingleThreadFeed") { .ifEmpty { null } val address = if (branch.root is AddressableNote) branch.root.idHex else null - val event = if (branch.root !is AddressableNote) branch.root.idHex else branch.root.event?.id() + val event = if (branch.root !is AddressableNote) branch.root.idHex else branch.root.event?.id return listOfNotNull( eventsToLoad?.let { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrUserProfileDataSource.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrUserProfileDataSource.kt index c94fea443..9a7a9e033 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrUserProfileDataSource.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrUserProfileDataSource.kt @@ -24,32 +24,32 @@ import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.ammolite.relays.COMMON_FEED_TYPES import com.vitorpamplona.ammolite.relays.TypedFilter import com.vitorpamplona.ammolite.relays.filters.SincePerRelayFilter -import com.vitorpamplona.quartz.events.AppRecommendationEvent -import com.vitorpamplona.quartz.events.AudioHeaderEvent -import com.vitorpamplona.quartz.events.AudioTrackEvent -import com.vitorpamplona.quartz.events.BadgeAwardEvent -import com.vitorpamplona.quartz.events.BadgeProfilesEvent -import com.vitorpamplona.quartz.events.BookmarkListEvent -import com.vitorpamplona.quartz.events.CommentEvent -import com.vitorpamplona.quartz.events.ContactListEvent -import com.vitorpamplona.quartz.events.GenericRepostEvent -import com.vitorpamplona.quartz.events.HighlightEvent -import com.vitorpamplona.quartz.events.InteractiveStoryPrologueEvent -import com.vitorpamplona.quartz.events.LnZapEvent -import com.vitorpamplona.quartz.events.LongTextNoteEvent -import com.vitorpamplona.quartz.events.MetadataEvent -import com.vitorpamplona.quartz.events.PeopleListEvent -import com.vitorpamplona.quartz.events.PictureEvent -import com.vitorpamplona.quartz.events.PinListEvent -import com.vitorpamplona.quartz.events.PollNoteEvent -import com.vitorpamplona.quartz.events.ProfileGalleryEntryEvent -import com.vitorpamplona.quartz.events.RepostEvent -import com.vitorpamplona.quartz.events.TextNoteEvent -import com.vitorpamplona.quartz.events.TorrentCommentEvent -import com.vitorpamplona.quartz.events.TorrentEvent -import com.vitorpamplona.quartz.events.VideoHorizontalEvent -import com.vitorpamplona.quartz.events.VideoVerticalEvent -import com.vitorpamplona.quartz.events.WikiNoteEvent +import com.vitorpamplona.quartz.experimental.audio.AudioHeaderEvent +import com.vitorpamplona.quartz.experimental.audio.AudioTrackEvent +import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStoryPrologueEvent +import com.vitorpamplona.quartz.experimental.profileGallery.ProfileGalleryEntryEvent +import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent +import com.vitorpamplona.quartz.nip01Core.MetadataEvent +import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent +import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent +import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent +import com.vitorpamplona.quartz.nip18Reposts.RepostEvent +import com.vitorpamplona.quartz.nip22Comments.CommentEvent +import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent +import com.vitorpamplona.quartz.nip35Torrents.TorrentCommentEvent +import com.vitorpamplona.quartz.nip35Torrents.TorrentEvent +import com.vitorpamplona.quartz.nip51Lists.BookmarkListEvent +import com.vitorpamplona.quartz.nip51Lists.PeopleListEvent +import com.vitorpamplona.quartz.nip51Lists.PinListEvent +import com.vitorpamplona.quartz.nip54Wiki.WikiNoteEvent +import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent +import com.vitorpamplona.quartz.nip58Badges.BadgeAwardEvent +import com.vitorpamplona.quartz.nip58Badges.BadgeProfilesEvent +import com.vitorpamplona.quartz.nip68Picture.PictureEvent +import com.vitorpamplona.quartz.nip71Video.VideoHorizontalEvent +import com.vitorpamplona.quartz.nip71Video.VideoVerticalEvent +import com.vitorpamplona.quartz.nip84Highlights.HighlightEvent +import com.vitorpamplona.quartz.nip89AppHandlers.AppRecommendationEvent object NostrUserProfileDataSource : AmethystNostrDataSource("UserProfileFeed") { var user: User? = null diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrVideoDataSource.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrVideoDataSource.kt index 62bed4179..7fbb2f386 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrVideoDataSource.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrVideoDataSource.kt @@ -27,11 +27,11 @@ import com.vitorpamplona.ammolite.relays.FeedType import com.vitorpamplona.ammolite.relays.TypedFilter import com.vitorpamplona.ammolite.relays.filters.SinceAuthorPerRelayFilter import com.vitorpamplona.ammolite.relays.filters.SincePerRelayFilter -import com.vitorpamplona.quartz.events.FileHeaderEvent -import com.vitorpamplona.quartz.events.FileStorageHeaderEvent -import com.vitorpamplona.quartz.events.PictureEvent -import com.vitorpamplona.quartz.events.VideoHorizontalEvent -import com.vitorpamplona.quartz.events.VideoVerticalEvent +import com.vitorpamplona.quartz.experimental.nip95.FileStorageHeaderEvent +import com.vitorpamplona.quartz.nip68Picture.PictureEvent +import com.vitorpamplona.quartz.nip71Video.VideoHorizontalEvent +import com.vitorpamplona.quartz.nip71Video.VideoVerticalEvent +import com.vitorpamplona.quartz.nip94FileMetadata.FileHeaderEvent import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlinx.coroutines.launch diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/ZapPaymentHandler.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/ZapPaymentHandler.kt index b1b639c18..7e77179cf 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/ZapPaymentHandler.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/ZapPaymentHandler.kt @@ -31,12 +31,13 @@ import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.service.NostrUserProfileDataSource.user import com.vitorpamplona.amethyst.service.lnurl.LightningAddressResolver import com.vitorpamplona.amethyst.ui.stringRes -import com.vitorpamplona.quartz.events.AdvertisedRelayListEvent -import com.vitorpamplona.quartz.events.AppDefinitionEvent -import com.vitorpamplona.quartz.events.LiveActivitiesEvent -import com.vitorpamplona.quartz.events.LnZapEvent -import com.vitorpamplona.quartz.events.PayInvoiceErrorResponse -import com.vitorpamplona.quartz.events.ZapSplitSetup +import com.vitorpamplona.quartz.nip47WalletConnect.PayInvoiceErrorResponse +import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent +import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent +import com.vitorpamplona.quartz.nip57Zaps.ZapSplitSetup +import com.vitorpamplona.quartz.nip57Zaps.zapSplitSetup +import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent +import com.vitorpamplona.quartz.nip89AppHandlers.AppDefinitionEvent import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.Dispatchers diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/lnurl/CachedLnInvoice.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/lnurl/CachedLnInvoice.kt index cd71080f2..ee4f1ac9e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/lnurl/CachedLnInvoice.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/lnurl/CachedLnInvoice.kt @@ -22,7 +22,7 @@ package com.vitorpamplona.amethyst.service.lnurl import android.util.LruCache import androidx.compose.runtime.Stable -import com.vitorpamplona.quartz.encoders.LnInvoiceUtil +import com.vitorpamplona.quartz.lightning.LnInvoiceUtil import kotlinx.coroutines.CancellationException import java.text.NumberFormat diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/lnurl/LightningAddressResolver.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/lnurl/LightningAddressResolver.kt index 089a16e4f..40ecb84b1 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/lnurl/LightningAddressResolver.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/lnurl/LightningAddressResolver.kt @@ -28,8 +28,8 @@ import com.vitorpamplona.amethyst.service.HttpStatusMessages import com.vitorpamplona.amethyst.service.checkNotInMainThread import com.vitorpamplona.amethyst.service.okhttp.HttpClientManager import com.vitorpamplona.amethyst.ui.stringRes -import com.vitorpamplona.quartz.encoders.LnInvoiceUtil -import com.vitorpamplona.quartz.encoders.Lud06 +import com.vitorpamplona.quartz.lightning.LnInvoiceUtil +import com.vitorpamplona.quartz.lightning.Lud06 import okhttp3.Request import okhttp3.Response import java.math.BigDecimal diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/EventNotificationConsumer.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/EventNotificationConsumer.kt index fc4db56e5..e3788f1da 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/EventNotificationConsumer.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/EventNotificationConsumer.kt @@ -34,18 +34,21 @@ import com.vitorpamplona.amethyst.service.notifications.NotificationUtils.sendDM import com.vitorpamplona.amethyst.service.notifications.NotificationUtils.sendZapNotification import com.vitorpamplona.amethyst.ui.note.showAmount import com.vitorpamplona.amethyst.ui.stringRes -import com.vitorpamplona.quartz.encoders.toNpub -import com.vitorpamplona.quartz.events.ChatMessageEncryptedFileHeaderEvent -import com.vitorpamplona.quartz.events.ChatMessageEvent -import com.vitorpamplona.quartz.events.DraftEvent -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 com.vitorpamplona.quartz.signers.NostrSigner -import com.vitorpamplona.quartz.signers.NostrSignerExternal +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.people.isTaggedUser +import com.vitorpamplona.quartz.nip01Core.people.taggedUsers +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip04Dm.PrivateDmEvent +import com.vitorpamplona.quartz.nip17Dm.ChatMessageEncryptedFileHeaderEvent +import com.vitorpamplona.quartz.nip17Dm.ChatMessageEvent +import com.vitorpamplona.quartz.nip19Bech32Entities.toNpub +import com.vitorpamplona.quartz.nip21UriScheme.toNostrUri +import com.vitorpamplona.quartz.nip37Drafts.DraftEvent +import com.vitorpamplona.quartz.nip55AndroidSigner.NostrSignerExternal +import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent +import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent +import com.vitorpamplona.quartz.nip59Giftwrap.GiftWrapEvent +import com.vitorpamplona.quartz.nip59Giftwrap.SealedGossipEvent import com.vitorpamplona.quartz.utils.TimeUtils import java.math.BigDecimal import kotlin.coroutines.cancellation.CancellationException @@ -223,7 +226,7 @@ class EventNotificationConsumer( ) if (isKnownRoom) { - val content = chatNote.event?.content() ?: "" + val content = chatNote.event?.content ?: "" val user = chatNote.author?.toBestDisplayName() ?: "" val userPicture = chatNote.author?.profilePicture() val noteUri = chatNote.toNEvent() + "?account=" + acc.keyPair.pubKey.toNpub() @@ -268,7 +271,7 @@ class EventNotificationConsumer( ) if (isKnownRoom) { - val content = chatNote.event?.content() ?: "" + val content = chatNote.event?.content ?: "" val user = chatNote.author?.toBestDisplayName() ?: "" val userPicture = chatNote.author?.profilePicture() val noteUri = chatNote.toNEvent() + "?account=" + acc.keyPair.pubKey.toNpub() @@ -350,7 +353,7 @@ class EventNotificationConsumer( onReady(it.content) } } else { - event?.content()?.let { onReady(it) } + event?.content?.let { onReady(it) } } } @@ -391,7 +394,7 @@ class EventNotificationConsumer( val author = LocalCache.getOrCreateUser(it.pubKey) val senderInfo = Pair(author, it.content.ifBlank { null }) - if (noteZapped.event?.content() != null) { + if (noteZapped.event?.content != null) { decryptContent(noteZapped, signer) { Log.d(TAG, "Notify Decrypted if Private Note") diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/PokeyReceiver.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/PokeyReceiver.kt index 07c54c582..168fb2e91 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/PokeyReceiver.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/PokeyReceiver.kt @@ -24,7 +24,7 @@ import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.util.Log -import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.nip01Core.core.Event import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob @@ -50,7 +50,9 @@ class PokeyReceiver : BroadcastReceiver() { scope.launch(Dispatchers.IO) { try { - EventNotificationConsumer(context.applicationContext).findAccountAndConsume(Event.fromJson(eventStr)) + EventNotificationConsumer(context.applicationContext).findAccountAndConsume( + Event.fromJson(eventStr), + ) } catch (e: Exception) { Log.e(TAG, "Failed to parse Pokey Event", e) } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/RegisterAccounts.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/RegisterAccounts.kt index 567fc7452..7b684007b 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/RegisterAccounts.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/RegisterAccounts.kt @@ -29,8 +29,8 @@ import com.vitorpamplona.amethyst.launchAndWaitAll import com.vitorpamplona.amethyst.model.AccountSettings import com.vitorpamplona.amethyst.service.okhttp.HttpClientManager import com.vitorpamplona.amethyst.tryAndWait -import com.vitorpamplona.quartz.events.RelayAuthEvent -import com.vitorpamplona.quartz.signers.NostrSignerExternal +import com.vitorpamplona.quartz.nip42RelayAuth.RelayAuthEvent +import com.vitorpamplona.quartz.nip55AndroidSigner.NostrSignerExternal import kotlinx.coroutines.CancellationException import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/okhttp/EncryptedBlobInterceptor.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/okhttp/EncryptedBlobInterceptor.kt index c42df6d5c..07aa7e2a5 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/okhttp/EncryptedBlobInterceptor.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/okhttp/EncryptedBlobInterceptor.kt @@ -21,8 +21,8 @@ package com.vitorpamplona.amethyst.service.okhttp import android.util.Log -import com.vitorpamplona.quartz.crypto.nip17.AESGCM -import com.vitorpamplona.quartz.crypto.nip17.NostrCipher +import com.vitorpamplona.quartz.nip17Dm.AESGCM +import com.vitorpamplona.quartz.nip17Dm.NostrCipher import okhttp3.Interceptor import okhttp3.Response import okhttp3.ResponseBody.Companion.toResponseBody diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/okhttp/EncryptionKeyCache.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/okhttp/EncryptionKeyCache.kt index 7c9006525..190bb64ea 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/okhttp/EncryptionKeyCache.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/okhttp/EncryptionKeyCache.kt @@ -21,7 +21,7 @@ package com.vitorpamplona.amethyst.service.okhttp import android.util.LruCache -import com.vitorpamplona.quartz.crypto.nip17.NostrCipher +import com.vitorpamplona.quartz.nip17Dm.NostrCipher /** * Neigther ExoPlayer, nor Coil support passing key and nonce to the Interceptor via diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/okhttp/HttpClientManager.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/okhttp/HttpClientManager.kt index b3dd23c4b..a3aae079a 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/okhttp/HttpClientManager.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/okhttp/HttpClientManager.kt @@ -21,7 +21,7 @@ package com.vitorpamplona.amethyst.service.okhttp import android.util.Log -import com.vitorpamplona.quartz.crypto.nip17.NostrCipher +import com.vitorpamplona.quartz.nip17Dm.NostrCipher import okhttp3.OkHttpClient import java.net.InetSocketAddress import java.net.Proxy diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/ots/OkHttpBlockstreamExplorer.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/ots/OkHttpBlockstreamExplorer.kt index 18f78207a..86b5957a5 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/ots/OkHttpBlockstreamExplorer.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/ots/OkHttpBlockstreamExplorer.kt @@ -25,9 +25,9 @@ import android.util.LruCache import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import com.vitorpamplona.amethyst.BuildConfig import com.vitorpamplona.amethyst.service.okhttp.HttpClientManager -import com.vitorpamplona.quartz.ots.BitcoinExplorer -import com.vitorpamplona.quartz.ots.BlockHeader -import com.vitorpamplona.quartz.ots.exceptions.UrlException +import com.vitorpamplona.quartz.nip03Timestamp.ots.BitcoinExplorer +import com.vitorpamplona.quartz.nip03Timestamp.ots.BlockHeader +import com.vitorpamplona.quartz.nip03Timestamp.ots.exceptions.UrlException import okhttp3.Request class OkHttpBlockstreamExplorer( @@ -65,7 +65,8 @@ class OkHttpBlockstreamExplorer( if (it.isSuccessful) { val jsonObject = jacksonObjectMapper().readTree(it.body.string()) - val blockHeader = BlockHeader() + val blockHeader = + BlockHeader() blockHeader.merkleroot = jsonObject["merkle_root"].asText() blockHeader.setTime(jsonObject["timestamp"].asInt().toString()) blockHeader.blockHash = hash @@ -75,7 +76,9 @@ class OkHttpBlockstreamExplorer( return blockHeader } else { - throw UrlException("Couldn't open $url: " + it.message + " " + it.code) + throw UrlException( + "Couldn't open $url: " + it.message + " " + it.code, + ) } } } @@ -114,7 +117,9 @@ class OkHttpBlockstreamExplorer( cacheHeights.put(height, blockHash) return blockHash } else { - throw UrlException("Couldn't open $url: " + it.message + " " + it.code) + throw UrlException( + "Couldn't open $url: " + it.message + " " + it.code, + ) } } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/ots/OkHttpCalendar.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/ots/OkHttpCalendar.kt index 561d8fa2a..c715891bd 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/ots/OkHttpCalendar.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/ots/OkHttpCalendar.kt @@ -22,14 +22,14 @@ package com.vitorpamplona.amethyst.service.ots import com.vitorpamplona.amethyst.BuildConfig import com.vitorpamplona.amethyst.service.okhttp.HttpClientManager -import com.vitorpamplona.quartz.encoders.Hex -import com.vitorpamplona.quartz.ots.ICalendar -import com.vitorpamplona.quartz.ots.StreamDeserializationContext -import com.vitorpamplona.quartz.ots.Timestamp -import com.vitorpamplona.quartz.ots.exceptions.CommitmentNotFoundException -import com.vitorpamplona.quartz.ots.exceptions.DeserializationException -import com.vitorpamplona.quartz.ots.exceptions.ExceededSizeException -import com.vitorpamplona.quartz.ots.exceptions.UrlException +import com.vitorpamplona.quartz.crypto.Hex +import com.vitorpamplona.quartz.nip03Timestamp.ots.ICalendar +import com.vitorpamplona.quartz.nip03Timestamp.ots.StreamDeserializationContext +import com.vitorpamplona.quartz.nip03Timestamp.ots.Timestamp +import com.vitorpamplona.quartz.nip03Timestamp.ots.exceptions.CommitmentNotFoundException +import com.vitorpamplona.quartz.nip03Timestamp.ots.exceptions.DeserializationException +import com.vitorpamplona.quartz.nip03Timestamp.ots.exceptions.ExceededSizeException +import com.vitorpamplona.quartz.nip03Timestamp.ots.exceptions.UrlException import okhttp3.MediaType.Companion.toMediaType import okhttp3.RequestBody.Companion.toRequestBody @@ -70,10 +70,15 @@ class OkHttpCalendar( client.newCall(request).execute().use { if (it.isSuccessful) { - val ctx = StreamDeserializationContext(it.body.bytes()) + val ctx = + StreamDeserializationContext( + it.body.bytes(), + ) return Timestamp.deserialize(ctx, digest) } else { - throw UrlException("Failed to open $url") + throw UrlException( + "Failed to open $url", + ) } } } catch (e: ExceededSizeException) { @@ -118,10 +123,15 @@ class OkHttpCalendar( client.newCall(request).execute().use { if (it.isSuccessful) { - val ctx = StreamDeserializationContext(it.body.bytes()) + val ctx = + StreamDeserializationContext( + it.body.bytes(), + ) return Timestamp.deserialize(ctx, commitment) } else { - throw CommitmentNotFoundException("Calendar response a status code != 200: " + it.code) + throw CommitmentNotFoundException( + "Calendar response a status code != 200: " + it.code, + ) } } } catch (e: DeserializationException) { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/ots/OkHttpCalendarAsyncSubmit.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/ots/OkHttpCalendarAsyncSubmit.kt index e04092040..eab7db495 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/ots/OkHttpCalendarAsyncSubmit.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/ots/OkHttpCalendarAsyncSubmit.kt @@ -22,9 +22,9 @@ package com.vitorpamplona.amethyst.service.ots import com.vitorpamplona.amethyst.BuildConfig import com.vitorpamplona.amethyst.service.okhttp.HttpClientManager -import com.vitorpamplona.quartz.ots.ICalendarAsyncSubmit -import com.vitorpamplona.quartz.ots.StreamDeserializationContext -import com.vitorpamplona.quartz.ots.Timestamp +import com.vitorpamplona.quartz.nip03Timestamp.ots.ICalendarAsyncSubmit +import com.vitorpamplona.quartz.nip03Timestamp.ots.StreamDeserializationContext +import com.vitorpamplona.quartz.nip03Timestamp.ots.Timestamp import okhttp3.MediaType.Companion.toMediaType import okhttp3.RequestBody.Companion.toRequestBody import java.util.Optional @@ -64,7 +64,10 @@ class OkHttpCalendarAsyncSubmit( client.newCall(request).execute().use { if (it.isSuccessful) { - val ctx = StreamDeserializationContext(it.body.bytes()) + val ctx = + StreamDeserializationContext( + it.body.bytes(), + ) val timestamp = Timestamp.deserialize(ctx, digest) val of = Optional.of(timestamp) queue!!.add(of) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/ots/OkHttpCalendarBuilder.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/ots/OkHttpCalendarBuilder.kt index 5240d8777..b792d5587 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/ots/OkHttpCalendarBuilder.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/ots/OkHttpCalendarBuilder.kt @@ -20,9 +20,9 @@ */ package com.vitorpamplona.amethyst.service.ots -import com.vitorpamplona.quartz.ots.CalendarBuilder -import com.vitorpamplona.quartz.ots.ICalendar -import com.vitorpamplona.quartz.ots.ICalendarAsyncSubmit +import com.vitorpamplona.quartz.nip03Timestamp.ots.CalendarBuilder +import com.vitorpamplona.quartz.nip03Timestamp.ots.ICalendar +import com.vitorpamplona.quartz.nip03Timestamp.ots.ICalendarAsyncSubmit class OkHttpCalendarBuilder( val forceProxy: (String) -> Boolean, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/uploads/EncryptFiles.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/uploads/EncryptFiles.kt index 188993569..f0410389d 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/uploads/EncryptFiles.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/uploads/EncryptFiles.kt @@ -24,8 +24,8 @@ import android.content.Context import android.net.Uri import androidx.core.net.toUri import com.vitorpamplona.quartz.crypto.CryptoUtils -import com.vitorpamplona.quartz.crypto.nip17.NostrCipher -import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.nip01Core.toHexKey +import com.vitorpamplona.quartz.nip17Dm.NostrCipher import java.io.File class EncryptFilesResult( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/uploads/FileHeader.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/uploads/FileHeader.kt index cf0417942..22efd5e46 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/uploads/FileHeader.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/uploads/FileHeader.kt @@ -31,8 +31,8 @@ import android.util.Log import com.vitorpamplona.amethyst.commons.blurhash.toBlurhash import com.vitorpamplona.amethyst.service.Blurhash import com.vitorpamplona.quartz.crypto.CryptoUtils -import com.vitorpamplona.quartz.encoders.Dimension -import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.nip01Core.toHexKey +import com.vitorpamplona.quartz.nip94FileMetadata.Dimension import kotlinx.coroutines.CancellationException import java.io.IOException diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/uploads/MediaUploadResult.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/uploads/MediaUploadResult.kt index b0d4eccf6..a3a3a7dc0 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/uploads/MediaUploadResult.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/uploads/MediaUploadResult.kt @@ -20,8 +20,8 @@ */ package com.vitorpamplona.amethyst.service.uploads -import com.vitorpamplona.quartz.encoders.Dimension -import com.vitorpamplona.quartz.encoders.HexKey +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip94FileMetadata.Dimension data class MediaUploadResult( // A publicly accessible URL to the BUD-01 GET / endpoint (optionally with a file extension) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/uploads/MultiOrchestrator.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/uploads/MultiOrchestrator.kt index f460e7f4f..16da96e91 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/uploads/MultiOrchestrator.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/uploads/MultiOrchestrator.kt @@ -26,7 +26,7 @@ import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.ui.actions.mediaServers.ServerName import com.vitorpamplona.amethyst.ui.actions.uploads.SelectedMedia import com.vitorpamplona.amethyst.ui.actions.uploads.SelectedMediaProcessing -import com.vitorpamplona.quartz.crypto.nip17.NostrCipher +import com.vitorpamplona.quartz.nip17Dm.NostrCipher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.joinAll diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/uploads/UploadOrchestrator.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/uploads/UploadOrchestrator.kt index ba663d559..b5d41763c 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/uploads/UploadOrchestrator.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/uploads/UploadOrchestrator.kt @@ -29,7 +29,7 @@ import com.vitorpamplona.amethyst.service.uploads.blossom.BlossomUploader import com.vitorpamplona.amethyst.service.uploads.nip96.Nip96Uploader import com.vitorpamplona.amethyst.ui.actions.mediaServers.ServerName import com.vitorpamplona.amethyst.ui.actions.mediaServers.ServerType -import com.vitorpamplona.quartz.crypto.nip17.NostrCipher +import com.vitorpamplona.quartz.nip17Dm.NostrCipher import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.map import kotlin.coroutines.cancellation.CancellationException diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/uploads/blossom/BlossomUploader.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/uploads/blossom/BlossomUploader.kt index abc6fc888..d37a25565 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/uploads/blossom/BlossomUploader.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/uploads/blossom/BlossomUploader.kt @@ -35,10 +35,10 @@ import com.vitorpamplona.amethyst.service.okhttp.HttpClientManager import com.vitorpamplona.amethyst.service.uploads.MediaUploadResult import com.vitorpamplona.amethyst.service.uploads.nip96.randomChars import com.vitorpamplona.amethyst.ui.stringRes +import com.vitorpamplona.quartz.blossom.BlossomAuthorizationEvent import com.vitorpamplona.quartz.crypto.CryptoUtils -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.toHexKey -import com.vitorpamplona.quartz.events.BlossomAuthorizationEvent +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.toHexKey import okhttp3.MediaType.Companion.toMediaType import okhttp3.Request import okhttp3.RequestBody diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/uploads/nip96/Nip96Uploader.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/uploads/nip96/Nip96Uploader.kt index cb7f76b61..788e384e9 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/uploads/nip96/Nip96Uploader.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/uploads/nip96/Nip96Uploader.kt @@ -35,8 +35,8 @@ import com.vitorpamplona.amethyst.service.checkNotInMainThread import com.vitorpamplona.amethyst.service.okhttp.HttpClientManager import com.vitorpamplona.amethyst.service.uploads.MediaUploadResult import com.vitorpamplona.amethyst.ui.stringRes -import com.vitorpamplona.quartz.encoders.Dimension -import com.vitorpamplona.quartz.events.HTTPAuthorizationEvent +import com.vitorpamplona.quartz.nip94FileMetadata.Dimension +import com.vitorpamplona.quartz.nip98HttpAuth.HTTPAuthorizationEvent import kotlinx.coroutines.delay import okhttp3.MediaType.Companion.toMediaType import okhttp3.MultipartBody diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/MainActivity.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/MainActivity.kt index 77908f03a..04e2b43fb 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/MainActivity.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/MainActivity.kt @@ -47,14 +47,20 @@ import com.vitorpamplona.amethyst.ui.screen.AccountScreen import com.vitorpamplona.amethyst.ui.screen.AccountStateViewModel import com.vitorpamplona.amethyst.ui.theme.AmethystTheme import com.vitorpamplona.amethyst.ui.tor.TorManager -import com.vitorpamplona.quartz.encoders.Nip19Bech32 -import com.vitorpamplona.quartz.encoders.Nip47WalletConnect -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 com.vitorpamplona.quartz.nip04Dm.PrivateDmEvent +import com.vitorpamplona.quartz.nip19Bech32Entities.Nip19Parser +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NAddress +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NEmbed +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NEvent +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NProfile +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NPub +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.Note +import com.vitorpamplona.quartz.nip28PublicChat.ChannelCreateEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelMessageEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelMetadataEvent +import com.vitorpamplona.quartz.nip47WalletConnect.Nip47WalletConnect +import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent +import com.vitorpamplona.quartz.nip72ModCommunities.CommunityDefinitionEvent import kotlinx.coroutines.CancellationException import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.Dispatchers @@ -262,12 +268,12 @@ fun uriToRoute(uri: String?): String? = if (uri?.startsWith("hashtag?id=") == true || uri?.startsWith("nostr:hashtag?id=") == true) { Route.Hashtag.route.replace("{id}", uri.removePrefix("nostr:").removePrefix("hashtag?id=")) } else { - val nip19 = Nip19Bech32.uriToRoute(uri)?.entity + val nip19 = Nip19Parser.uriToRoute(uri)?.entity when (nip19) { - is Nip19Bech32.NPub -> "User/${nip19.hex}" - is Nip19Bech32.NProfile -> "User/${nip19.hex}" - is Nip19Bech32.Note -> "Note/${nip19.hex}" - is Nip19Bech32.NEvent -> { + is NPub -> "User/${nip19.hex}" + is NProfile -> "User/${nip19.hex}" + is Note -> "Note/${nip19.hex}" + is NEvent -> { if (nip19.kind == PrivateDmEvent.KIND) { nip19.author?.let { "RoomByAuthor/$it" } } else if ( @@ -281,17 +287,17 @@ fun uriToRoute(uri: String?): String? = } } - is Nip19Bech32.NAddress -> { + is NAddress -> { if (nip19.kind == CommunityDefinitionEvent.KIND) { - "Community/${nip19.atag}" + "Community/${nip19.aTag()}" } else if (nip19.kind == LiveActivitiesEvent.KIND) { - "Channel/${nip19.atag}" + "Channel/${nip19.aTag()}" } else { - "Event/${nip19.atag}" + "Event/${nip19.aTag()}" } } - is Nip19Bech32.NEmbed -> { + is NEmbed -> { if (LocalCache.getNoteIfExists(nip19.event.id) == null) { LocalCache.verifyAndConsume(nip19.event, null) } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/EditPostViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/EditPostViewModel.kt index fdf1eda15..a9f56d0f6 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/EditPostViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/EditPostViewModel.kt @@ -46,10 +46,10 @@ import com.vitorpamplona.amethyst.ui.actions.uploads.SelectedMediaProcessing import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.ammolite.relays.RelaySetupInfo -import com.vitorpamplona.quartz.encoders.IMetaTag -import com.vitorpamplona.quartz.encoders.IMetaTagBuilder -import com.vitorpamplona.quartz.events.FileStorageEvent -import com.vitorpamplona.quartz.events.FileStorageHeaderEvent +import com.vitorpamplona.quartz.experimental.nip95.FileStorageEvent +import com.vitorpamplona.quartz.experimental.nip95.FileStorageHeaderEvent +import com.vitorpamplona.quartz.nip92IMeta.IMetaTag +import com.vitorpamplona.quartz.nip92IMeta.IMetaTagBuilder import kotlinx.collections.immutable.ImmutableList import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -103,7 +103,7 @@ open class EditPostViewModel : ViewModel() { canAddInvoice = accountViewModel.userProfile().info?.lnAddress() != null multiOrchestrator = null - message = TextFieldValue(versionLookingAt?.event?.content() ?: edit.event?.content() ?: "") + message = TextFieldValue(versionLookingAt?.event?.content ?: edit.event?.content ?: "") urlPreview = findUrlInMessage() editedFromNote = edit diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewMessageTagger.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewMessageTagger.kt index 3d09153ca..35ff25816 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewMessageTagger.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewMessageTagger.kt @@ -24,11 +24,18 @@ import androidx.compose.runtime.Immutable import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.quartz.crypto.KeyPair -import com.vitorpamplona.quartz.encoders.Bech32 -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.Nip19Bech32 -import com.vitorpamplona.quartz.encoders.bechToBytes -import com.vitorpamplona.quartz.encoders.toNpub +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip19Bech32Entities.Nip19Parser +import com.vitorpamplona.quartz.nip19Bech32Entities.bech32.Bech32 +import com.vitorpamplona.quartz.nip19Bech32Entities.bech32.bechToBytes +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NAddress +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NEmbed +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NEvent +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NProfile +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NPub +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NRelay +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NSec +import com.vitorpamplona.quartz.nip19Bech32Entities.toNpub import kotlinx.coroutines.CancellationException class NewMessageTagger( @@ -63,22 +70,22 @@ class NewMessageTagger( val results = parseDirtyWordForKey(word) when (val entity = results?.key?.entity) { - is Nip19Bech32.NPub -> addUserToMentions(dao.getOrCreateUser(entity.hex)) - is Nip19Bech32.NProfile -> addUserToMentions(dao.getOrCreateUser(entity.hex)) + is NPub -> addUserToMentions(dao.getOrCreateUser(entity.hex)) + is NProfile -> addUserToMentions(dao.getOrCreateUser(entity.hex)) - is Nip19Bech32.Note -> addNoteToReplyTos(dao.getOrCreateNote(entity.hex)) - is Nip19Bech32.NEvent -> addNoteToReplyTos(dao.getOrCreateNote(entity.hex)) - is Nip19Bech32.NEmbed -> addNoteToReplyTos(dao.getOrCreateNote(entity.event.id)) + is com.vitorpamplona.quartz.nip19Bech32Entities.entities.Note -> addNoteToReplyTos(dao.getOrCreateNote(entity.hex)) + is NEvent -> addNoteToReplyTos(dao.getOrCreateNote(entity.hex)) + is NEmbed -> addNoteToReplyTos(dao.getOrCreateNote(entity.event.id)) - is Nip19Bech32.NAddress -> { - val note = dao.checkGetOrCreateAddressableNote(entity.atag) + is NAddress -> { + val note = dao.checkGetOrCreateAddressableNote(entity.aTag()) if (note != null) { addNoteToReplyTos(note) } } - is Nip19Bech32.NSec -> {} - is Nip19Bech32.NRelay -> {} + is NSec -> {} + is NRelay -> {} } } } @@ -93,22 +100,22 @@ class NewMessageTagger( .map { word: String -> val results = parseDirtyWordForKey(word) when (val entity = results?.key?.entity) { - is Nip19Bech32.NPub -> { + is NPub -> { getNostrAddress(dao.getOrCreateUser(entity.hex).toNProfile(), results.restOfWord) } - is Nip19Bech32.NProfile -> { + is NProfile -> { getNostrAddress(dao.getOrCreateUser(entity.hex).toNProfile(), results.restOfWord) } - is Nip19Bech32.Note -> { + is com.vitorpamplona.quartz.nip19Bech32Entities.entities.Note -> { getNostrAddress(dao.getOrCreateNote(entity.hex).toNEvent(), results.restOfWord) } - is Nip19Bech32.NEvent -> { + is NEvent -> { getNostrAddress(dao.getOrCreateNote(entity.hex).toNEvent(), results.restOfWord) } - is Nip19Bech32.NAddress -> { - val note = dao.checkGetOrCreateAddressableNote(entity.atag) + is NAddress -> { + val note = dao.checkGetOrCreateAddressableNote(entity.aTag()) if (note != null) { getNostrAddress(note.idNote(), results.restOfWord) } else { @@ -116,15 +123,15 @@ class NewMessageTagger( } } - is Nip19Bech32.NEmbed -> { + is NEmbed -> { word } - is Nip19Bech32.NSec -> { + is NSec -> { word } - is Nip19Bech32.NRelay -> { + is NRelay -> { word } @@ -151,7 +158,7 @@ class NewMessageTagger( } @Immutable data class DirtyKeyInfo( - val key: Nip19Bech32.ParseReturn, + val key: Nip19Parser.ParseReturn, val restOfWord: String?, ) @@ -173,7 +180,7 @@ class NewMessageTagger( val restOfWord = key.substring(63) // Converts to npub val pubkey = - Nip19Bech32.uriToRoute(KeyPair(privKey = keyB32.bechToBytes()).pubKey.toNpub()) ?: return null + Nip19Parser.uriToRoute(KeyPair(privKey = keyB32.bechToBytes()).pubKey.toNpub()) ?: return null return DirtyKeyInfo(pubkey, restOfWord.ifEmpty { null }) } else if (key.startsWith("npub1", true)) { @@ -184,7 +191,7 @@ class NewMessageTagger( val keyB32 = key.substring(0, 63) val restOfWord = key.substring(63) - val pubkey = Nip19Bech32.uriToRoute(keyB32) ?: return null + val pubkey = Nip19Parser.uriToRoute(keyB32) ?: return null return DirtyKeyInfo(pubkey, restOfWord.ifEmpty { null }) } else if (key.startsWith("note1", true)) { @@ -195,19 +202,19 @@ class NewMessageTagger( val keyB32 = key.substring(0, 63) val restOfWord = key.substring(63) - val noteId = Nip19Bech32.uriToRoute(keyB32) ?: return null + val noteId = Nip19Parser.uriToRoute(keyB32) ?: return null return DirtyKeyInfo(noteId, restOfWord.ifEmpty { null }) } else if (key.startsWith("nprofile", true)) { - val pubkeyRelay = Nip19Bech32.uriToRoute(key) ?: return null + val pubkeyRelay = Nip19Parser.uriToRoute(key) ?: return null return DirtyKeyInfo(pubkeyRelay, pubkeyRelay.additionalChars) } else if (key.startsWith("nevent1", true)) { - val noteRelayId = Nip19Bech32.uriToRoute(key) ?: return null + val noteRelayId = Nip19Parser.uriToRoute(key) ?: return null return DirtyKeyInfo(noteRelayId, noteRelayId.additionalChars) } else if (key.startsWith("naddr1", true)) { - val address = Nip19Bech32.uriToRoute(key) ?: return null + val address = Nip19Parser.uriToRoute(key) ?: return null return DirtyKeyInfo( address, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostViewModel.kt index 87f7cc44d..9ce473a51 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostViewModel.kt @@ -20,7 +20,6 @@ */ package com.vitorpamplona.amethyst.ui.actions -import android.R.attr.mimeType import android.content.Context import android.util.Log import android.webkit.MimeTypeMap @@ -56,33 +55,38 @@ import com.vitorpamplona.amethyst.ui.components.Split import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.ammolite.relays.RelaySetupInfo -import com.vitorpamplona.quartz.encoders.Hex -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.IMetaTag -import com.vitorpamplona.quartz.encoders.IMetaTagBuilder -import com.vitorpamplona.quartz.encoders.Nip30CustomEmoji -import com.vitorpamplona.quartz.encoders.toNpub -import com.vitorpamplona.quartz.events.AddressableEvent -import com.vitorpamplona.quartz.events.AdvertisedRelayListEvent -import com.vitorpamplona.quartz.events.BaseTextNoteEvent -import com.vitorpamplona.quartz.events.ClassifiedsEvent -import com.vitorpamplona.quartz.events.CommentEvent -import com.vitorpamplona.quartz.events.CommunityDefinitionEvent -import com.vitorpamplona.quartz.events.DraftEvent -import com.vitorpamplona.quartz.events.EmojiUrl -import com.vitorpamplona.quartz.events.Event -import com.vitorpamplona.quartz.events.FileStorageEvent -import com.vitorpamplona.quartz.events.FileStorageHeaderEvent -import com.vitorpamplona.quartz.events.GitIssueEvent -import com.vitorpamplona.quartz.events.NIP17Group -import com.vitorpamplona.quartz.events.Price -import com.vitorpamplona.quartz.events.PrivateDmEvent -import com.vitorpamplona.quartz.events.RootScope -import com.vitorpamplona.quartz.events.TextNoteEvent -import com.vitorpamplona.quartz.events.TorrentCommentEvent -import com.vitorpamplona.quartz.events.TorrentEvent -import com.vitorpamplona.quartz.events.ZapSplitSetup -import com.vitorpamplona.quartz.events.findURLs +import com.vitorpamplona.quartz.crypto.Hex +import com.vitorpamplona.quartz.experimental.nip95.FileStorageEvent +import com.vitorpamplona.quartz.experimental.nip95.FileStorageHeaderEvent +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.AddressableEvent +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.geohash.getGeoHash +import com.vitorpamplona.quartz.nip04Dm.PrivateDmEvent +import com.vitorpamplona.quartz.nip10Notes.BaseTextNoteEvent +import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent +import com.vitorpamplona.quartz.nip10Notes.findURLs +import com.vitorpamplona.quartz.nip14Subject.subject +import com.vitorpamplona.quartz.nip17Dm.NIP17Group +import com.vitorpamplona.quartz.nip19Bech32Entities.toNpub +import com.vitorpamplona.quartz.nip22Comments.CommentEvent +import com.vitorpamplona.quartz.nip22Comments.RootScope +import com.vitorpamplona.quartz.nip30CustomEmoji.CustomEmoji +import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiUrl +import com.vitorpamplona.quartz.nip34Git.GitIssueEvent +import com.vitorpamplona.quartz.nip35Torrents.TorrentCommentEvent +import com.vitorpamplona.quartz.nip35Torrents.TorrentEvent +import com.vitorpamplona.quartz.nip36SensitiveContent.isSensitiveOrNSFW +import com.vitorpamplona.quartz.nip37Drafts.DraftEvent +import com.vitorpamplona.quartz.nip57Zaps.ZapSplitSetup +import com.vitorpamplona.quartz.nip57Zaps.zapSplitSetup +import com.vitorpamplona.quartz.nip57Zaps.zapraiserAmount +import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent +import com.vitorpamplona.quartz.nip72ModCommunities.CommunityDefinitionEvent +import com.vitorpamplona.quartz.nip92IMeta.IMetaTag +import com.vitorpamplona.quartz.nip92IMeta.IMetaTagBuilder +import com.vitorpamplona.quartz.nip99Classifieds.ClassifiedsEvent +import com.vitorpamplona.quartz.nip99Classifieds.Price import kotlinx.collections.immutable.ImmutableList import kotlinx.coroutines.CancellationException import kotlinx.coroutines.Dispatchers @@ -300,10 +304,10 @@ open class NewPostViewModel : ViewModel() { } fork?.let { - message = TextFieldValue(version?.event?.content() ?: it.event?.content() ?: "") + message = TextFieldValue(version?.event?.content ?: it.event?.content ?: "") urlPreview = findUrlInMessage() - it.event?.isSensitive()?.let { + it.event?.isSensitiveOrNSFW()?.let { if (it) wantsToMarkAsSensitive = true } @@ -364,7 +368,7 @@ open class NewPostViewModel : ViewModel() { canAddZapRaiser = accountViewModel.userProfile().info?.lnAddress() != null multiOrchestrator = null - val localfowardZapTo = draftEvent.tags().filter { it.size > 1 && it[0] == "zap" } + val localfowardZapTo = draftEvent.tags.filter { it.size > 1 && it[0] == "zap" } forwardZapTo = Split() localfowardZapTo.forEach { val user = LocalCache.getOrCreateUser(it[1]) @@ -374,15 +378,15 @@ open class NewPostViewModel : ViewModel() { forwardZapToEditting = TextFieldValue("") wantsForwardZapTo = localfowardZapTo.isNotEmpty() - wantsToMarkAsSensitive = draftEvent.tags().any { it.size > 1 && it[0] == "content-warning" } + wantsToMarkAsSensitive = draftEvent.tags.any { it.size > 1 && it[0] == "content-warning" } val geohash = draftEvent.getGeoHash() wantsToAddGeoHash = geohash != null if (geohash != null) { - wantsExclusiveGeoPost = draftEvent.kind() == CommentEvent.KIND + wantsExclusiveGeoPost = draftEvent.kind == CommentEvent.KIND } - val zapraiser = draftEvent.tags().filter { it.size > 1 && it[0] == "zapraiser" } + val zapraiser = draftEvent.tags.filter { it.size > 1 && it[0] == "zapraiser" } wantsZapraiser = zapraiser.isNotEmpty() zapRaiserAmount = null if (wantsZapraiser) { @@ -390,26 +394,26 @@ open class NewPostViewModel : ViewModel() { } eTags = - draftEvent.tags().filter { it.size > 1 && (it[0] == "e" || it[0] == "a") && it.getOrNull(3) != "fork" }.mapNotNull { + draftEvent.tags.filter { it.size > 1 && (it[0] == "e" || it[0] == "a") && it.getOrNull(3) != "fork" }.mapNotNull { val note = LocalCache.checkGetOrCreateNote(it[1]) note } if (draftEvent !is PrivateDmEvent && draftEvent !is NIP17Group) { pTags = - draftEvent.tags().filter { it.size > 1 && it[0] == "p" }.map { + draftEvent.tags.filter { it.size > 1 && it[0] == "p" }.map { LocalCache.getOrCreateUser(it[1]) } } - draftEvent.tags().filter { it.size > 3 && (it[0] == "e" || it[0] == "a") && it.get(3) == "fork" }.forEach { + draftEvent.tags.filter { it.size > 3 && (it[0] == "e" || it[0] == "a") && it.get(3) == "fork" }.forEach { val note = LocalCache.checkGetOrCreateNote(it[1]) forkedFromNote = note } originalNote = draftEvent - .tags() + .tags .filter { it.size > 1 && (it[0] == "e" || it[0] == "a") && it.getOrNull(3) == "reply" } .map { LocalCache.checkGetOrCreateNote(it[1]) @@ -418,7 +422,7 @@ open class NewPostViewModel : ViewModel() { if (originalNote == null) { originalNote = draftEvent - .tags() + .tags .filter { it.size > 1 && (it[0] == "e" || it[0] == "a") && it.getOrNull(3) == "root" } .map { LocalCache.checkGetOrCreateNote(it[1]) @@ -431,14 +435,14 @@ open class NewPostViewModel : ViewModel() { wantsForwardZapTo = true } - val polls = draftEvent.tags().filter { it.size > 1 && it[0] == "poll_option" } + val polls = draftEvent.tags.filter { it.size > 1 && it[0] == "poll_option" } wantsPoll = polls.isNotEmpty() polls.forEach { pollOptions[it[1].toInt()] = it[2] } - val minMax = draftEvent.tags().filter { it.size > 1 && (it[0] == "value_minimum" || it[0] == "value_maximum") } + val minMax = draftEvent.tags.filter { it.size > 1 && (it[0] == "value_minimum" || it[0] == "value_maximum") } minMax.forEach { if (it[0] == "value_maximum") { valueMaximum = it[1].toInt() @@ -447,12 +451,12 @@ open class NewPostViewModel : ViewModel() { } } - wantsProduct = draftEvent.kind() == 30402 + wantsProduct = draftEvent.kind == 30402 title = TextFieldValue( draftEvent - .tags() + .tags .filter { it.size > 1 && it[0] == "title" } .map { it[1] } ?.firstOrNull() ?: "", @@ -460,7 +464,7 @@ open class NewPostViewModel : ViewModel() { price = TextFieldValue( draftEvent - .tags() + .tags .filter { it.size > 1 && it[0] == "price" } .map { it[1] } ?.firstOrNull() ?: "", @@ -468,7 +472,7 @@ open class NewPostViewModel : ViewModel() { category = TextFieldValue( draftEvent - .tags() + .tags .filter { it.size > 1 && it[0] == "t" } .map { it[1] } ?.firstOrNull() ?: "", @@ -476,7 +480,7 @@ open class NewPostViewModel : ViewModel() { locationText = TextFieldValue( draftEvent - .tags() + .tags .filter { it.size > 1 && it[0] == "location" } .map { it[1] } ?.firstOrNull() ?: "", @@ -484,7 +488,7 @@ open class NewPostViewModel : ViewModel() { condition = ClassifiedsEvent.CONDITION.entries.firstOrNull { it.value == draftEvent - .tags() + .tags .filter { it.size > 1 && it[0] == "condition" } .map { it[1] } .firstOrNull() @@ -502,7 +506,7 @@ open class NewPostViewModel : ViewModel() { toUsers = TextFieldValue("@$recepientNpub") TextFieldValue(draftEvent.cachedContentFor(accountViewModel.account.signer) ?: "") } else { - TextFieldValue(draftEvent.content()) + TextFieldValue(draftEvent.content) } requiresNIP17 = draftEvent is NIP17Group @@ -907,7 +911,7 @@ open class NewPostViewModel : ViewModel() { myEmojiSet: List?, ): List { if (myEmojiSet == null) return emptyList() - return Nip30CustomEmoji.findAllEmojiCodes(message).mapNotNull { possibleEmoji -> + return CustomEmoji.findAllEmojiCodes(message).mapNotNull { possibleEmoji -> myEmojiSet.firstOrNull { it.code == possibleEmoji }?.let { EmojiUrl(it.code, it.url.url) } } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewUserMetadataViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewUserMetadataViewModel.kt index 14cf48702..fc2cd0a0d 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewUserMetadataViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewUserMetadataViewModel.kt @@ -35,9 +35,10 @@ import com.vitorpamplona.amethyst.service.uploads.nip96.Nip96Uploader import com.vitorpamplona.amethyst.ui.actions.mediaServers.ServerType import com.vitorpamplona.amethyst.ui.actions.uploads.SelectedMedia import com.vitorpamplona.amethyst.ui.stringRes -import com.vitorpamplona.quartz.events.GitHubIdentity -import com.vitorpamplona.quartz.events.MastodonIdentity -import com.vitorpamplona.quartz.events.TwitterIdentity +import com.vitorpamplona.quartz.nip39ExtIdentities.GitHubIdentity +import com.vitorpamplona.quartz.nip39ExtIdentities.MastodonIdentity +import com.vitorpamplona.quartz.nip39ExtIdentities.TwitterIdentity +import com.vitorpamplona.quartz.nip39ExtIdentities.identityClaims import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlin.coroutines.cancellation.CancellationException diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NotifyRequestDialog.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NotifyRequestDialog.kt index a7d70d89b..540473a61 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NotifyRequestDialog.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NotifyRequestDialog.kt @@ -46,7 +46,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.Size16dp import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer -import com.vitorpamplona.quartz.events.EmptyTagList +import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList @Composable fun NotifyRequestDialog( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/RelaySelectionDialog.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/RelaySelectionDialog.kt index 1ca610c91..21330a85a 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/RelaySelectionDialog.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/RelaySelectionDialog.kt @@ -56,7 +56,7 @@ import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.FeedPadding import com.vitorpamplona.ammolite.relays.RelayBriefInfoCache import com.vitorpamplona.ammolite.relays.RelaySetupInfo -import com.vitorpamplona.quartz.encoders.Nip11RelayInformation +import com.vitorpamplona.quartz.nip11RelayInfo.Nip11RelayInformation import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/UrlUserTagTransformation.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/UrlUserTagTransformation.kt index 265f32891..2af641e00 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/UrlUserTagTransformation.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/UrlUserTagTransformation.kt @@ -31,8 +31,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.quartz.encoders.decodePublicKey -import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.nip01Core.toHexKey +import com.vitorpamplona.quartz.nip19Bech32Entities.decodePublicKey import kotlin.coroutines.cancellation.CancellationException data class RangesChanges( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/mediaServers/MediaServerEditField.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/mediaServers/MediaServerEditField.kt index ddbaf1b87..69ec4ef8b 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/mediaServers/MediaServerEditField.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/mediaServers/MediaServerEditField.kt @@ -40,7 +40,7 @@ import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.ButtonBorder import com.vitorpamplona.amethyst.ui.theme.Size10dp import com.vitorpamplona.amethyst.ui.theme.placeholderText -import com.vitorpamplona.quartz.encoders.HttpUrlFormatter +import com.vitorpamplona.quartz.nip96FileStorage.HttpUrlFormatter @Composable fun MediaServerEditField( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/relays/BasicRelaySetupInfo.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/relays/BasicRelaySetupInfo.kt index aba820179..d016c3468 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/relays/BasicRelaySetupInfo.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/relays/BasicRelaySetupInfo.kt @@ -24,7 +24,7 @@ import androidx.compose.runtime.Immutable import com.vitorpamplona.ammolite.relays.FeedType import com.vitorpamplona.ammolite.relays.RelayBriefInfoCache import com.vitorpamplona.ammolite.relays.RelayStat -import com.vitorpamplona.quartz.encoders.HexKey +import com.vitorpamplona.quartz.nip01Core.HexKey @Immutable data class BasicRelaySetupInfo( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/relays/BasicRelaySetupInfoModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/relays/BasicRelaySetupInfoModel.kt index a7623c75d..a002dc8ef 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/relays/BasicRelaySetupInfoModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/relays/BasicRelaySetupInfoModel.kt @@ -25,7 +25,7 @@ import androidx.lifecycle.viewModelScope import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.service.Nip11CachedRetriever import com.vitorpamplona.ammolite.relays.RelayStats -import com.vitorpamplona.quartz.encoders.RelayUrlFormatter +import com.vitorpamplona.quartz.nip65RelayList.RelayUrlFormatter import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/relays/Kind3RelayListView.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/relays/Kind3RelayListView.kt index 9ee7b57a2..aa95a2a1c 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/relays/Kind3RelayListView.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/relays/Kind3RelayListView.kt @@ -95,7 +95,7 @@ import com.vitorpamplona.ammolite.relays.Constants.activeTypesGlobalChats import com.vitorpamplona.ammolite.relays.FeedType import com.vitorpamplona.ammolite.relays.RelayBriefInfoCache import com.vitorpamplona.ammolite.relays.RelayStat -import com.vitorpamplona.quartz.encoders.RelayUrlFormatter +import com.vitorpamplona.quartz.nip65RelayList.RelayUrlFormatter import kotlinx.coroutines.launch @Composable diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/relays/Kind3RelayListViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/relays/Kind3RelayListViewModel.kt index 8a0b6256e..d5f6f80c5 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/relays/Kind3RelayListViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/relays/Kind3RelayListViewModel.kt @@ -30,8 +30,8 @@ import com.vitorpamplona.ammolite.relays.Constants.activeTypesGlobalChats import com.vitorpamplona.ammolite.relays.FeedType import com.vitorpamplona.ammolite.relays.RelaySetupInfo import com.vitorpamplona.ammolite.relays.RelayStats -import com.vitorpamplona.quartz.encoders.RelayUrlFormatter -import com.vitorpamplona.quartz.utils.RelayListRecommendationProcessor +import com.vitorpamplona.quartz.nip65RelayList.RelayListRecommendationProcessor +import com.vitorpamplona.quartz.nip65RelayList.RelayUrlFormatter import kotlinx.collections.immutable.toImmutableSet import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/relays/Nip65RelayListViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/relays/Nip65RelayListViewModel.kt index 516580fd1..7306643e5 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/relays/Nip65RelayListViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/relays/Nip65RelayListViewModel.kt @@ -26,8 +26,8 @@ import androidx.lifecycle.viewModelScope import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.service.Nip11CachedRetriever import com.vitorpamplona.ammolite.relays.RelayStats -import com.vitorpamplona.quartz.encoders.RelayUrlFormatter -import com.vitorpamplona.quartz.events.AdvertisedRelayListEvent +import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent +import com.vitorpamplona.quartz.nip65RelayList.RelayUrlFormatter import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/relays/RelayInformationDialog.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/relays/RelayInformationDialog.kt index b7384966b..fcfc24366 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/relays/RelayInformationDialog.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/relays/RelayInformationDialog.kt @@ -71,8 +71,8 @@ import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer import com.vitorpamplona.amethyst.ui.theme.largeRelayIconModifier import com.vitorpamplona.ammolite.relays.RelayBriefInfoCache import com.vitorpamplona.ammolite.relays.RelayStats -import com.vitorpamplona.quartz.encoders.Nip11RelayInformation -import com.vitorpamplona.quartz.events.EmptyTagList +import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList +import com.vitorpamplona.quartz.nip11RelayInfo.Nip11RelayInformation import kotlinx.collections.immutable.toImmutableList @OptIn(ExperimentalLayoutApi::class) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/relays/RelayUrlEditField.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/relays/RelayUrlEditField.kt index 3cbe0af8a..efd9e6f97 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/relays/RelayUrlEditField.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/relays/RelayUrlEditField.kt @@ -41,7 +41,7 @@ import com.vitorpamplona.amethyst.ui.theme.ButtonBorder import com.vitorpamplona.amethyst.ui.theme.Size10dp import com.vitorpamplona.amethyst.ui.theme.placeholderText import com.vitorpamplona.ammolite.relays.RelayStat -import com.vitorpamplona.quartz.encoders.RelayUrlFormatter +import com.vitorpamplona.quartz.nip65RelayList.RelayUrlFormatter @Composable fun RelayUrlEditField(onNewRelay: (BasicRelaySetupInfo) -> Unit) { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableRoute.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableRoute.kt index b7c756dd8..017e32189 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableRoute.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableRoute.kt @@ -63,35 +63,43 @@ import com.vitorpamplona.amethyst.ui.navigation.INav import com.vitorpamplona.amethyst.ui.note.LoadChannel import com.vitorpamplona.amethyst.ui.note.njumpLink import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.Nip19Bech32 -import com.vitorpamplona.quartz.encoders.Nip30CustomEmoji -import com.vitorpamplona.quartz.events.ChannelCreateEvent -import com.vitorpamplona.quartz.events.EmptyTagList -import com.vitorpamplona.quartz.events.Event -import com.vitorpamplona.quartz.events.ImmutableListOfLists -import com.vitorpamplona.quartz.events.PrivateDmEvent +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList +import com.vitorpamplona.quartz.nip02FollowList.ImmutableListOfLists +import com.vitorpamplona.quartz.nip04Dm.PrivateDmEvent +import com.vitorpamplona.quartz.nip19Bech32Entities.Nip19Parser +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NAddress +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NEmbed +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NEvent +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NProfile +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NPub +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NRelay +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NSec +import com.vitorpamplona.quartz.nip19Bech32Entities.toNIP19 +import com.vitorpamplona.quartz.nip28PublicChat.ChannelCreateEvent +import com.vitorpamplona.quartz.nip30CustomEmoji.CustomEmoji import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableMap @Composable fun ClickableRoute( word: String, - nip19: Nip19Bech32.ParseReturn, + nip19: Nip19Parser.ParseReturn, accountViewModel: AccountViewModel, nav: INav, ) { when (val entity = nip19.entity) { - is Nip19Bech32.NPub -> DisplayUser(entity.hex, nip19.nip19raw, nip19.additionalChars, accountViewModel, nav) - is Nip19Bech32.NProfile -> DisplayUser(entity.hex, nip19.nip19raw, nip19.additionalChars, accountViewModel, nav) - is Nip19Bech32.Note -> DisplayEvent(entity.hex, null, nip19.nip19raw, nip19.additionalChars, accountViewModel, nav) - is Nip19Bech32.NEvent -> DisplayEvent(entity.hex, entity.kind, nip19.nip19raw, nip19.additionalChars, accountViewModel, nav) - is Nip19Bech32.NEmbed -> LoadAndDisplayEvent(entity.event, nip19.additionalChars, accountViewModel, nav) - is Nip19Bech32.NAddress -> DisplayAddress(entity, nip19.nip19raw, nip19.additionalChars, accountViewModel, nav) - is Nip19Bech32.NRelay -> { + is NPub -> DisplayUser(entity.hex, nip19.nip19raw, nip19.additionalChars, accountViewModel, nav) + is NProfile -> DisplayUser(entity.hex, nip19.nip19raw, nip19.additionalChars, accountViewModel, nav) + is com.vitorpamplona.quartz.nip19Bech32Entities.entities.Note -> DisplayEvent(entity.hex, null, nip19.nip19raw, nip19.additionalChars, accountViewModel, nav) + is NEvent -> DisplayEvent(entity.hex, entity.kind, nip19.nip19raw, nip19.additionalChars, accountViewModel, nav) + is NEmbed -> LoadAndDisplayEvent(entity.event, nip19.additionalChars, accountViewModel, nav) + is NAddress -> DisplayAddress(entity, nip19.nip19raw, nip19.additionalChars, accountViewModel, nav) + is NRelay -> { Text(word) } - is Nip19Bech32.NSec -> { + is NSec -> { Text(word) } else -> { @@ -230,24 +238,24 @@ private fun DisplayNoteLink( @Composable private fun DisplayAddress( - nip19: Nip19Bech32.NAddress, + nip19: NAddress, originalNip19: String, additionalChars: String?, accountViewModel: AccountViewModel, nav: INav, ) { - var noteBase by remember(nip19) { mutableStateOf(accountViewModel.getNoteIfExists(nip19.atag)) } + var noteBase by remember(nip19) { mutableStateOf(accountViewModel.getNoteIfExists(nip19.aTag())) } if (noteBase == null) { - LaunchedEffect(key1 = nip19.atag) { - accountViewModel.checkGetOrCreateAddressableNote(nip19.atag) { noteBase = it } + LaunchedEffect(key1 = nip19) { + accountViewModel.checkGetOrCreateAddressableNote(nip19.aTag()) { noteBase = it } } } noteBase?.let { val noteState by it.live().metadata.observeAsState() - val route = remember(noteState) { "Note/${nip19.atag}" } + val route = remember(noteState) { "Note/${nip19.aTag()}" } val displayName = remember(noteState) { "@${noteState?.note?.idDisplayNote()}" } CreateClickableText( @@ -433,20 +441,20 @@ fun CustomEmojiChecker( text: String, tags: ImmutableListOfLists?, onRegularText: @Composable (String) -> Unit, - onEmojiText: @Composable (ImmutableList) -> Unit, + onEmojiText: @Composable (ImmutableList) -> Unit, ) { val mayContainEmoji by remember(text, tags) { - mutableStateOf(Nip30CustomEmoji.fastMightContainEmoji(text, tags)) + mutableStateOf(CustomEmoji.fastMightContainEmoji(text, tags)) } if (mayContainEmoji) { var emojiList by remember(text, tags) { - mutableStateOf?>(null) + mutableStateOf?>(null) } LaunchedEffect(text, tags) { - val newEmojiList = Nip30CustomEmoji.assembleAnnotatedList(text, tags) + val newEmojiList = CustomEmoji.assembleAnnotatedList(text, tags) if (newEmojiList != null) { emojiList = newEmojiList } @@ -467,20 +475,20 @@ fun CustomEmojiChecker( text: String, emojis: ImmutableMap, onRegularText: @Composable (String) -> Unit, - onEmojiText: @Composable (ImmutableList) -> Unit, + onEmojiText: @Composable (ImmutableList) -> Unit, ) { val mayContainEmoji by remember(text, emojis) { - mutableStateOf(Nip30CustomEmoji.fastMightContainEmoji(text, emojis)) + mutableStateOf(CustomEmoji.fastMightContainEmoji(text, emojis)) } if (mayContainEmoji) { var emojiList by remember(text, emojis) { - mutableStateOf?>(null) + mutableStateOf?>(null) } LaunchedEffect(text, emojis) { - val newEmojiList = Nip30CustomEmoji.assembleAnnotatedList(text, emojis) + val newEmojiList = CustomEmoji.assembleAnnotatedList(text, emojis) if (newEmojiList != null) { emojiList = newEmojiList } @@ -667,7 +675,7 @@ fun CreateClickableTextWithEmoji( @Composable fun ClickableInLineIconRenderer( - wordsInOrder: ImmutableList, + wordsInOrder: ImmutableList, maxLines: Int = Int.MAX_VALUE, style: SpanStyle, suffix: String? = null, @@ -686,7 +694,7 @@ fun ClickableInLineIconRenderer( val inlineContent = wordsInOrder .mapIndexedNotNull { idx, value -> - if (value is Nip30CustomEmoji.ImageUrlType) { + if (value is CustomEmoji.ImageUrlType) { Pair( "inlineContent$idx", InlineTextContent( @@ -717,9 +725,9 @@ fun ClickableInLineIconRenderer( withStyle( style, ) { - if (value is Nip30CustomEmoji.TextType) { + if (value is CustomEmoji.TextType) { append(value.text) - } else if (value is Nip30CustomEmoji.ImageUrlType) { + } else if (value is CustomEmoji.ImageUrlType) { appendInlineContent("inlineContent$idx", "[icon]") } } @@ -751,7 +759,7 @@ fun ClickableInLineIconRenderer( @Composable fun InLineIconRenderer( - wordsInOrder: ImmutableList, + wordsInOrder: ImmutableList, style: SpanStyle, fontSize: TextUnit = TextUnit.Unspecified, maxLines: Int = Int.MAX_VALUE, @@ -770,7 +778,7 @@ fun InLineIconRenderer( val inlineContent = wordsInOrder .mapIndexedNotNull { idx, value -> - if (value is Nip30CustomEmoji.ImageUrlType) { + if (value is CustomEmoji.ImageUrlType) { Pair( "inlineContent$idx", InlineTextContent( @@ -802,9 +810,9 @@ fun InLineIconRenderer( withStyle( style, ) { - if (value is Nip30CustomEmoji.TextType) { + if (value is CustomEmoji.TextType) { append(value.text) - } else if (value is Nip30CustomEmoji.ImageUrlType) { + } else if (value is CustomEmoji.ImageUrlType) { appendInlineContent("inlineContent$idx", "[icon]") } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableWithdrawal.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableWithdrawal.kt index 647d31c39..947f1d5ac 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableWithdrawal.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableWithdrawal.kt @@ -39,7 +39,7 @@ import com.vitorpamplona.amethyst.ui.note.ErrorMessageDialog import com.vitorpamplona.amethyst.ui.note.payViaIntent import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.stringRes -import com.vitorpamplona.quartz.encoders.LnWithdrawalUtil +import com.vitorpamplona.quartz.lightning.LnWithdrawalUtil import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/DisplayNotifyMessages.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/DisplayNotifyMessages.kt index b4b49166b..1e63e6988 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/DisplayNotifyMessages.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/DisplayNotifyMessages.kt @@ -27,7 +27,7 @@ import com.vitorpamplona.amethyst.ui.actions.NotifyRequestDialog import com.vitorpamplona.amethyst.ui.navigation.INav import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.stringRes -import com.vitorpamplona.quartz.encoders.RelayUrlFormatter +import com.vitorpamplona.quartz.nip65RelayList.RelayUrlFormatter @Composable fun DisplayNotifyMessages( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ExpandableRichTextViewer.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ExpandableRichTextViewer.kt index 2a36cb95e..ac331bde1 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ExpandableRichTextViewer.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ExpandableRichTextViewer.kt @@ -51,7 +51,7 @@ import com.vitorpamplona.amethyst.ui.theme.ButtonBorder import com.vitorpamplona.amethyst.ui.theme.ButtonPadding import com.vitorpamplona.amethyst.ui.theme.StdTopPadding import com.vitorpamplona.amethyst.ui.theme.secondaryButtonBackground -import com.vitorpamplona.quartz.events.ImmutableListOfLists +import com.vitorpamplona.quartz.nip02FollowList.ImmutableListOfLists object ShowFullTextCache { val cache = LruCache(10) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/RichTextViewer.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/RichTextViewer.kt index 9c89ed4a7..5d167d910 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/RichTextViewer.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/RichTextViewer.kt @@ -96,8 +96,8 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockAccountViewModel import com.vitorpamplona.amethyst.ui.theme.HalfVertPadding import com.vitorpamplona.amethyst.ui.theme.inlinePlaceholder import com.vitorpamplona.amethyst.ui.theme.innerPostModifier -import com.vitorpamplona.quartz.events.EmptyTagList -import com.vitorpamplona.quartz.events.ImmutableListOfLists +import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList +import com.vitorpamplona.quartz.nip02FollowList.ImmutableListOfLists fun isMarkdown(content: String): Boolean = content.startsWith("> ") || diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/SensitivityWarning.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/SensitivityWarning.kt index 99ce44f9c..356c9ec3f 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/SensitivityWarning.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/SensitivityWarning.kt @@ -57,7 +57,8 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.ButtonBorder import com.vitorpamplona.amethyst.ui.theme.ButtonPadding -import com.vitorpamplona.quartz.events.EventInterface +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip36SensitiveContent.isSensitiveOrNSFW @Composable fun SensitivityWarning( @@ -70,11 +71,11 @@ fun SensitivityWarning( @Composable fun SensitivityWarning( - event: EventInterface, + event: Event, accountViewModel: AccountViewModel, content: @Composable () -> Unit, ) { - val hasSensitiveContent = remember(event) { event.isSensitive() } + val hasSensitiveContent = remember(event) { event.isSensitiveOrNSFW() } SensitivityWarning(hasSensitiveContent, accountViewModel, content) } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/VideoView.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/VideoView.kt index 77a52c90a..423ea160f 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/VideoView.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/VideoView.kt @@ -119,7 +119,7 @@ import com.vitorpamplona.amethyst.ui.theme.Size75dp import com.vitorpamplona.amethyst.ui.theme.VolumeBottomIconSize import com.vitorpamplona.amethyst.ui.theme.imageModifier import com.vitorpamplona.amethyst.ui.theme.videoGalleryModifier -import com.vitorpamplona.quartz.encoders.Dimension +import com.vitorpamplona.quartz.nip94FileMetadata.Dimension import kotlinx.collections.immutable.ImmutableList import kotlinx.coroutines.CancellationException import kotlinx.coroutines.Dispatchers diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ZoomableContentView.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ZoomableContentView.kt index 020953990..29b0d0955 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ZoomableContentView.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ZoomableContentView.kt @@ -94,9 +94,10 @@ import com.vitorpamplona.amethyst.ui.theme.Size75dp import com.vitorpamplona.amethyst.ui.theme.hashVerifierMark import com.vitorpamplona.amethyst.ui.theme.imageModifier import com.vitorpamplona.quartz.crypto.CryptoUtils -import com.vitorpamplona.quartz.encoders.Dimension -import com.vitorpamplona.quartz.encoders.Nip19Bech32 -import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.nip01Core.toHexKey +import com.vitorpamplona.quartz.nip19Bech32Entities.Nip19Parser +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NEvent +import com.vitorpamplona.quartz.nip94FileMetadata.Dimension import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.Dispatchers @@ -676,7 +677,7 @@ fun ShareImageAction( text = { Text(stringRes(R.string.add_media_to_gallery)) }, onClick = { if (videoUri != null) { - val n19 = Nip19Bech32.uriToRoute(postNostrUri)?.entity as? Nip19Bech32.NEvent + val n19 = Nip19Parser.uriToRoute(postNostrUri)?.entity as? NEvent if (n19 != null) { accountViewModel.addMediaToGallery(n19.hex, videoUri, n19.relay[0], blurhash, dim, hash, mimeType) // TODO Whole list or first? accountViewModel.toast(R.string.media_added, R.string.media_added_to_profile_gallery) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/markdown/MarkdownMediaRenderer.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/markdown/MarkdownMediaRenderer.kt index 273dbfc83..4340ddd21 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/markdown/MarkdownMediaRenderer.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/markdown/MarkdownMediaRenderer.kt @@ -48,9 +48,15 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.LoadedBechLink import com.vitorpamplona.amethyst.ui.theme.Font17SP import com.vitorpamplona.amethyst.ui.theme.Size17Modifier -import com.vitorpamplona.quartz.encoders.Nip19Bech32 -import com.vitorpamplona.quartz.events.EmptyTagList -import com.vitorpamplona.quartz.events.ImmutableListOfLists +import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList +import com.vitorpamplona.quartz.nip02FollowList.ImmutableListOfLists +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NAddress +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NEmbed +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NEvent +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NProfile +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NPub +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NRelay +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NSec import kotlinx.coroutines.runBlocking class MarkdownMediaRenderer( @@ -164,14 +170,14 @@ class MarkdownMediaRenderer( } } else if (loadedLink?.nip19 != null) { when (val entity = loadedLink.nip19.entity) { - is Nip19Bech32.NPub -> renderObservableUser(entity.hex, loadedLink.nip19.nip19raw, richTextStringBuilder) - is Nip19Bech32.NProfile -> renderObservableUser(entity.hex, loadedLink.nip19.nip19raw, richTextStringBuilder) - is Nip19Bech32.Note -> renderObservableShortNoteUri(loadedLink, uri, richTextStringBuilder) - is Nip19Bech32.NEvent -> renderObservableShortNoteUri(loadedLink, uri, richTextStringBuilder) - is Nip19Bech32.NEmbed -> renderObservableShortNoteUri(loadedLink, uri, richTextStringBuilder) - is Nip19Bech32.NAddress -> renderObservableShortNoteUri(loadedLink, uri, richTextStringBuilder) - is Nip19Bech32.NRelay -> renderShortNostrURI(uri, richTextStringBuilder) - is Nip19Bech32.NSec -> renderShortNostrURI(uri, richTextStringBuilder) + is NPub -> renderObservableUser(entity.hex, loadedLink.nip19.nip19raw, richTextStringBuilder) + is NProfile -> renderObservableUser(entity.hex, loadedLink.nip19.nip19raw, richTextStringBuilder) + is com.vitorpamplona.quartz.nip19Bech32Entities.entities.Note -> renderObservableShortNoteUri(loadedLink, uri, richTextStringBuilder) + is NEvent -> renderObservableShortNoteUri(loadedLink, uri, richTextStringBuilder) + is NEmbed -> renderObservableShortNoteUri(loadedLink, uri, richTextStringBuilder) + is NAddress -> renderObservableShortNoteUri(loadedLink, uri, richTextStringBuilder) + is NRelay -> renderShortNostrURI(uri, richTextStringBuilder) + is NSec -> renderShortNostrURI(uri, richTextStringBuilder) else -> renderShortNostrURI(uri, richTextStringBuilder) } } else { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/markdown/RenderContentAsMarkdown.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/markdown/RenderContentAsMarkdown.kt index 50b8fe48b..d7ce17ee5 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/markdown/RenderContentAsMarkdown.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/markdown/RenderContentAsMarkdown.kt @@ -49,10 +49,10 @@ import com.vitorpamplona.amethyst.ui.theme.MarkdownTextStyle import com.vitorpamplona.amethyst.ui.theme.ThemeComparisonRow import com.vitorpamplona.amethyst.ui.theme.markdownStyle import com.vitorpamplona.amethyst.ui.uriToRoute -import com.vitorpamplona.quartz.events.EmptyTagList -import com.vitorpamplona.quartz.events.ImmutableListOfLists -import com.vitorpamplona.quartz.events.LongTextNoteEvent -import com.vitorpamplona.quartz.events.MetadataEvent +import com.vitorpamplona.quartz.nip01Core.MetadataEvent +import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList +import com.vitorpamplona.quartz.nip02FollowList.ImmutableListOfLists +import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChatroomFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChatroomFeedFilter.kt index 234da7305..6293aeb4e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChatroomFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChatroomFeedFilter.kt @@ -22,7 +22,7 @@ package com.vitorpamplona.amethyst.ui.dal import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.Note -import com.vitorpamplona.quartz.events.ChatroomKey +import com.vitorpamplona.quartz.nip17Dm.ChatroomKey class ChatroomFeedFilter( val withUser: ChatroomKey, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChatroomListKnownFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChatroomListKnownFeedFilter.kt index 70e0074c7..641681a01 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChatroomListKnownFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChatroomListKnownFeedFilter.kt @@ -24,9 +24,10 @@ import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.ui.actions.relays.updated -import com.vitorpamplona.quartz.events.ChannelMessageEvent -import com.vitorpamplona.quartz.events.ChatroomKey -import com.vitorpamplona.quartz.events.ChatroomKeyable +import com.vitorpamplona.quartz.nip01Core.events.taggedEvents +import com.vitorpamplona.quartz.nip17Dm.ChatroomKey +import com.vitorpamplona.quartz.nip17Dm.ChatroomKeyable +import com.vitorpamplona.quartz.nip28PublicChat.ChannelMessageEvent class ChatroomListKnownFeedFilter( val account: Account, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChatroomListNewFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChatroomListNewFeedFilter.kt index 1e6589e95..1d55278a0 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChatroomListNewFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChatroomListNewFeedFilter.kt @@ -23,9 +23,9 @@ package com.vitorpamplona.amethyst.ui.dal import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.ui.actions.relays.updated -import com.vitorpamplona.quartz.events.ChatroomKey -import com.vitorpamplona.quartz.events.ChatroomKeyable -import com.vitorpamplona.quartz.events.PrivateDmEvent +import com.vitorpamplona.quartz.nip04Dm.PrivateDmEvent +import com.vitorpamplona.quartz.nip17Dm.ChatroomKey +import com.vitorpamplona.quartz.nip17Dm.ChatroomKeyable class ChatroomListNewFeedFilter( val account: Account, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/CommunityFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/CommunityFeedFilter.kt index 1b3f628bf..5839dd93c 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/CommunityFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/CommunityFeedFilter.kt @@ -24,8 +24,9 @@ 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.quartz.encoders.HexKey -import com.vitorpamplona.quartz.events.CommunityPostApprovalEvent +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.isTaggedAddressableNote +import com.vitorpamplona.quartz.nip72ModCommunities.CommunityPostApprovalEvent class CommunityFeedFilter( val note: AddressableNote, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/DefaultFeedOrder.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/DefaultFeedOrder.kt index 43baf14ab..6391031f9 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/DefaultFeedOrder.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/DefaultFeedOrder.kt @@ -22,7 +22,7 @@ package com.vitorpamplona.amethyst.ui.dal import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.ui.screen.loggedIn.notifications.Card -import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.nip01Core.core.Event val DefaultFeedOrder: Comparator = compareByDescending diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverChatFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverChatFeedFilter.kt index afba5e510..0a26b7b32 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverChatFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverChatFeedFilter.kt @@ -24,10 +24,10 @@ import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.PublicChatChannel -import com.vitorpamplona.quartz.events.ChannelCreateEvent -import com.vitorpamplona.quartz.events.IsInPublicChatChannel -import com.vitorpamplona.quartz.events.MuteListEvent -import com.vitorpamplona.quartz.events.PeopleListEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelCreateEvent +import com.vitorpamplona.quartz.nip28PublicChat.IsInPublicChatChannel +import com.vitorpamplona.quartz.nip51Lists.MuteListEvent +import com.vitorpamplona.quartz.nip51Lists.PeopleListEvent open class DiscoverChatFeedFilter( val account: Account, @@ -86,8 +86,10 @@ open class DiscoverChatFeedFilter( } } else if (noteEvent is IsInPublicChatChannel) { val channel = noteEvent.channel()?.let { LocalCache.checkGetOrCreateNote(it) } + val channelEvent = channel?.event + if (channel != null && - (channel.event == null || (channel.event is ChannelCreateEvent && params.match(channel.event))) + (channelEvent == null || (channelEvent is ChannelCreateEvent && params.match(channelEvent))) ) { if ((LocalCache.getChannelIfExists(channel.idHex)?.notes?.size() ?: 0) > 0) { channel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverCommunityFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverCommunityFeedFilter.kt index f5114ee9e..7d7dc3a31 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverCommunityFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverCommunityFeedFilter.kt @@ -23,11 +23,12 @@ 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.quartz.encoders.ATag -import com.vitorpamplona.quartz.events.CommunityDefinitionEvent -import com.vitorpamplona.quartz.events.CommunityPostApprovalEvent -import com.vitorpamplona.quartz.events.MuteListEvent -import com.vitorpamplona.quartz.events.PeopleListEvent +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip19Bech32Entities.parseAtagUnckecked +import com.vitorpamplona.quartz.nip51Lists.MuteListEvent +import com.vitorpamplona.quartz.nip51Lists.PeopleListEvent +import com.vitorpamplona.quartz.nip72ModCommunities.CommunityDefinitionEvent +import com.vitorpamplona.quartz.nip72ModCommunities.CommunityPostApprovalEvent open class DiscoverCommunityFeedFilter( val account: Account, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverLiveFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverLiveFeedFilter.kt index 544407858..c31137858 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverLiveFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverLiveFeedFilter.kt @@ -24,12 +24,12 @@ import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.ParticipantListBuilder -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 com.vitorpamplona.quartz.events.MuteListEvent -import com.vitorpamplona.quartz.events.PeopleListEvent +import com.vitorpamplona.quartz.nip51Lists.MuteListEvent +import com.vitorpamplona.quartz.nip51Lists.PeopleListEvent +import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent +import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent.Companion.STATUS_ENDED +import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent.Companion.STATUS_LIVE +import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent.Companion.STATUS_PLANNED open class DiscoverLiveFeedFilter( val account: Account, @@ -62,7 +62,10 @@ open class DiscoverLiveFeedFilter( hiddenUsers = account.flowHiddenUsers.value, ) - return collection.filterTo(HashSet()) { it.event is LiveActivitiesEvent && filterParams.match(it.event) } + return collection.filterTo(HashSet()) { + val noteEvent = it.event + noteEvent is LiveActivitiesEvent && filterParams.match(noteEvent) + } } override fun sort(collection: Set): List { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverMarketplaceFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverMarketplaceFeedFilter.kt index 69c2083c1..581f03a56 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverMarketplaceFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverMarketplaceFeedFilter.kt @@ -23,9 +23,9 @@ 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.quartz.events.ClassifiedsEvent -import com.vitorpamplona.quartz.events.MuteListEvent -import com.vitorpamplona.quartz.events.PeopleListEvent +import com.vitorpamplona.quartz.nip51Lists.MuteListEvent +import com.vitorpamplona.quartz.nip51Lists.PeopleListEvent +import com.vitorpamplona.quartz.nip99Classifieds.ClassifiedsEvent open class DiscoverMarketplaceFeedFilter( val account: Account, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverNIP89FeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverNIP89FeedFilter.kt index ca32d18d2..19b13c880 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverNIP89FeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverNIP89FeedFilter.kt @@ -23,9 +23,9 @@ 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.quartz.events.AppDefinitionEvent -import com.vitorpamplona.quartz.events.MuteListEvent -import com.vitorpamplona.quartz.events.PeopleListEvent +import com.vitorpamplona.quartz.nip51Lists.MuteListEvent +import com.vitorpamplona.quartz.nip51Lists.PeopleListEvent +import com.vitorpamplona.quartz.nip89AppHandlers.AppDefinitionEvent import com.vitorpamplona.quartz.utils.TimeUtils open class DiscoverNIP89FeedFilter( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/DraftEventsFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/DraftEventsFeedFilter.kt index 25bebe5d6..0b42f7c79 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/DraftEventsFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/DraftEventsFeedFilter.kt @@ -23,7 +23,7 @@ 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.quartz.events.DraftEvent +import com.vitorpamplona.quartz.nip37Drafts.DraftEvent class DraftEventsFeedFilter( val account: Account, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/FilterByListParams.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/FilterByListParams.kt index 5871ba75b..997ac3d53 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/FilterByListParams.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/FilterByListParams.kt @@ -23,13 +23,15 @@ package com.vitorpamplona.amethyst.ui.dal import com.vitorpamplona.amethyst.model.AROUND_ME import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.GLOBAL_FOLLOWS -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.events.CommentEvent -import com.vitorpamplona.quartz.events.Event -import com.vitorpamplona.quartz.events.EventInterface -import com.vitorpamplona.quartz.events.LiveActivitiesEvent -import com.vitorpamplona.quartz.events.MuteListEvent -import com.vitorpamplona.quartz.events.PeopleListEvent +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.addressables.isTaggedAddressableNotes +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.geohash.isTaggedGeoHashes +import com.vitorpamplona.quartz.nip01Core.hashtags.isTaggedHashes +import com.vitorpamplona.quartz.nip22Comments.CommentEvent +import com.vitorpamplona.quartz.nip51Lists.MuteListEvent +import com.vitorpamplona.quartz.nip51Lists.PeopleListEvent +import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent import com.vitorpamplona.quartz.utils.TimeUtils class FilterByListParams( @@ -72,11 +74,6 @@ class FilterByListParams( return aTag.pubKeyHex in followLists.authors } - fun match( - noteEvent: EventInterface?, - isGlobalRelay: Boolean = true, - ) = if (noteEvent is Event) match(noteEvent, isGlobalRelay) else false - fun match( noteEvent: Event, isGlobalRelay: Boolean = true, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/GeoHashFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/GeoHashFeedFilter.kt index f1d2131cf..087235ea9 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/GeoHashFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/GeoHashFeedFilter.kt @@ -23,13 +23,14 @@ 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.quartz.events.AudioHeaderEvent -import com.vitorpamplona.quartz.events.ChannelMessageEvent -import com.vitorpamplona.quartz.events.LongTextNoteEvent -import com.vitorpamplona.quartz.events.PollNoteEvent -import com.vitorpamplona.quartz.events.PrivateDmEvent -import com.vitorpamplona.quartz.events.TextNoteEvent -import com.vitorpamplona.quartz.events.WikiNoteEvent +import com.vitorpamplona.quartz.experimental.audio.AudioHeaderEvent +import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent +import com.vitorpamplona.quartz.nip01Core.geohash.isTaggedGeoHash +import com.vitorpamplona.quartz.nip04Dm.PrivateDmEvent +import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent +import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelMessageEvent +import com.vitorpamplona.quartz.nip54Wiki.WikiNoteEvent class GeoHashFeedFilter( val tag: String, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/HashtagFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/HashtagFeedFilter.kt index 74a0b99f8..2129efdec 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/HashtagFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/HashtagFeedFilter.kt @@ -23,15 +23,16 @@ 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.quartz.events.AudioHeaderEvent -import com.vitorpamplona.quartz.events.ChannelMessageEvent -import com.vitorpamplona.quartz.events.GenericRepostEvent -import com.vitorpamplona.quartz.events.LongTextNoteEvent -import com.vitorpamplona.quartz.events.PollNoteEvent -import com.vitorpamplona.quartz.events.PrivateDmEvent -import com.vitorpamplona.quartz.events.RepostEvent -import com.vitorpamplona.quartz.events.TextNoteEvent -import com.vitorpamplona.quartz.events.WikiNoteEvent +import com.vitorpamplona.quartz.experimental.audio.AudioHeaderEvent +import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent +import com.vitorpamplona.quartz.nip01Core.hashtags.isTaggedHash +import com.vitorpamplona.quartz.nip04Dm.PrivateDmEvent +import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent +import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent +import com.vitorpamplona.quartz.nip18Reposts.RepostEvent +import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelMessageEvent +import com.vitorpamplona.quartz.nip54Wiki.WikiNoteEvent class HashtagFeedFilter( val tag: String, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/HomeConversationsFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/HomeConversationsFeedFilter.kt index 2132975b2..f4678e056 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/HomeConversationsFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/HomeConversationsFeedFilter.kt @@ -23,13 +23,14 @@ 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.quartz.events.ChannelMessageEvent -import com.vitorpamplona.quartz.events.CommentEvent -import com.vitorpamplona.quartz.events.LiveActivitiesChatMessageEvent -import com.vitorpamplona.quartz.events.MuteListEvent -import com.vitorpamplona.quartz.events.PeopleListEvent -import com.vitorpamplona.quartz.events.PollNoteEvent -import com.vitorpamplona.quartz.events.TextNoteEvent +import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent +import com.vitorpamplona.quartz.nip22Comments.CommentEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelMessageEvent +import com.vitorpamplona.quartz.nip51Lists.MuteListEvent +import com.vitorpamplona.quartz.nip51Lists.PeopleListEvent +import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesChatMessageEvent class HomeConversationsFeedFilter( val account: Account, @@ -69,18 +70,22 @@ class HomeConversationsFeedFilter( } fun acceptableEvent( - it: Note, + event: Event?, filterParams: FilterByListParams, ): Boolean = ( - it.event is TextNoteEvent || - it.event is PollNoteEvent || - it.event is ChannelMessageEvent || - it.event is CommentEvent || - it.event is LiveActivitiesChatMessageEvent + event is TextNoteEvent || + event is PollNoteEvent || + event is ChannelMessageEvent || + event is CommentEvent || + event is LiveActivitiesChatMessageEvent ) && - filterParams.match(it.event) && - !it.isNewThread() + filterParams.match(event) + + fun acceptableEvent( + note: Note, + filterParams: FilterByListParams, + ): Boolean = acceptableEvent(note.event, filterParams) && !note.isNewThread() override fun sort(collection: Set): List = collection.sortedWith(DefaultFeedOrder) } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/HomeNewThreadFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/HomeNewThreadFeedFilter.kt index b6bcc7d9e..87661230a 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/HomeNewThreadFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/HomeNewThreadFeedFilter.kt @@ -23,20 +23,20 @@ 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.quartz.events.AudioHeaderEvent -import com.vitorpamplona.quartz.events.AudioTrackEvent -import com.vitorpamplona.quartz.events.ClassifiedsEvent -import com.vitorpamplona.quartz.events.CommentEvent -import com.vitorpamplona.quartz.events.GenericRepostEvent -import com.vitorpamplona.quartz.events.HighlightEvent -import com.vitorpamplona.quartz.events.InteractiveStoryPrologueEvent -import com.vitorpamplona.quartz.events.LongTextNoteEvent -import com.vitorpamplona.quartz.events.MuteListEvent -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.events.WikiNoteEvent +import com.vitorpamplona.quartz.experimental.audio.AudioHeaderEvent +import com.vitorpamplona.quartz.experimental.audio.AudioTrackEvent +import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStoryPrologueEvent +import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent +import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent +import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent +import com.vitorpamplona.quartz.nip18Reposts.RepostEvent +import com.vitorpamplona.quartz.nip22Comments.CommentEvent +import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent +import com.vitorpamplona.quartz.nip51Lists.MuteListEvent +import com.vitorpamplona.quartz.nip51Lists.PeopleListEvent +import com.vitorpamplona.quartz.nip54Wiki.WikiNoteEvent +import com.vitorpamplona.quartz.nip84Highlights.HighlightEvent +import com.vitorpamplona.quartz.nip99Classifieds.ClassifiedsEvent class HomeNewThreadFeedFilter( val account: Account, @@ -62,7 +62,7 @@ class HomeNewThreadFeedFilter( val notes = LocalCache.notes.filterIntoSet { _, note -> // Avoids processing addressables twice. - (note.event?.kind() ?: 99999) < 10000 && acceptableEvent(note, gRelays, filterParams) + (note.event?.kind ?: 99999) < 10000 && acceptableEvent(note, gRelays, filterParams) } val longFormNotes = diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/NIP90ContentDiscoveryResponseFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/NIP90ContentDiscoveryResponseFilter.kt index f1a3c975d..e91838bce 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/NIP90ContentDiscoveryResponseFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/NIP90ContentDiscoveryResponseFilter.kt @@ -24,9 +24,10 @@ import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.observables.CreatedAtComparator -import com.vitorpamplona.quartz.events.MuteListEvent -import com.vitorpamplona.quartz.events.NIP90ContentDiscoveryResponseEvent -import com.vitorpamplona.quartz.events.PeopleListEvent +import com.vitorpamplona.quartz.nip01Core.events.isTaggedEvent +import com.vitorpamplona.quartz.nip51Lists.MuteListEvent +import com.vitorpamplona.quartz.nip51Lists.PeopleListEvent +import com.vitorpamplona.quartz.nip90Dvms.NIP90ContentDiscoveryResponseEvent open class NIP90ContentDiscoveryResponseFilter( val account: Account, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/NotificationFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/NotificationFeedFilter.kt index 0351d9fb2..175304374 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/NotificationFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/NotificationFeedFilter.kt @@ -23,26 +23,27 @@ 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.quartz.encoders.HexKey -import com.vitorpamplona.quartz.events.BadgeDefinitionEvent -import com.vitorpamplona.quartz.events.BadgeProfilesEvent -import com.vitorpamplona.quartz.events.BaseTextNoteEvent -import com.vitorpamplona.quartz.events.ChannelCreateEvent -import com.vitorpamplona.quartz.events.ChannelMetadataEvent -import com.vitorpamplona.quartz.events.GenericRepostEvent -import com.vitorpamplona.quartz.events.GiftWrapEvent -import com.vitorpamplona.quartz.events.GitIssueEvent -import com.vitorpamplona.quartz.events.GitPatchEvent -import com.vitorpamplona.quartz.events.HighlightEvent -import com.vitorpamplona.quartz.events.LnZapEvent -import com.vitorpamplona.quartz.events.LnZapRequestEvent -import com.vitorpamplona.quartz.events.MuteListEvent -import com.vitorpamplona.quartz.events.NIP90ContentDiscoveryRequestEvent -import com.vitorpamplona.quartz.events.NIP90ContentDiscoveryResponseEvent -import com.vitorpamplona.quartz.events.NIP90StatusEvent -import com.vitorpamplona.quartz.events.PeopleListEvent -import com.vitorpamplona.quartz.events.ReactionEvent -import com.vitorpamplona.quartz.events.RepostEvent +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.people.isTaggedUser +import com.vitorpamplona.quartz.nip10Notes.BaseTextNoteEvent +import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent +import com.vitorpamplona.quartz.nip18Reposts.RepostEvent +import com.vitorpamplona.quartz.nip25Reactions.ReactionEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelCreateEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelMetadataEvent +import com.vitorpamplona.quartz.nip34Git.GitIssueEvent +import com.vitorpamplona.quartz.nip34Git.GitPatchEvent +import com.vitorpamplona.quartz.nip51Lists.MuteListEvent +import com.vitorpamplona.quartz.nip51Lists.PeopleListEvent +import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent +import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent +import com.vitorpamplona.quartz.nip58Badges.BadgeDefinitionEvent +import com.vitorpamplona.quartz.nip58Badges.BadgeProfilesEvent +import com.vitorpamplona.quartz.nip59Giftwrap.GiftWrapEvent +import com.vitorpamplona.quartz.nip84Highlights.HighlightEvent +import com.vitorpamplona.quartz.nip90Dvms.NIP90ContentDiscoveryRequestEvent +import com.vitorpamplona.quartz.nip90Dvms.NIP90ContentDiscoveryResponseEvent +import com.vitorpamplona.quartz.nip90Dvms.NIP90StatusEvent class NotificationFeedFilter( val account: Account, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileAppRecommendationsFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileAppRecommendationsFeedFilter.kt index d85ac7d1f..986457950 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileAppRecommendationsFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileAppRecommendationsFeedFilter.kt @@ -23,7 +23,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.quartz.events.AppRecommendationEvent +import com.vitorpamplona.quartz.nip89AppHandlers.AppRecommendationEvent class UserProfileAppRecommendationsFeedFilter( val user: User, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileBookmarksFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileBookmarksFeedFilter.kt index 8044ab846..0e9590995 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileBookmarksFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileBookmarksFeedFilter.kt @@ -24,6 +24,8 @@ 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.quartz.nip01Core.addressables.taggedAddresses +import com.vitorpamplona.quartz.nip01Core.events.taggedEvents class UserProfileBookmarksFeedFilter( val user: User, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileConversationsFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileConversationsFeedFilter.kt index 90d8136c7..18d10f1ce 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileConversationsFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileConversationsFeedFilter.kt @@ -24,12 +24,12 @@ 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.quartz.events.ChannelMessageEvent -import com.vitorpamplona.quartz.events.CommentEvent -import com.vitorpamplona.quartz.events.LiveActivitiesChatMessageEvent -import com.vitorpamplona.quartz.events.PollNoteEvent -import com.vitorpamplona.quartz.events.TextNoteEvent -import com.vitorpamplona.quartz.events.TorrentCommentEvent +import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent +import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent +import com.vitorpamplona.quartz.nip22Comments.CommentEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelMessageEvent +import com.vitorpamplona.quartz.nip35Torrents.TorrentCommentEvent +import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesChatMessageEvent class UserProfileConversationsFeedFilter( val user: User, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileFollowsFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileFollowsFeedFilter.kt index a05722c62..f6b9c0ff0 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileFollowsFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileFollowsFeedFilter.kt @@ -23,7 +23,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.quartz.events.ContactListEvent +import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent class UserProfileFollowsFeedFilter( val user: User, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileGalleryFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileGalleryFeedFilter.kt index 9d1cc1e5e..fc9b69852 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileGalleryFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileGalleryFeedFilter.kt @@ -24,11 +24,11 @@ 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.quartz.events.MuteListEvent -import com.vitorpamplona.quartz.events.PeopleListEvent -import com.vitorpamplona.quartz.events.PictureEvent -import com.vitorpamplona.quartz.events.ProfileGalleryEntryEvent -import com.vitorpamplona.quartz.events.VideoEvent +import com.vitorpamplona.quartz.experimental.profileGallery.ProfileGalleryEntryEvent +import com.vitorpamplona.quartz.nip51Lists.MuteListEvent +import com.vitorpamplona.quartz.nip51Lists.PeopleListEvent +import com.vitorpamplona.quartz.nip68Picture.PictureEvent +import com.vitorpamplona.quartz.nip71Video.VideoEvent class UserProfileGalleryFeedFilter( val user: User, @@ -67,7 +67,7 @@ class UserProfileGalleryFeedFilter( ): Boolean { val noteEvent = it.event return ( - (it.event?.pubKey() == user.pubkeyHex && (noteEvent is PictureEvent || noteEvent is VideoEvent || (noteEvent is ProfileGalleryEntryEvent) && noteEvent.hasUrl() && noteEvent.hasFromEvent())) // && noteEvent.isOneOf(SUPPORTED_VIDEO_FEED_MIME_TYPES_SET)) + (it.event?.pubKey == user.pubkeyHex && (noteEvent is PictureEvent || noteEvent is VideoEvent || (noteEvent is ProfileGalleryEntryEvent) && noteEvent.hasUrl() && noteEvent.hasFromEvent())) // && noteEvent.isOneOf(SUPPORTED_VIDEO_FEED_MIME_TYPES_SET)) ) && params.match(noteEvent) && account.isAcceptable(it) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileNewThreadFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileNewThreadFeedFilter.kt index 0f8b99305..16fb34d01 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileNewThreadFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileNewThreadFeedFilter.kt @@ -25,19 +25,19 @@ import com.vitorpamplona.amethyst.model.AddressableNote import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User -import com.vitorpamplona.quartz.events.AddressableEvent -import com.vitorpamplona.quartz.events.AudioHeaderEvent -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.InteractiveStoryPrologueEvent -import com.vitorpamplona.quartz.events.LongTextNoteEvent -import com.vitorpamplona.quartz.events.PollNoteEvent -import com.vitorpamplona.quartz.events.RepostEvent -import com.vitorpamplona.quartz.events.TextNoteEvent -import com.vitorpamplona.quartz.events.TorrentEvent -import com.vitorpamplona.quartz.events.WikiNoteEvent +import com.vitorpamplona.quartz.experimental.audio.AudioHeaderEvent +import com.vitorpamplona.quartz.experimental.audio.AudioTrackEvent +import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStoryPrologueEvent +import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent +import com.vitorpamplona.quartz.nip01Core.addressables.AddressableEvent +import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent +import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent +import com.vitorpamplona.quartz.nip18Reposts.RepostEvent +import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent +import com.vitorpamplona.quartz.nip35Torrents.TorrentEvent +import com.vitorpamplona.quartz.nip54Wiki.WikiNoteEvent +import com.vitorpamplona.quartz.nip84Highlights.HighlightEvent +import com.vitorpamplona.quartz.nip99Classifieds.ClassifiedsEvent class UserProfileNewThreadFeedFilter( val user: User, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileReportsFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileReportsFeedFilter.kt index 931d500a1..454eb3152 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileReportsFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileReportsFeedFilter.kt @@ -22,7 +22,8 @@ package com.vitorpamplona.amethyst.ui.dal import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User -import com.vitorpamplona.quartz.events.ReportEvent +import com.vitorpamplona.quartz.nip01Core.people.isTaggedUser +import com.vitorpamplona.quartz.nip56Reports.ReportEvent class UserProfileReportsFeedFilter( val user: User, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileZapsFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileZapsFeedFilter.kt index b76a61f69..ac1c7c007 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileZapsFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileZapsFeedFilter.kt @@ -23,7 +23,7 @@ package com.vitorpamplona.amethyst.ui.dal import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.ui.screen.loggedIn.profile.ZapReqResponse -import com.vitorpamplona.quartz.events.LnZapEventInterface +import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent class UserProfileZapsFeedFilter( val user: User, @@ -41,7 +41,7 @@ class UserProfileZapsFeedFilter( return ( zaps .mapNotNull { entry -> entry.value?.let { ZapReqResponse(entry.key, it) } } - .sortedBy { (it.zapEvent.event as? LnZapEventInterface)?.amount() } + .sortedBy { (it.zapEvent.event as? LnZapEvent)?.amount() } .reversed() ) } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/VideoFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/VideoFeedFilter.kt index fd50f9f97..eadbaee62 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/VideoFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/VideoFeedFilter.kt @@ -26,15 +26,15 @@ import com.vitorpamplona.amethyst.model.AddressableNote import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.service.SUPPORTED_VIDEO_FEED_MIME_TYPES_SET -import com.vitorpamplona.quartz.events.AddressableEvent -import com.vitorpamplona.quartz.events.FileHeaderEvent -import com.vitorpamplona.quartz.events.FileStorageHeaderEvent -import com.vitorpamplona.quartz.events.MuteListEvent -import com.vitorpamplona.quartz.events.PeopleListEvent -import com.vitorpamplona.quartz.events.PictureEvent -import com.vitorpamplona.quartz.events.VideoHorizontalEvent -import com.vitorpamplona.quartz.events.VideoMeta -import com.vitorpamplona.quartz.events.VideoVerticalEvent +import com.vitorpamplona.quartz.experimental.nip95.FileStorageHeaderEvent +import com.vitorpamplona.quartz.nip01Core.addressables.AddressableEvent +import com.vitorpamplona.quartz.nip51Lists.MuteListEvent +import com.vitorpamplona.quartz.nip51Lists.PeopleListEvent +import com.vitorpamplona.quartz.nip68Picture.PictureEvent +import com.vitorpamplona.quartz.nip71Video.VideoHorizontalEvent +import com.vitorpamplona.quartz.nip71Video.VideoMeta +import com.vitorpamplona.quartz.nip71Video.VideoVerticalEvent +import com.vitorpamplona.quartz.nip94FileMetadata.FileHeaderEvent class VideoFeedFilter( val account: Account, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/feeds/FeedContentState.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/feeds/FeedContentState.kt index 206c4f0bd..5aa526208 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/feeds/FeedContentState.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/feeds/FeedContentState.kt @@ -31,7 +31,7 @@ import com.vitorpamplona.amethyst.ui.dal.FeedFilter import com.vitorpamplona.amethyst.ui.screen.loggedIn.notifications.equalImmutableLists import com.vitorpamplona.ammolite.relays.BundledInsert import com.vitorpamplona.ammolite.relays.BundledUpdate -import com.vitorpamplona.quartz.events.DeletionEvent +import com.vitorpamplona.quartz.nip09Deletions.DeletionEvent import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.CoroutineScope diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AccountSwitchBottomSheet.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AccountSwitchBottomSheet.kt index c2030ee9d..a1d14f0f3 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AccountSwitchBottomSheet.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AccountSwitchBottomSheet.kt @@ -71,7 +71,7 @@ import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.AccountPictureModifier import com.vitorpamplona.amethyst.ui.theme.Size10dp import com.vitorpamplona.amethyst.ui.theme.Size55dp -import com.vitorpamplona.quartz.encoders.decodePublicKeyAsHexOrNull +import com.vitorpamplona.quartz.nip19Bech32Entities.decodePublicKeyAsHexOrNull import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt index 565d4961c..791adcfc3 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt @@ -80,7 +80,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.threadview.ThreadScreen import com.vitorpamplona.amethyst.ui.screen.loggedIn.video.VideoScreen import com.vitorpamplona.amethyst.ui.screen.loggedOff.AddAccountDialog import com.vitorpamplona.amethyst.ui.uriToRoute -import com.vitorpamplona.quartz.encoders.Nip19Bech32 +import com.vitorpamplona.quartz.nip19Bech32Entities.Nip19Parser import kotlinx.coroutines.delay import kotlinx.coroutines.launch import java.net.URI @@ -417,7 +417,7 @@ private fun NavigateIfIntentRequested( } } else if (intentNextPage.contains("ncryptsec1")) { // login functions - Nip19Bech32.tryParseAndClean(intentNextPage)?.let { + Nip19Parser.tryParseAndClean(intentNextPage)?.let { newAccount = it } @@ -472,7 +472,7 @@ private fun NavigateIfIntentRequested( } } else if (uri.contains("ncryptsec")) { // login functions - Nip19Bech32.tryParseAndClean(uri)?.let { + Nip19Parser.tryParseAndClean(uri)?.let { newAccount = it } } else { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/DrawerContent.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/DrawerContent.kt index 8c3df6ec3..cbb6029ce 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/DrawerContent.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/DrawerContent.kt @@ -112,9 +112,9 @@ import com.vitorpamplona.amethyst.ui.theme.placeholderText import com.vitorpamplona.amethyst.ui.theme.profileContentHeaderModifier import com.vitorpamplona.amethyst.ui.tor.ConnectTorDialog import com.vitorpamplona.ammolite.relays.RelayPoolStatus -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.events.ImmutableListOfLists +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip02FollowList.ImmutableListOfLists @Composable fun DrawerContent( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/FeedFilterSpinner.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/FeedFilterSpinner.kt index 0f7af14ec..5ecd955d0 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/FeedFilterSpinner.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/FeedFilterSpinner.kt @@ -70,7 +70,7 @@ import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.Size20Modifier import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer import com.vitorpamplona.amethyst.ui.theme.placeholderText -import com.vitorpamplona.quartz.events.PeopleListEvent +import com.vitorpamplona.quartz.nip51Lists.PeopleListEvent import kotlinx.collections.immutable.ImmutableList @OptIn(ExperimentalPermissionsApi::class) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/RouteMaker.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/RouteMaker.kt index e3911fa22..f3c4e358d 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/RouteMaker.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/RouteMaker.kt @@ -24,18 +24,18 @@ import com.vitorpamplona.amethyst.model.Channel import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.events.AddressableEvent -import com.vitorpamplona.quartz.events.AppDefinitionEvent -import com.vitorpamplona.quartz.events.ChannelCreateEvent -import com.vitorpamplona.quartz.events.ChatroomKey -import com.vitorpamplona.quartz.events.ChatroomKeyable -import com.vitorpamplona.quartz.events.CommunityDefinitionEvent -import com.vitorpamplona.quartz.events.DraftEvent -import com.vitorpamplona.quartz.events.EventInterface -import com.vitorpamplona.quartz.events.IsInPublicChatChannel -import com.vitorpamplona.quartz.events.LiveActivitiesChatMessageEvent -import com.vitorpamplona.quartz.events.LiveActivitiesEvent +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.AddressableEvent +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip17Dm.ChatroomKey +import com.vitorpamplona.quartz.nip17Dm.ChatroomKeyable +import com.vitorpamplona.quartz.nip28PublicChat.ChannelCreateEvent +import com.vitorpamplona.quartz.nip28PublicChat.IsInPublicChatChannel +import com.vitorpamplona.quartz.nip37Drafts.DraftEvent +import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesChatMessageEvent +import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent +import com.vitorpamplona.quartz.nip72ModCommunities.CommunityDefinitionEvent +import com.vitorpamplona.quartz.nip89AppHandlers.AppDefinitionEvent import kotlinx.collections.immutable.persistentSetOf import java.net.URLEncoder @@ -49,7 +49,7 @@ fun routeFor( } fun routeFor( - noteEvent: EventInterface, + noteEvent: Event, loggedIn: User, ): String? { if (noteEvent is DraftEvent) { @@ -74,7 +74,7 @@ fun routeFor( } else if (innerEvent is AddressableEvent) { return "Note/${URLEncoder.encode(noteEvent.address().toTag(), "utf-8")}" } else { - return "Note/${URLEncoder.encode(noteEvent.id(), "utf-8")}" + return "Note/${URLEncoder.encode(noteEvent.id, "utf-8")}" } } else if (noteEvent is AppDefinitionEvent) { return "ContentDiscovery/${noteEvent.id}" @@ -101,7 +101,7 @@ fun routeFor( } else if (noteEvent is AddressableEvent) { return "Note/${URLEncoder.encode(noteEvent.address().toTag(), "utf-8")}" } else { - return "Note/${URLEncoder.encode(noteEvent.id(), "utf-8")}" + return "Note/${URLEncoder.encode(noteEvent.id, "utf-8")}" } return null diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ChannelCardCompose.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ChannelCardCompose.kt index fa5221237..5074e8fd5 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ChannelCardCompose.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ChannelCardCompose.kt @@ -102,16 +102,16 @@ import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer import com.vitorpamplona.amethyst.ui.theme.bitcoinColor import com.vitorpamplona.amethyst.ui.theme.grayText import com.vitorpamplona.amethyst.ui.theme.nip05 -import com.vitorpamplona.quartz.events.AppDefinitionEvent -import com.vitorpamplona.quartz.events.ChannelCreateEvent -import com.vitorpamplona.quartz.events.ClassifiedsEvent -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 com.vitorpamplona.quartz.events.Participant -import com.vitorpamplona.quartz.events.Price +import com.vitorpamplona.quartz.experimental.audio.Participant +import com.vitorpamplona.quartz.nip28PublicChat.ChannelCreateEvent +import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent +import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent.Companion.STATUS_ENDED +import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent.Companion.STATUS_LIVE +import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent.Companion.STATUS_PLANNED +import com.vitorpamplona.quartz.nip72ModCommunities.CommunityDefinitionEvent +import com.vitorpamplona.quartz.nip89AppHandlers.AppDefinitionEvent +import com.vitorpamplona.quartz.nip99Classifieds.ClassifiedsEvent +import com.vitorpamplona.quartz.nip99Classifieds.Price import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList @@ -130,7 +130,7 @@ fun ChannelCardCompose( nav: INav, ) { WatchNoteEvent(baseNote = baseNote, accountViewModel = accountViewModel) { - if (forceEventKind == null || baseNote.event?.kind() == forceEventKind) { + if (forceEventKind == null || baseNote.event?.kind == forceEventKind) { CheckHiddenFeedWatchBlockAndReport( note = baseNote, modifier = modifier, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/Loaders.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/Loaders.kt index d6007fb01..b0c232a27 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/Loaders.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/Loaders.kt @@ -39,7 +39,7 @@ import com.vitorpamplona.amethyst.service.CachedGeoLocations import com.vitorpamplona.amethyst.ui.components.GenericLoadable import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.notifications.equalImmutableLists -import com.vitorpamplona.quartz.encoders.ATag +import com.vitorpamplona.quartz.nip01Core.addressables.ATag import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.Dispatchers @@ -75,7 +75,7 @@ fun LoadDecryptedContentOrNull( ) { @Suppress("ProduceStateDoesNotAssignValue") val decryptedContent by - produceState(initialValue = accountViewModel.cachedDecrypt(note), key1 = note.event?.id()) { + produceState(initialValue = accountViewModel.cachedDecrypt(note), key1 = note.event?.id) { accountViewModel.decrypt(note) { if (value != it) { value = it @@ -184,7 +184,7 @@ fun LoadOts( } ?: run { val pendingAttestations by accountViewModel.account.settings.pendingAttestations .collectAsStateWithLifecycle() - val id = note.event?.id() ?: note.idHex + val id = note.event?.id ?: note.idHex if (pendingAttestations[id] != null) { whenPending() diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/MultiSetCompose.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/MultiSetCompose.kt index 8ca2c1770..aa60ee5ba 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/MultiSetCompose.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/MultiSetCompose.kt @@ -88,8 +88,8 @@ import com.vitorpamplona.amethyst.ui.theme.WidthAuthorPictureModifierWithPadding import com.vitorpamplona.amethyst.ui.theme.bitcoinColor import com.vitorpamplona.amethyst.ui.theme.overPictureBackground import com.vitorpamplona.amethyst.ui.theme.profile35dpModifier -import com.vitorpamplona.quartz.encoders.Nip30CustomEmoji -import com.vitorpamplona.quartz.events.EmptyTagList +import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList +import com.vitorpamplona.quartz.nip30CustomEmoji.CustomEmoji import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.launch @@ -200,7 +200,7 @@ fun RenderLikeGallery( val url = noStartColon.substringAfter(":") val renderable = - persistentListOf(Nip30CustomEmoji.ImageUrlType(url)) + persistentListOf(CustomEmoji.ImageUrlType(url)) InLineIconRenderer( renderable, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NIP05VerificationDisplay.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NIP05VerificationDisplay.kt index 7eadf8b70..a7caf54fc 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NIP05VerificationDisplay.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NIP05VerificationDisplay.kt @@ -72,9 +72,11 @@ import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer import com.vitorpamplona.amethyst.ui.theme.lessImportantLink import com.vitorpamplona.amethyst.ui.theme.nip05 import com.vitorpamplona.amethyst.ui.theme.placeholderText -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.events.AddressableEvent -import com.vitorpamplona.quartz.events.UserMetadata +import com.vitorpamplona.quartz.nip01Core.UserMetadata +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.addressables.firstTaggedAddress +import com.vitorpamplona.quartz.nip01Core.events.firstTaggedEvent +import com.vitorpamplona.quartz.nip38UserStatus.StatusEvent import com.vitorpamplona.quartz.utils.TimeUtils import kotlinx.collections.immutable.ImmutableList import kotlinx.coroutines.delay @@ -246,14 +248,23 @@ fun DisplayStatus( nav: INav, ) { val noteState by addressableNote.live().metadata.observeAsState() - val noteEvent = noteState?.note?.event ?: return + val noteEvent = noteState?.note?.event as? StatusEvent ?: return + DisplayStatus(noteEvent, accountViewModel, nav) +} + +@Composable +fun DisplayStatus( + event: StatusEvent, + accountViewModel: AccountViewModel, + nav: INav, +) { DisplayStatusInner( - noteEvent.content(), - (noteEvent as? AddressableEvent)?.dTag() ?: "", - noteEvent.firstTaggedUrl()?.ifBlank { null }, - noteEvent.firstTaggedAddress(), - noteEvent.firstTaggedEvent()?.ifBlank { null }, + event.content, + event.dTag(), + event.firstTaggedUrl()?.ifBlank { null }, + event.firstTaggedAddress(), + event.firstTaggedEvent()?.ifBlank { null }, accountViewModel, nav, ) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt index e50cb178f..38ceac260 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt @@ -149,57 +149,62 @@ import com.vitorpamplona.amethyst.ui.theme.newItemBackgroundColor import com.vitorpamplona.amethyst.ui.theme.normalWithTopMarginNoteModifier import com.vitorpamplona.amethyst.ui.theme.placeholderText import com.vitorpamplona.amethyst.ui.theme.replyModifier -import com.vitorpamplona.quartz.events.AdvertisedRelayListEvent -import com.vitorpamplona.quartz.events.AppDefinitionEvent -import com.vitorpamplona.quartz.events.AudioHeaderEvent -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.ChatMessageEncryptedFileHeaderEvent -import com.vitorpamplona.quartz.events.ChatMessageEvent -import com.vitorpamplona.quartz.events.ChatMessageRelayListEvent -import com.vitorpamplona.quartz.events.ClassifiedsEvent -import com.vitorpamplona.quartz.events.CommentEvent -import com.vitorpamplona.quartz.events.CommunityDefinitionEvent -import com.vitorpamplona.quartz.events.CommunityPostApprovalEvent -import com.vitorpamplona.quartz.events.DraftEvent -import com.vitorpamplona.quartz.events.EmojiPackEvent -import com.vitorpamplona.quartz.events.FhirResourceEvent -import com.vitorpamplona.quartz.events.FileHeaderEvent -import com.vitorpamplona.quartz.events.FileStorageHeaderEvent -import com.vitorpamplona.quartz.events.GenericRepostEvent -import com.vitorpamplona.quartz.events.GitIssueEvent -import com.vitorpamplona.quartz.events.GitPatchEvent -import com.vitorpamplona.quartz.events.GitRepositoryEvent -import com.vitorpamplona.quartz.events.HighlightEvent -import com.vitorpamplona.quartz.events.InteractiveStoryBaseEvent -import com.vitorpamplona.quartz.events.LiveActivitiesChatMessageEvent -import com.vitorpamplona.quartz.events.LiveActivitiesEvent -import com.vitorpamplona.quartz.events.LongTextNoteEvent -import com.vitorpamplona.quartz.events.NIP90ContentDiscoveryResponseEvent -import com.vitorpamplona.quartz.events.NIP90StatusEvent -import com.vitorpamplona.quartz.events.PeopleListEvent -import com.vitorpamplona.quartz.events.PictureEvent -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.SearchRelayListEvent -import com.vitorpamplona.quartz.events.TextNoteEvent -import com.vitorpamplona.quartz.events.TextNoteModificationEvent -import com.vitorpamplona.quartz.events.TorrentCommentEvent -import com.vitorpamplona.quartz.events.TorrentEvent -import com.vitorpamplona.quartz.events.VideoEvent -import com.vitorpamplona.quartz.events.VideoHorizontalEvent -import com.vitorpamplona.quartz.events.VideoVerticalEvent -import com.vitorpamplona.quartz.events.WikiNoteEvent +import com.vitorpamplona.quartz.experimental.audio.AudioHeaderEvent +import com.vitorpamplona.quartz.experimental.audio.AudioTrackEvent +import com.vitorpamplona.quartz.experimental.bounties.getReward +import com.vitorpamplona.quartz.experimental.edits.TextNoteModificationEvent +import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStoryBaseEvent +import com.vitorpamplona.quartz.experimental.medical.FhirResourceEvent +import com.vitorpamplona.quartz.experimental.nip95.FileStorageHeaderEvent +import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent +import com.vitorpamplona.quartz.nip01Core.addressables.isTaggedAddressableKind +import com.vitorpamplona.quartz.nip01Core.geohash.getGeoHash +import com.vitorpamplona.quartz.nip04Dm.PrivateDmEvent +import com.vitorpamplona.quartz.nip10Notes.BaseTextNoteEvent +import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent +import com.vitorpamplona.quartz.nip13Pow.getPoWRank +import com.vitorpamplona.quartz.nip17Dm.ChatMessageEncryptedFileHeaderEvent +import com.vitorpamplona.quartz.nip17Dm.ChatMessageEvent +import com.vitorpamplona.quartz.nip17Dm.ChatMessageRelayListEvent +import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent +import com.vitorpamplona.quartz.nip18Reposts.RepostEvent +import com.vitorpamplona.quartz.nip22Comments.CommentEvent +import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent +import com.vitorpamplona.quartz.nip25Reactions.ReactionEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelCreateEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelMessageEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelMetadataEvent +import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiPackEvent +import com.vitorpamplona.quartz.nip34Git.GitIssueEvent +import com.vitorpamplona.quartz.nip34Git.GitPatchEvent +import com.vitorpamplona.quartz.nip34Git.GitRepositoryEvent +import com.vitorpamplona.quartz.nip35Torrents.TorrentCommentEvent +import com.vitorpamplona.quartz.nip35Torrents.TorrentEvent +import com.vitorpamplona.quartz.nip37Drafts.DraftEvent +import com.vitorpamplona.quartz.nip50Search.SearchRelayListEvent +import com.vitorpamplona.quartz.nip51Lists.PeopleListEvent +import com.vitorpamplona.quartz.nip51Lists.PinListEvent +import com.vitorpamplona.quartz.nip51Lists.RelaySetEvent +import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesChatMessageEvent +import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent +import com.vitorpamplona.quartz.nip54Wiki.WikiNoteEvent +import com.vitorpamplona.quartz.nip56Reports.ReportEvent +import com.vitorpamplona.quartz.nip57Zaps.hasZapSplitSetup +import com.vitorpamplona.quartz.nip58Badges.BadgeAwardEvent +import com.vitorpamplona.quartz.nip58Badges.BadgeDefinitionEvent +import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent +import com.vitorpamplona.quartz.nip68Picture.PictureEvent +import com.vitorpamplona.quartz.nip71Video.VideoEvent +import com.vitorpamplona.quartz.nip71Video.VideoHorizontalEvent +import com.vitorpamplona.quartz.nip71Video.VideoVerticalEvent +import com.vitorpamplona.quartz.nip72ModCommunities.CommunityDefinitionEvent +import com.vitorpamplona.quartz.nip72ModCommunities.CommunityPostApprovalEvent +import com.vitorpamplona.quartz.nip84Highlights.HighlightEvent +import com.vitorpamplona.quartz.nip89AppHandlers.AppDefinitionEvent +import com.vitorpamplona.quartz.nip90Dvms.NIP90ContentDiscoveryResponseEvent +import com.vitorpamplona.quartz.nip90Dvms.NIP90StatusEvent +import com.vitorpamplona.quartz.nip94FileMetadata.FileHeaderEvent +import com.vitorpamplona.quartz.nip99Classifieds.ClassifiedsEvent @Composable fun NoteCompose( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteQuickActionMenu.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteQuickActionMenu.kt index fb6940ec7..dab45d740 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteQuickActionMenu.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteQuickActionMenu.kt @@ -95,9 +95,11 @@ import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.WarningColor import com.vitorpamplona.amethyst.ui.theme.isLight 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 com.vitorpamplona.quartz.experimental.audio.AudioTrackEvent +import com.vitorpamplona.quartz.experimental.bounties.getReward +import com.vitorpamplona.quartz.nip19Bech32Entities.toNAddr +import com.vitorpamplona.quartz.nip51Lists.PeopleListEvent +import com.vitorpamplona.quartz.nip94FileMetadata.FileHeaderEvent import kotlinx.coroutines.launch private fun lightenColor( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/PollNote.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/PollNote.kt index 4058efc27..208de6b75 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/PollNote.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/PollNote.kt @@ -93,11 +93,11 @@ import com.vitorpamplona.amethyst.ui.theme.ThemeComparisonColumn import com.vitorpamplona.amethyst.ui.theme.mediumImportanceLink import com.vitorpamplona.amethyst.ui.theme.placeholderText import com.vitorpamplona.amethyst.ui.theme.ripple24dp -import com.vitorpamplona.quartz.events.EmptyTagList -import com.vitorpamplona.quartz.events.ImmutableListOfLists -import com.vitorpamplona.quartz.events.LnZapEvent -import com.vitorpamplona.quartz.events.PollNoteEvent -import com.vitorpamplona.quartz.events.toImmutableListOfLists +import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent +import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList +import com.vitorpamplona.quartz.nip02FollowList.ImmutableListOfLists +import com.vitorpamplona.quartz.nip02FollowList.toImmutableListOfLists +import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.Dispatchers @@ -297,7 +297,7 @@ private fun OptionNote( backgroundColor: MutableState, nav: INav, ) { - val tags = remember(baseNote) { baseNote.event?.tags()?.toImmutableListOfLists() ?: EmptyTagList } + val tags = remember(baseNote) { baseNote.event?.tags?.toImmutableListOfLists() ?: EmptyTagList } Row( verticalAlignment = Alignment.CenterVertically, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/PollNoteViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/PollNoteViewModel.kt index ad05a333a..942278a7a 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/PollNoteViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/PollNoteViewModel.kt @@ -28,13 +28,13 @@ import androidx.lifecycle.viewModelScope import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User -import com.vitorpamplona.quartz.events.CLOSED_AT -import com.vitorpamplona.quartz.events.CONSENSUS_THRESHOLD -import com.vitorpamplona.quartz.events.LnZapEvent -import com.vitorpamplona.quartz.events.LnZapRequestEvent -import com.vitorpamplona.quartz.events.PollNoteEvent -import com.vitorpamplona.quartz.events.VALUE_MAXIMUM -import com.vitorpamplona.quartz.events.VALUE_MINIMUM +import com.vitorpamplona.quartz.experimental.zapPolls.CLOSED_AT +import com.vitorpamplona.quartz.experimental.zapPolls.CONSENSUS_THRESHOLD +import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent +import com.vitorpamplona.quartz.experimental.zapPolls.VALUE_MAXIMUM +import com.vitorpamplona.quartz.experimental.zapPolls.VALUE_MINIMUM +import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent +import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent import com.vitorpamplona.quartz.utils.TimeUtils import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/PubKeyFormatter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/PubKeyFormatter.kt index d06ed9ccb..f873e7041 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/PubKeyFormatter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/PubKeyFormatter.kt @@ -20,8 +20,8 @@ */ package com.vitorpamplona.amethyst.ui.note -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.toHexKey fun ByteArray.toShortenHex(): String = toHexKey().toShortenHex() diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt index 9fe891647..56b1c3742 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt @@ -104,7 +104,6 @@ import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.FeatureSetType import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User -import com.vitorpamplona.amethyst.service.NostrUserProfileDataSource.user import com.vitorpamplona.amethyst.service.ZapPaymentHandler import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.components.ClickableBox @@ -148,8 +147,9 @@ import com.vitorpamplona.amethyst.ui.theme.placeholderText import com.vitorpamplona.amethyst.ui.theme.reactionBox import com.vitorpamplona.amethyst.ui.theme.ripple24dp import com.vitorpamplona.amethyst.ui.theme.selectedReactionBoxModifier -import com.vitorpamplona.quartz.encoders.Nip30CustomEmoji -import com.vitorpamplona.quartz.events.BaseTextNoteEvent +import com.vitorpamplona.quartz.nip10Notes.BaseTextNoteEvent +import com.vitorpamplona.quartz.nip30CustomEmoji.CustomEmoji +import com.vitorpamplona.quartz.nip57Zaps.zapraiserAmount import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableSet import kotlinx.collections.immutable.persistentListOf @@ -581,7 +581,7 @@ private fun BoostWithDialog( val forkEvent = wantsToFork?.event if (forkEvent is BaseTextNoteEvent) { val hex = forkEvent.replyingTo() - wantsToFork?.replyTo?.filter { it.event?.id() == hex }?.firstOrNull() + wantsToFork?.replyTo?.filter { it.event?.id == hex }?.firstOrNull() } else { null } @@ -924,7 +924,7 @@ private fun RenderReactionType( val renderable = remember(reactionType) { persistentListOf( - Nip30CustomEmoji.ImageUrlType(reactionType.removePrefix(":").substringAfter(":")), + CustomEmoji.ImageUrlType(reactionType.removePrefix(":").substringAfter(":")), ) } @@ -1518,7 +1518,7 @@ fun RenderReaction(reactionType: String) { InLineIconRenderer( persistentListOf( - Nip30CustomEmoji.ImageUrlType(url), + CustomEmoji.ImageUrlType(url), ), style = SpanStyle(color = MaterialTheme.colorScheme.onBackground), maxLines = 1, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ShowEmojiSuggestionList.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ShowEmojiSuggestionList.kt index 2a6b21edf..adef49621 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ShowEmojiSuggestionList.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ShowEmojiSuggestionList.kt @@ -21,7 +21,6 @@ package com.vitorpamplona.amethyst.ui.note import androidx.compose.foundation.clickable -import androidx.compose.foundation.content.MediaType.Companion.Text import androidx.compose.foundation.layout.Arrangement.spacedBy import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.PaddingValues @@ -30,7 +29,6 @@ import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.grid.items import androidx.compose.foundation.lazy.items import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.OpenInFull @@ -55,7 +53,8 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.profile.gallery.UrlImageVie import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.DividerThickness import com.vitorpamplona.amethyst.ui.theme.Size10dp -import com.vitorpamplona.quartz.events.EmojiPackSelectionEvent +import com.vitorpamplona.quartz.nip01Core.addressables.taggedAddresses +import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiPackSelectionEvent import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.flow.Flow diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UpdateReactionTypeDialog.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UpdateReactionTypeDialog.kt index bcb40a371..c1b579a76 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UpdateReactionTypeDialog.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UpdateReactionTypeDialog.kt @@ -86,10 +86,11 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.SaveButton import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.ButtonBorder import com.vitorpamplona.amethyst.ui.theme.placeholderText -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.Nip30CustomEmoji -import com.vitorpamplona.quartz.events.EmojiPackSelectionEvent -import com.vitorpamplona.quartz.events.EmojiUrl +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.addressables.taggedAddresses +import com.vitorpamplona.quartz.nip30CustomEmoji.CustomEmoji +import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiPackSelectionEvent +import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiUrl import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList @@ -293,8 +294,8 @@ private fun RenderReactionOption( val renderable = persistentListOf( - Nip30CustomEmoji.ImageUrlType(url), - Nip30CustomEmoji.TextType(" ✖"), + CustomEmoji.ImageUrlType(url), + CustomEmoji.TextType(" ✖"), ) InLineIconRenderer( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UpdateZapAmountDialog.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UpdateZapAmountDialog.kt index 722a434a6..738899202 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UpdateZapAmountDialog.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UpdateZapAmountDialog.kt @@ -98,12 +98,12 @@ import com.vitorpamplona.amethyst.ui.theme.ButtonBorder import com.vitorpamplona.amethyst.ui.theme.DividerThickness import com.vitorpamplona.amethyst.ui.theme.Font14SP import com.vitorpamplona.amethyst.ui.theme.placeholderText -import com.vitorpamplona.quartz.encoders.Nip47WalletConnect -import com.vitorpamplona.quartz.encoders.RelayUrlFormatter -import com.vitorpamplona.quartz.encoders.decodePrivateKeyAsHexOrNull -import com.vitorpamplona.quartz.encoders.decodePublicKey -import com.vitorpamplona.quartz.encoders.toHexKey -import com.vitorpamplona.quartz.events.LnZapEvent +import com.vitorpamplona.quartz.nip01Core.toHexKey +import com.vitorpamplona.quartz.nip19Bech32Entities.decodePrivateKeyAsHexOrNull +import com.vitorpamplona.quartz.nip19Bech32Entities.decodePublicKey +import com.vitorpamplona.quartz.nip47WalletConnect.Nip47WalletConnect +import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent +import com.vitorpamplona.quartz.nip65RelayList.RelayUrlFormatter import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.CancellationException import kotlinx.coroutines.Dispatchers diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UserProfilePicture.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UserProfilePicture.kt index a1f447424..0e3fbc5f0 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UserProfilePicture.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UserProfilePicture.kt @@ -46,7 +46,7 @@ import com.vitorpamplona.amethyst.ui.navigation.INav import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.chatrooms.LoadUser import com.vitorpamplona.amethyst.ui.stringRes -import com.vitorpamplona.quartz.events.ChatroomKey +import com.vitorpamplona.quartz.nip17Dm.ChatroomKey @Composable fun NoteAuthorPicture( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UsernameDisplay.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UsernameDisplay.kt index b2c2084ce..6ba65b507 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UsernameDisplay.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UsernameDisplay.kt @@ -44,7 +44,7 @@ import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.theme.StdButtonSizeModifier import com.vitorpamplona.amethyst.ui.theme.placeholderText -import com.vitorpamplona.quartz.events.ImmutableListOfLists +import com.vitorpamplona.quartz.nip02FollowList.ImmutableListOfLists @Composable fun NoteUsernameDisplay( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapCustomDialog.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapCustomDialog.kt index 2cccf7099..b9c0da284 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapCustomDialog.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapCustomDialog.kt @@ -79,7 +79,7 @@ import com.vitorpamplona.amethyst.ui.theme.Size55dp import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer import com.vitorpamplona.amethyst.ui.theme.ZeroPadding import com.vitorpamplona.amethyst.ui.theme.placeholderText -import com.vitorpamplona.quartz.events.LnZapEvent +import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.CancellationException diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapNoteCompose.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapNoteCompose.kt index 4512eea17..b58a23692 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapNoteCompose.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapNoteCompose.kt @@ -56,7 +56,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.profile.ZapReqResponse 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.LnZapEvent +import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/AddInboxRelayForDMCard.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/AddInboxRelayForDMCard.kt index e56775327..3f29bca70 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/AddInboxRelayForDMCard.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/AddInboxRelayForDMCard.kt @@ -51,8 +51,8 @@ import com.vitorpamplona.amethyst.ui.theme.StdPadding import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer import com.vitorpamplona.amethyst.ui.theme.ThemeComparisonColumn import com.vitorpamplona.amethyst.ui.theme.imageModifier -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.events.ChatMessageRelayListEvent +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip17Dm.ChatMessageRelayListEvent @Preview @Composable diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/AddInboxRelayForSearchCard.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/AddInboxRelayForSearchCard.kt index b1337d3a2..69b85288a 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/AddInboxRelayForSearchCard.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/AddInboxRelayForSearchCard.kt @@ -51,8 +51,8 @@ import com.vitorpamplona.amethyst.ui.theme.StdPadding import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer import com.vitorpamplona.amethyst.ui.theme.ThemeComparisonColumn import com.vitorpamplona.amethyst.ui.theme.imageModifier -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.events.SearchRelayListEvent +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip50Search.SearchRelayListEvent @Preview @Composable diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayCommunity.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayCommunity.kt index 53294064e..63466220e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayCommunity.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayCommunity.kt @@ -33,8 +33,9 @@ import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.ui.navigation.INav import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.theme.HalfStartPadding -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.events.CommunityDefinitionEvent +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.addressables.getTagOfAddressableKind +import com.vitorpamplona.quartz.nip72ModCommunities.CommunityDefinitionEvent @Composable fun DisplayFollowingCommunityInPost( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayHashtags.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayHashtags.kt index 774bb763a..ac7a4372d 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayHashtags.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayHashtags.kt @@ -38,6 +38,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.ui.navigation.INav import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel +import com.vitorpamplona.quartz.nip01Core.hashtags.firstIsTaggedHashes @Composable fun DisplayFollowingHashtagsInPost( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayUncitedHashtags.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayUncitedHashtags.kt index 113cf5ced..3cc0bfe0c 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayUncitedHashtags.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayUncitedHashtags.kt @@ -35,8 +35,9 @@ import com.vitorpamplona.amethyst.service.CachedRichTextParser import com.vitorpamplona.amethyst.ui.navigation.INav import com.vitorpamplona.amethyst.ui.theme.HalfTopPadding import com.vitorpamplona.amethyst.ui.theme.lessImportantLink -import com.vitorpamplona.quartz.events.Event -import com.vitorpamplona.quartz.events.toImmutableListOfLists +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.hashtags.hashtags +import com.vitorpamplona.quartz.nip02FollowList.toImmutableListOfLists import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayZapSplits.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayZapSplits.kt index 2b8162fe1..c14767b80 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayZapSplits.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayZapSplits.kt @@ -38,13 +38,14 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange import com.vitorpamplona.amethyst.ui.theme.Size25dp import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer -import com.vitorpamplona.quartz.events.EventInterface -import com.vitorpamplona.quartz.events.ZapSplitSetup +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip57Zaps.ZapSplitSetup +import com.vitorpamplona.quartz.nip57Zaps.zapSplitSetup @OptIn(ExperimentalLayoutApi::class) @Composable fun DisplayZapSplits( - noteEvent: EventInterface, + noteEvent: Event, useAuthorIfEmpty: Boolean = false, accountViewModel: AccountViewModel, nav: INav, @@ -55,7 +56,7 @@ fun DisplayZapSplits( if (list.isEmpty() && useAuthorIfEmpty) { listOf( ZapSplitSetup( - lnAddressOrPubKeyHex = noteEvent.pubKey(), + lnAddressOrPubKeyHex = noteEvent.pubKey, relay = null, weight = 1.0, isLnAddress = false, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DropDownMenu.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DropDownMenu.kt index 37f3fd944..f39be374e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DropDownMenu.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DropDownMenu.kt @@ -55,7 +55,8 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.ReportNoteDialog import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.DividerThickness import com.vitorpamplona.amethyst.ui.theme.Size24Modifier -import com.vitorpamplona.quartz.events.TextNoteEvent +import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent +import com.vitorpamplona.quartz.nip36SensitiveContent.isSensitiveOrNSFW import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -402,7 +403,7 @@ fun WatchBookmarksFollowsAndAccount( isPrivateBookmarkNote = it, isPublicBookmarkNote = accountViewModel.isInPublicBookmarks(note), isLoggedUser = accountViewModel.isLoggedUser(note.author), - isSensitive = note.event?.isSensitive() ?: false, + isSensitive = note.event?.isSensitiveOrNSFW() ?: false, showSensitiveContent = showSensitiveContent, ) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/ForkInfo.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/ForkInfo.kt index bdf0e14b1..4a6376a24 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/ForkInfo.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/ForkInfo.kt @@ -45,7 +45,7 @@ import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.Font14SP import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer import com.vitorpamplona.amethyst.ui.theme.nip05 -import com.vitorpamplona.quartz.events.BaseTextNoteEvent +import com.vitorpamplona.quartz.nip10Notes.BaseTextNoteEvent @Composable fun ShowForkInformation( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/ZapTheDevsCard.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/ZapTheDevsCard.kt index e48cf9721..c92fd13aa 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/ZapTheDevsCard.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/ZapTheDevsCard.kt @@ -89,7 +89,7 @@ import com.vitorpamplona.amethyst.ui.theme.Size35dp import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer import com.vitorpamplona.amethyst.ui.theme.ThemeComparisonColumn import com.vitorpamplona.amethyst.ui.theme.imageModifier -import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.nip01Core.core.Event import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/AppDefinition.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/AppDefinition.kt index ec7a3a63c..907ff9612 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/AppDefinition.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/AppDefinition.kt @@ -70,10 +70,10 @@ import com.vitorpamplona.amethyst.ui.stringRes 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.events.AppDefinitionEvent -import com.vitorpamplona.quartz.events.AppMetadata -import com.vitorpamplona.quartz.events.EmptyTagList -import com.vitorpamplona.quartz.events.toImmutableListOfLists +import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList +import com.vitorpamplona.quartz.nip02FollowList.toImmutableListOfLists +import com.vitorpamplona.quartz.nip89AppHandlers.AppDefinitionEvent +import com.vitorpamplona.quartz.nip89AppHandlers.AppMetadata import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext @@ -197,7 +197,7 @@ fun RenderAppDefinition( text = it, tags = remember { - (note.event?.tags() ?: emptyArray()).toImmutableListOfLists() + (note.event?.tags ?: emptyArray()).toImmutableListOfLists() }, fontWeight = FontWeight.Bold, fontSize = 25.sp, @@ -225,7 +225,7 @@ fun RenderAppDefinition( ) { val tags = remember(note) { - note.event?.tags()?.toImmutableListOfLists() ?: EmptyTagList + note.event?.tags?.toImmutableListOfLists() ?: EmptyTagList } val bgColor = MaterialTheme.colorScheme.background val backgroundColor = remember { mutableStateOf(bgColor) } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/AudioTrack.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/AudioTrack.kt index a76052a01..d023307f9 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/AudioTrack.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/AudioTrack.kt @@ -52,10 +52,12 @@ import com.vitorpamplona.amethyst.ui.note.UsernameDisplay import com.vitorpamplona.amethyst.ui.note.elements.DisplayUncitedHashtags import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.theme.placeholderText -import com.vitorpamplona.quartz.events.AudioHeaderEvent -import com.vitorpamplona.quartz.events.AudioTrackEvent -import com.vitorpamplona.quartz.events.Participant -import com.vitorpamplona.quartz.events.toImmutableListOfLists +import com.vitorpamplona.quartz.experimental.audio.AudioHeaderEvent +import com.vitorpamplona.quartz.experimental.audio.AudioTrackEvent +import com.vitorpamplona.quartz.experimental.audio.Participant +import com.vitorpamplona.quartz.nip01Core.hashtags.hasHashtags +import com.vitorpamplona.quartz.nip02FollowList.toImmutableListOfLists +import com.vitorpamplona.quartz.nip14Subject.subject import kotlinx.collections.immutable.toImmutableList import java.util.Locale @@ -82,7 +84,7 @@ fun AudioTrackHeader( val media = remember { noteEvent.media() } val cover = remember { noteEvent.cover() } val subject = remember { noteEvent.subject() } - val content = remember { noteEvent.content() } + val content = remember { noteEvent.content } val participants = remember { noteEvent.participants() } var participantUsers by remember { mutableStateOf>>(emptyList()) } @@ -192,11 +194,11 @@ fun AudioHeader( ) { val media = remember { noteEvent.stream() ?: noteEvent.download() } val waveform = remember { noteEvent.wavefrom()?.toImmutableList()?.ifEmpty { null } } - val content = remember { noteEvent.content().ifBlank { null } } + val content = remember { noteEvent.content.ifBlank { null } } val defaultBackground = MaterialTheme.colorScheme.background val background = remember { mutableStateOf(defaultBackground) } - val tags = remember(noteEvent) { noteEvent.tags().toImmutableListOfLists() } + val tags = remember(noteEvent) { noteEvent.tags.toImmutableListOfLists() } Row(modifier = Modifier.padding(top = 5.dp)) { Column(modifier = Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Badge.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Badge.kt index 83e8e2759..ae2b1dd4a 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Badge.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Badge.kt @@ -53,8 +53,8 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.Size35dp import com.vitorpamplona.amethyst.ui.theme.ThemeComparisonRow -import com.vitorpamplona.quartz.events.BadgeAwardEvent -import com.vitorpamplona.quartz.events.BadgeDefinitionEvent +import com.vitorpamplona.quartz.nip58Badges.BadgeAwardEvent +import com.vitorpamplona.quartz.nip58Badges.BadgeDefinitionEvent @Composable fun BadgeDisplay(baseNote: Note) { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/ChannelMessage.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/ChannelMessage.kt index f1d97abd5..0f2a5eff6 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/ChannelMessage.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/ChannelMessage.kt @@ -36,7 +36,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.chatrooms.ChannelHeader import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer import com.vitorpamplona.amethyst.ui.theme.replyModifier -import com.vitorpamplona.quartz.events.ChannelMessageEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelMessageEvent @Composable fun RenderChannelMessage( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/ChatMessage.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/ChatMessage.kt index 316d9698c..9e3c1705e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/ChatMessage.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/ChatMessage.kt @@ -39,7 +39,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.chatrooms.ChatroomHeader import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer import com.vitorpamplona.amethyst.ui.theme.replyModifier -import com.vitorpamplona.quartz.events.ChatroomKeyable +import com.vitorpamplona.quartz.nip17Dm.ChatroomKeyable @Composable fun RenderChatMessage( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/ChatMessageEncryptedFile.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/ChatMessageEncryptedFile.kt index 7adc1a7de..c60a99b21 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/ChatMessageEncryptedFile.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/ChatMessageEncryptedFile.kt @@ -54,10 +54,11 @@ import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.HalfVertPadding import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer import com.vitorpamplona.amethyst.ui.theme.replyModifier -import com.vitorpamplona.quartz.crypto.nip17.AESGCM -import com.vitorpamplona.quartz.events.ChatMessageEncryptedFileHeaderEvent -import com.vitorpamplona.quartz.events.ChatroomKeyable -import com.vitorpamplona.quartz.events.EmptyTagList +import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList +import com.vitorpamplona.quartz.nip17Dm.AESGCM +import com.vitorpamplona.quartz.nip17Dm.ChatMessageEncryptedFileHeaderEvent +import com.vitorpamplona.quartz.nip17Dm.ChatroomKeyable +import com.vitorpamplona.quartz.nip21UriScheme.toNostrUri import kotlinx.collections.immutable.persistentListOf @Composable diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Classifieds.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Classifieds.kt index 1bdb0c4a1..b6b5e97c7 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Classifieds.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Classifieds.kt @@ -50,7 +50,7 @@ import com.vitorpamplona.amethyst.ui.theme.DoubleVertSpacer import com.vitorpamplona.amethyst.ui.theme.QuoteBorder import com.vitorpamplona.amethyst.ui.theme.SmallBorder import com.vitorpamplona.amethyst.ui.theme.subtleBorder -import com.vitorpamplona.quartz.events.ClassifiedsEvent +import com.vitorpamplona.quartz.nip99Classifieds.ClassifiedsEvent @Composable fun RenderClassifieds( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/CommunityHeader.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/CommunityHeader.kt index 2743b646b..ba8a616e9 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/CommunityHeader.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/CommunityHeader.kt @@ -75,9 +75,11 @@ import com.vitorpamplona.amethyst.ui.theme.Size35dp import com.vitorpamplona.amethyst.ui.theme.Size5dp import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer import com.vitorpamplona.amethyst.ui.theme.innerPostModifier -import com.vitorpamplona.quartz.events.CommunityDefinitionEvent -import com.vitorpamplona.quartz.events.EmptyTagList -import com.vitorpamplona.quartz.events.Participant +import com.vitorpamplona.quartz.experimental.audio.Participant +import com.vitorpamplona.quartz.nip01Core.hashtags.hasHashtags +import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList +import com.vitorpamplona.quartz.nip14Subject.subject +import com.vitorpamplona.quartz.nip72ModCommunities.CommunityDefinitionEvent import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import java.util.Locale diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Emoji.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Emoji.kt index 3dcc749af..8ed2e1e06 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Emoji.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Emoji.kt @@ -56,10 +56,12 @@ import com.vitorpamplona.amethyst.ui.note.elements.RemoveButton import com.vitorpamplona.amethyst.ui.note.getGradient import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.theme.Size35Modifier -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.events.EmojiPackEvent -import com.vitorpamplona.quartz.events.EmojiPackSelectionEvent -import com.vitorpamplona.quartz.events.EmojiUrl +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.addressables.isTaggedAddressableNote +import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiPackEvent +import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiPackSelectionEvent +import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiUrl +import com.vitorpamplona.quartz.nip30CustomEmoji.taggedEmojis @Composable public fun RenderEmojiPack( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/FileHeader.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/FileHeader.kt index df65fde27..11410be70 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/FileHeader.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/FileHeader.kt @@ -33,7 +33,7 @@ import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.ui.components.SensitivityWarning import com.vitorpamplona.amethyst.ui.components.ZoomableContentView import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel -import com.vitorpamplona.quartz.events.FileHeaderEvent +import com.vitorpamplona.quartz.nip94FileMetadata.FileHeaderEvent @Composable fun FileHeaderDisplay( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/FileStorage.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/FileStorage.kt index 176d24d17..b608b1903 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/FileStorage.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/FileStorage.kt @@ -37,7 +37,7 @@ import com.vitorpamplona.amethyst.ui.components.LoadNote import com.vitorpamplona.amethyst.ui.components.SensitivityWarning import com.vitorpamplona.amethyst.ui.components.ZoomableContentView import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel -import com.vitorpamplona.quartz.events.FileStorageHeaderEvent +import com.vitorpamplona.quartz.experimental.nip95.FileStorageHeaderEvent import java.io.File @Composable diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Git.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Git.kt index 5695e183a..50955515c 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Git.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Git.kt @@ -61,12 +61,14 @@ import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer 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.EmptyTagList -import com.vitorpamplona.quartz.events.GitIssueEvent -import com.vitorpamplona.quartz.events.GitPatchEvent -import com.vitorpamplona.quartz.events.GitRepositoryEvent -import com.vitorpamplona.quartz.events.TextNoteEvent -import com.vitorpamplona.quartz.events.toImmutableListOfLists +import com.vitorpamplona.quartz.nip01Core.hashtags.hasHashtags +import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList +import com.vitorpamplona.quartz.nip02FollowList.toImmutableListOfLists +import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent +import com.vitorpamplona.quartz.nip14Subject.subject +import com.vitorpamplona.quartz.nip34Git.GitIssueEvent +import com.vitorpamplona.quartz.nip34Git.GitPatchEvent +import com.vitorpamplona.quartz.nip34Git.GitRepositoryEvent @Composable fun RenderGitPatchEvent( @@ -177,7 +179,7 @@ private fun RenderGitPatchEvent( note = note, accountViewModel = accountViewModel, ) { - val tags = remember(note) { note.event?.tags()?.toImmutableListOfLists() ?: EmptyTagList } + val tags = remember(note) { note.event?.tags?.toImmutableListOfLists() ?: EmptyTagList } TranslatableRichTextViewer( content = eventContent, @@ -283,7 +285,7 @@ private fun RenderGitIssueEvent( accountViewModel = accountViewModel, ) { val tags = - remember(note) { note.event?.tags()?.toImmutableListOfLists() ?: EmptyTagList } + remember(note) { note.event?.tags?.toImmutableListOfLists() ?: EmptyTagList } TranslatableRichTextViewer( content = eventContent, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Highlight.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Highlight.kt index 6410ada34..7a1aa4d9b 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Highlight.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Highlight.kt @@ -53,11 +53,13 @@ import com.vitorpamplona.amethyst.ui.components.measureSpaceWidth import com.vitorpamplona.amethyst.ui.navigation.INav import com.vitorpamplona.amethyst.ui.navigation.routeFor import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.events.BaseTextNoteEvent -import com.vitorpamplona.quartz.events.EmptyTagList -import com.vitorpamplona.quartz.events.HighlightEvent +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.core.firstTagValueFor +import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList +import com.vitorpamplona.quartz.nip10Notes.BaseTextNoteEvent +import com.vitorpamplona.quartz.nip19Bech32Entities.toNIP19 +import com.vitorpamplona.quartz.nip84Highlights.HighlightEvent import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import java.net.URL @@ -247,7 +249,7 @@ fun DisplayEntryForNote( val noteEvent = noteState?.note?.event as? BaseTextNoteEvent ?: return - val description = noteEvent.firstTagFor("title", "subject", "alt") + val description = noteEvent.tags.firstTagValueFor("title", "subject", "alt") Text("-", maxLines = 1) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/InteractiveStory.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/InteractiveStory.kt index 6d857a0af..d5e1a5beb 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/InteractiveStory.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/InteractiveStory.kt @@ -43,10 +43,10 @@ import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer import com.vitorpamplona.amethyst.ui.navigation.INav import com.vitorpamplona.amethyst.ui.note.LoadAddressableNote import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.events.EmptyTagList -import com.vitorpamplona.quartz.events.InteractiveStoryBaseEvent -import com.vitorpamplona.quartz.events.InteractiveStoryReadingStateEvent +import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStoryBaseEvent +import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStoryReadingStateEvent +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList @Composable fun RenderInteractiveStory( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/LiveActivity.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/LiveActivity.kt index 8ac38dccc..98a9dfed5 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/LiveActivity.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/LiveActivity.kt @@ -69,9 +69,9 @@ import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer import com.vitorpamplona.amethyst.ui.theme.ThemeComparisonColumn import com.vitorpamplona.amethyst.ui.theme.imageModifier import com.vitorpamplona.amethyst.ui.theme.placeholderText -import com.vitorpamplona.quartz.events.Event -import com.vitorpamplona.quartz.events.LiveActivitiesEvent -import com.vitorpamplona.quartz.events.Participant +import com.vitorpamplona.quartz.experimental.audio.Participant +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent import com.vitorpamplona.quartz.utils.TimeUtils import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/LiveActivityChatMessage.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/LiveActivityChatMessage.kt index 76c27309a..91e3f9e0f 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/LiveActivityChatMessage.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/LiveActivityChatMessage.kt @@ -36,7 +36,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.chatrooms.ChannelHeader import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer import com.vitorpamplona.amethyst.ui.theme.replyModifier -import com.vitorpamplona.quartz.events.LiveActivitiesChatMessageEvent +import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesChatMessageEvent @Composable fun RenderLiveActivityChatMessage( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/LongForm.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/LongForm.kt index c039ee055..d02d4f42d 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/LongForm.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/LongForm.kt @@ -46,7 +46,7 @@ import com.vitorpamplona.amethyst.ui.theme.QuoteBorder import com.vitorpamplona.amethyst.ui.theme.Size5dp import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer import com.vitorpamplona.amethyst.ui.theme.subtleBorder -import com.vitorpamplona.quartz.events.LongTextNoteEvent +import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent @Composable fun RenderLongFormContent( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/MedicalData.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/MedicalData.kt index a6731b7c0..8d2e8697f 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/MedicalData.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/MedicalData.kt @@ -57,8 +57,8 @@ import com.vitorpamplona.amethyst.ui.theme.DividerThickness import com.vitorpamplona.amethyst.ui.theme.DoubleVertSpacer import com.vitorpamplona.amethyst.ui.theme.Size10dp import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer -import com.vitorpamplona.quartz.events.Event -import com.vitorpamplona.quartz.events.FhirResourceEvent +import com.vitorpamplona.quartz.experimental.medical.FhirResourceEvent +import com.vitorpamplona.quartz.nip01Core.core.Event import kotlinx.collections.immutable.ImmutableMap import kotlinx.collections.immutable.toImmutableMap import kotlinx.coroutines.Dispatchers diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/NIP90ContentDiscoveryResponse.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/NIP90ContentDiscoveryResponse.kt index 613fc4e8a..2305a8184 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/NIP90ContentDiscoveryResponse.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/NIP90ContentDiscoveryResponse.kt @@ -32,9 +32,10 @@ import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer import com.vitorpamplona.amethyst.ui.navigation.INav import com.vitorpamplona.amethyst.ui.note.elements.DisplayUncitedHashtags import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel -import com.vitorpamplona.quartz.events.EmptyTagList -import com.vitorpamplona.quartz.events.NIP90ContentDiscoveryResponseEvent -import com.vitorpamplona.quartz.events.toImmutableListOfLists +import com.vitorpamplona.quartz.nip01Core.hashtags.hasHashtags +import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList +import com.vitorpamplona.quartz.nip02FollowList.toImmutableListOfLists +import com.vitorpamplona.quartz.nip90Dvms.NIP90ContentDiscoveryResponseEvent @Composable fun RenderNIP90ContentDiscoveryResponse( @@ -55,7 +56,7 @@ fun RenderNIP90ContentDiscoveryResponse( ) { val modifier = remember(note) { Modifier.fillMaxWidth() } val tags = - remember(note) { note.event?.tags()?.toImmutableListOfLists() ?: EmptyTagList } + remember(note) { note.event?.tags?.toImmutableListOfLists() ?: EmptyTagList } TranslatableRichTextViewer( content = noteEvent.content, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/NIP90Status.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/NIP90Status.kt index 19fe270db..eae45a229 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/NIP90Status.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/NIP90Status.kt @@ -25,7 +25,7 @@ import androidx.compose.runtime.Composable import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.ui.navigation.INav import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel -import com.vitorpamplona.quartz.events.NIP90StatusEvent +import com.vitorpamplona.quartz.nip90Dvms.NIP90StatusEvent @Composable fun RenderNIP90Status( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PeopleList.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PeopleList.kt index cf7c7255e..d78900ec2 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PeopleList.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PeopleList.kt @@ -54,7 +54,7 @@ import com.vitorpamplona.amethyst.ui.note.UserCompose import com.vitorpamplona.amethyst.ui.note.getGradient import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.theme.DividerThickness -import com.vitorpamplona.quartz.events.PeopleListEvent +import com.vitorpamplona.quartz.nip51Lists.PeopleListEvent import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PictureDisplay.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PictureDisplay.kt index 28f7520e6..a2ff34d8e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PictureDisplay.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PictureDisplay.kt @@ -44,8 +44,8 @@ import com.vitorpamplona.amethyst.ui.components.ZoomableContentView import com.vitorpamplona.amethyst.ui.navigation.INav import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer -import com.vitorpamplona.quartz.events.EmptyTagList -import com.vitorpamplona.quartz.events.PictureEvent +import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList +import com.vitorpamplona.quartz.nip68Picture.PictureEvent import kotlinx.collections.immutable.toImmutableList @Composable diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PinList.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PinList.kt index 71469478d..7f4cf671b 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PinList.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PinList.kt @@ -53,8 +53,8 @@ import com.vitorpamplona.amethyst.ui.note.PinIcon import com.vitorpamplona.amethyst.ui.note.getGradient import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.theme.Size15Modifier -import com.vitorpamplona.quartz.events.EmptyTagList -import com.vitorpamplona.quartz.events.PinListEvent +import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList +import com.vitorpamplona.quartz.nip51Lists.PinListEvent @OptIn(ExperimentalLayoutApi::class) @Composable diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Poll.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Poll.kt index cd21e7be3..acf933fa9 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Poll.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Poll.kt @@ -42,10 +42,12 @@ import com.vitorpamplona.amethyst.ui.note.elements.DisplayUncitedHashtags import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer import com.vitorpamplona.amethyst.ui.theme.placeholderText -import com.vitorpamplona.quartz.events.CommunityDefinitionEvent -import com.vitorpamplona.quartz.events.EmptyTagList -import com.vitorpamplona.quartz.events.PollNoteEvent -import com.vitorpamplona.quartz.events.toImmutableListOfLists +import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent +import com.vitorpamplona.quartz.nip01Core.hashtags.hasHashtags +import com.vitorpamplona.quartz.nip01Core.people.hasAnyTaggedUser +import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList +import com.vitorpamplona.quartz.nip02FollowList.toImmutableListOfLists +import com.vitorpamplona.quartz.nip72ModCommunities.CommunityDefinitionEvent @Composable fun RenderPoll( @@ -59,7 +61,7 @@ fun RenderPoll( nav: INav, ) { val noteEvent = note.event as? PollNoteEvent ?: return - val eventContent = noteEvent.content() + val eventContent = noteEvent.content val showReply by remember(note) { @@ -74,13 +76,13 @@ fun RenderPoll( val replyingTo = noteEvent.replyingToAddressOrEvent() if (replyingTo != null) { val newNote = accountViewModel.getNoteIfExists(replyingTo) - if (newNote != null && newNote.channelHex() == null && newNote.event?.kind() != CommunityDefinitionEvent.KIND) { + if (newNote != null && newNote.channelHex() == null && newNote.event?.kind != CommunityDefinitionEvent.KIND) { newNote } else { - note.replyTo?.lastOrNull { it.event?.kind() != CommunityDefinitionEvent.KIND } + note.replyTo?.lastOrNull { it.event?.kind != CommunityDefinitionEvent.KIND } } } else { - note.replyTo?.lastOrNull { it.event?.kind() != CommunityDefinitionEvent.KIND } + note.replyTo?.lastOrNull { it.event?.kind != CommunityDefinitionEvent.KIND } } } if (replyingDirectlyTo != null) { @@ -97,7 +99,7 @@ fun RenderPoll( overflow = TextOverflow.Ellipsis, ) } else { - val tags = remember(note) { note.event?.tags()?.toImmutableListOfLists() ?: EmptyTagList } + val tags = remember(note) { note.event?.tags?.toImmutableListOfLists() ?: EmptyTagList } val callbackUri = remember(note) { note.toNostrUri() } SensitivityWarning( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PrivateMessage.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PrivateMessage.kt index 9be64d541..47de87957 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PrivateMessage.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PrivateMessage.kt @@ -48,11 +48,12 @@ import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer import com.vitorpamplona.amethyst.ui.theme.placeholderText import com.vitorpamplona.amethyst.ui.theme.replyModifier -import com.vitorpamplona.quartz.encoders.toNpub -import com.vitorpamplona.quartz.events.ChatroomKeyable -import com.vitorpamplona.quartz.events.EmptyTagList -import com.vitorpamplona.quartz.events.PrivateDmEvent -import com.vitorpamplona.quartz.events.toImmutableListOfLists +import com.vitorpamplona.quartz.nip01Core.hashtags.hasHashtags +import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList +import com.vitorpamplona.quartz.nip02FollowList.toImmutableListOfLists +import com.vitorpamplona.quartz.nip04Dm.PrivateDmEvent +import com.vitorpamplona.quartz.nip17Dm.ChatroomKeyable +import com.vitorpamplona.quartz.nip19Bech32Entities.toNpub @Composable fun RenderPrivateMessage( @@ -87,12 +88,12 @@ fun RenderPrivateMessage( val withMe = remember { noteEvent.with(accountViewModel.userProfile().pubkeyHex) } if (withMe) { LoadDecryptedContent(note, accountViewModel) { eventContent -> - val modifier = remember(note.event?.id()) { Modifier.fillMaxWidth() } + val modifier = remember(note.event?.id) { Modifier.fillMaxWidth() } val isAuthorTheLoggedUser = - remember(note.event?.id()) { accountViewModel.isLoggedUser(note.author) } + remember(note.event?.id) { accountViewModel.isLoggedUser(note.author) } val tags = - remember(note) { note.event?.tags()?.toImmutableListOfLists() ?: EmptyTagList } + remember(note) { note.event?.tags?.toImmutableListOfLists() ?: EmptyTagList } if (makeItShort && isAuthorTheLoggedUser) { Text( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Reaction.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Reaction.kt index 1dfdaa9ca..e0cee39b2 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Reaction.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Reaction.kt @@ -52,7 +52,7 @@ fun RenderReaction( } // Reposts have trash in their contents. - val refactorReactionText = if (note.event?.content() == "+") "❤" else note.event?.content() ?: "" + val refactorReactionText = if (note.event?.content == "+") "❤" else note.event?.content ?: "" Text( text = refactorReactionText, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/RelayList.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/RelayList.kt index 431935d5e..256eabbea 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/RelayList.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/RelayList.kt @@ -54,10 +54,11 @@ import com.vitorpamplona.amethyst.ui.note.getGradient import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.ammolite.relays.RelayBriefInfoCache -import com.vitorpamplona.quartz.events.AdvertisedRelayListEvent -import com.vitorpamplona.quartz.events.ChatMessageRelayListEvent -import com.vitorpamplona.quartz.events.RelaySetEvent -import com.vitorpamplona.quartz.events.SearchRelayListEvent +import com.vitorpamplona.quartz.nip01Core.core.firstTagValueFor +import com.vitorpamplona.quartz.nip17Dm.ChatMessageRelayListEvent +import com.vitorpamplona.quartz.nip50Search.SearchRelayListEvent +import com.vitorpamplona.quartz.nip51Lists.RelaySetEvent +import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList @@ -82,7 +83,7 @@ fun DisplayRelaySet( DisplayRelaySet( relays, - noteEvent.firstTagFor("title", "name") ?: "#${noteEvent.dTag()}", + noteEvent.tags.firstTagValueFor("title", "name") ?: "#${noteEvent.dTag()}", noteEvent.description(), backgroundColor, accountViewModel, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/RenderPostApproval.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/RenderPostApproval.kt index 612d107c2..05517f21e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/RenderPostApproval.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/RenderPostApproval.kt @@ -41,7 +41,7 @@ import com.vitorpamplona.amethyst.ui.note.NoteCompose import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.replyModifier -import com.vitorpamplona.quartz.events.CommunityPostApprovalEvent +import com.vitorpamplona.quartz.nip72ModCommunities.CommunityPostApprovalEvent @Composable fun RenderPostApproval( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Report.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Report.kt index 10eefb78e..4c3aaa019 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Report.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Report.kt @@ -34,8 +34,8 @@ import com.vitorpamplona.amethyst.ui.note.NoteCompose import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.replyModifier -import com.vitorpamplona.quartz.events.EmptyTagList -import com.vitorpamplona.quartz.events.ReportEvent +import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList +import com.vitorpamplona.quartz.nip56Reports.ReportEvent @Composable fun RenderReport( @@ -70,7 +70,7 @@ fun RenderReport( remember { reportType + ( note.event - ?.content() + ?.content ?.ifBlank { null } ?.let { ": $it" } ?: "" ) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Text.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Text.kt index e8dbb0362..5f89e2a7e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Text.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Text.kt @@ -44,12 +44,15 @@ import com.vitorpamplona.amethyst.ui.note.elements.DisplayUncitedHashtags import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer import com.vitorpamplona.amethyst.ui.theme.placeholderText -import com.vitorpamplona.quartz.events.BaseTextNoteEvent -import com.vitorpamplona.quartz.events.CommunityDefinitionEvent -import com.vitorpamplona.quartz.events.EmptyTagList -import com.vitorpamplona.quartz.events.Event -import com.vitorpamplona.quartz.events.TextNoteEvent -import com.vitorpamplona.quartz.events.toImmutableListOfLists +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.hashtags.hasHashtags +import com.vitorpamplona.quartz.nip01Core.people.hasAnyTaggedUser +import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList +import com.vitorpamplona.quartz.nip02FollowList.toImmutableListOfLists +import com.vitorpamplona.quartz.nip10Notes.BaseTextNoteEvent +import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent +import com.vitorpamplona.quartz.nip14Subject.subject +import com.vitorpamplona.quartz.nip72ModCommunities.CommunityDefinitionEvent @Composable fun RenderTextEvent( @@ -79,16 +82,16 @@ fun RenderTextEvent( val replyingTo = noteEvent.replyingToAddressOrEvent() if (replyingTo != null) { val newNote = accountViewModel.getNoteIfExists(replyingTo) - if (newNote != null && newNote.channelHex() == null && newNote.event?.kind() != CommunityDefinitionEvent.KIND) { + if (newNote != null && newNote.channelHex() == null && newNote.event?.kind != CommunityDefinitionEvent.KIND) { newNote } else { - note.replyTo?.lastOrNull { it.event?.kind() != CommunityDefinitionEvent.KIND } + note.replyTo?.lastOrNull { it.event?.kind != CommunityDefinitionEvent.KIND } } } else { - note.replyTo?.lastOrNull { it.event?.kind() != CommunityDefinitionEvent.KIND } + note.replyTo?.lastOrNull { it.event?.kind != CommunityDefinitionEvent.KIND } } } else { - note.replyTo?.lastOrNull { it.event?.kind() != CommunityDefinitionEvent.KIND } + note.replyTo?.lastOrNull { it.event?.kind != CommunityDefinitionEvent.KIND } } } if (replyingDirectlyTo != null && unPackReply) { @@ -109,7 +112,7 @@ fun RenderTextEvent( ?.modificationToShow ?.value ?.event - ?.content() ?: body + ?.content ?: body } else { body } @@ -136,7 +139,7 @@ fun RenderTextEvent( accountViewModel = accountViewModel, ) { val tags = - remember(note) { note.event?.tags()?.toImmutableListOfLists() ?: EmptyTagList } + remember(note) { note.event?.tags?.toImmutableListOfLists() ?: EmptyTagList } TranslatableRichTextViewer( content = eventContent, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/TextModification.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/TextModification.kt index 8c61f1436..265e104dc 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/TextModification.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/TextModification.kt @@ -59,8 +59,8 @@ import com.vitorpamplona.amethyst.ui.theme.Size10dp import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer import com.vitorpamplona.amethyst.ui.theme.imageModifier import com.vitorpamplona.amethyst.ui.theme.innerPostModifier -import com.vitorpamplona.quartz.events.EmptyTagList -import com.vitorpamplona.quartz.events.TextNoteModificationEvent +import com.vitorpamplona.quartz.experimental.edits.TextNoteModificationEvent +import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList import kotlinx.collections.immutable.persistentListOf @Composable diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Torrent.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Torrent.kt index 15ea5c486..c2902ac3d 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Torrent.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Torrent.kt @@ -64,8 +64,8 @@ import com.vitorpamplona.amethyst.ui.theme.Size20dp import com.vitorpamplona.amethyst.ui.theme.Size30dp import com.vitorpamplona.amethyst.ui.theme.Size5dp import com.vitorpamplona.amethyst.ui.theme.ThemeComparisonColumn -import com.vitorpamplona.quartz.events.TorrentEvent -import com.vitorpamplona.quartz.events.TorrentFile +import com.vitorpamplona.quartz.nip35Torrents.TorrentEvent +import com.vitorpamplona.quartz.nip35Torrents.TorrentFile import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.Dispatchers @@ -158,8 +158,8 @@ fun RenderTorrent( val size = " (" + countToHumanReadableBytes(noteEvent.totalSizeBytes()) + ")" val description = - if (noteEvent.content() != name) { - noteEvent.content() + if (noteEvent.content != name) { + noteEvent.content } else { null } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/TorrentComment.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/TorrentComment.kt index 024a1ae52..28dcb1522 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/TorrentComment.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/TorrentComment.kt @@ -59,8 +59,8 @@ import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer import com.vitorpamplona.amethyst.ui.theme.ThemeComparisonColumn import com.vitorpamplona.amethyst.ui.theme.replyModifier -import com.vitorpamplona.quartz.events.TorrentCommentEvent -import com.vitorpamplona.quartz.events.TorrentEvent +import com.vitorpamplona.quartz.nip35Torrents.TorrentCommentEvent +import com.vitorpamplona.quartz.nip35Torrents.TorrentEvent import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Video.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Video.kt index f2e1a3acf..70d62a1a9 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Video.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Video.kt @@ -58,9 +58,10 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.Size5dp import com.vitorpamplona.amethyst.ui.theme.imageModifier -import com.vitorpamplona.quartz.events.EmptyTagList -import com.vitorpamplona.quartz.events.VideoEvent -import com.vitorpamplona.quartz.events.toImmutableListOfLists +import com.vitorpamplona.quartz.nip01Core.hashtags.hasHashtags +import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList +import com.vitorpamplona.quartz.nip02FollowList.toImmutableListOfLists +import com.vitorpamplona.quartz.nip71Video.VideoEvent @Composable fun VideoDisplay( @@ -79,7 +80,7 @@ fun VideoDisplay( val summary = event.content.ifBlank { null }?.takeIf { title != it } val image = imeta.image.firstOrNull() val isYouTube = imeta.url.contains("youtube.com") || imeta.url.contains("youtu.be") - val tags = remember(note) { note.event?.tags()?.toImmutableListOfLists() ?: EmptyTagList } + val tags = remember(note) { note.event?.tags?.toImmutableListOfLists() ?: EmptyTagList } val content by remember(note) { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/VideoDisplay.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/VideoDisplay.kt index 545455b3b..57c773478 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/VideoDisplay.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/VideoDisplay.kt @@ -33,7 +33,7 @@ import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.ui.components.SensitivityWarning import com.vitorpamplona.amethyst.ui.components.ZoomableContentView import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel -import com.vitorpamplona.quartz.events.VideoEvent +import com.vitorpamplona.quartz.nip71Video.VideoEvent @Composable fun JustVideoDisplay( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Wiki.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Wiki.kt index 1fd39cc5d..9bde2174e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Wiki.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Wiki.kt @@ -47,7 +47,7 @@ import com.vitorpamplona.amethyst.ui.theme.QuoteBorder import com.vitorpamplona.amethyst.ui.theme.Size5dp import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer import com.vitorpamplona.amethyst.ui.theme.subtleBorder -import com.vitorpamplona.quartz.events.WikiNoteEvent +import com.vitorpamplona.quartz.nip54Wiki.WikiNoteEvent @Composable fun RenderWikiContent( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/AccountScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/AccountScreen.kt index b3ac53388..d19575501 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/AccountScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/AccountScreen.kt @@ -58,7 +58,7 @@ import com.vitorpamplona.amethyst.ui.navigation.AppNavigation import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedOff.LoginOrSignupScreen import com.vitorpamplona.amethyst.ui.stringRes -import com.vitorpamplona.quartz.signers.NostrSignerExternal +import com.vitorpamplona.quartz.nip55AndroidSigner.NostrSignerExternal import kotlinx.coroutines.CancellationException @Composable diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/AccountStateViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/AccountStateViewModel.kt index c1eb75801..6c22d9b81 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/AccountStateViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/AccountStateViewModel.kt @@ -37,20 +37,27 @@ import com.vitorpamplona.amethyst.ui.tor.TorSettings import com.vitorpamplona.amethyst.ui.tor.TorSettingsFlow import com.vitorpamplona.ammolite.relays.Constants import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.crypto.Hex import com.vitorpamplona.quartz.crypto.KeyPair -import com.vitorpamplona.quartz.encoders.Hex -import com.vitorpamplona.quartz.encoders.Nip19Bech32 -import com.vitorpamplona.quartz.encoders.bechToBytes -import com.vitorpamplona.quartz.encoders.hexToByteArray -import com.vitorpamplona.quartz.encoders.toHexKey -import com.vitorpamplona.quartz.encoders.toNpub -import com.vitorpamplona.quartz.events.AdvertisedRelayListEvent -import com.vitorpamplona.quartz.events.ChatMessageRelayListEvent -import com.vitorpamplona.quartz.events.Contact -import com.vitorpamplona.quartz.events.ContactListEvent -import com.vitorpamplona.quartz.events.MetadataEvent -import com.vitorpamplona.quartz.events.SearchRelayListEvent -import com.vitorpamplona.quartz.signers.NostrSignerSync +import com.vitorpamplona.quartz.nip01Core.MetadataEvent +import com.vitorpamplona.quartz.nip01Core.hexToByteArray +import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerSync +import com.vitorpamplona.quartz.nip01Core.toHexKey +import com.vitorpamplona.quartz.nip02FollowList.Contact +import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent +import com.vitorpamplona.quartz.nip17Dm.ChatMessageRelayListEvent +import com.vitorpamplona.quartz.nip19Bech32Entities.Nip19Parser +import com.vitorpamplona.quartz.nip19Bech32Entities.bech32.bechToBytes +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NAddress +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NEmbed +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NEvent +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NProfile +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NPub +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NRelay +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NSec +import com.vitorpamplona.quartz.nip19Bech32Entities.toNpub +import com.vitorpamplona.quartz.nip50Search.SearchRelayListEvent +import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent import kotlinx.coroutines.CancellationException import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.FlowPreview @@ -97,17 +104,17 @@ class AccountStateViewModel : ViewModel() { loginWithExternalSigner: Boolean = false, packageName: String = "", ) = withContext(Dispatchers.IO) { - val parsed = Nip19Bech32.uriToRoute(key)?.entity + val parsed = Nip19Parser.uriToRoute(key)?.entity val pubKeyParsed = when (parsed) { - is Nip19Bech32.NSec -> null - is Nip19Bech32.NPub -> parsed.hex.hexToByteArray() - is Nip19Bech32.NProfile -> parsed.hex.hexToByteArray() - is Nip19Bech32.Note -> null - is Nip19Bech32.NEvent -> null - is Nip19Bech32.NEmbed -> null - is Nip19Bech32.NRelay -> null - is Nip19Bech32.NAddress -> null + is NSec -> null + is NPub -> parsed.hex.hexToByteArray() + is NProfile -> parsed.hex.hexToByteArray() + is com.vitorpamplona.quartz.nip19Bech32Entities.entities.Note -> null + is NEvent -> null + is NEmbed -> null + is NRelay -> null + is NAddress -> null else -> try { if (loginWithExternalSigner) Hex.decode(key) else null diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/FeedViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/FeedViewModel.kt index 7610d51db..24de4b228 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/FeedViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/FeedViewModel.kt @@ -57,7 +57,7 @@ import com.vitorpamplona.amethyst.ui.dal.UserProfileReportsFeedFilter import com.vitorpamplona.amethyst.ui.feeds.FeedContentState import com.vitorpamplona.amethyst.ui.feeds.FeedState import com.vitorpamplona.amethyst.ui.feeds.InvalidatableContent -import com.vitorpamplona.quartz.events.ChatroomKey +import com.vitorpamplona.quartz.nip17Dm.ChatroomKey import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.Job diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/FollowListState.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/FollowListState.kt index ee5812705..48ed1482a 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/FollowListState.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/FollowListState.kt @@ -34,25 +34,25 @@ import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.service.checkNotInMainThread import com.vitorpamplona.amethyst.ui.stringRes -import com.vitorpamplona.quartz.events.AudioHeaderEvent -import com.vitorpamplona.quartz.events.AudioTrackEvent -import com.vitorpamplona.quartz.events.ClassifiedsEvent -import com.vitorpamplona.quartz.events.CommunityPostApprovalEvent -import com.vitorpamplona.quartz.events.ContactListEvent -import com.vitorpamplona.quartz.events.DeletionEvent -import com.vitorpamplona.quartz.events.GenericRepostEvent -import com.vitorpamplona.quartz.events.HighlightEvent -import com.vitorpamplona.quartz.events.InteractiveStoryPrologueEvent -import com.vitorpamplona.quartz.events.LiveActivitiesChatMessageEvent -import com.vitorpamplona.quartz.events.LiveActivitiesEvent -import com.vitorpamplona.quartz.events.LongTextNoteEvent -import com.vitorpamplona.quartz.events.MuteListEvent -import com.vitorpamplona.quartz.events.PeopleListEvent -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 com.vitorpamplona.quartz.events.WikiNoteEvent +import com.vitorpamplona.quartz.experimental.audio.AudioHeaderEvent +import com.vitorpamplona.quartz.experimental.audio.AudioTrackEvent +import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStoryPrologueEvent +import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent +import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent +import com.vitorpamplona.quartz.nip09Deletions.DeletionEvent +import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent +import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent +import com.vitorpamplona.quartz.nip18Reposts.RepostEvent +import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent +import com.vitorpamplona.quartz.nip51Lists.MuteListEvent +import com.vitorpamplona.quartz.nip51Lists.PeopleListEvent +import com.vitorpamplona.quartz.nip51Lists.PinListEvent +import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesChatMessageEvent +import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent +import com.vitorpamplona.quartz.nip54Wiki.WikiNoteEvent +import com.vitorpamplona.quartz.nip72ModCommunities.CommunityPostApprovalEvent +import com.vitorpamplona.quartz.nip84Highlights.HighlightEvent +import com.vitorpamplona.quartz.nip99Classifieds.ClassifiedsEvent import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.CoroutineScope @@ -130,7 +130,7 @@ class FollowListState( newNotes.any { val noteEvent = it.event - noteEvent?.pubKey() == account.userProfile().pubkeyHex && + noteEvent?.pubKey == account.userProfile().pubkeyHex && ( ( noteEvent is PeopleListEvent || diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountBackupDialog.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountBackupDialog.kt index ef32ca148..accd41e71 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountBackupDialog.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountBackupDialog.kt @@ -103,8 +103,8 @@ import com.vitorpamplona.amethyst.ui.theme.ThemeComparisonRow import com.vitorpamplona.amethyst.ui.theme.grayText import com.vitorpamplona.amethyst.ui.theme.placeholderText import com.vitorpamplona.quartz.crypto.CryptoUtils -import com.vitorpamplona.quartz.encoders.toHexKey -import com.vitorpamplona.quartz.encoders.toNsec +import com.vitorpamplona.quartz.nip01Core.toHexKey +import com.vitorpamplona.quartz.nip19Bech32Entities.toNsec import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt index b1e9b2ce6..712b60989 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt @@ -73,34 +73,42 @@ import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.tor.TorSettings import com.vitorpamplona.ammolite.relays.BundledInsert import com.vitorpamplona.quartz.crypto.KeyPair -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.Dimension -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.Nip11RelayInformation -import com.vitorpamplona.quartz.encoders.Nip19Bech32 -import com.vitorpamplona.quartz.encoders.RelayUrlFormatter -import com.vitorpamplona.quartz.events.AddressableEvent -import com.vitorpamplona.quartz.events.AdvertisedRelayListEvent -import com.vitorpamplona.quartz.events.ChatMessageRelayListEvent -import com.vitorpamplona.quartz.events.ChatroomKey -import com.vitorpamplona.quartz.events.ChatroomKeyable -import com.vitorpamplona.quartz.events.DraftEvent -import com.vitorpamplona.quartz.events.Event -import com.vitorpamplona.quartz.events.EventInterface -import com.vitorpamplona.quartz.events.GenericRepostEvent -import com.vitorpamplona.quartz.events.GiftWrapEvent -import com.vitorpamplona.quartz.events.InteractiveStoryBaseEvent -import com.vitorpamplona.quartz.events.InteractiveStoryReadingStateEvent -import com.vitorpamplona.quartz.events.LnZapEvent -import com.vitorpamplona.quartz.events.LnZapRequestEvent -import com.vitorpamplona.quartz.events.NIP90ContentDiscoveryResponseEvent -import com.vitorpamplona.quartz.events.Participant -import com.vitorpamplona.quartz.events.ReportEvent -import com.vitorpamplona.quartz.events.RepostEvent -import com.vitorpamplona.quartz.events.Response -import com.vitorpamplona.quartz.events.SealedGossipEvent -import com.vitorpamplona.quartz.events.SearchRelayListEvent -import com.vitorpamplona.quartz.events.UserMetadata +import com.vitorpamplona.quartz.experimental.audio.Participant +import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStoryBaseEvent +import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStoryReadingStateEvent +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.UserMetadata +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.addressables.AddressableEvent +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.people.isTaggedUser +import com.vitorpamplona.quartz.nip11RelayInfo.Nip11RelayInformation +import com.vitorpamplona.quartz.nip17Dm.ChatMessageRelayListEvent +import com.vitorpamplona.quartz.nip17Dm.ChatroomKey +import com.vitorpamplona.quartz.nip17Dm.ChatroomKeyable +import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent +import com.vitorpamplona.quartz.nip18Reposts.RepostEvent +import com.vitorpamplona.quartz.nip19Bech32Entities.Nip19Parser +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NAddress +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NEmbed +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NEvent +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NProfile +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NPub +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NRelay +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NSec +import com.vitorpamplona.quartz.nip37Drafts.DraftEvent +import com.vitorpamplona.quartz.nip47WalletConnect.Response +import com.vitorpamplona.quartz.nip50Search.SearchRelayListEvent +import com.vitorpamplona.quartz.nip56Reports.ReportEvent +import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent +import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent +import com.vitorpamplona.quartz.nip57Zaps.zapraiserAmount +import com.vitorpamplona.quartz.nip59Giftwrap.GiftWrapEvent +import com.vitorpamplona.quartz.nip59Giftwrap.SealedGossipEvent +import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent +import com.vitorpamplona.quartz.nip65RelayList.RelayUrlFormatter +import com.vitorpamplona.quartz.nip90Dvms.NIP90ContentDiscoveryResponseEvent +import com.vitorpamplona.quartz.nip94FileMetadata.Dimension import com.vitorpamplona.quartz.utils.TimeUtils import fr.acinq.secp256k1.Hex import kotlinx.collections.immutable.ImmutableList @@ -215,7 +223,7 @@ class AccountViewModel( (chat.event as? ChatroomKeyable)?.let { event -> val room = event.chatroomKey(account.signer.pubKey) account.settings.getLastReadFlow("Room/${room.hashCode()}").map { - (chat.event?.createdAt() ?: 0) > it + (chat.event?.createdAt ?: 0) > it } } } @@ -524,7 +532,7 @@ class AccountViewModel( ZapAmountCommentNotification( it.request.author, it.request.event - ?.content() + ?.content ?.ifBlank { null }, showAmountAxis((it.response.event as? LnZapEvent)?.amount), ) @@ -565,7 +573,7 @@ class AccountViewModel( ZapAmountCommentNotification( it.request.author, it.request.event - ?.content() + ?.content ?.ifBlank { null }, showAmountAxis((it.response.event as? LnZapEvent)?.amount), ) @@ -574,7 +582,7 @@ class AccountViewModel( ZapAmountCommentNotification( it.request.author, it.request.event - ?.content() + ?.content ?.ifBlank { null }, showAmountAxis((it.response.event as? LnZapEvent)?.amount), ) @@ -599,7 +607,7 @@ class AccountViewModel( ZapAmountCommentNotification( it.first.author, it.first.event - ?.content() + ?.content ?.ifBlank { null }, showAmountAxis((it.second?.event as? LnZapEvent)?.amount), ) @@ -608,7 +616,7 @@ class AccountViewModel( ZapAmountCommentNotification( it.first.author, it.first.event - ?.content() + ?.content ?.ifBlank { null }, showAmountAxis((it.second?.event as? LnZapEvent)?.amount), ) @@ -630,7 +638,7 @@ class AccountViewModel( ZapAmountCommentNotification( it.first.author, it.first.event - ?.content() + ?.content ?.ifBlank { null }, showAmountAxis((it.second?.event as? LnZapEvent)?.amount), ) @@ -683,11 +691,11 @@ class AccountViewModel( } } else { val amount = (zapEvent?.event as? LnZapEvent)?.amount - if (!zapRequest.event?.content().isNullOrBlank() || amount != null) { + if (!zapRequest.event?.content.isNullOrBlank() || amount != null) { onReady( ZapAmountCommentNotification( zapRequest.author, - zapRequest.event?.content()?.ifBlank { null }, + zapRequest.event?.content?.ifBlank { null }, showAmountAxis(amount), ), ) @@ -834,7 +842,7 @@ class AccountViewModel( fun cachedDecrypt(note: Note): String? = account.cachedDecryptContent(note) - fun cachedDecrypt(event: EventInterface?): String? = account.cachedDecryptContent(event) + fun cachedDecrypt(event: Event?): String? = account.cachedDecryptContent(event) fun decrypt( note: Note, @@ -1251,7 +1259,7 @@ class AccountViewModel( } route?.let { - account.markAsRead(route, noteEvent.createdAt()) + account.markAsRead(route, noteEvent.createdAt) } } } @@ -1421,7 +1429,7 @@ class AccountViewModel( } fun unwrapIfNeeded( - event: EventInterface?, + event: Event?, onReady: (Note) -> Unit, ) { when (event) { @@ -1474,7 +1482,7 @@ class AccountViewModel( } } else -> { - event?.id()?.let { + event?.id?.let { LocalCache.getNoteIfExists(it)?.let { onReady(it) } @@ -1547,7 +1555,7 @@ class AccountViewModel( ) // If we have a response, get the tagged Request Event otherwise null - return@withContext response?.event?.tags()?.firstOrNull { it.size > 1 && it[0] == "e" }?.get(1)?.let { + return@withContext response?.event?.tags?.firstOrNull { it.size > 1 && it[0] == "e" }?.get(1)?.let { LocalCache.getOrCreateNote(it) } } @@ -1662,24 +1670,24 @@ class AccountViewModel( ) : GenericBaseCache(20) { override suspend fun compute(key: String): LoadedBechLink? = withContext(Dispatchers.Default) { - Nip19Bech32.uriToRoute(key)?.let { + Nip19Parser.uriToRoute(key)?.let { var returningNote: Note? = null when (val parsed = it.entity) { - is Nip19Bech32.NSec -> {} - is Nip19Bech32.NPub -> {} - is Nip19Bech32.NProfile -> {} - is Nip19Bech32.Note -> { + is NSec -> {} + is NPub -> {} + is NProfile -> {} + is com.vitorpamplona.quartz.nip19Bech32Entities.entities.Note -> { LocalCache.checkGetOrCreateNote(parsed.hex)?.let { note -> returningNote = note } } - is Nip19Bech32.NEvent -> { + is NEvent -> { LocalCache.checkGetOrCreateNote(parsed.hex)?.let { note -> returningNote = note } } - is Nip19Bech32.NEmbed -> + is NEmbed -> withContext(Dispatchers.Default) { val baseNote = LocalCache.getOrCreateNote(parsed.event) if (baseNote.event == null) { @@ -1691,9 +1699,9 @@ class AccountViewModel( returningNote = baseNote } - is Nip19Bech32.NRelay -> {} - is Nip19Bech32.NAddress -> { - LocalCache.checkGetOrCreateNote(parsed.atag)?.let { note -> + is NRelay -> {} + is NAddress -> { + LocalCache.checkGetOrCreateNote(parsed.aTag())?.let { note -> returningNote = note } } @@ -1708,7 +1716,7 @@ class AccountViewModel( @Immutable data class LoadedBechLink( val baseNote: Note?, - val nip19: Nip19Bech32.ParseReturn, + val nip19: Nip19Parser.ParseReturn, ) @Composable diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/LoadRedirectScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/LoadRedirectScreen.kt index b2219d217..f9ef76479 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/LoadRedirectScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/LoadRedirectScreen.kt @@ -43,16 +43,16 @@ import com.vitorpamplona.amethyst.ui.navigation.INav import com.vitorpamplona.amethyst.ui.navigation.Nav import com.vitorpamplona.amethyst.ui.navigation.Route import com.vitorpamplona.amethyst.ui.stringRes -import com.vitorpamplona.quartz.encoders.HexKey -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.EventInterface -import com.vitorpamplona.quartz.events.GiftWrapEvent -import com.vitorpamplona.quartz.events.LiveActivitiesChatMessageEvent -import com.vitorpamplona.quartz.events.LiveActivitiesEvent -import com.vitorpamplona.quartz.events.SealedGossipEvent +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip17Dm.ChatroomKeyable +import com.vitorpamplona.quartz.nip28PublicChat.ChannelCreateEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelMessageEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelMetadataEvent +import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesChatMessageEvent +import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent +import com.vitorpamplona.quartz.nip59Giftwrap.GiftWrapEvent +import com.vitorpamplona.quartz.nip59Giftwrap.SealedGossipEvent import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -122,7 +122,7 @@ fun redirect( } fun redirect( - event: EventInterface, + event: Event, accountViewModel: AccountViewModel, nav: INav, ) { @@ -157,7 +157,7 @@ fun redirect( } } else { if (event is ChannelCreateEvent) { - nav.popUpTo("Channel/${event.id()}", Route.Event.route) + nav.popUpTo("Channel/${event.id}", Route.Event.route) } else if (event is ChatroomKeyable) { val withKey = event.chatroomKey(accountViewModel.userProfile().pubkeyHex) accountViewModel.userProfile().createChatroom(withKey) @@ -165,7 +165,7 @@ fun redirect( } else if (channelHex != null) { nav.popUpTo("Channel/$channelHex", Route.Event.route) } else { - nav.popUpTo("Note/${event.id()}", Route.Event.route) + nav.popUpTo("Note/${event.id}", Route.Event.route) } } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/NewPostScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/NewPostScreen.kt index b9ed00a23..9eac03605 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/NewPostScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/NewPostScreen.kt @@ -182,7 +182,7 @@ 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.ClassifiedsEvent +import com.vitorpamplona.quartz.nip99Classifieds.ClassifiedsEvent import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ReportNoteDialog.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ReportNoteDialog.kt index 745932cab..1fb25ddfa 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ReportNoteDialog.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ReportNoteDialog.kt @@ -63,7 +63,7 @@ import com.vitorpamplona.amethyst.ui.note.ArrowBackIcon import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.DividerThickness import com.vitorpamplona.amethyst.ui.theme.WarningColor -import com.vitorpamplona.quartz.events.ReportEvent +import com.vitorpamplona.quartz.nip56Reports.ReportEvent import kotlinx.collections.immutable.toImmutableList @OptIn(ExperimentalMaterial3Api::class) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chatrooms/ChannelScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chatrooms/ChannelScreen.kt index 74f744f1f..9808dc4b7 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chatrooms/ChannelScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chatrooms/ChannelScreen.kt @@ -165,11 +165,14 @@ import com.vitorpamplona.amethyst.ui.theme.ZeroPadding import com.vitorpamplona.amethyst.ui.theme.innerPostModifier import com.vitorpamplona.amethyst.ui.theme.liveStreamTag import com.vitorpamplona.amethyst.ui.theme.placeholderText -import com.vitorpamplona.quartz.events.EmptyTagList -import com.vitorpamplona.quartz.events.LiveActivitiesEvent.Companion.STATUS_LIVE -import com.vitorpamplona.quartz.events.Participant -import com.vitorpamplona.quartz.events.findURLs -import com.vitorpamplona.quartz.events.toImmutableListOfLists +import com.vitorpamplona.quartz.experimental.audio.Participant +import com.vitorpamplona.quartz.nip01Core.events.isTaggedEvent +import com.vitorpamplona.quartz.nip01Core.hashtags.hasHashtags +import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList +import com.vitorpamplona.quartz.nip02FollowList.toImmutableListOfLists +import com.vitorpamplona.quartz.nip10Notes.findURLs +import com.vitorpamplona.quartz.nip21UriScheme.toNostrUri +import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent.Companion.STATUS_LIVE import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList @@ -913,7 +916,7 @@ fun LongChannelHeader( val tags = remember(channelState) { if (baseChannel is LiveActivitiesChannel) { - baseChannel.info?.tags()?.toImmutableListOfLists() ?: EmptyTagList + baseChannel.info?.tags?.toImmutableListOfLists() ?: EmptyTagList } else { EmptyTagList } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chatrooms/ChatFileUploadModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chatrooms/ChatFileUploadModel.kt index 7e36cde13..78e7a1f67 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chatrooms/ChatFileUploadModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chatrooms/ChatFileUploadModel.kt @@ -39,8 +39,8 @@ import com.vitorpamplona.amethyst.ui.actions.mediaServers.ServerName import com.vitorpamplona.amethyst.ui.actions.uploads.SelectedMedia import com.vitorpamplona.amethyst.ui.actions.uploads.SelectedMediaProcessing import com.vitorpamplona.amethyst.ui.stringRes -import com.vitorpamplona.quartz.crypto.nip17.AESGCM -import com.vitorpamplona.quartz.events.ChatroomKey +import com.vitorpamplona.quartz.nip17Dm.AESGCM +import com.vitorpamplona.quartz.nip17Dm.ChatroomKey import kotlinx.collections.immutable.ImmutableList import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chatrooms/ChatroomFeedView.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chatrooms/ChatroomFeedView.kt index ee25d798e..11f64078f 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chatrooms/ChatroomFeedView.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chatrooms/ChatroomFeedView.kt @@ -55,7 +55,8 @@ import com.vitorpamplona.amethyst.ui.theme.FeedPadding import com.vitorpamplona.amethyst.ui.theme.Font14SP import com.vitorpamplona.amethyst.ui.theme.HalfPadding import com.vitorpamplona.amethyst.ui.theme.StdPadding -import com.vitorpamplona.quartz.events.DraftEvent +import com.vitorpamplona.quartz.nip14Subject.subject +import com.vitorpamplona.quartz.nip37Drafts.DraftEvent @Composable fun RefreshingChatroomFeedView( @@ -178,8 +179,8 @@ fun NewDateSubject( val never = stringRes(R.string.never) val today = stringRes(R.string.today) - val prevDate = remember(previous) { dateFormatter(previous.event?.createdAt(), never, today) } - val date = remember(note) { dateFormatter(note.event?.createdAt(), never, today) } + val prevDate = remember(previous) { dateFormatter(previous.event?.createdAt, never, today) } + val date = remember(note) { dateFormatter(note.event?.createdAt, never, today) } val subject = remember(note) { note.event?.subject() } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chatrooms/ChatroomHeaderCompose.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chatrooms/ChatroomHeaderCompose.kt index c0b90e360..7120cff01 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chatrooms/ChatroomHeaderCompose.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chatrooms/ChatroomHeaderCompose.kt @@ -80,12 +80,12 @@ import com.vitorpamplona.amethyst.ui.theme.AccountPictureModifier import com.vitorpamplona.amethyst.ui.theme.Size55dp 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 com.vitorpamplona.quartz.events.DraftEvent +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip17Dm.ChatroomKey +import com.vitorpamplona.quartz.nip17Dm.ChatroomKeyable +import com.vitorpamplona.quartz.nip28PublicChat.ChannelCreateEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelMetadataEvent +import com.vitorpamplona.quartz.nip37Drafts.DraftEvent @Composable fun ChatroomHeaderCompose( @@ -194,7 +194,7 @@ private fun ChannelRoomCompose( } else if (noteEvent is ChannelMetadataEvent) { "${stringRes(R.string.channel_information_changed_to)} " } else { - noteEvent?.content()?.take(200) + noteEvent?.content?.take(200) } val lastReadTime by accountViewModel.account.loadLastReadFlow(route).collectAsStateWithLifecycle() @@ -205,7 +205,7 @@ private fun ChannelRoomCompose( channelTitle = { modifier -> ChannelTitleWithLabelInfo(channelName, modifier) }, channelLastTime = note.createdAt(), channelLastContent = "$authorName: $description", - hasNewMessages = (noteEvent?.createdAt() ?: Long.MIN_VALUE) > lastReadTime, + hasNewMessages = (noteEvent?.createdAt ?: Long.MIN_VALUE) > lastReadTime, loadProfilePicture = accountViewModel.settings.showProfilePictures.value, loadRobohash = accountViewModel.settings.featureSet != FeatureSetType.PERFORMANCE, onClick = { nav.nav(route) }, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chatrooms/ChatroomMessageCompose.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chatrooms/ChatroomMessageCompose.kt index 0f4f00342..6b441473e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chatrooms/ChatroomMessageCompose.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chatrooms/ChatroomMessageCompose.kt @@ -101,16 +101,16 @@ import com.vitorpamplona.amethyst.ui.theme.incognitoIconModifier import com.vitorpamplona.amethyst.ui.theme.mediumImportanceLink import com.vitorpamplona.amethyst.ui.theme.messageBubbleLimits import com.vitorpamplona.amethyst.ui.theme.placeholderText -import com.vitorpamplona.quartz.events.ChannelCreateEvent -import com.vitorpamplona.quartz.events.ChannelMetadataEvent -import com.vitorpamplona.quartz.events.ChatMessageEncryptedFileHeaderEvent -import com.vitorpamplona.quartz.events.ChatroomKeyable -import com.vitorpamplona.quartz.events.DraftEvent -import com.vitorpamplona.quartz.events.EmptyTagList -import com.vitorpamplona.quartz.events.ImmutableListOfLists -import com.vitorpamplona.quartz.events.NIP17Group -import com.vitorpamplona.quartz.events.PrivateDmEvent -import com.vitorpamplona.quartz.events.toImmutableListOfLists +import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList +import com.vitorpamplona.quartz.nip02FollowList.ImmutableListOfLists +import com.vitorpamplona.quartz.nip02FollowList.toImmutableListOfLists +import com.vitorpamplona.quartz.nip04Dm.PrivateDmEvent +import com.vitorpamplona.quartz.nip17Dm.ChatMessageEncryptedFileHeaderEvent +import com.vitorpamplona.quartz.nip17Dm.ChatroomKeyable +import com.vitorpamplona.quartz.nip17Dm.NIP17Group +import com.vitorpamplona.quartz.nip28PublicChat.ChannelCreateEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelMetadataEvent +import com.vitorpamplona.quartz.nip37Drafts.DraftEvent @Composable fun ChatroomMessageCompose( @@ -690,7 +690,7 @@ private fun RenderRegularTextNote( note = note, accountViewModel = accountViewModel, ) { - val tags = remember(note.event) { note.event?.tags()?.toImmutableListOfLists() ?: EmptyTagList } + val tags = remember(note.event) { note.event?.tags?.toImmutableListOfLists() ?: EmptyTagList } TranslatableRichTextViewer( content = eventContent, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chatrooms/ChatroomScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chatrooms/ChatroomScreen.kt index 31cddc896..146b5a9ed 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chatrooms/ChatroomScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chatrooms/ChatroomScreen.kt @@ -79,7 +79,6 @@ import androidx.lifecycle.distinctUntilChanged import androidx.lifecycle.map import androidx.lifecycle.viewmodel.compose.viewModel import com.vitorpamplona.amethyst.R -import com.vitorpamplona.amethyst.model.Chatroom import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.service.NostrChatroomDataSource @@ -119,9 +118,9 @@ import com.vitorpamplona.amethyst.ui.theme.Size34dp import com.vitorpamplona.amethyst.ui.theme.StdPadding import com.vitorpamplona.amethyst.ui.theme.ZeroPadding import com.vitorpamplona.amethyst.ui.theme.placeholderText -import com.vitorpamplona.quartz.events.ChatroomKey -import com.vitorpamplona.quartz.events.NIP17Group -import com.vitorpamplona.quartz.events.findURLs +import com.vitorpamplona.quartz.nip10Notes.findURLs +import com.vitorpamplona.quartz.nip17Dm.ChatroomKey +import com.vitorpamplona.quartz.nip17Dm.NIP17Group import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentSetOf import kotlinx.collections.immutable.toPersistentList diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/DiscoverScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/DiscoverScreen.kt index c286fbac6..9ba6e2fa5 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/DiscoverScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/DiscoverScreen.kt @@ -78,11 +78,11 @@ import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.DividerThickness import com.vitorpamplona.amethyst.ui.theme.FeedPadding import com.vitorpamplona.amethyst.ui.theme.TabRowHeight -import com.vitorpamplona.quartz.events.AppDefinitionEvent -import com.vitorpamplona.quartz.events.ChannelCreateEvent -import com.vitorpamplona.quartz.events.ClassifiedsEvent -import com.vitorpamplona.quartz.events.CommunityDefinitionEvent -import com.vitorpamplona.quartz.events.LiveActivitiesEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelCreateEvent +import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent +import com.vitorpamplona.quartz.nip72ModCommunities.CommunityDefinitionEvent +import com.vitorpamplona.quartz.nip89AppHandlers.AppDefinitionEvent +import com.vitorpamplona.quartz.nip99Classifieds.ClassifiedsEvent import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.launch diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/dvms/DvmContentDiscoveryScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/dvms/DvmContentDiscoveryScreen.kt index 8ca18ab14..c99bc0d74 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/dvms/DvmContentDiscoveryScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/dvms/DvmContentDiscoveryScreen.kt @@ -93,12 +93,12 @@ import com.vitorpamplona.amethyst.ui.theme.QuoteBorder import com.vitorpamplona.amethyst.ui.theme.Size20Modifier import com.vitorpamplona.amethyst.ui.theme.Size35dp import com.vitorpamplona.amethyst.ui.theme.Size75dp -import com.vitorpamplona.quartz.encoders.LnInvoiceUtil -import com.vitorpamplona.quartz.events.AppDefinitionEvent -import com.vitorpamplona.quartz.events.AppMetadata -import com.vitorpamplona.quartz.events.NIP90ContentDiscoveryResponseEvent -import com.vitorpamplona.quartz.events.NIP90StatusEvent -import com.vitorpamplona.quartz.events.PayInvoiceErrorResponse +import com.vitorpamplona.quartz.lightning.LnInvoiceUtil +import com.vitorpamplona.quartz.nip47WalletConnect.PayInvoiceErrorResponse +import com.vitorpamplona.quartz.nip89AppHandlers.AppDefinitionEvent +import com.vitorpamplona.quartz.nip89AppHandlers.AppMetadata +import com.vitorpamplona.quartz.nip90Dvms.NIP90ContentDiscoveryResponseEvent +import com.vitorpamplona.quartz.nip90Dvms.NIP90StatusEvent import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.Dispatchers @@ -200,7 +200,10 @@ fun ObserverContentDiscoveryResponse( val resultFlow = remember(dvmRequestId) { - accountViewModel.observeByETag(NIP90ContentDiscoveryResponseEvent.KIND, dvmRequestId.idHex) + accountViewModel.observeByETag( + NIP90ContentDiscoveryResponseEvent.KIND, + dvmRequestId.idHex, + ) } val latestResponse by resultFlow.collectAsStateWithLifecycle() diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/CardFeedContentState.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/CardFeedContentState.kt index b08832eb1..aa9ac23ac 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/CardFeedContentState.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/CardFeedContentState.kt @@ -38,15 +38,15 @@ import com.vitorpamplona.amethyst.ui.feeds.InvalidatableContent import com.vitorpamplona.amethyst.ui.feeds.LoadedFeedState import com.vitorpamplona.ammolite.relays.BundledInsert import com.vitorpamplona.ammolite.relays.BundledUpdate -import com.vitorpamplona.quartz.events.BadgeAwardEvent -import com.vitorpamplona.quartz.events.ChannelCreateEvent -import com.vitorpamplona.quartz.events.ChannelMetadataEvent -import com.vitorpamplona.quartz.events.GenericRepostEvent -import com.vitorpamplona.quartz.events.LnZapEvent -import com.vitorpamplona.quartz.events.NIP17Group -import com.vitorpamplona.quartz.events.PrivateDmEvent -import com.vitorpamplona.quartz.events.ReactionEvent -import com.vitorpamplona.quartz.events.RepostEvent +import com.vitorpamplona.quartz.nip04Dm.PrivateDmEvent +import com.vitorpamplona.quartz.nip17Dm.NIP17Group +import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent +import com.vitorpamplona.quartz.nip18Reposts.RepostEvent +import com.vitorpamplona.quartz.nip25Reactions.ReactionEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelCreateEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelMetadataEvent +import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent +import com.vitorpamplona.quartz.nip58Badges.BadgeAwardEvent import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.CoroutineScope diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/CardFeedState.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/CardFeedState.kt index c23686910..1d958fecb 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/CardFeedState.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/CardFeedState.kt @@ -26,7 +26,7 @@ import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.service.firstFullCharOrEmoji import com.vitorpamplona.amethyst.ui.feeds.LoadedFeedState -import com.vitorpamplona.quartz.events.ImmutableListOfLists +import com.vitorpamplona.quartz.nip02FollowList.ImmutableListOfLists import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableMap @@ -94,8 +94,8 @@ class MultiSetCard( likeEvents .groupBy { it.event - ?.content() - ?.firstFullCharOrEmoji(ImmutableListOfLists(it.event?.tags() ?: emptyArray())) + ?.content + ?.firstFullCharOrEmoji(ImmutableListOfLists(it.event?.tags ?: emptyArray())) ?: "+" }.mapValues { it.value.toImmutableList() } .toImmutableMap() diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/NotificationSummaryState.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/NotificationSummaryState.kt index df5c81cce..37008a17e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/NotificationSummaryState.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/NotificationSummaryState.kt @@ -34,12 +34,13 @@ import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.service.checkNotInMainThread import com.vitorpamplona.amethyst.ui.note.showCount import com.vitorpamplona.ammolite.relays.BundledInsert -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.events.BaseTextNoteEvent -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.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.people.isTaggedUser +import com.vitorpamplona.quartz.nip10Notes.BaseTextNoteEvent +import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent +import com.vitorpamplona.quartz.nip18Reposts.RepostEvent +import com.vitorpamplona.quartz.nip25Reactions.ReactionEvent +import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow @@ -103,18 +104,18 @@ class NotificationSummaryState( LocalCache.notes.forEach { _, it -> val noteEvent = it.event - if (noteEvent != null && !takenIntoAccount.contains(noteEvent.id())) { + if (noteEvent != null && !takenIntoAccount.contains(noteEvent.id)) { if (noteEvent is ReactionEvent) { if (noteEvent.isTaggedUser(currentUser) && noteEvent.pubKey != currentUser) { val netDate = formatDate(noteEvent.createdAt) reactions[netDate] = (reactions[netDate] ?: 0) + 1 - takenIntoAccount.add(noteEvent.id()) + takenIntoAccount.add(noteEvent.id) } } else if (noteEvent is RepostEvent || noteEvent is GenericRepostEvent) { - if (noteEvent.isTaggedUser(currentUser) && noteEvent.pubKey() != currentUser) { - val netDate = formatDate(noteEvent.createdAt()) + if (noteEvent.isTaggedUser(currentUser) && noteEvent.pubKey != currentUser) { + val netDate = formatDate(noteEvent.createdAt) boosts[netDate] = (boosts[netDate] ?: 0) + 1 - takenIntoAccount.add(noteEvent.id()) + takenIntoAccount.add(noteEvent.id) } } else if (noteEvent is LnZapEvent) { if ( @@ -123,7 +124,7 @@ class NotificationSummaryState( val netDate = formatDate(noteEvent.createdAt) zaps[netDate] = (zaps[netDate] ?: BigDecimal.ZERO) + (noteEvent.amount ?: BigDecimal.ZERO) - takenIntoAccount.add(noteEvent.id()) + takenIntoAccount.add(noteEvent.id) } } else if (noteEvent is BaseTextNoteEvent) { if (noteEvent.isTaggedUser(currentUser) && noteEvent.pubKey != currentUser) { @@ -138,7 +139,7 @@ class NotificationSummaryState( } else { replies[netDate] = (replies[netDate] ?: 0) + 1 } - takenIntoAccount.add(noteEvent.id()) + takenIntoAccount.add(noteEvent.id) } } } @@ -168,19 +169,19 @@ class NotificationSummaryState( newBlockNotes.forEach { newNotes -> newNotes.forEach { val noteEvent = it.event - if (noteEvent != null && !takenIntoAccount.contains(noteEvent.id())) { + if (noteEvent != null && !takenIntoAccount.contains(noteEvent.id)) { if (noteEvent is ReactionEvent) { if (noteEvent.isTaggedUser(currentUser) && noteEvent.pubKey != currentUser) { val netDate = formatDate(noteEvent.createdAt) reactions[netDate] = (reactions[netDate] ?: 0) + 1 - takenIntoAccount.add(noteEvent.id()) + takenIntoAccount.add(noteEvent.id) hasNewElements = true } } else if (noteEvent is RepostEvent || noteEvent is GenericRepostEvent) { - if (noteEvent.isTaggedUser(currentUser) && noteEvent.pubKey() != currentUser) { - val netDate = formatDate(noteEvent.createdAt()) + if (noteEvent.isTaggedUser(currentUser) && noteEvent.pubKey != currentUser) { + val netDate = formatDate(noteEvent.createdAt) boosts[netDate] = (boosts[netDate] ?: 0) + 1 - takenIntoAccount.add(noteEvent.id()) + takenIntoAccount.add(noteEvent.id) hasNewElements = true } } else if (noteEvent is LnZapEvent) { @@ -190,7 +191,7 @@ class NotificationSummaryState( val netDate = formatDate(noteEvent.createdAt) zaps[netDate] = (zaps[netDate] ?: BigDecimal.ZERO) + (noteEvent.amount ?: BigDecimal.ZERO) - takenIntoAccount.add(noteEvent.id()) + takenIntoAccount.add(noteEvent.id) hasNewElements = true } } else if (noteEvent is BaseTextNoteEvent) { @@ -206,7 +207,7 @@ class NotificationSummaryState( } else { replies[netDate] = (replies[netDate] ?: 0) + 1 } - takenIntoAccount.add(noteEvent.id()) + takenIntoAccount.add(noteEvent.id) hasNewElements = true } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/ProfileScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/ProfileScreen.kt index 4c2b4c252..088341a28 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/ProfileScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/ProfileScreen.kt @@ -176,18 +176,21 @@ import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer import com.vitorpamplona.amethyst.ui.theme.ZeroPadding import com.vitorpamplona.amethyst.ui.theme.placeholderText import com.vitorpamplona.amethyst.ui.theme.userProfileBorderModifier -import com.vitorpamplona.quartz.events.AppDefinitionEvent -import com.vitorpamplona.quartz.events.BadgeDefinitionEvent -import com.vitorpamplona.quartz.events.BadgeProfilesEvent -import com.vitorpamplona.quartz.events.EmptyTagList -import com.vitorpamplona.quartz.events.GitHubIdentity -import com.vitorpamplona.quartz.events.IdentityClaim -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.nip01Core.addressables.taggedAddresses +import com.vitorpamplona.quartz.nip01Core.events.taggedEvents +import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList +import com.vitorpamplona.quartz.nip39ExtIdentities.GitHubIdentity +import com.vitorpamplona.quartz.nip39ExtIdentities.IdentityClaim +import com.vitorpamplona.quartz.nip39ExtIdentities.MastodonIdentity +import com.vitorpamplona.quartz.nip39ExtIdentities.TelegramIdentity +import com.vitorpamplona.quartz.nip39ExtIdentities.TwitterIdentity +import com.vitorpamplona.quartz.nip39ExtIdentities.identityClaims +import com.vitorpamplona.quartz.nip47WalletConnect.PayInvoiceErrorResponse +import com.vitorpamplona.quartz.nip47WalletConnect.PayInvoiceSuccessResponse +import com.vitorpamplona.quartz.nip56Reports.ReportEvent +import com.vitorpamplona.quartz.nip58Badges.BadgeDefinitionEvent +import com.vitorpamplona.quartz.nip58Badges.BadgeProfilesEvent +import com.vitorpamplona.quartz.nip89AppHandlers.AppDefinitionEvent import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.Dispatchers diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/RelayFeedViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/RelayFeedViewModel.kt index c41726832..0d6257a42 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/RelayFeedViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/RelayFeedViewModel.kt @@ -31,7 +31,7 @@ import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.model.UserState import com.vitorpamplona.amethyst.ui.feeds.InvalidatableContent import com.vitorpamplona.ammolite.relays.BundledUpdate -import com.vitorpamplona.quartz.encoders.RelayUrlFormatter +import com.vitorpamplona.quartz.nip65RelayList.RelayUrlFormatter import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/gallery/GalleryCardCompose.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/gallery/GalleryCardCompose.kt index 6756ed43d..981fcebe5 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/gallery/GalleryCardCompose.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/gallery/GalleryCardCompose.kt @@ -36,9 +36,9 @@ import com.vitorpamplona.amethyst.ui.navigation.routeFor import com.vitorpamplona.amethyst.ui.note.CheckHiddenFeedWatchBlockAndReport import com.vitorpamplona.amethyst.ui.note.WatchNoteEvent import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel -import com.vitorpamplona.quartz.events.GenericRepostEvent -import com.vitorpamplona.quartz.events.ProfileGalleryEntryEvent -import com.vitorpamplona.quartz.events.RepostEvent +import com.vitorpamplona.quartz.experimental.profileGallery.ProfileGalleryEntryEvent +import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent +import com.vitorpamplona.quartz.nip18Reposts.RepostEvent @Composable fun GalleryCardCompose( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/gallery/GalleryThumb.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/gallery/GalleryThumb.kt index 2de7b23b5..2e01fc52e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/gallery/GalleryThumb.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/gallery/GalleryThumb.kt @@ -61,7 +61,6 @@ import com.vitorpamplona.amethyst.ui.components.GetMediaItem import com.vitorpamplona.amethyst.ui.components.GetVideoController import com.vitorpamplona.amethyst.ui.components.ImageUrlWithDownloadButton import com.vitorpamplona.amethyst.ui.components.SensitivityWarning -import com.vitorpamplona.amethyst.ui.components.UrlImageView import com.vitorpamplona.amethyst.ui.navigation.INav import com.vitorpamplona.amethyst.ui.note.DownloadForOfflineIcon import com.vitorpamplona.amethyst.ui.note.WatchAuthor @@ -69,9 +68,9 @@ import com.vitorpamplona.amethyst.ui.note.elements.BannerImage import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.theme.QuoteBorder import com.vitorpamplona.amethyst.ui.theme.Size75dp -import com.vitorpamplona.quartz.events.PictureEvent -import com.vitorpamplona.quartz.events.ProfileGalleryEntryEvent -import com.vitorpamplona.quartz.events.VideoEvent +import com.vitorpamplona.quartz.experimental.profileGallery.ProfileGalleryEntryEvent +import com.vitorpamplona.quartz.nip68Picture.PictureEvent +import com.vitorpamplona.quartz.nip71Video.VideoEvent @Composable fun GalleryThumbnail( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/qrcode/ShowQRDialog.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/qrcode/ShowQRDialog.kt index 5029a7eb6..989050479 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/qrcode/ShowQRDialog.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/qrcode/ShowQRDialog.kt @@ -65,7 +65,7 @@ import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.Font14SP import com.vitorpamplona.amethyst.ui.theme.Size10dp import com.vitorpamplona.amethyst.ui.theme.Size35dp -import com.vitorpamplona.quartz.events.UserMetadata +import com.vitorpamplona.quartz.nip01Core.UserMetadata @Preview @Composable diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/search/SearchBarViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/search/SearchBarViewModel.kt index 747ddf6f7..a8eb8fe91 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/search/SearchBarViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/search/SearchBarViewModel.kt @@ -35,7 +35,7 @@ import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.ammolite.relays.BundledUpdate -import com.vitorpamplona.quartz.events.findHashtags +import com.vitorpamplona.quartz.nip10Notes.findHashtags import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/threadview/ThreadFeedView.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/threadview/ThreadFeedView.kt index 6cba1dda9..63754128e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/threadview/ThreadFeedView.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/threadview/ThreadFeedView.kt @@ -163,46 +163,51 @@ import com.vitorpamplona.amethyst.ui.theme.ThemeComparisonColumn 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.AdvertisedRelayListEvent -import com.vitorpamplona.quartz.events.AppDefinitionEvent -import com.vitorpamplona.quartz.events.AudioHeaderEvent -import com.vitorpamplona.quartz.events.AudioTrackEvent -import com.vitorpamplona.quartz.events.BadgeDefinitionEvent -import com.vitorpamplona.quartz.events.ChannelCreateEvent -import com.vitorpamplona.quartz.events.ChannelMessageEvent -import com.vitorpamplona.quartz.events.ChannelMetadataEvent -import com.vitorpamplona.quartz.events.ChatMessageRelayListEvent -import com.vitorpamplona.quartz.events.ClassifiedsEvent -import com.vitorpamplona.quartz.events.CommentEvent -import com.vitorpamplona.quartz.events.CommunityDefinitionEvent -import com.vitorpamplona.quartz.events.CommunityPostApprovalEvent -import com.vitorpamplona.quartz.events.DraftEvent -import com.vitorpamplona.quartz.events.EmojiPackEvent -import com.vitorpamplona.quartz.events.Event -import com.vitorpamplona.quartz.events.FhirResourceEvent -import com.vitorpamplona.quartz.events.FileHeaderEvent -import com.vitorpamplona.quartz.events.FileStorageHeaderEvent -import com.vitorpamplona.quartz.events.GenericRepostEvent -import com.vitorpamplona.quartz.events.GitIssueEvent -import com.vitorpamplona.quartz.events.GitPatchEvent -import com.vitorpamplona.quartz.events.GitRepositoryEvent -import com.vitorpamplona.quartz.events.HighlightEvent -import com.vitorpamplona.quartz.events.InteractiveStoryBaseEvent -import com.vitorpamplona.quartz.events.LiveActivitiesChatMessageEvent -import com.vitorpamplona.quartz.events.LongTextNoteEvent -import com.vitorpamplona.quartz.events.PeopleListEvent -import com.vitorpamplona.quartz.events.PictureEvent -import com.vitorpamplona.quartz.events.PinListEvent -import com.vitorpamplona.quartz.events.PollNoteEvent -import com.vitorpamplona.quartz.events.PrivateDmEvent -import com.vitorpamplona.quartz.events.RelaySetEvent -import com.vitorpamplona.quartz.events.RepostEvent -import com.vitorpamplona.quartz.events.SearchRelayListEvent -import com.vitorpamplona.quartz.events.TextNoteModificationEvent -import com.vitorpamplona.quartz.events.TorrentCommentEvent -import com.vitorpamplona.quartz.events.TorrentEvent -import com.vitorpamplona.quartz.events.VideoEvent -import com.vitorpamplona.quartz.events.WikiNoteEvent +import com.vitorpamplona.quartz.experimental.audio.AudioHeaderEvent +import com.vitorpamplona.quartz.experimental.audio.AudioTrackEvent +import com.vitorpamplona.quartz.experimental.bounties.getReward +import com.vitorpamplona.quartz.experimental.edits.TextNoteModificationEvent +import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStoryBaseEvent +import com.vitorpamplona.quartz.experimental.medical.FhirResourceEvent +import com.vitorpamplona.quartz.experimental.nip95.FileStorageHeaderEvent +import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent +import com.vitorpamplona.quartz.nip01Core.addressables.isTaggedAddressableKind +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.geohash.getGeoHash +import com.vitorpamplona.quartz.nip04Dm.PrivateDmEvent +import com.vitorpamplona.quartz.nip13Pow.getPoWRank +import com.vitorpamplona.quartz.nip17Dm.ChatMessageRelayListEvent +import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent +import com.vitorpamplona.quartz.nip18Reposts.RepostEvent +import com.vitorpamplona.quartz.nip22Comments.CommentEvent +import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelCreateEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelMessageEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelMetadataEvent +import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiPackEvent +import com.vitorpamplona.quartz.nip34Git.GitIssueEvent +import com.vitorpamplona.quartz.nip34Git.GitPatchEvent +import com.vitorpamplona.quartz.nip34Git.GitRepositoryEvent +import com.vitorpamplona.quartz.nip35Torrents.TorrentCommentEvent +import com.vitorpamplona.quartz.nip35Torrents.TorrentEvent +import com.vitorpamplona.quartz.nip37Drafts.DraftEvent +import com.vitorpamplona.quartz.nip50Search.SearchRelayListEvent +import com.vitorpamplona.quartz.nip51Lists.PeopleListEvent +import com.vitorpamplona.quartz.nip51Lists.PinListEvent +import com.vitorpamplona.quartz.nip51Lists.RelaySetEvent +import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesChatMessageEvent +import com.vitorpamplona.quartz.nip54Wiki.WikiNoteEvent +import com.vitorpamplona.quartz.nip57Zaps.hasZapSplitSetup +import com.vitorpamplona.quartz.nip58Badges.BadgeDefinitionEvent +import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent +import com.vitorpamplona.quartz.nip68Picture.PictureEvent +import com.vitorpamplona.quartz.nip71Video.VideoEvent +import com.vitorpamplona.quartz.nip72ModCommunities.CommunityDefinitionEvent +import com.vitorpamplona.quartz.nip72ModCommunities.CommunityPostApprovalEvent +import com.vitorpamplona.quartz.nip84Highlights.HighlightEvent +import com.vitorpamplona.quartz.nip89AppHandlers.AppDefinitionEvent +import com.vitorpamplona.quartz.nip94FileMetadata.FileHeaderEvent +import com.vitorpamplona.quartz.nip99Classifieds.ClassifiedsEvent import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/video/VideoScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/video/VideoScreen.kt index f934e37f6..c69ee81a1 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/video/VideoScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/video/VideoScreen.kt @@ -103,10 +103,10 @@ import com.vitorpamplona.amethyst.ui.theme.Size40dp import com.vitorpamplona.amethyst.ui.theme.Size55dp import com.vitorpamplona.amethyst.ui.theme.VideoReactionColumnPadding import com.vitorpamplona.amethyst.ui.theme.placeholderText -import com.vitorpamplona.quartz.events.FileHeaderEvent -import com.vitorpamplona.quartz.events.FileStorageHeaderEvent -import com.vitorpamplona.quartz.events.PictureEvent -import com.vitorpamplona.quartz.events.VideoEvent +import com.vitorpamplona.quartz.experimental.nip95.FileStorageHeaderEvent +import com.vitorpamplona.quartz.nip68Picture.PictureEvent +import com.vitorpamplona.quartz.nip71Video.VideoEvent +import com.vitorpamplona.quartz.nip94FileMetadata.FileHeaderEvent @Composable fun VideoScreen( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedOff/LoginScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedOff/LoginScreen.kt index cc030afbf..2a270e7f1 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedOff/LoginScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedOff/LoginScreen.kt @@ -105,9 +105,9 @@ import com.vitorpamplona.amethyst.ui.theme.Size40dp import com.vitorpamplona.amethyst.ui.theme.ThemeComparisonRow import com.vitorpamplona.amethyst.ui.theme.placeholderText import com.vitorpamplona.amethyst.ui.tor.TorSettings -import com.vitorpamplona.quartz.encoders.Nip19Bech32 -import com.vitorpamplona.quartz.signers.ExternalSignerLauncher -import com.vitorpamplona.quartz.signers.SignerType +import com.vitorpamplona.quartz.nip19Bech32Entities.Nip19Parser +import com.vitorpamplona.quartz.nip55AndroidSigner.ExternalSignerLauncher +import com.vitorpamplona.quartz.nip55AndroidSigner.SignerType import kotlinx.coroutines.CancellationException import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay @@ -699,7 +699,7 @@ private fun OpenURIIfNotLoggedIn(onNewNIP19: suspend (String) -> Unit) { currentIntentNextPage?.let { intentNextPage -> var nip19 by remember { mutableStateOf( - Nip19Bech32.tryParseAndClean(currentIntentNextPage), + Nip19Parser.tryParseAndClean(currentIntentNextPage), ) } @@ -731,7 +731,7 @@ private fun OpenURIIfNotLoggedIn(onNewNIP19: suspend (String) -> Unit) { Consumer { intent -> val uri = intent.data?.toString() if (!uri.isNullOrBlank()) { - val newNip19 = Nip19Bech32.tryParseAndClean(uri) + val newNip19 = Nip19Parser.tryParseAndClean(uri) if (newNip19 != null) { scope.launch { onNewNIP19(newNip19) diff --git a/amethyst/src/play/java/com/vitorpamplona/amethyst/service/notifications/PushNotificationReceiverService.kt b/amethyst/src/play/java/com/vitorpamplona/amethyst/service/notifications/PushNotificationReceiverService.kt index a51e4094f..84431be21 100644 --- a/amethyst/src/play/java/com/vitorpamplona/amethyst/service/notifications/PushNotificationReceiverService.kt +++ b/amethyst/src/play/java/com/vitorpamplona/amethyst/service/notifications/PushNotificationReceiverService.kt @@ -29,8 +29,8 @@ import com.google.firebase.messaging.RemoteMessage import com.vitorpamplona.amethyst.LocalPreferences import com.vitorpamplona.amethyst.service.notifications.NotificationUtils.getOrCreateDMChannel import com.vitorpamplona.amethyst.service.notifications.NotificationUtils.getOrCreateZapChannel -import com.vitorpamplona.quartz.events.Event -import com.vitorpamplona.quartz.events.GiftWrapEvent +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip59Giftwrap.GiftWrapEvent import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob diff --git a/amethyst/src/play/java/com/vitorpamplona/amethyst/ui/components/TranslatableRichTextViewer.kt b/amethyst/src/play/java/com/vitorpamplona/amethyst/ui/components/TranslatableRichTextViewer.kt index 0e1f626a9..1c2e86911 100644 --- a/amethyst/src/play/java/com/vitorpamplona/amethyst/ui/components/TranslatableRichTextViewer.kt +++ b/amethyst/src/play/java/com/vitorpamplona/amethyst/ui/components/TranslatableRichTextViewer.kt @@ -64,7 +64,7 @@ import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.DividerThickness import com.vitorpamplona.amethyst.ui.theme.Font14SP import com.vitorpamplona.amethyst.ui.theme.lessImportantLink -import com.vitorpamplona.quartz.events.ImmutableListOfLists +import com.vitorpamplona.quartz.nip02FollowList.ImmutableListOfLists import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext diff --git a/amethyst/src/test/java/com/vitorpamplona/amethyst/NewMessageTaggerKeyParseTest.kt b/amethyst/src/test/java/com/vitorpamplona/amethyst/NewMessageTaggerKeyParseTest.kt index ae82373dd..df7969f01 100644 --- a/amethyst/src/test/java/com/vitorpamplona/amethyst/NewMessageTaggerKeyParseTest.kt +++ b/amethyst/src/test/java/com/vitorpamplona/amethyst/NewMessageTaggerKeyParseTest.kt @@ -20,11 +20,11 @@ */ package com.vitorpamplona.amethyst -import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.ui.actions.Dao import com.vitorpamplona.amethyst.ui.actions.NewMessageTagger -import com.vitorpamplona.quartz.encoders.Nip19Bech32 +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NPub +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.Note import org.junit.Assert.assertEquals import org.junit.Assert.assertTrue import org.junit.Test @@ -39,9 +39,13 @@ class NewMessageTaggerKeyParseTest { object : Dao { override suspend fun getOrCreateUser(hex: String): User = User(hex) - override suspend fun getOrCreateNote(hex: String): Note = Note(hex) + override suspend fun getOrCreateNote(hex: String) = + com.vitorpamplona.amethyst.model + .Note(hex) - override suspend fun checkGetOrCreateAddressableNote(hex: String): Note? = Note(hex) + override suspend fun checkGetOrCreateAddressableNote(hex: String) = + com.vitorpamplona.amethyst.model + .Note(hex) } @Test @@ -49,10 +53,10 @@ class NewMessageTaggerKeyParseTest { val result = NewMessageTagger(message = "", dao = dao) .parseDirtyWordForKey("note1z5e2m0smx6d7e2d0zaq8d3rnd7httm6j0uf8tf90yqqjrs842czshwtkmn") - assertTrue(result?.key?.entity is Nip19Bech32.Note) + assertTrue(result?.key?.entity is Note) assertEquals( "1532adbe1b369beca9af174076c4736faeb5ef527f1275a4af200121c0f55605", - (result?.key?.entity as? Nip19Bech32.Note)?.hex, + (result?.key?.entity as? Note)?.hex, ) assertEquals(null, result?.restOfWord) } @@ -62,10 +66,10 @@ class NewMessageTaggerKeyParseTest { val result = NewMessageTagger(message = "", dao = dao) .parseDirtyWordForKey("npub1gcxzte5zlkncx26j68ez60fzkvtkm9e0vrwdcvsjakxf9mu9qewqlfnj5z") - assertTrue(result?.key?.entity is Nip19Bech32.NPub) + assertTrue(result?.key?.entity is NPub) assertEquals( "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", - (result?.key?.entity as? Nip19Bech32.NPub)?.hex, + (result?.key?.entity as? NPub)?.hex, ) assertEquals(null, result?.restOfWord) } @@ -75,10 +79,10 @@ class NewMessageTaggerKeyParseTest { val result = NewMessageTagger(message = "", dao = dao) .parseDirtyWordForKey("note1z5e2m0smx6d7e2d0zaq8d3rnd7httm6j0uf8tf90yqqjrs842czshwtkmn,") - assertTrue(result?.key?.entity is Nip19Bech32.Note) + assertTrue(result?.key?.entity is Note) assertEquals( "1532adbe1b369beca9af174076c4736faeb5ef527f1275a4af200121c0f55605", - (result?.key?.entity as? Nip19Bech32.Note)?.hex, + (result?.key?.entity as? Note)?.hex, ) assertEquals(",", result?.restOfWord) } @@ -88,10 +92,10 @@ class NewMessageTaggerKeyParseTest { val result = NewMessageTagger(message = "", dao = dao) .parseDirtyWordForKey("npub1gcxzte5zlkncx26j68ez60fzkvtkm9e0vrwdcvsjakxf9mu9qewqlfnj5z,") - assertTrue(result?.key?.entity is Nip19Bech32.NPub) + assertTrue(result?.key?.entity is NPub) assertEquals( "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", - (result?.key?.entity as? Nip19Bech32.NPub)?.hex, + (result?.key?.entity as? NPub)?.hex, ) assertEquals(",", result?.restOfWord) } @@ -101,10 +105,10 @@ class NewMessageTaggerKeyParseTest { val result = NewMessageTagger(message = "", dao = dao) .parseDirtyWordForKey("@note1z5e2m0smx6d7e2d0zaq8d3rnd7httm6j0uf8tf90yqqjrs842czshwtkmn,") - assertTrue(result?.key?.entity is Nip19Bech32.Note) + assertTrue(result?.key?.entity is Note) assertEquals( "1532adbe1b369beca9af174076c4736faeb5ef527f1275a4af200121c0f55605", - (result?.key?.entity as? Nip19Bech32.Note)?.hex, + (result?.key?.entity as? Note)?.hex, ) assertEquals(",", result?.restOfWord) } @@ -114,10 +118,10 @@ class NewMessageTaggerKeyParseTest { val result = NewMessageTagger(message = "", dao = dao) .parseDirtyWordForKey("@npub1gcxzte5zlkncx26j68ez60fzkvtkm9e0vrwdcvsjakxf9mu9qewqlfnj5z,") - assertTrue(result?.key?.entity is Nip19Bech32.NPub) + assertTrue(result?.key?.entity is NPub) assertEquals( "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", - (result?.key?.entity as? Nip19Bech32.NPub)?.hex, + (result?.key?.entity as? NPub)?.hex, ) assertEquals(",", result?.restOfWord) } @@ -129,10 +133,10 @@ class NewMessageTaggerKeyParseTest { .parseDirtyWordForKey( "nostr:note1z5e2m0smx6d7e2d0zaq8d3rnd7httm6j0uf8tf90yqqjrs842czshwtkmn,", ) - assertTrue(result?.key?.entity is Nip19Bech32.Note) + assertTrue(result?.key?.entity is Note) assertEquals( "1532adbe1b369beca9af174076c4736faeb5ef527f1275a4af200121c0f55605", - (result?.key?.entity as? Nip19Bech32.Note)?.hex, + (result?.key?.entity as? Note)?.hex, ) assertEquals(",", result?.restOfWord) } @@ -144,10 +148,10 @@ class NewMessageTaggerKeyParseTest { .parseDirtyWordForKey( "nostr:npub1gcxzte5zlkncx26j68ez60fzkvtkm9e0vrwdcvsjakxf9mu9qewqlfnj5z,", ) - assertTrue(result?.key?.entity is Nip19Bech32.NPub) + assertTrue(result?.key?.entity is NPub) assertEquals( "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", - (result?.key?.entity as? Nip19Bech32.NPub)?.hex, + (result?.key?.entity as? NPub)?.hex, ) assertEquals(",", result?.restOfWord) } @@ -159,10 +163,10 @@ class NewMessageTaggerKeyParseTest { .parseDirtyWordForKey( "Nostr:note1z5e2m0smx6d7e2d0zaq8d3rnd7httm6j0uf8tf90yqqjrs842czshwtkmn,", ) - assertTrue(result?.key?.entity is Nip19Bech32.Note) + assertTrue(result?.key?.entity is Note) assertEquals( "1532adbe1b369beca9af174076c4736faeb5ef527f1275a4af200121c0f55605", - (result?.key?.entity as? Nip19Bech32.Note)?.hex, + (result?.key?.entity as? Note)?.hex, ) assertEquals(",", result?.restOfWord) } @@ -174,10 +178,10 @@ class NewMessageTaggerKeyParseTest { .parseDirtyWordForKey( "nOstr:npub1gcxzte5zlkncx26j68ez60fzkvtkm9e0vrwdcvsjakxf9mu9qewqlfnj5z,", ) - assertTrue(result?.key?.entity is Nip19Bech32.NPub) + assertTrue(result?.key?.entity is NPub) assertEquals( "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", - (result?.key?.entity as? Nip19Bech32.NPub)?.hex, + (result?.key?.entity as? NPub)?.hex, ) assertEquals(",", result?.restOfWord) } diff --git a/amethyst/src/test/java/com/vitorpamplona/amethyst/service/zaps/UserProfileZapsFeedFilterTest.kt b/amethyst/src/test/java/com/vitorpamplona/amethyst/service/zaps/UserProfileZapsFeedFilterTest.kt index df49e615d..ba03be0d2 100644 --- a/amethyst/src/test/java/com/vitorpamplona/amethyst/service/zaps/UserProfileZapsFeedFilterTest.kt +++ b/amethyst/src/test/java/com/vitorpamplona/amethyst/service/zaps/UserProfileZapsFeedFilterTest.kt @@ -22,8 +22,8 @@ package com.vitorpamplona.amethyst.service.zaps import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.ui.dal.UserProfileZapsFeedFilter -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.events.LnZapEventInterface +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent import io.mockk.every import io.mockk.mockk import org.junit.Assert @@ -59,7 +59,7 @@ class UserProfileZapsFeedFilterTest { Assert.assertEquals(zapRequest, actual.first().zapRequest) Assert.assertEquals( BigDecimal(200), - (actual.first().zapEvent.event as LnZapEventInterface).amount(), + (actual.first().zapEvent.event as LnZapEvent).amount(), ) } @@ -67,9 +67,9 @@ class UserProfileZapsFeedFilterTest { pubkey: HexKey, amount: Int, ): Note { - val lnZapEvent = mockk() + val lnZapEvent = mockk() every { lnZapEvent.amount() } returns amount.toBigDecimal() - every { lnZapEvent.pubKey() } returns pubkey + every { lnZapEvent.pubKey } returns pubkey val zapNote = mockk() every { zapNote.event } returns lnZapEvent diff --git a/amethyst/src/test/java/com/vitorpamplona/amethyst/ui/actions/NewPostViewModelTest.kt b/amethyst/src/test/java/com/vitorpamplona/amethyst/ui/actions/NewPostViewModelTest.kt index 8db0d9fde..e683d8d8b 100644 --- a/amethyst/src/test/java/com/vitorpamplona/amethyst/ui/actions/NewPostViewModelTest.kt +++ b/amethyst/src/test/java/com/vitorpamplona/amethyst/ui/actions/NewPostViewModelTest.kt @@ -25,8 +25,8 @@ import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.events.TextNoteEvent +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent import io.mockk.MockKAnnotations import io.mockk.every import io.mockk.impl.annotations.MockK diff --git a/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/Constants.kt b/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/Constants.kt index 79878a561..6cc64322a 100644 --- a/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/Constants.kt +++ b/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/Constants.kt @@ -20,7 +20,7 @@ */ package com.vitorpamplona.ammolite.relays -import com.vitorpamplona.quartz.encoders.RelayUrlFormatter +import com.vitorpamplona.quartz.nip65RelayList.RelayUrlFormatter object Constants { val activeTypes = setOf(FeedType.FOLLOWS, FeedType.PRIVATE_DMS) diff --git a/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/Limits.kt b/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/Limits.kt index 65ed98590..16a91de50 100644 --- a/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/Limits.kt +++ b/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/Limits.kt @@ -22,7 +22,8 @@ package com.vitorpamplona.ammolite.relays import com.fasterxml.jackson.annotation.JsonProperty import com.vitorpamplona.ammolite.relays.filters.Filter -import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip13Pow.getPoWRank import com.vitorpamplona.quartz.utils.TimeUtils.now class Limits( diff --git a/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/NostrClient.kt b/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/NostrClient.kt index 24197edf9..be1b202b0 100644 --- a/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/NostrClient.kt +++ b/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/NostrClient.kt @@ -23,8 +23,7 @@ package com.vitorpamplona.ammolite.relays import android.util.Log import com.vitorpamplona.ammolite.service.checkNotInMainThread import com.vitorpamplona.ammolite.sockets.WebsocketBuilder -import com.vitorpamplona.quartz.events.Event -import com.vitorpamplona.quartz.events.EventInterface +import com.vitorpamplona.quartz.nip01Core.core.Event import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope @@ -144,7 +143,7 @@ class NostrClient( @OptIn(DelicateCoroutinesApi::class) suspend fun sendAndWaitForResponse( - signedEvent: EventInterface, + signedEvent: Event, relay: String? = null, forceProxy: Boolean = false, feedTypes: Set? = null, @@ -196,7 +195,7 @@ class NostrClient( message: String, relay: Relay, ) { - if (eventId == signedEvent.id()) { + if (eventId == signedEvent.id) { if (success) { result = true } @@ -243,7 +242,7 @@ class NostrClient( } fun sendIfExists( - signedEvent: EventInterface, + signedEvent: Event, connectedRelay: Relay, ) { checkNotInMainThread() @@ -254,7 +253,7 @@ class NostrClient( } fun sendSingle( - signedEvent: EventInterface, + signedEvent: Event, relayTemplate: RelaySetupInfoToConnect, onDone: (() -> Unit), ) { @@ -265,13 +264,13 @@ class NostrClient( } } - fun send(signedEvent: EventInterface) { + fun send(signedEvent: Event) { checkNotInMainThread() relayPool.send(signedEvent) } fun send( - signedEvent: EventInterface, + signedEvent: Event, relayList: List, ) { checkNotInMainThread() @@ -280,7 +279,7 @@ class NostrClient( } fun sendPrivately( - signedEvent: EventInterface, + signedEvent: Event, relayList: List, ) { checkNotInMainThread() @@ -375,7 +374,7 @@ class NostrClient( @OptIn(DelicateCoroutinesApi::class) override fun onBeforeSend( relay: Relay, - event: EventInterface, + event: Event, ) { GlobalScope.launch(Dispatchers.Default) { listeners.forEach { it.onBeforeSend(relay, event) } @@ -453,7 +452,7 @@ class NostrClient( open fun onBeforeSend( relay: Relay, - event: EventInterface, + event: Event, ) = Unit open fun onError( diff --git a/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/NostrDataSource.kt b/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/NostrDataSource.kt index b70ce6d92..46d759afb 100644 --- a/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/NostrDataSource.kt +++ b/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/NostrDataSource.kt @@ -22,7 +22,7 @@ package com.vitorpamplona.ammolite.relays import android.util.Log import com.vitorpamplona.ammolite.service.checkNotInMainThread -import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.utils.TimeUtils import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.DelicateCoroutinesApi diff --git a/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/Relay.kt b/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/Relay.kt index f1e8a1ef1..f60c83337 100644 --- a/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/Relay.kt +++ b/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/Relay.kt @@ -26,10 +26,10 @@ import com.vitorpamplona.ammolite.service.checkNotInMainThread import com.vitorpamplona.ammolite.sockets.WebSocket import com.vitorpamplona.ammolite.sockets.WebSocketListener import com.vitorpamplona.ammolite.sockets.WebsocketBuilder -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.events.Event -import com.vitorpamplona.quartz.events.EventInterface -import com.vitorpamplona.quartz.events.RelayAuthEvent +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper +import com.vitorpamplona.quartz.nip42RelayAuth.RelayAuthEvent import com.vitorpamplona.quartz.utils.TimeUtils import com.vitorpamplona.quartz.utils.bytesUsedInMemory import kotlinx.coroutines.CancellationException @@ -80,7 +80,7 @@ class Relay( private val authResponse = mutableMapOf() private val authChallengesSent = mutableSetOf() - private val outboxCache = mutableMapOf() + private val outboxCache = mutableMapOf() fun register(listener: Listener) { listeners = listeners.plus(listener) @@ -257,12 +257,12 @@ class Relay( } fun processNewRelayMessage(newMessage: String) { - val msgArray = Event.mapper.readTree(newMessage) + val msgArray = EventMapper.mapper.readTree(newMessage) when (val type = msgArray.get(0).asText()) { "EVENT" -> { val subscriptionId = msgArray.get(1).asText() - val event = Event.fromJson(msgArray.get(2)) + val event = EventMapper.fromJson(msgArray.get(2)) // Log.w("Relay", "Relay onEVENT ${event.kind} $url, $subscriptionId ${msgArray.get(2)}") @@ -452,7 +452,7 @@ class Relay( } // This function sends the event regardless of the relay being write or not. - fun sendOverride(signedEvent: EventInterface) { + fun sendOverride(signedEvent: Event) { checkNotInMainThread() listeners.forEach { listener -> @@ -466,7 +466,7 @@ class Relay( } } - fun send(signedEvent: EventInterface) { + fun send(signedEvent: Event) { checkNotInMainThread() listeners.forEach { listener -> @@ -498,9 +498,9 @@ class Relay( } } - private fun sendEvent(signedEvent: EventInterface) { + private fun sendEvent(signedEvent: Event) { synchronized(outboxCache) { - outboxCache.put(signedEvent.id(), signedEvent) + outboxCache.put(signedEvent.id, signedEvent) } if (isConnected()) { @@ -618,7 +618,7 @@ class Relay( fun onBeforeSend( relay: Relay, - event: EventInterface, + event: Event, ) } } diff --git a/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/RelayBriefInfoCache.kt b/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/RelayBriefInfoCache.kt index 51757c1a9..a3de6adff 100644 --- a/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/RelayBriefInfoCache.kt +++ b/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/RelayBriefInfoCache.kt @@ -22,7 +22,7 @@ package com.vitorpamplona.ammolite.relays import android.util.LruCache import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.RelayUrlFormatter +import com.vitorpamplona.quartz.nip65RelayList.RelayUrlFormatter object RelayBriefInfoCache { val cache = LruCache(50) diff --git a/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/RelayPool.kt b/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/RelayPool.kt index fe9a5e09f..8740ee9b1 100644 --- a/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/RelayPool.kt +++ b/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/RelayPool.kt @@ -22,8 +22,7 @@ package com.vitorpamplona.ammolite.relays import androidx.compose.runtime.Immutable import com.vitorpamplona.ammolite.service.checkNotInMainThread -import com.vitorpamplona.quartz.events.Event -import com.vitorpamplona.quartz.events.EventInterface +import com.vitorpamplona.quartz.nip01Core.core.Event import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.channels.BufferOverflow @@ -121,16 +120,16 @@ class RelayPool : Relay.Listener { fun sendToSelectedRelays( list: List, - signedEvent: EventInterface, + signedEvent: Event, ) { list.forEach { relay -> relays.filter { it.url == relay.url }.forEach { it.sendOverride(signedEvent) } } } - fun send(signedEvent: EventInterface) { + fun send(signedEvent: Event) { relays.forEach { it.send(signedEvent) } } - fun sendOverride(signedEvent: EventInterface) { + fun sendOverride(signedEvent: Event) { relays.forEach { it.sendOverride(signedEvent) } } @@ -205,7 +204,7 @@ class RelayPool : Relay.Listener { fun onBeforeSend( relay: Relay, - event: EventInterface, + event: Event, ) fun onError( @@ -277,7 +276,7 @@ class RelayPool : Relay.Listener { override fun onBeforeSend( relay: Relay, - event: EventInterface, + event: Event, ) { listeners.forEach { it.onBeforeSend(relay, event) } } diff --git a/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/filters/Filter.kt b/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/filters/Filter.kt index af776ae02..4aa4da626 100644 --- a/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/filters/Filter.kt +++ b/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/filters/Filter.kt @@ -20,7 +20,7 @@ */ package com.vitorpamplona.ammolite.relays.filters -import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.nip01Core.core.Event class Filter( val ids: List? = null, diff --git a/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/filters/FilterMatcher.kt b/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/filters/FilterMatcher.kt index 3bc52f781..d980be70b 100644 --- a/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/filters/FilterMatcher.kt +++ b/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/filters/FilterMatcher.kt @@ -20,7 +20,7 @@ */ package com.vitorpamplona.ammolite.relays.filters -import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.nip01Core.core.Event object FilterMatcher { fun match( diff --git a/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/filters/FilterSerializer.kt b/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/filters/FilterSerializer.kt index 700198b6b..d83340c71 100644 --- a/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/filters/FilterSerializer.kt +++ b/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/filters/FilterSerializer.kt @@ -20,8 +20,9 @@ */ package com.vitorpamplona.ammolite.relays.filters +import com.fasterxml.jackson.databind.node.JsonNodeFactory import com.fasterxml.jackson.databind.node.ObjectNode -import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper object FilterSerializer { fun toJsonObject( @@ -34,7 +35,7 @@ object FilterSerializer { limit: Int? = null, search: String? = null, ): ObjectNode { - val factory = Event.mapper.nodeFactory + val factory = JsonNodeFactory.instance return factory.objectNode().apply { ids?.run { replace( @@ -79,7 +80,7 @@ object FilterSerializer { limit: Int? = null, search: String? = null, ): String = - Event.mapper.writeValueAsString( + EventMapper.mapper.writeValueAsString( toJsonObject( ids, authors, diff --git a/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/filters/IPerRelayFilter.kt b/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/filters/IPerRelayFilter.kt index 7599ea51d..23affce82 100644 --- a/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/filters/IPerRelayFilter.kt +++ b/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/filters/IPerRelayFilter.kt @@ -20,7 +20,7 @@ */ package com.vitorpamplona.ammolite.relays.filters -import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.nip01Core.core.Event interface IPerRelayFilter { fun toJson(forRelay: String): String diff --git a/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/filters/SinceAuthorPerRelayFilter.kt b/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/filters/SinceAuthorPerRelayFilter.kt index 42e3304a8..40cce89f2 100644 --- a/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/filters/SinceAuthorPerRelayFilter.kt +++ b/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/filters/SinceAuthorPerRelayFilter.kt @@ -20,8 +20,10 @@ */ package com.vitorpamplona.ammolite.relays.filters -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.events.Event +import com.fasterxml.jackson.databind.node.JsonNodeFactory +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper /** * This is a nostr filter with per-relay authors list and since parameters @@ -49,7 +51,7 @@ class SinceAuthorPerRelayFilter( ) = FilterMatcher.match(event, ids, authors?.get(forRelay), kinds, tags, since?.get(forRelay)?.time, until) override fun toDebugJson(): String { - val factory = Event.mapper.nodeFactory + val factory = JsonNodeFactory.instance val obj = FilterSerializer.toJsonObject(ids, null, kinds, tags, null, until, limit, search) authors?.run { if (isNotEmpty()) { @@ -70,6 +72,6 @@ class SinceAuthorPerRelayFilter( obj.put("since", jsonObjectSince) } } - return Event.mapper.writeValueAsString(obj) + return EventMapper.mapper.writeValueAsString(obj) } } diff --git a/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/filters/SincePerRelayFilter.kt b/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/filters/SincePerRelayFilter.kt index 8d5a5c5c9..e81faeefd 100644 --- a/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/filters/SincePerRelayFilter.kt +++ b/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/filters/SincePerRelayFilter.kt @@ -20,7 +20,9 @@ */ package com.vitorpamplona.ammolite.relays.filters -import com.vitorpamplona.quartz.events.Event +import com.fasterxml.jackson.databind.node.JsonNodeFactory +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper /** * This is a nostr filter with per-relay authors list and since parameters @@ -45,7 +47,7 @@ class SincePerRelayFilter( ) = FilterMatcher.match(event, ids, authors, kinds, tags, since?.get(forRelay)?.time, until) override fun toDebugJson(): String { - val factory = Event.mapper.nodeFactory + val factory = JsonNodeFactory.instance val obj = FilterSerializer.toJsonObject(ids, authors, kinds, tags, null, until, limit, search) since?.run { @@ -57,6 +59,6 @@ class SincePerRelayFilter( obj.put("since", jsonObjectSince) } } - return Event.mapper.writeValueAsString(obj) + return EventMapper.toJson(obj) } } diff --git a/benchmark/src/androidTest/java/com/vitorpamplona/amethyst/benchmark/RichTextParserBenchmark.kt b/benchmark/src/androidTest/java/com/vitorpamplona/amethyst/benchmark/RichTextParserBenchmark.kt index d0af6b68c..1a2b38456 100644 --- a/benchmark/src/androidTest/java/com/vitorpamplona/amethyst/benchmark/RichTextParserBenchmark.kt +++ b/benchmark/src/androidTest/java/com/vitorpamplona/amethyst/benchmark/RichTextParserBenchmark.kt @@ -29,8 +29,8 @@ import com.vitorpamplona.amethyst.commons.richtext.HashTagSegment import com.vitorpamplona.amethyst.commons.richtext.ImageSegment import com.vitorpamplona.amethyst.commons.richtext.LinkSegment import com.vitorpamplona.amethyst.commons.richtext.RichTextParser -import com.vitorpamplona.quartz.events.EmptyTagList -import com.vitorpamplona.quartz.events.ImmutableListOfLists +import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList +import com.vitorpamplona.quartz.nip02FollowList.ImmutableListOfLists import junit.framework.TestCase.assertNull import junit.framework.TestCase.assertTrue import org.junit.Rule diff --git a/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/BechBenchmark.kt b/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/BechBenchmark.kt index 0bd3b3f74..ee5df1d89 100644 --- a/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/BechBenchmark.kt +++ b/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/BechBenchmark.kt @@ -23,9 +23,9 @@ package com.vitorpamplona.quartz.benchmark import androidx.benchmark.junit4.BenchmarkRule import androidx.benchmark.junit4.measureRepeated import androidx.test.ext.junit.runners.AndroidJUnit4 -import com.vitorpamplona.quartz.encoders.Hex -import com.vitorpamplona.quartz.encoders.bechToBytes -import com.vitorpamplona.quartz.encoders.toNpub +import com.vitorpamplona.quartz.crypto.Hex +import com.vitorpamplona.quartz.nip19Bech32Entities.bech32.bechToBytes +import com.vitorpamplona.quartz.nip19Bech32Entities.toNpub import junit.framework.TestCase.assertEquals import org.junit.Rule import org.junit.Test diff --git a/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/CacheBenchmark.kt b/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/CacheBenchmark.kt index a72b0f084..447e7824d 100644 --- a/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/CacheBenchmark.kt +++ b/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/CacheBenchmark.kt @@ -26,8 +26,9 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation import com.fasterxml.jackson.module.kotlin.readValue import com.vitorpamplona.amethyst.commons.data.LargeCache -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper import org.junit.Assert.assertTrue import org.junit.Rule import org.junit.Test @@ -43,7 +44,7 @@ open class BaseCacheBenchmark { // This file includes duplicates val fullDBInputStream = getInstrumentation().context.assets.open("nostr_vitor_startup_data.json") - return Event.mapper.readValue>( + return EventMapper.mapper.readValue>( GZIPInputStream(fullDBInputStream), ) } diff --git a/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/EventBenchmark.kt b/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/EventBenchmark.kt index d1973390b..370d9d0d9 100644 --- a/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/EventBenchmark.kt +++ b/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/EventBenchmark.kt @@ -23,8 +23,9 @@ package com.vitorpamplona.quartz.benchmark import androidx.benchmark.junit4.BenchmarkRule import androidx.benchmark.junit4.measureRepeated import androidx.test.ext.junit.runners.AndroidJUnit4 -import com.vitorpamplona.quartz.events.Event -import com.vitorpamplona.quartz.events.EventFactory +import com.vitorpamplona.quartz.nip01Core.EventFactory +import com.vitorpamplona.quartz.nip01Core.hasValidSignature +import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper import com.vitorpamplona.quartz.utils.TimeUtils import junit.framework.TestCase.assertTrue import org.junit.Rule @@ -43,20 +44,20 @@ class EventBenchmark { @Test fun parseREQString() { - benchmarkRule.measureRepeated { Event.mapper.readTree(reqResponseEvent) } + benchmarkRule.measureRepeated { EventMapper.mapper.readTree(reqResponseEvent) } } @Test fun parseEvent() { - val msg = Event.mapper.readTree(reqResponseEvent) + val msg = EventMapper.mapper.readTree(reqResponseEvent) - benchmarkRule.measureRepeated { Event.fromJson(msg[2]) } + benchmarkRule.measureRepeated { EventMapper.fromJson(msg[2]) } } @Test fun checkSignature() { - val msg = Event.mapper.readTree(reqResponseEvent) - val event = Event.fromJson(msg[2]) + val msg = EventMapper.mapper.readTree(reqResponseEvent) + val event = EventMapper.fromJson(msg[2]) benchmarkRule.measureRepeated { // Should pass assertTrue(event.hasValidSignature()) diff --git a/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/EventHasherBenchmark.kt b/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/EventHasherBenchmark.kt index 7f65b048b..866bcc55c 100644 --- a/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/EventHasherBenchmark.kt +++ b/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/EventHasherBenchmark.kt @@ -23,7 +23,10 @@ package com.vitorpamplona.quartz.benchmark import androidx.benchmark.junit4.BenchmarkRule import androidx.benchmark.junit4.measureRepeated import androidx.test.ext.junit.runners.AndroidJUnit4 -import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.generateId +import com.vitorpamplona.quartz.nip01Core.hasCorrectIDHash +import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper import junit.framework.TestCase.assertNotNull import junit.framework.TestCase.assertTrue import org.junit.Rule @@ -42,7 +45,7 @@ class EventHasherBenchmark { @Test fun checkIDHashKind1WihtoutTags() { - val event = Event.fromJson(Event.mapper.readTree(reqResponseEvent)) + val event = EventMapper.fromJson(EventMapper.mapper.readTree(reqResponseEvent)) benchmarkRule.measureRepeated { // Should pass diff --git a/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/EventSerializerBenchmark.kt b/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/EventSerializerBenchmark.kt index f3f2d1c9d..f02909288 100644 --- a/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/EventSerializerBenchmark.kt +++ b/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/EventSerializerBenchmark.kt @@ -24,8 +24,8 @@ import androidx.benchmark.junit4.BenchmarkRule import androidx.benchmark.junit4.measureRepeated import androidx.test.ext.junit.runners.AndroidJUnit4 import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper -import com.vitorpamplona.quartz.encoders.Nip01Serializer -import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.experimental.Nip01Serializer import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith diff --git a/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/GiftWrapBenchmark.kt b/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/GiftWrapBenchmark.kt index 3f3ae0aaf..f1dc8d6b2 100644 --- a/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/GiftWrapBenchmark.kt +++ b/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/GiftWrapBenchmark.kt @@ -25,11 +25,12 @@ import androidx.benchmark.junit4.measureRepeated import androidx.test.ext.junit.runners.AndroidJUnit4 import com.vitorpamplona.quartz.crypto.CryptoUtils import com.vitorpamplona.quartz.crypto.KeyPair -import com.vitorpamplona.quartz.events.Event -import com.vitorpamplona.quartz.events.GiftWrapEvent -import com.vitorpamplona.quartz.events.NIP17Factory -import com.vitorpamplona.quartz.events.SealedGossipEvent -import com.vitorpamplona.quartz.signers.NostrSignerInternal +import com.vitorpamplona.quartz.nip01Core.checkSignature +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerInternal +import com.vitorpamplona.quartz.nip17Dm.NIP17Factory +import com.vitorpamplona.quartz.nip59Giftwrap.GiftWrapEvent +import com.vitorpamplona.quartz.nip59Giftwrap.SealedGossipEvent import junit.framework.TestCase import org.junit.Assert import org.junit.Assert.assertTrue diff --git a/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/GiftWrapReceivingBenchmark.kt b/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/GiftWrapReceivingBenchmark.kt index 21a27914a..4426e7dac 100644 --- a/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/GiftWrapReceivingBenchmark.kt +++ b/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/GiftWrapReceivingBenchmark.kt @@ -25,14 +25,16 @@ import androidx.benchmark.junit4.measureRepeated import androidx.test.ext.junit.runners.AndroidJUnit4 import com.vitorpamplona.quartz.crypto.CryptoUtils import com.vitorpamplona.quartz.crypto.KeyPair -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 com.vitorpamplona.quartz.signers.NostrSigner -import com.vitorpamplona.quartz.signers.NostrSignerInternal +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.hasCorrectIDHash +import com.vitorpamplona.quartz.nip01Core.hasVerifiedSignature +import com.vitorpamplona.quartz.nip01Core.hexToByteArray +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerInternal +import com.vitorpamplona.quartz.nip17Dm.ChatMessageEvent +import com.vitorpamplona.quartz.nip59Giftwrap.GiftWrapEvent +import com.vitorpamplona.quartz.nip59Giftwrap.Gossip +import com.vitorpamplona.quartz.nip59Giftwrap.SealedGossipEvent import junit.framework.TestCase.assertNotNull import junit.framework.TestCase.assertTrue import org.junit.Rule diff --git a/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/GiftWrapSigningBenchmark.kt b/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/GiftWrapSigningBenchmark.kt index 294f71525..87880403b 100644 --- a/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/GiftWrapSigningBenchmark.kt +++ b/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/GiftWrapSigningBenchmark.kt @@ -24,10 +24,10 @@ import androidx.benchmark.junit4.BenchmarkRule import androidx.benchmark.junit4.measureRepeated import androidx.test.ext.junit.runners.AndroidJUnit4 import com.vitorpamplona.quartz.crypto.KeyPair -import com.vitorpamplona.quartz.events.ChatMessageEvent -import com.vitorpamplona.quartz.events.GiftWrapEvent -import com.vitorpamplona.quartz.events.SealedGossipEvent -import com.vitorpamplona.quartz.signers.NostrSignerInternal +import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerInternal +import com.vitorpamplona.quartz.nip17Dm.ChatMessageEvent +import com.vitorpamplona.quartz.nip59Giftwrap.GiftWrapEvent +import com.vitorpamplona.quartz.nip59Giftwrap.SealedGossipEvent import junit.framework.TestCase.assertTrue import org.junit.Rule import org.junit.Test diff --git a/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/HexBenchmark.kt b/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/HexBenchmark.kt index 68266efd8..74b52f9c2 100644 --- a/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/HexBenchmark.kt +++ b/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/HexBenchmark.kt @@ -23,7 +23,7 @@ package com.vitorpamplona.quartz.benchmark import androidx.benchmark.junit4.BenchmarkRule import androidx.benchmark.junit4.measureRepeated import androidx.test.ext.junit.runners.AndroidJUnit4 -import com.vitorpamplona.quartz.encoders.HexValidator +import com.vitorpamplona.quartz.crypto.Hex import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @@ -46,7 +46,7 @@ class HexBenchmark { @Test fun hexDecodeOurs() { r.measureRepeated { - com.vitorpamplona.quartz.encoders.Hex + Hex .decode(hex) } } @@ -54,7 +54,7 @@ class HexBenchmark { @Test fun hexEncodeOurs() { r.measureRepeated { - com.vitorpamplona.quartz.encoders.Hex + Hex .encode(bytes) } } @@ -89,6 +89,6 @@ class HexBenchmark { @Test fun isHex() { - r.measureRepeated { HexValidator.isHex(hex) } + r.measureRepeated { Hex.isHex(hex) } } } diff --git a/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/LargeCacheBenchmark.kt b/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/LargeCacheBenchmark.kt index 37c25c573..90ce0661b 100644 --- a/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/LargeCacheBenchmark.kt +++ b/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/LargeCacheBenchmark.kt @@ -26,8 +26,9 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation import com.fasterxml.jackson.module.kotlin.readValue import com.vitorpamplona.amethyst.commons.data.LargeCache -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper import org.junit.Assert.assertTrue import org.junit.Rule import org.junit.Test @@ -41,7 +42,7 @@ open class BaseLargeCacheBenchmark { // This file includes duplicates val fullDBInputStream = getInstrumentation().context.assets.open("nostr_vitor_startup_data.json") - return Event.mapper.readValue>( + return EventMapper.mapper.readValue>( GZIPInputStream(fullDBInputStream), ) } diff --git a/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/Sha256Benchmark.kt b/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/Sha256Benchmark.kt index 068966c54..1c99033e3 100644 --- a/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/Sha256Benchmark.kt +++ b/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/Sha256Benchmark.kt @@ -23,9 +23,9 @@ package com.vitorpamplona.quartz.benchmark import androidx.benchmark.junit4.BenchmarkRule import androidx.benchmark.junit4.measureRepeated import androidx.test.ext.junit.runners.AndroidJUnit4 -import com.vitorpamplona.quartz.crypto.nip01.EventHasher import com.vitorpamplona.quartz.crypto.sha256Hash -import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.nip01Core.EventHasher +import com.vitorpamplona.quartz.nip01Core.core.Event import junit.framework.TestCase.assertNotNull import org.junit.Rule import org.junit.Test diff --git a/commons/src/androidTest/java/com/vitorpamplona/amethyst/commons/preview/BlurhashTest.kt b/commons/src/androidTest/java/com/vitorpamplona/amethyst/commons/preview/BlurhashTest.kt index cc4b1c848..c533ffee9 100644 --- a/commons/src/androidTest/java/com/vitorpamplona/amethyst/commons/preview/BlurhashTest.kt +++ b/commons/src/androidTest/java/com/vitorpamplona/amethyst/commons/preview/BlurhashTest.kt @@ -95,8 +95,8 @@ class BlurhashTest { @Test fun testLorikeet() { - println("${load("/lorikeet.jpg").toBlurhash()}") - assertEquals("rFDcT@_LNs#p%Mt*nNM}E2VrIVX6VuV@WUo{xtjv9]RRw[OXS}rrWFX9w{OZxaxWNHX4n\$M}NGaK%0RkM}w{xto|jFs,Sh-Tj]bcwJnjXSxZs.NI", load("/lorikeet.jpg").toBlurhash()) + val blurhash = load("/lorikeet.jpg").toBlurhash() + assertEquals("rFDcT@_LNs#p%Mt*nNM}E2VrIVX6VuV@WUo{xtjv9]RRw[OXS}rrWFX9w{OZxaxWNHX4n\$M}NGaK%0RkM}w{xto|jFs,Sh-Tj]bcwJnjXSxZs.NI", blurhash) } private fun load(filename: String): Bitmap = diff --git a/commons/src/androidTest/java/com/vitorpamplona/amethyst/commons/richtext/RichTextParserTest.kt b/commons/src/androidTest/java/com/vitorpamplona/amethyst/commons/richtext/RichTextParserTest.kt index 81e444c65..6e3e7d0f0 100644 --- a/commons/src/androidTest/java/com/vitorpamplona/amethyst/commons/richtext/RichTextParserTest.kt +++ b/commons/src/androidTest/java/com/vitorpamplona/amethyst/commons/richtext/RichTextParserTest.kt @@ -21,8 +21,8 @@ package com.vitorpamplona.amethyst.commons.richtext import androidx.test.ext.junit.runners.AndroidJUnit4 -import com.vitorpamplona.quartz.events.EmptyTagList -import com.vitorpamplona.quartz.events.ImmutableListOfLists +import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList +import com.vitorpamplona.quartz.nip02FollowList.ImmutableListOfLists import org.junit.Test import org.junit.runner.RunWith diff --git a/commons/src/main/java/com/vitorpamplona/amethyst/commons/data/DeletionIndex.kt b/commons/src/main/java/com/vitorpamplona/amethyst/commons/data/DeletionIndex.kt index f8ec1ac48..6bb41330a 100644 --- a/commons/src/main/java/com/vitorpamplona/amethyst/commons/data/DeletionIndex.kt +++ b/commons/src/main/java/com/vitorpamplona/amethyst/commons/data/DeletionIndex.kt @@ -20,10 +20,10 @@ */ package com.vitorpamplona.amethyst.commons.data -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.events.AddressableEvent -import com.vitorpamplona.quartz.events.DeletionEvent -import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.AddressableEvent +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip09Deletions.DeletionEvent class DeletionIndex { data class DeletionRequest( diff --git a/commons/src/main/java/com/vitorpamplona/amethyst/commons/richtext/MediaContentModels.kt b/commons/src/main/java/com/vitorpamplona/amethyst/commons/richtext/MediaContentModels.kt index e7dee4dba..15255f8cd 100644 --- a/commons/src/main/java/com/vitorpamplona/amethyst/commons/richtext/MediaContentModels.kt +++ b/commons/src/main/java/com/vitorpamplona/amethyst/commons/richtext/MediaContentModels.kt @@ -21,7 +21,7 @@ package com.vitorpamplona.amethyst.commons.richtext import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.Dimension +import com.vitorpamplona.quartz.nip94FileMetadata.Dimension import java.io.File @Immutable diff --git a/commons/src/main/java/com/vitorpamplona/amethyst/commons/richtext/RichTextParser.kt b/commons/src/main/java/com/vitorpamplona/amethyst/commons/richtext/RichTextParser.kt index 36ac18a77..60b6c1a9a 100644 --- a/commons/src/main/java/com/vitorpamplona/amethyst/commons/richtext/RichTextParser.kt +++ b/commons/src/main/java/com/vitorpamplona/amethyst/commons/richtext/RichTextParser.kt @@ -24,12 +24,12 @@ import android.util.Log import android.util.Patterns import com.linkedin.urls.detection.UrlDetector import com.linkedin.urls.detection.UrlDetectorOptions -import com.vitorpamplona.quartz.encoders.Dimension -import com.vitorpamplona.quartz.encoders.Nip30CustomEmoji -import com.vitorpamplona.quartz.encoders.Nip54InlineMetadata -import com.vitorpamplona.quartz.encoders.Nip92MediaAttachments -import com.vitorpamplona.quartz.events.FileHeaderEvent -import com.vitorpamplona.quartz.events.ImmutableListOfLists +import com.vitorpamplona.quartz.experimental.inlineMetadata.Nip54InlineMetadata +import com.vitorpamplona.quartz.nip02FollowList.ImmutableListOfLists +import com.vitorpamplona.quartz.nip30CustomEmoji.CustomEmoji +import com.vitorpamplona.quartz.nip92IMeta.Nip92MediaAttachments +import com.vitorpamplona.quartz.nip94FileMetadata.Dimension +import com.vitorpamplona.quartz.nip94FileMetadata.FileHeaderEvent import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList @@ -135,7 +135,7 @@ class RichTextParser { val imagesForPager = urlSet.mapNotNull { fullUrl -> createMediaContent(fullUrl, tags, content, callbackUri) }.associateBy { it.url } - val emojiMap = Nip30CustomEmoji.createEmojiMap(tags) + val emojiMap = CustomEmoji.createEmojiMap(tags) val segments = findTextSegments(content, imagesForPager.keys, urlSet, emojiMap, tags) @@ -238,7 +238,7 @@ class RichTextParser { if (urls.contains(word)) return LinkSegment(word) - if (Nip30CustomEmoji.fastMightContainEmoji(word, emojis) && emojis.any { word.contains(it.key) }) return EmojiSegment(word) + if (CustomEmoji.fastMightContainEmoji(word, emojis) && emojis.any { word.contains(it.key) }) return EmojiSegment(word) if (word.startsWith("lnbc", true)) return InvoiceSegment(word) diff --git a/commons/src/main/java/com/vitorpamplona/amethyst/commons/robohash/RobohashAssembler.kt b/commons/src/main/java/com/vitorpamplona/amethyst/commons/robohash/RobohashAssembler.kt index 10b89ae2f..9406a1b5b 100644 --- a/commons/src/main/java/com/vitorpamplona/amethyst/commons/robohash/RobohashAssembler.kt +++ b/commons/src/main/java/com/vitorpamplona/amethyst/commons/robohash/RobohashAssembler.kt @@ -86,8 +86,7 @@ import com.vitorpamplona.amethyst.commons.robohash.parts.mouth7Happy import com.vitorpamplona.amethyst.commons.robohash.parts.mouth8Buttons import com.vitorpamplona.amethyst.commons.robohash.parts.mouth9Closed import com.vitorpamplona.quartz.crypto.CryptoUtils -import com.vitorpamplona.quartz.encoders.Hex -import com.vitorpamplona.quartz.encoders.HexValidator +import com.vitorpamplona.quartz.crypto.Hex val Black = SolidColor(Color.Black) val Gray = SolidColor(Color(0xFF6d6e70)) @@ -165,7 +164,7 @@ class RobohashAssembler { isLightTheme: Boolean, ): ImageVector { val hash = - if (HexValidator.isHex(msg) && msg.length > 10) { + if (Hex.isHex(msg) && msg.length > 10) { Hex.decode(msg) } else { Log.w("Robohash", "$msg is not a hex") diff --git a/quartz/consumer-rules.pro b/quartz/consumer-rules.pro index c458d7fb7..5dc1d419e 100644 --- a/quartz/consumer-rules.pro +++ b/quartz/consumer-rules.pro @@ -58,11 +58,4 @@ } # JSON parsing --keep class com.vitorpamplona.quartz.crypto.** { *; } --keep class com.vitorpamplona.quartz.encoders.** { *; } --keep class com.vitorpamplona.quartz.events.** { *; } --keep class com.vitorpamplona.quartz.signers.** { *; } --keep class com.vitorpamplona.quartz.utils.** { *; } - --keep class com.vitorpamplona.amethyst.model.** { *; } --keep class com.vitorpamplona.amethyst.service.** { *; } \ No newline at end of file +-keep class com.vitorpamplona.quartz.** { *; } \ No newline at end of file diff --git a/quartz/proguard-rules.pro b/quartz/proguard-rules.pro index 8aec7f5b1..5dc1d419e 100644 --- a/quartz/proguard-rules.pro +++ b/quartz/proguard-rules.pro @@ -58,12 +58,4 @@ } # JSON parsing --keep class com.vitorpamplona.quartz.crypto.** { *; } --keep class com.vitorpamplona.quartz.encoders.** { *; } --keep class com.vitorpamplona.quartz.events.** { *; } --keep class com.vitorpamplona.quartz.signers.** { *; } --keep class com.vitorpamplona.quartz.utils.** { *; } --keep class com.vitorpamplona.quartz.ots.** { *; } - --keep class com.vitorpamplona.amethyst.model.** { *; } --keep class com.vitorpamplona.amethyst.service.** { *; } \ No newline at end of file +-keep class com.vitorpamplona.quartz.** { *; } \ No newline at end of file diff --git a/quartz/src/androidTest/java/com/vitorpamplona/quartz/bloom/BloomFilter.kt b/quartz/src/androidTest/java/com/vitorpamplona/quartz/bloom/BloomFilter.kt index 805816dd6..f22011f78 100644 --- a/quartz/src/androidTest/java/com/vitorpamplona/quartz/bloom/BloomFilter.kt +++ b/quartz/src/androidTest/java/com/vitorpamplona/quartz/bloom/BloomFilter.kt @@ -22,8 +22,8 @@ package com.vitorpamplona.quartz.bloom import androidx.test.ext.junit.runners.AndroidJUnit4 import com.vitorpamplona.quartz.crypto.CryptoUtils -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.hexToByteArray +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.hexToByteArray import junit.framework.TestCase.assertEquals import junit.framework.TestCase.assertFalse import junit.framework.TestCase.assertTrue @@ -134,7 +134,7 @@ class BloomFilterTest { val bloomFilter = BloomFilter.decode(testEncoded) var failureCounter = 0 - for (seed in 0..10000000) { + for (seed in 0..1000000) { if (bloomFilter.mightContains(CryptoUtils.pubkeyCreate(CryptoUtils.privkeyCreate()))) { failureCounter++ } diff --git a/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/CryptoUtilsTest.kt b/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/CryptoUtilsTest.kt index 840a7068a..b62c4115b 100644 --- a/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/CryptoUtilsTest.kt +++ b/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/CryptoUtilsTest.kt @@ -21,8 +21,8 @@ package com.vitorpamplona.quartz.crypto import androidx.test.ext.junit.runners.AndroidJUnit4 -import com.vitorpamplona.quartz.encoders.hexToByteArray -import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.nip01Core.hexToByteArray +import com.vitorpamplona.quartz.nip01Core.toHexKey import org.junit.Assert.assertEquals import org.junit.Test import org.junit.runner.RunWith diff --git a/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/LargeDBSignatureCheck.kt b/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/LargeDBSignatureCheck.kt index 8e47f9c92..1ed11d63d 100644 --- a/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/LargeDBSignatureCheck.kt +++ b/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/LargeDBSignatureCheck.kt @@ -23,7 +23,9 @@ package com.vitorpamplona.quartz.crypto 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 com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.hasValidSignature +import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper import junit.framework.TestCase.assertEquals import junit.framework.TestCase.assertTrue import kotlinx.coroutines.runBlocking @@ -40,7 +42,7 @@ class LargeDBSignatureCheck { val fullDBInputStream = getInstrumentation().context.assets.open("nostr_vitor_short.json") val eventArray = - Event.mapper.readValue>( + EventMapper.mapper.readValue>( InputStreamReader(fullDBInputStream), ) as List @@ -60,7 +62,7 @@ class LargeDBSignatureCheck { val fullDBInputStream = getInstrumentation().context.assets.open("nostr_vitor_startup_data.json") val eventArray = - Event.mapper.readValue>( + EventMapper.mapper.readValue>( GZIPInputStream(fullDBInputStream), ) as List diff --git a/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/nip01/Nip01Test.kt b/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/nip01/Nip01Test.kt index db3b11992..6e31fcaf6 100644 --- a/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/nip01/Nip01Test.kt +++ b/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/nip01/Nip01Test.kt @@ -22,8 +22,9 @@ package com.vitorpamplona.quartz.crypto.nip01 import androidx.test.ext.junit.runners.AndroidJUnit4 import com.vitorpamplona.quartz.crypto.sha256Hash -import com.vitorpamplona.quartz.encoders.hexToByteArray -import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.nip01Core.Nip01 +import com.vitorpamplona.quartz.nip01Core.hexToByteArray +import com.vitorpamplona.quartz.nip01Core.toHexKey import fr.acinq.secp256k1.Secp256k1 import org.junit.Assert.assertEquals import org.junit.Assert.assertNotEquals diff --git a/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/nip04/Nip04Test.kt b/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/nip04/Nip04Test.kt index 1564cc46c..eac63bae5 100644 --- a/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/nip04/Nip04Test.kt +++ b/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/nip04/Nip04Test.kt @@ -20,9 +20,10 @@ */ package com.vitorpamplona.quartz.crypto.nip04 -import com.vitorpamplona.quartz.crypto.nip01.Nip01 -import com.vitorpamplona.quartz.encoders.hexToByteArray -import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.nip01Core.Nip01 +import com.vitorpamplona.quartz.nip01Core.hexToByteArray +import com.vitorpamplona.quartz.nip01Core.toHexKey +import com.vitorpamplona.quartz.nip04Dm.Nip04 import fr.acinq.secp256k1.Secp256k1 import junit.framework.TestCase.assertEquals import junit.framework.TestCase.assertTrue @@ -91,7 +92,9 @@ class Nip04Test { fun isNIP04Encode() { assertTrue(Nip04.isNIP04("Xj/oZZolaItdyQ5v7xYFpA==?iv=+a6zagBp+mr5m1aFbHQ8lA==")) assertTrue(Nip04.isNIP04("zJxfaJ32rN5Dg1ODjOlEew==?iv=EV5bUjcc4OX2Km/zPp4ndQ==")) - assertTrue(Nip04.isNIP04("6f8dMstm+udOu7yipSn33orTmwQpWbtfuY95NH+eTU1kArysWJIDkYgI2D25EAGIDJsNd45jOJ2NbVOhFiL3ZP/NWsTwXokk34iyHyA/lkjzugQ1bHXoMD1fP/Ay4hB4al1NHb8HXHKZaxPrErwdRDb8qa/I6dXb/1xxyVvNQBHHvmsM5yIFaPwnCN1DZqXf2KbTA/Ekz7Hy+7R+Sy3TXLQDFpWYqykppkXc7Fs0qSuPRyxz5+anuN0dxZa9GTwTEnBrZPbthKkNRrvZMdTGJ6WumOh9aUq8OJJWy9aOgsXvs7qjN1UqcCqQqYaVnEOhCaqWNDsVtsFrVDj+SaLIBvCiomwF4C4nIgngJ5I69tx0UNI0q+ZnvOGQZ7m1PpW2NYP7Yw43HJNdeUEQAmdCPnh/PJwzLTnIxHmQU7n7SPlMdV0SFa6H8y2HHvex697GAkyE5t8c2uO24OnqIwF1tR3blIqXzTSRl0GA6QvrSj2p4UtnWjvF7xT7RiIEyTtgU/AsihTrXyXzWWZaIBJogpgw6erlZqWjCH7sZy/WoGYEiblobOAqMYxax6vRbeuGtoYksr/myX+x9rfLrYuoDRTw4woXOLmMrrj+Mf0TbAgc3SjdkqdsPU1553rlSqIEZXuFgoWmxvVQDtekgTYyS97G81TDSK9nTJT5ilku8NVq2LgtBXGwsNIw/xekcOUzJke3kpnFPutNaexR1VF3ohIuqRKYRGcd8ADJP2lfwMcaGRiplAmFoaVS1YUhQwYFNq9rMLf7YauRGV4BJg/t9srdGxf5RoKCvRo+XM/nLxxysTR9MVaEP/3lDqjwChMxs+eWfLHE5vRWV8hUEqdrWNZV29gsx5nQpzJ4PARGZVu310pQzc6JAlc2XAhhFk6RamkYJnmCSMnb/RblzIATBi2kNrCVAlaXIon188inB62rEpZGPkRIP7PUfu27S/elLQHBHeGDsxOXsBRo1gl3te+raoBHsxo6zvRnYbwdAQa5taDE63eh+fT6kFI+xYmXNAQkU8Dp0MVhEh4JQI06Ni/AKrvYpC95TXXIphZcF+/Pv/vaGkhG2X9S3uhugwWK?iv=2vWkOQQi0WynNJz/aZ4k2g==")) + assertTrue( + Nip04.isNIP04("6f8dMstm+udOu7yipSn33orTmwQpWbtfuY95NH+eTU1kArysWJIDkYgI2D25EAGIDJsNd45jOJ2NbVOhFiL3ZP/NWsTwXokk34iyHyA/lkjzugQ1bHXoMD1fP/Ay4hB4al1NHb8HXHKZaxPrErwdRDb8qa/I6dXb/1xxyVvNQBHHvmsM5yIFaPwnCN1DZqXf2KbTA/Ekz7Hy+7R+Sy3TXLQDFpWYqykppkXc7Fs0qSuPRyxz5+anuN0dxZa9GTwTEnBrZPbthKkNRrvZMdTGJ6WumOh9aUq8OJJWy9aOgsXvs7qjN1UqcCqQqYaVnEOhCaqWNDsVtsFrVDj+SaLIBvCiomwF4C4nIgngJ5I69tx0UNI0q+ZnvOGQZ7m1PpW2NYP7Yw43HJNdeUEQAmdCPnh/PJwzLTnIxHmQU7n7SPlMdV0SFa6H8y2HHvex697GAkyE5t8c2uO24OnqIwF1tR3blIqXzTSRl0GA6QvrSj2p4UtnWjvF7xT7RiIEyTtgU/AsihTrXyXzWWZaIBJogpgw6erlZqWjCH7sZy/WoGYEiblobOAqMYxax6vRbeuGtoYksr/myX+x9rfLrYuoDRTw4woXOLmMrrj+Mf0TbAgc3SjdkqdsPU1553rlSqIEZXuFgoWmxvVQDtekgTYyS97G81TDSK9nTJT5ilku8NVq2LgtBXGwsNIw/xekcOUzJke3kpnFPutNaexR1VF3ohIuqRKYRGcd8ADJP2lfwMcaGRiplAmFoaVS1YUhQwYFNq9rMLf7YauRGV4BJg/t9srdGxf5RoKCvRo+XM/nLxxysTR9MVaEP/3lDqjwChMxs+eWfLHE5vRWV8hUEqdrWNZV29gsx5nQpzJ4PARGZVu310pQzc6JAlc2XAhhFk6RamkYJnmCSMnb/RblzIATBi2kNrCVAlaXIon188inB62rEpZGPkRIP7PUfu27S/elLQHBHeGDsxOXsBRo1gl3te+raoBHsxo6zvRnYbwdAQa5taDE63eh+fT6kFI+xYmXNAQkU8Dp0MVhEh4JQI06Ni/AKrvYpC95TXXIphZcF+/Pv/vaGkhG2X9S3uhugwWK?iv=2vWkOQQi0WynNJz/aZ4k2g=="), + ) } @Test diff --git a/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/nip06/Bip32SeedDerivationTest.kt b/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/nip06/Bip32SeedDerivationTest.kt index e3e14f256..5fe81aee8 100644 --- a/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/nip06/Bip32SeedDerivationTest.kt +++ b/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/nip06/Bip32SeedDerivationTest.kt @@ -21,7 +21,10 @@ package com.vitorpamplona.quartz.crypto.nip06 import androidx.test.ext.junit.runners.AndroidJUnit4 -import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.nip01Core.toHexKey +import com.vitorpamplona.quartz.nip06KeyDerivation.Bip32SeedDerivation +import com.vitorpamplona.quartz.nip06KeyDerivation.Bip39Mnemonics +import com.vitorpamplona.quartz.nip06KeyDerivation.KeyPath import fr.acinq.secp256k1.Secp256k1 import junit.framework.TestCase.assertEquals import org.junit.Test diff --git a/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/nip06/Bip39KeyPathTest.kt b/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/nip06/Bip39KeyPathTest.kt index d60d479d8..05c43a2ff 100644 --- a/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/nip06/Bip39KeyPathTest.kt +++ b/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/nip06/Bip39KeyPathTest.kt @@ -21,6 +21,8 @@ package com.vitorpamplona.quartz.crypto.nip06 import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.vitorpamplona.quartz.nip06KeyDerivation.Hardener +import com.vitorpamplona.quartz.nip06KeyDerivation.KeyPath import junit.framework.TestCase.assertEquals import org.junit.Test import org.junit.runner.RunWith diff --git a/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/nip06/Bip39MnemonicsTest.kt b/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/nip06/Bip39MnemonicsTest.kt index 8e804f7b1..b8744c17b 100644 --- a/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/nip06/Bip39MnemonicsTest.kt +++ b/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/nip06/Bip39MnemonicsTest.kt @@ -24,8 +24,9 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.platform.app.InstrumentationRegistry import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import com.vitorpamplona.quartz.crypto.CryptoUtils -import com.vitorpamplona.quartz.encoders.Hex -import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.Hex +import com.vitorpamplona.quartz.nip01Core.toHexKey +import com.vitorpamplona.quartz.nip06KeyDerivation.Bip39Mnemonics import junit.framework.TestCase.assertEquals import junit.framework.TestCase.assertTrue import junit.framework.TestCase.fail diff --git a/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/nip06/Nip06Test.kt b/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/nip06/Nip06Test.kt index eaa39101e..265cb55ad 100644 --- a/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/nip06/Nip06Test.kt +++ b/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/nip06/Nip06Test.kt @@ -21,7 +21,8 @@ package com.vitorpamplona.quartz.crypto.nip06 import androidx.test.ext.junit.runners.AndroidJUnit4 -import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.nip01Core.toHexKey +import com.vitorpamplona.quartz.nip06KeyDerivation.Nip06 import fr.acinq.secp256k1.Secp256k1 import junit.framework.TestCase.assertEquals import org.junit.Ignore diff --git a/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/nip17/AESGCMTest.kt b/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/nip17/AESGCMTest.kt index a53868404..1ae3e9928 100644 --- a/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/nip17/AESGCMTest.kt +++ b/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/nip17/AESGCMTest.kt @@ -22,8 +22,8 @@ package com.vitorpamplona.quartz.crypto.nip17 import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation -import com.vitorpamplona.quartz.crypto.CryptoUtils.decrypt -import com.vitorpamplona.quartz.encoders.hexToByteArray +import com.vitorpamplona.quartz.nip01Core.hexToByteArray +import com.vitorpamplona.quartz.nip17Dm.AESGCM import junit.framework.TestCase.assertEquals import org.junit.Test import org.junit.runner.RunWith diff --git a/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/nip44/NIP44v2Test.kt b/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/nip44/NIP44v2Test.kt index 288857980..cf42324d4 100644 --- a/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/nip44/NIP44v2Test.kt +++ b/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/nip44/NIP44v2Test.kt @@ -24,10 +24,11 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import com.vitorpamplona.quartz.crypto.KeyPair -import com.vitorpamplona.quartz.crypto.nip01.Nip01 import com.vitorpamplona.quartz.crypto.sha256Hash -import com.vitorpamplona.quartz.encoders.hexToByteArray -import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.nip01Core.Nip01 +import com.vitorpamplona.quartz.nip01Core.hexToByteArray +import com.vitorpamplona.quartz.nip01Core.toHexKey +import com.vitorpamplona.quartz.nip44Encryption.Nip44v2 import fr.acinq.secp256k1.Secp256k1 import junit.framework.TestCase.assertEquals import junit.framework.TestCase.assertNotNull diff --git a/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/nip49/NIP49Test.kt b/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/nip49/NIP49Test.kt index ca6a2700b..faeaff138 100644 --- a/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/nip49/NIP49Test.kt +++ b/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/nip49/NIP49Test.kt @@ -21,7 +21,8 @@ package com.vitorpamplona.quartz.crypto.nip49 import androidx.test.ext.junit.runners.AndroidJUnit4 -import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.nip01Core.toHexKey +import com.vitorpamplona.quartz.nip49PrivKeyEnc.Nip49 import fr.acinq.secp256k1.Secp256k1 import junit.framework.TestCase.assertEquals import junit.framework.TestCase.assertNotNull diff --git a/quartz/src/androidTest/java/com/vitorpamplona/quartz/encoders/HexEncodingTest.kt b/quartz/src/androidTest/java/com/vitorpamplona/quartz/encoders/HexEncodingTest.kt index 9f0185310..3dbae038d 100644 --- a/quartz/src/androidTest/java/com/vitorpamplona/quartz/encoders/HexEncodingTest.kt +++ b/quartz/src/androidTest/java/com/vitorpamplona/quartz/encoders/HexEncodingTest.kt @@ -22,6 +22,7 @@ package com.vitorpamplona.quartz.encoders import androidx.test.ext.junit.runners.AndroidJUnit4 import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.crypto.Hex import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue @@ -74,16 +75,16 @@ class HexEncodingTest { @Test fun testIsHex() { - assertFalse("/0", HexValidator.isHex("/0")) - assertFalse("/.", HexValidator.isHex("/.")) - assertFalse("!!", HexValidator.isHex("!!")) - assertFalse("::", HexValidator.isHex("::")) - assertFalse("@@", HexValidator.isHex("@@")) - assertFalse("GG", HexValidator.isHex("GG")) - assertFalse("FG", HexValidator.isHex("FG")) - assertFalse("`a", HexValidator.isHex("`a")) - assertFalse("gg", HexValidator.isHex("gg")) - assertFalse("fg", HexValidator.isHex("fg")) + assertFalse("/0", Hex.isHex("/0")) + assertFalse("/.", Hex.isHex("/.")) + assertFalse("::", Hex.isHex("::")) + assertFalse("!!", Hex.isHex("!!")) + assertFalse("@@", Hex.isHex("@@")) + assertFalse("GG", Hex.isHex("GG")) + assertFalse("FG", Hex.isHex("FG")) + assertFalse("`a", Hex.isHex("`a")) + assertFalse("gg", Hex.isHex("gg")) + assertFalse("fg", Hex.isHex("fg")) } @OptIn(ExperimentalStdlibApi::class) @@ -92,9 +93,9 @@ class HexEncodingTest { for (i in 0..10000) { val bytes = CryptoUtils.privkeyCreate() val hex = bytes.toHexString(HexFormat.Default) - assertTrue(hex, HexValidator.isHex(hex)) + assertTrue(hex, Hex.isHex(hex)) val hexUpper = bytes.toHexString(HexFormat.UpperCase) - assertTrue(hexUpper, HexValidator.isHex(hexUpper)) + assertTrue(hexUpper, Hex.isHex(hexUpper)) } } diff --git a/quartz/src/androidTest/java/com/vitorpamplona/quartz/encoders/LnInvoiceUtilTest.kt b/quartz/src/androidTest/java/com/vitorpamplona/quartz/encoders/LnInvoiceUtilTest.kt index 0c3f8e6da..89b57313b 100644 --- a/quartz/src/androidTest/java/com/vitorpamplona/quartz/encoders/LnInvoiceUtilTest.kt +++ b/quartz/src/androidTest/java/com/vitorpamplona/quartz/encoders/LnInvoiceUtilTest.kt @@ -21,6 +21,7 @@ package com.vitorpamplona.quartz.encoders import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.vitorpamplona.quartz.lightning.LnInvoiceUtil import org.junit.Assert import org.junit.Test import org.junit.runner.RunWith diff --git a/quartz/src/androidTest/java/com/vitorpamplona/quartz/encoders/NIP19EmbedTests.kt b/quartz/src/androidTest/java/com/vitorpamplona/quartz/encoders/NIP19EmbedTests.kt index aafe64b5b..ca48e5e11 100644 --- a/quartz/src/androidTest/java/com/vitorpamplona/quartz/encoders/NIP19EmbedTests.kt +++ b/quartz/src/androidTest/java/com/vitorpamplona/quartz/encoders/NIP19EmbedTests.kt @@ -21,11 +21,17 @@ package com.vitorpamplona.quartz.encoders import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.vitorpamplona.quartz.crypto.Hex import com.vitorpamplona.quartz.crypto.KeyPair -import com.vitorpamplona.quartz.events.Event -import com.vitorpamplona.quartz.events.FhirResourceEvent -import com.vitorpamplona.quartz.events.TextNoteEvent -import com.vitorpamplona.quartz.signers.NostrSignerInternal +import com.vitorpamplona.quartz.experimental.medical.FhirResourceEvent +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.hasValidSignature +import com.vitorpamplona.quartz.nip01Core.hexToByteArray +import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerInternal +import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent +import com.vitorpamplona.quartz.nip19Bech32Entities.Nip19Parser +import com.vitorpamplona.quartz.nip19Bech32Entities.decodePrivateKeyAsHexOrNull +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NEmbed import junit.framework.TestCase.assertEquals import junit.framework.TestCase.assertNotNull import junit.framework.TestCase.assertTrue @@ -57,11 +63,11 @@ class NIP19EmbedTests { assertNotNull(textNote) - val bech32 = Nip19Bech32.createNEmbed(textNote!!) + val bech32 = NEmbed.create(textNote!!) println(bech32) - val decodedNote = (Nip19Bech32.uriToRoute(bech32)?.entity as Nip19Bech32.NEmbed).event + val decodedNote = (Nip19Parser.uriToRoute(bech32)?.entity as NEmbed).event assertTrue(decodedNote.hasValidSignature()) @@ -88,12 +94,12 @@ class NIP19EmbedTests { assertNotNull(eyeglassesPrescriptionEvent) - val bech32 = Nip19Bech32.createNEmbed(eyeglassesPrescriptionEvent!!) + val bech32 = NEmbed.create(eyeglassesPrescriptionEvent!!) println(eyeglassesPrescriptionEvent!!.toJson()) println(bech32) - val decodedNote = (Nip19Bech32.uriToRoute(bech32)?.entity as Nip19Bech32.NEmbed).event + val decodedNote = (Nip19Parser.uriToRoute(bech32)?.entity as NEmbed).event assertTrue(decodedNote.hasValidSignature()) @@ -120,12 +126,12 @@ class NIP19EmbedTests { assertNotNull(eyeglassesPrescriptionEvent) - val bech32 = Nip19Bech32.createNEmbed(eyeglassesPrescriptionEvent!!) + val bech32 = NEmbed.create(eyeglassesPrescriptionEvent!!) println(eyeglassesPrescriptionEvent!!.toJson()) println(bech32) - val decodedNote = (Nip19Bech32.uriToRoute(bech32)?.entity as Nip19Bech32.NEmbed).event + val decodedNote = (Nip19Parser.uriToRoute(bech32)?.entity as NEmbed).event assertTrue(decodedNote.hasValidSignature()) @@ -152,12 +158,12 @@ class NIP19EmbedTests { assertNotNull(eyeglassesPrescriptionEvent) - val bech32 = Nip19Bech32.createNEmbed(eyeglassesPrescriptionEvent!!) + val bech32 = NEmbed.create(eyeglassesPrescriptionEvent!!) println(eyeglassesPrescriptionEvent!!.toJson()) println(bech32) - val decodedNote = (Nip19Bech32.uriToRoute(bech32)?.entity as Nip19Bech32.NEmbed).event + val decodedNote = (Nip19Parser.uriToRoute(bech32)?.entity as NEmbed).event assertTrue(decodedNote.hasValidSignature()) diff --git a/quartz/src/androidTest/java/com/vitorpamplona/quartz/encoders/PoWRankTest.kt b/quartz/src/androidTest/java/com/vitorpamplona/quartz/encoders/PoWRankTest.kt index f38818a0a..79a60ac7d 100644 --- a/quartz/src/androidTest/java/com/vitorpamplona/quartz/encoders/PoWRankTest.kt +++ b/quartz/src/androidTest/java/com/vitorpamplona/quartz/encoders/PoWRankTest.kt @@ -21,6 +21,7 @@ package com.vitorpamplona.quartz.encoders import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.vitorpamplona.quartz.nip13Pow.PoWRank import org.junit.Assert.assertEquals import org.junit.Test import org.junit.runner.RunWith diff --git a/quartz/src/androidTest/java/com/vitorpamplona/quartz/events/ChatroomKeyTest.kt b/quartz/src/androidTest/java/com/vitorpamplona/quartz/events/ChatroomKeyTest.kt index 58f679a98..948c2b175 100644 --- a/quartz/src/androidTest/java/com/vitorpamplona/quartz/events/ChatroomKeyTest.kt +++ b/quartz/src/androidTest/java/com/vitorpamplona/quartz/events/ChatroomKeyTest.kt @@ -21,6 +21,7 @@ package com.vitorpamplona.quartz.events import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.vitorpamplona.quartz.nip17Dm.ChatroomKey import kotlinx.collections.immutable.persistentSetOf import org.junit.Assert.assertEquals import org.junit.Test diff --git a/quartz/src/androidTest/java/com/vitorpamplona/quartz/events/CitationTests.kt b/quartz/src/androidTest/java/com/vitorpamplona/quartz/events/CitationTests.kt index 5a5b7bf7c..c92642fdb 100644 --- a/quartz/src/androidTest/java/com/vitorpamplona/quartz/events/CitationTests.kt +++ b/quartz/src/androidTest/java/com/vitorpamplona/quartz/events/CitationTests.kt @@ -21,6 +21,8 @@ package com.vitorpamplona.quartz.events import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper +import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent import junit.framework.TestCase.assertEquals import org.junit.Test import org.junit.runner.RunWith @@ -94,7 +96,7 @@ class CitationTests { @Test fun parseEvent() { - val event = Event.fromJson(json) as TextNoteEvent + val event = EventMapper.fromJson(json) as TextNoteEvent val expectedCitations = setOf( diff --git a/quartz/src/androidTest/java/com/vitorpamplona/quartz/events/EventSigCheck.kt b/quartz/src/androidTest/java/com/vitorpamplona/quartz/events/EventSigCheck.kt index 55b733111..771323d8e 100644 --- a/quartz/src/androidTest/java/com/vitorpamplona/quartz/events/EventSigCheck.kt +++ b/quartz/src/androidTest/java/com/vitorpamplona/quartz/events/EventSigCheck.kt @@ -21,6 +21,8 @@ package com.vitorpamplona.quartz.events import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.vitorpamplona.quartz.nip01Core.checkSignature +import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper import org.junit.Test import org.junit.runner.RunWith @@ -51,8 +53,8 @@ class EventSigCheck { @Test fun testUnicode2028and2029ShouldNotBeEscaped() { - val msg = Event.mapper.readTree(payload1) - val event = Event.fromJson(msg[2]) + val msg = EventMapper.mapper.readTree(payload1) + val event = EventMapper.fromJson(msg[2]) // Should pass event.checkSignature() diff --git a/quartz/src/androidTest/java/com/vitorpamplona/quartz/events/GiftWrapEventTest.kt b/quartz/src/androidTest/java/com/vitorpamplona/quartz/events/GiftWrapEventTest.kt index 4fc96e6e2..fc0b23a39 100644 --- a/quartz/src/androidTest/java/com/vitorpamplona/quartz/events/GiftWrapEventTest.kt +++ b/quartz/src/androidTest/java/com/vitorpamplona/quartz/events/GiftWrapEventTest.kt @@ -21,11 +21,18 @@ package com.vitorpamplona.quartz.events import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.vitorpamplona.quartz.crypto.Hex import com.vitorpamplona.quartz.crypto.KeyPair -import com.vitorpamplona.quartz.encoders.Hex -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.hexToByteArray -import com.vitorpamplona.quartz.signers.NostrSignerInternal +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.checkSignature +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.hexToByteArray +import com.vitorpamplona.quartz.nip01Core.people.isTaggedUser +import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerInternal +import com.vitorpamplona.quartz.nip17Dm.ChatMessageEvent +import com.vitorpamplona.quartz.nip17Dm.NIP17Factory +import com.vitorpamplona.quartz.nip59Giftwrap.GiftWrapEvent +import com.vitorpamplona.quartz.nip59Giftwrap.SealedGossipEvent import org.junit.Assert.assertEquals import org.junit.Assert.assertNotEquals import org.junit.Assert.assertNotNull diff --git a/quartz/src/androidTest/java/com/vitorpamplona/quartz/events/PrivateZapTests.kt b/quartz/src/androidTest/java/com/vitorpamplona/quartz/events/PrivateZapTests.kt index 5b5493850..ccda59c56 100644 --- a/quartz/src/androidTest/java/com/vitorpamplona/quartz/events/PrivateZapTests.kt +++ b/quartz/src/androidTest/java/com/vitorpamplona/quartz/events/PrivateZapTests.kt @@ -21,11 +21,15 @@ package com.vitorpamplona.quartz.events import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.vitorpamplona.quartz.crypto.Hex import com.vitorpamplona.quartz.crypto.KeyPair -import com.vitorpamplona.quartz.encoders.Hex -import com.vitorpamplona.quartz.encoders.toHexKey -import com.vitorpamplona.quartz.events.LnZapRequestEvent.Companion.createEncryptionPrivateKey -import com.vitorpamplona.quartz.signers.NostrSignerInternal +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper +import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerInternal +import com.vitorpamplona.quartz.nip01Core.toHexKey +import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent +import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent +import com.vitorpamplona.quartz.nip57Zaps.PrivateZapEncryption.Companion.createEncryptionPrivateKey import junit.framework.TestCase.assertNotNull import junit.framework.TestCase.fail import org.junit.Test @@ -36,7 +40,7 @@ class PrivateZapTests { @Test fun testPollZap() { val poll = - Event.fromJson( + EventMapper.fromJson( """{ "content": "New poll \n\n #zappoll", "created_at": 1682440713, @@ -81,7 +85,9 @@ class PrivateZapTests { val loggedIn = NostrSignerInternal( - KeyPair(Hex.decode("e8e7197ccc53c9ed4cf9b1c8dce085475fa1ffdd71f2c14e44fe23d0bdf77598")), + KeyPair( + Hex.decode("e8e7197ccc53c9ed4cf9b1c8dce085475fa1ffdd71f2c14e44fe23d0bdf77598"), + ), ) var resultPrivateZap: Event? = null diff --git a/quartz/src/androidTest/java/com/vitorpamplona/quartz/events/nip46/Nip46Test.kt b/quartz/src/androidTest/java/com/vitorpamplona/quartz/events/nip46/Nip46Test.kt index 38ce6f725..0de6def6d 100644 --- a/quartz/src/androidTest/java/com/vitorpamplona/quartz/events/nip46/Nip46Test.kt +++ b/quartz/src/androidTest/java/com/vitorpamplona/quartz/events/nip46/Nip46Test.kt @@ -22,9 +22,28 @@ package com.vitorpamplona.quartz.events.nip46 import androidx.test.ext.junit.runners.AndroidJUnit4 import com.vitorpamplona.quartz.crypto.KeyPair -import com.vitorpamplona.quartz.events.ContactListEvent -import com.vitorpamplona.quartz.events.Event -import com.vitorpamplona.quartz.signers.NostrSignerInternal +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerInternal +import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerMessage +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestConnect +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestGetPublicKey +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestGetRelays +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestNip04Decrypt +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestNip04Encrypt +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestNip44Decrypt +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestNip44Encrypt +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestPing +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestSign +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponseAck +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponseDecrypt +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponseEncrypt +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponseError +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponseEvent +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponseGetRelays +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponsePong +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponsePublicKey +import com.vitorpamplona.quartz.nip46RemoteSigner.NostrConnectEvent import com.vitorpamplona.quartz.utils.TimeUtils import junit.framework.TestCase.assertEquals import org.junit.Ignore diff --git a/quartz/src/androidTest/java/com/vitorpamplona/quartz/ots/OtsTest.kt b/quartz/src/androidTest/java/com/vitorpamplona/quartz/nip03Timestamp/ots/OtsTest.kt similarity index 97% rename from quartz/src/androidTest/java/com/vitorpamplona/quartz/ots/OtsTest.kt rename to quartz/src/androidTest/java/com/vitorpamplona/quartz/nip03Timestamp/ots/OtsTest.kt index 6471fa8f7..5902ec18c 100644 --- a/quartz/src/androidTest/java/com/vitorpamplona/quartz/ots/OtsTest.kt +++ b/quartz/src/androidTest/java/com/vitorpamplona/quartz/nip03Timestamp/ots/OtsTest.kt @@ -18,13 +18,13 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.ots +package com.vitorpamplona.quartz.nip03Timestamp.ots import androidx.test.ext.junit.runners.AndroidJUnit4 import com.vitorpamplona.quartz.crypto.KeyPair -import com.vitorpamplona.quartz.events.Event -import com.vitorpamplona.quartz.events.OtsEvent -import com.vitorpamplona.quartz.signers.NostrSignerInternal +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerInternal +import com.vitorpamplona.quartz.nip03Timestamp.OtsEvent import junit.framework.TestCase.assertEquals import junit.framework.TestCase.fail import org.junit.Assert @@ -43,7 +43,7 @@ class OtsTest { @Test fun verifyNostrEvent() { - val ots = Event.Companion.fromJson(otsEvent) as OtsEvent + val ots = Event.fromJson(otsEvent) as OtsEvent println(ots.info()) assertEquals(1707688818L, ots.verify()) } diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/BlossomAuthorizationEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/blossom/BlossomAuthorizationEvent.kt similarity index 94% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/BlossomAuthorizationEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/blossom/BlossomAuthorizationEvent.kt index 9b8d9aa1b..2108ac6f2 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/BlossomAuthorizationEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/blossom/BlossomAuthorizationEvent.kt @@ -18,11 +18,12 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.blossom import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.utils.TimeUtils @Immutable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/BlossomServersEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/blossom/BlossomServersEvent.kt similarity index 92% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/BlossomServersEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/blossom/BlossomServersEvent.kt index 02b1bb384..3796b8146 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/BlossomServersEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/blossom/BlossomServersEvent.kt @@ -18,12 +18,13 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.blossom import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.addressables.BaseAddressableEvent +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.utils.TimeUtils @Immutable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/crypto/CryptoUtils.kt b/quartz/src/main/java/com/vitorpamplona/quartz/crypto/CryptoUtils.kt index 7583e612e..af11c1cf9 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/crypto/CryptoUtils.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/crypto/CryptoUtils.kt @@ -20,13 +20,13 @@ */ package com.vitorpamplona.quartz.crypto -import com.vitorpamplona.quartz.crypto.nip01.Nip01 -import com.vitorpamplona.quartz.crypto.nip04.Nip04 -import com.vitorpamplona.quartz.crypto.nip06.Nip06 -import com.vitorpamplona.quartz.crypto.nip44.Nip44 -import com.vitorpamplona.quartz.crypto.nip44.Nip44v2 -import com.vitorpamplona.quartz.crypto.nip49.Nip49 -import com.vitorpamplona.quartz.encoders.HexKey +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.Nip01 +import com.vitorpamplona.quartz.nip04Dm.Nip04 +import com.vitorpamplona.quartz.nip06KeyDerivation.Nip06 +import com.vitorpamplona.quartz.nip44Encryption.Nip44 +import com.vitorpamplona.quartz.nip44Encryption.Nip44v2 +import com.vitorpamplona.quartz.nip49PrivKeyEnc.Nip49 import fr.acinq.secp256k1.Secp256k1 import java.security.SecureRandom @@ -34,11 +34,11 @@ object CryptoUtils { private val secp256k1 = Secp256k1.get() private val random = SecureRandom() - public val nip01 = Nip01(secp256k1, random) - public val nip06 = Nip06(secp256k1) - public val nip04 = Nip04(secp256k1, random) - public val nip44 = Nip44(secp256k1, random, nip04) - public val nip49 = Nip49(secp256k1, random) + val nip01 = Nip01(secp256k1, random) + val nip06 = Nip06(secp256k1) + val nip04 = Nip04(secp256k1, random) + val nip44 = Nip44(secp256k1, random, nip04) + val nip49 = Nip49(secp256k1, random) fun clearCache() { nip04.clearCache() diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/HexUtils.kt b/quartz/src/main/java/com/vitorpamplona/quartz/crypto/Hex.kt similarity index 70% rename from quartz/src/main/java/com/vitorpamplona/quartz/encoders/HexUtils.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/crypto/Hex.kt index 9f87a658d..998e92918 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/HexUtils.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/crypto/Hex.kt @@ -18,31 +18,25 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.encoders +package com.vitorpamplona.quartz.crypto -/** Makes the distinction between String and Hex * */ -typealias HexKey = String +object Hex { + private val lowerCaseHex = arrayOf('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f') + private val upperCaseHex = arrayOf('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F') -fun ByteArray.toHexKey(): HexKey = Hex.encode(this) + private val hexToByte: IntArray = + IntArray(256) { -1 }.apply { + lowerCaseHex.forEachIndexed { index, char -> this[char.code] = index } + upperCaseHex.forEachIndexed { index, char -> this[char.code] = index } + } -fun HexKey.hexToByteArray(): ByteArray = Hex.decode(this) + // Encodes both chars in a single Int variable + private val byteToHex = + IntArray(256) { + (lowerCaseHex[(it shr 4)].code shl 8) or lowerCaseHex[(it and 0xF)].code + } -val lowerCaseHex = arrayOf('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f') -val upperCaseHex = arrayOf('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F') - -val hexToByte: IntArray = - IntArray(256) { -1 }.apply { - lowerCaseHex.forEachIndexed { index, char -> this[char.code] = index } - upperCaseHex.forEachIndexed { index, char -> this[char.code] = index } - } - -// Encodes both chars in a single Int variable -val byteToHex = - IntArray(256) { - (lowerCaseHex[(it shr 4)].code shl 8) or lowerCaseHex[(it and 0xF)].code - } - -object HexValidator { + @JvmStatic fun isHex(hex: String?): Boolean { if (hex == null) return false if (hex.isEmpty()) return false @@ -54,9 +48,7 @@ object HexValidator { return true } -} -object Hex { @JvmStatic fun decode(hex: String): ByteArray { // faster version of hex decoder diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/crypto/KeyPair.kt b/quartz/src/main/java/com/vitorpamplona/quartz/crypto/KeyPair.kt index d6390abc2..68218e6c5 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/crypto/KeyPair.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/crypto/KeyPair.kt @@ -20,7 +20,7 @@ */ package com.vitorpamplona.quartz.crypto -import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.nip01Core.toHexKey class KeyPair( privKey: ByteArray? = null, diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/ATag.kt b/quartz/src/main/java/com/vitorpamplona/quartz/encoders/ATag.kt deleted file mode 100644 index b2165e543..000000000 --- a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/ATag.kt +++ /dev/null @@ -1,133 +0,0 @@ -/** - * Copyright (c) 2024 Vitor Pamplona - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the - * Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -package com.vitorpamplona.quartz.encoders - -import android.util.Log -import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.utils.bytesUsedInMemory -import com.vitorpamplona.quartz.utils.pointerSizeInBytes -import com.vitorpamplona.quartz.utils.removeTrailingNullsAndEmptyOthers - -@Immutable -data class ATag( - val kind: Int, - val pubKeyHex: String, - val dTag: String, -) { - var relay: String? = null - - constructor( - kind: Int, - pubKeyHex: String, - dTag: String, - relayHint: String?, - ) : this(kind, pubKeyHex, dTag) { - this.relay = relayHint - } - - fun countMemory(): Long = - 5 * pointerSizeInBytes + // 7 fields, 4 bytes each reference (32bit) - 8L + // kind - pubKeyHex.bytesUsedInMemory() + - dTag.bytesUsedInMemory() + - (relay?.bytesUsedInMemory() ?: 0) - - fun toTag() = assembleATag(kind, pubKeyHex, dTag) - - fun toATagArray() = removeTrailingNullsAndEmptyOthers("a", toTag(), relay) - - fun toQTagArray() = removeTrailingNullsAndEmptyOthers("q", toTag(), relay) - - fun toNAddr(overrideRelay: String? = relay): String = - TlvBuilder() - .apply { - addString(Nip19Bech32.TlvTypes.SPECIAL, dTag) - addStringIfNotNull(Nip19Bech32.TlvTypes.RELAY, overrideRelay ?: relay) - addHex(Nip19Bech32.TlvTypes.AUTHOR, pubKeyHex) - addInt(Nip19Bech32.TlvTypes.KIND, kind) - }.build() - .toNAddress() - - companion object { - fun assembleATag( - kind: Int, - pubKeyHex: String, - dTag: String, - ) = "$kind:$pubKeyHex:$dTag" - - fun isATag(key: String): Boolean = key.startsWith("naddr1") || key.contains(":") - - fun parse( - address: String, - relay: String?, - ): ATag? = - if (address.startsWith("naddr") || address.startsWith("nostr:naddr")) { - parseNAddr(address) - } else { - parseAtag(address, relay) - } - - fun parseAtag( - atag: String, - relay: String?, - ): ATag? = - try { - val parts = atag.split(":", limit = 3) - Hex.decode(parts[1]) - ATag(parts[0].toInt(), parts[1], parts[2], relay) - } catch (t: Throwable) { - Log.w("ATag", "Error parsing A Tag: $atag: ${t.message}") - null - } - - fun parseAtagUnckecked(atag: String): ATag? = - try { - val parts = atag.split(":") - ATag(parts[0].toInt(), parts[1], parts[2], null) - } catch (t: Throwable) { - null - } - - fun parseNAddr(naddr: String): ATag? { - try { - val key = naddr.removePrefix("nostr:") - - if (key.startsWith("naddr")) { - val tlv = Tlv.parse(key.bechToBytes()) - - val d = tlv.firstAsString(Nip19Bech32.TlvTypes.SPECIAL) ?: "" - val relay = tlv.firstAsString(Nip19Bech32.TlvTypes.RELAY) - val author = tlv.firstAsHex(Nip19Bech32.TlvTypes.AUTHOR) - val kind = tlv.firstAsInt(Nip19Bech32.TlvTypes.KIND) - - if (kind != null && author != null) { - return ATag(kind, author, d, relay) - } - } - } catch (e: Throwable) { - Log.w("ATag", "Issue trying to Decode NIP19 $this: ${e.message}") - // e.printStackTrace() - } - - return null - } - } -} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/Nip19Bech32.kt b/quartz/src/main/java/com/vitorpamplona/quartz/encoders/Nip19Bech32.kt deleted file mode 100644 index 1e0953792..000000000 --- a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/Nip19Bech32.kt +++ /dev/null @@ -1,418 +0,0 @@ -/** - * Copyright (c) 2024 Vitor Pamplona - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the - * Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -package com.vitorpamplona.quartz.encoders - -import android.util.Log -import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.crypto.KeyPair -import com.vitorpamplona.quartz.events.Event -import kotlinx.coroutines.CancellationException -import java.io.ByteArrayOutputStream -import java.util.regex.Pattern -import java.util.zip.GZIPInputStream -import java.util.zip.GZIPOutputStream - -object Nip19Bech32 { - enum class Type { - USER, - NOTE, - EVENT, - RELAY, - ADDRESS, - } - - enum class TlvTypes( - val id: Byte, - ) { - SPECIAL(0), - RELAY(1), - AUTHOR(2), - KIND(3), - } - - val nip19PlusNip46regex = - Pattern.compile( - "(nostr:)?@?(nsec1|npub1|nevent1|naddr1|note1|nprofile1|nrelay1|nembed1|ncryptsec1)([qpzry9x8gf2tvdw0s3jn54khce6mua7l]+)([\\S]*)", - Pattern.CASE_INSENSITIVE, - ) - - val nip19regex = - Pattern.compile( - "(nostr:)?@?(nsec1|npub1|nevent1|naddr1|note1|nprofile1|nrelay1|nembed1)([qpzry9x8gf2tvdw0s3jn54khce6mua7l]+)([\\S]*)", - Pattern.CASE_INSENSITIVE, - ) - - @Immutable - data class ParseReturn( - val entity: Entity, - val nip19raw: String, - val additionalChars: String? = null, - ) - - interface Entity - - @Immutable - data class NSec( - val hex: String, - ) : Entity - - @Immutable - data class NPub( - val hex: String, - ) : Entity - - @Immutable - data class Note( - val hex: String, - ) : Entity - - @Immutable - data class NProfile( - val hex: String, - val relay: List, - ) : Entity - - @Immutable - data class NEvent( - val hex: String, - val relay: List, - val author: String?, - val kind: Int?, - ) : Entity - - @Immutable - data class NAddress( - val atag: String, - val relay: List, - val author: String, - val kind: Int, - ) : Entity - - @Immutable - data class NRelay( - val relay: List, - ) : Entity - - @Immutable - data class NEmbed( - val event: Event, - ) : Entity - - fun tryParseAndClean(uri: String?): String? { - if (uri == null) return null - - try { - val matcher = nip19PlusNip46regex.matcher(uri) - if (!matcher.find()) { - return null - } - - val type = matcher.group(2) // npub1 - val key = matcher.group(3) // bech32 - - return type + key - } catch (e: Throwable) { - Log.e("NIP19 Parser", "Issue trying to Decode NIP19 $uri: ${e.message}", e) - } - - return null - } - - fun uriToRoute(uri: String?): ParseReturn? { - if (uri == null) return null - - try { - val matcher = nip19regex.matcher(uri) - if (!matcher.find()) { - return null - } - - val type = matcher.group(2) // npub1 - val key = matcher.group(3) // bech32 - val additionalChars = matcher.group(4) // additional chars - - if (type == null) return null - - return parseComponents(type, key, additionalChars.ifEmpty { null }) - } catch (e: Throwable) { - Log.e("NIP19 Parser", "Issue trying to Decode NIP19 $uri: ${e.message}", e) - } - - return null - } - - fun parseComponents( - type: String, - key: String?, - additionalChars: String?, - ): ParseReturn? = - try { - val nip19 = (type + key) - val bytes = nip19.bechToBytes() - - when (type.lowercase()) { - "nsec1" -> nsec(bytes) - "npub1" -> npub(bytes) - "note1" -> note(bytes) - "nprofile1" -> nprofile(bytes) - "nevent1" -> nevent(bytes) - "nrelay1" -> nrelay(bytes) - "naddr1" -> naddr(bytes) - "nembed1" -> nembed(bytes) - else -> null - }?.let { - ParseReturn(it, nip19, additionalChars) - } - } catch (e: Throwable) { - Log.w("NIP19 Parser", "Issue trying to Decode NIP19 $key: ${e.message}", e) - null - } - - private fun nembed(bytes: ByteArray): NEmbed? { - if (bytes.isEmpty()) return null - return NEmbed(Event.fromJson(ungzip(bytes))) - } - - private fun nsec(bytes: ByteArray): NSec? { - if (bytes.isEmpty()) return null - return NSec(bytes.toHexKey()) - } - - private fun npub(bytes: ByteArray): NPub? { - if (bytes.isEmpty()) return null - return NPub(bytes.toHexKey()) - } - - private fun note(bytes: ByteArray): Note? { - if (bytes.isEmpty()) return null - return Note(bytes.toHexKey()) - } - - private fun nprofile(bytes: ByteArray): NProfile? { - if (bytes.isEmpty()) return null - - val tlv = Tlv.parse(bytes) - - val hex = tlv.firstAsHex(TlvTypes.SPECIAL) ?: return null - val relay = tlv.asStringList(TlvTypes.RELAY) ?: emptyList() - - if (hex.isBlank()) return null - - return NProfile(hex, relay) - } - - private fun nevent(bytes: ByteArray): NEvent? { - if (bytes.isEmpty()) return null - - val tlv = Tlv.parse(bytes) - - val hex = tlv.firstAsHex(TlvTypes.SPECIAL) ?: return null - val relay = tlv.asStringList(TlvTypes.RELAY) ?: emptyList() - val author = tlv.firstAsHex(TlvTypes.AUTHOR) - val kind = tlv.firstAsInt(TlvTypes.KIND.id) - - if (hex.isBlank()) return null - - return NEvent(hex, relay, author, kind) - } - - private fun nrelay(bytes: ByteArray): NRelay? { - if (bytes.isEmpty()) return null - - val relayUrl = Tlv.parse(bytes).asStringList(TlvTypes.SPECIAL.id) ?: return null - - return NRelay(relayUrl) - } - - private fun naddr(bytes: ByteArray): NAddress? { - if (bytes.isEmpty()) return null - - val tlv = Tlv.parse(bytes) - - val d = tlv.firstAsString(TlvTypes.SPECIAL.id) ?: "" - val relay = tlv.asStringList(TlvTypes.RELAY.id) ?: emptyList() - val author = tlv.firstAsHex(TlvTypes.AUTHOR.id) ?: return null - val kind = tlv.firstAsInt(TlvTypes.KIND.id) ?: return null - - return NAddress("$kind:$author:$d", relay, author, kind) - } - - fun createNEvent( - idHex: String, - author: String?, - kind: Int?, - relay: String?, - ): String = - TlvBuilder() - .apply { - addHex(TlvTypes.SPECIAL, idHex) - addStringIfNotNull(TlvTypes.RELAY, relay) - addHexIfNotNull(TlvTypes.AUTHOR, author) - addIntIfNotNull(TlvTypes.KIND, kind) - }.build() - .toNEvent() - - @Deprecated("Use nevent instead") - fun createNote(eventId: HexKey): String = eventId.hexToByteArray().toNote() - - fun createNPub(authorPubKeyHex: HexKey): String = authorPubKeyHex.hexToByteArray().toNpub() - - fun createNProfile( - authorPubKeyHex: String, - relay: List, - ): String = - TlvBuilder() - .apply { - addHex(TlvTypes.SPECIAL, authorPubKeyHex) - relay.forEach { - addStringIfNotNull(TlvTypes.RELAY, it) - } - }.build() - .toNProfile() - - fun createNEmbed(event: Event): String = gzip(event.toJson()).toNEmbed() - - fun gzip(content: String): ByteArray { - val bos = ByteArrayOutputStream() - GZIPOutputStream(bos).bufferedWriter(Charsets.UTF_8).use { it.write(content) } - val array = bos.toByteArray() - return array - } - - fun ungzip(content: ByteArray): String = GZIPInputStream(content.inputStream()).bufferedReader(Charsets.UTF_8).use { it.readText() } -} - -fun ByteArray.toNsec() = Bech32.encodeBytes(hrp = "nsec", this, Bech32.Encoding.Bech32) - -fun ByteArray.toNpub() = Bech32.encodeBytes(hrp = "npub", this, Bech32.Encoding.Bech32) - -@Deprecated("Prefer nevent1 instead") -fun ByteArray.toNote() = Bech32.encodeBytes(hrp = "note", this, Bech32.Encoding.Bech32) - -fun ByteArray.toNEvent() = Bech32.encodeBytes(hrp = "nevent", this, Bech32.Encoding.Bech32) - -fun ByteArray.toNProfile() = Bech32.encodeBytes(hrp = "nprofile", this, Bech32.Encoding.Bech32) - -fun ByteArray.toNAddress() = Bech32.encodeBytes(hrp = "naddr", this, Bech32.Encoding.Bech32) - -fun ByteArray.toLnUrl() = Bech32.encodeBytes(hrp = "lnurl", this, Bech32.Encoding.Bech32) - -fun ByteArray.toNEmbed() = Bech32.encodeBytes(hrp = "nembed", this, Bech32.Encoding.Bech32) - -fun decodePublicKey(key: String): ByteArray = - when (val parsed = Nip19Bech32.uriToRoute(key)?.entity) { - is Nip19Bech32.NSec -> KeyPair(privKey = key.bechToBytes()).pubKey - is Nip19Bech32.NPub -> parsed.hex.hexToByteArray() - is Nip19Bech32.NProfile -> parsed.hex.hexToByteArray() - else -> Hex.decode(key) // crashes on purpose - } - -fun decodePrivateKeyAsHexOrNull(key: String): HexKey? = - try { - when (val parsed = Nip19Bech32.uriToRoute(key)?.entity) { - is Nip19Bech32.NSec -> parsed.hex - is Nip19Bech32.NPub -> null - is Nip19Bech32.NProfile -> null - is Nip19Bech32.Note -> null - is Nip19Bech32.NEvent -> null - is Nip19Bech32.NEmbed -> null - is Nip19Bech32.NRelay -> null - is Nip19Bech32.NAddress -> null - else -> Hex.decode(key).toHexKey() - } - } catch (e: Exception) { - if (e is CancellationException) throw e - null - } - -fun decodePublicKeyAsHexOrNull(key: String): HexKey? = - try { - when (val parsed = Nip19Bech32.uriToRoute(key)?.entity) { - is Nip19Bech32.NSec -> KeyPair(privKey = key.bechToBytes()).pubKey.toHexKey() - is Nip19Bech32.NPub -> parsed.hex - is Nip19Bech32.NProfile -> parsed.hex - is Nip19Bech32.Note -> null - is Nip19Bech32.NEvent -> null - is Nip19Bech32.NEmbed -> null - is Nip19Bech32.NRelay -> null - is Nip19Bech32.NAddress -> null - else -> Hex.decode(key).toHexKey() - } - } catch (e: Exception) { - if (e is CancellationException) throw e - null - } - -fun decodeEventIdAsHexOrNull(key: String): HexKey? = - try { - when (val parsed = Nip19Bech32.uriToRoute(key)?.entity) { - is Nip19Bech32.NSec -> null - is Nip19Bech32.NPub -> null - is Nip19Bech32.NProfile -> null - is Nip19Bech32.Note -> parsed.hex - is Nip19Bech32.NEvent -> parsed.hex - is Nip19Bech32.NAddress -> parsed.atag - is Nip19Bech32.NEmbed -> null - is Nip19Bech32.NRelay -> null - else -> Hex.decode(key).toHexKey() - } - } catch (e: Exception) { - if (e is CancellationException) throw e - null - } - -fun TlvBuilder.addString( - type: Nip19Bech32.TlvTypes, - string: String, -) = addString(type.id, string) - -fun TlvBuilder.addHex( - type: Nip19Bech32.TlvTypes, - key: HexKey, -) = addHex(type.id, key) - -fun TlvBuilder.addInt( - type: Nip19Bech32.TlvTypes, - data: Int, -) = addInt(type.id, data) - -fun TlvBuilder.addStringIfNotNull( - type: Nip19Bech32.TlvTypes, - data: String?, -) = addStringIfNotNull(type.id, data) - -fun TlvBuilder.addHexIfNotNull( - type: Nip19Bech32.TlvTypes, - data: HexKey?, -) = addHexIfNotNull(type.id, data) - -fun TlvBuilder.addIntIfNotNull( - type: Nip19Bech32.TlvTypes, - data: Int?, -) = addIntIfNotNull(type.id, data) - -fun Tlv.firstAsInt(type: Nip19Bech32.TlvTypes) = firstAsInt(type.id) - -fun Tlv.firstAsHex(type: Nip19Bech32.TlvTypes) = firstAsHex(type.id) - -fun Tlv.firstAsString(type: Nip19Bech32.TlvTypes) = firstAsString(type.id) - -fun Tlv.asStringList(type: Nip19Bech32.TlvTypes) = asStringList(type.id) diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/Event.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/Event.kt deleted file mode 100644 index 5ed3d13cd..000000000 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/Event.kt +++ /dev/null @@ -1,559 +0,0 @@ -/** - * Copyright (c) 2024 Vitor Pamplona - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the - * Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -package com.vitorpamplona.quartz.events - -import android.util.Log -import androidx.compose.runtime.Immutable -import com.fasterxml.jackson.annotation.JsonProperty -import com.fasterxml.jackson.core.JsonGenerator -import com.fasterxml.jackson.core.JsonParser -import com.fasterxml.jackson.core.json.JsonReadFeature -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.crypto.nip01.EventHasher -import com.vitorpamplona.quartz.crypto.nip01.EventHasher.Companion.hashId -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.Hex -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.Nip19Bech32 -import com.vitorpamplona.quartz.encoders.PoWRank -import com.vitorpamplona.quartz.events.nip46.BunkerMessage -import com.vitorpamplona.quartz.events.nip46.BunkerRequest -import com.vitorpamplona.quartz.events.nip46.BunkerResponse -import com.vitorpamplona.quartz.signers.NostrSigner -import com.vitorpamplona.quartz.utils.TimeUtils -import com.vitorpamplona.quartz.utils.bytesUsedInMemory -import com.vitorpamplona.quartz.utils.pointerSizeInBytes -import com.vitorpamplona.quartz.utils.remove -import java.math.BigDecimal - -@Immutable -open class Event( - val id: HexKey, - @JsonProperty("pubkey") val pubKey: HexKey, - @JsonProperty("created_at") val createdAt: Long, - val kind: Int, - val tags: Array>, - val content: String, - val sig: HexKey, -) : EventInterface { - override fun isContentEncoded() = false - - override fun countMemory(): Long = - 7 * pointerSizeInBytes + // 7 fields, 4 bytes each reference (32bit) - 12L + // createdAt + kind - id.bytesUsedInMemory() + - pubKey.bytesUsedInMemory() + - tags.sumOf { pointerSizeInBytes + it.sumOf { pointerSizeInBytes + it.bytesUsedInMemory() } } + - content.bytesUsedInMemory() + - sig.bytesUsedInMemory() - - override fun id(): HexKey = id - - override fun pubKey(): HexKey = pubKey - - override fun createdAt(): Long = createdAt - - override fun kind(): Int = kind - - override fun tags(): Array> = tags - - override fun content(): String = content - - override fun sig(): HexKey = sig - - override fun toJson(): String = mapper.writeValueAsString(toJsonObject()) - - override fun hasAnyTaggedUser() = hasTagWithContent("p") - - override fun hasTagWithContent(tagName: String) = tags.any { it.size > 1 && it[0] == tagName } - - override fun forEachTaggedEvent(onEach: (eventId: HexKey) -> Unit) = forEachTagged("e", onEach) - - override fun forEachHashTag(onEach: (eventId: HexKey) -> Unit) = forEachTagged("t", onEach) - - private fun forEachTagged( - tagName: String, - onEach: (eventId: HexKey) -> Unit, - ) = tags.forEach { - if (it.size > 1 && it[0] == tagName) { - onEach(it[1]) - } - } - - override fun anyHashTag(onEach: (str: String) -> Boolean) = anyTagged("t", onEach) - - private fun anyTagged( - tagName: String, - onEach: (str: String) -> Boolean, - ) = tags.any { - if (it.size > 1 && it[0] == tagName) { - onEach(it[1]) - } else { - false - } - } - - override fun mapTaggedEvent(map: (eventId: HexKey) -> R) = mapTagged("e", map) - - override fun mapTaggedAddress(map: (address: String) -> R) = mapTagged("a", map) - - private fun mapTagged( - tagName: String, - map: (eventId: HexKey) -> R, - ) = tags.mapNotNull { - if (it.size > 1 && it[0] == tagName) { - map(it[1]) - } else { - null - } - } - - override fun taggedUsers() = tags.filter { it.size > 1 && it[0] == "p" }.map { it[1] } - - override fun taggedEvents() = tags.filter { it.size > 1 && it[0] == "e" }.map { it[1] } - - override fun taggedUrls() = tags.filter { it.size > 1 && it[0] == "r" }.map { it[1] } - - override fun firstTag(key: String) = tags.firstOrNull { it.size > 1 && it[0] == key }?.let { it[1] } - - override fun firstTagFor(vararg key: String) = tags.firstOrNull { it.size > 1 && it[0] in key }?.let { it[1] } - - override fun firstTaggedUser() = tags.firstOrNull { it.size > 1 && it[0] == "p" }?.let { it[1] } - - override fun firstTaggedEvent() = tags.firstOrNull { it.size > 1 && it[0] == "e" }?.let { it[1] } - - override fun firstTaggedUrl() = tags.firstOrNull { it.size > 1 && it[0] == "r" }?.let { it[1] } - - override fun firstTaggedK() = tags.firstOrNull { it.size > 1 && it[0] == "k" }?.let { it[1].toIntOrNull() } - - override fun firstTaggedAddress() = - tags - .firstOrNull { it.size > 1 && it[0] == "a" } - ?.let { - val aTagValue = it[1] - val relay = it.getOrNull(2) - - ATag.parse(aTagValue, relay) - } - - override fun taggedEmojis() = tags.filter { it.size > 2 && it[0] == "emoji" }.mapNotNull { EmojiUrl.parse(it) } - - override fun isSensitive() = - tags.any { - (it.size > 0 && it[0] == "content-warning") || - (it.size > 1 && it[0] == "t" && (it[1].equals("nsfw", true) || it[1].equals("nude", true))) - } - - override fun subject() = tags.firstOrNull { it.size > 1 && it[0] == "subject" }?.get(1) - - override fun zapraiserAmount() = tags.firstOrNull { (it.size > 1 && it[0] == "zapraiser") }?.get(1)?.toLongOrNull() - - override fun hasZapSplitSetup() = tags.any { it.size > 1 && it[0] == "zap" } - - override fun zapSplitSetup(): List = - tags - .filter { it.size > 1 && it[0] == "zap" } - .mapNotNull { - val isLnAddress = it[0].contains("@") || it[0].startsWith("LNURL", true) - val weight = if (isLnAddress) 1.0 else (it.getOrNull(3)?.toDoubleOrNull() ?: 0.0) - - if (weight > 0) { - ZapSplitSetup( - it[1], - it.getOrNull(2), - weight, - isLnAddress, - ) - } else { - null - } - } - - override fun taggedAddresses() = - tags - .filter { it.size > 1 && it[0] == "a" } - .mapNotNull { - val aTagValue = it[1] - val relay = it.getOrNull(2) - - ATag.parse(aTagValue, relay) - } - - override fun hasHashtags() = tags.any { it.size > 1 && it[0] == "t" } - - override fun hasGeohashes() = tags.any { it.size > 1 && it[0] == "g" } - - override fun hashtags() = tags.filter { it.size > 1 && it[0] == "t" }.map { it[1] } - - override fun geohashes() = tags.filter { it.size > 1 && it[0] == "g" }.map { it[1] } - - override fun matchTag1With(text: String) = tags.any { it.size > 1 && it[1].contains(text, true) } - - override fun isTagged( - key: String, - tag: String, - ) = tags.any { it.size > 1 && it[0] == key && it[1] == tag } - - override fun isAnyTagged( - key: String, - tags: Set, - ) = this.tags.any { it.size > 1 && it[0] == key && it[1] in tags } - - override fun isTaggedWord(word: String) = isTagged("word", word) - - override fun isTaggedUser(idHex: String) = isTagged("p", idHex) - - override fun isTaggedUsers(idHexes: Set) = isAnyTagged("p", idHexes) - - override fun isTaggedEvent(idHex: String) = isTagged("e", idHex) - - override fun isTaggedAddressableNote(idHex: String) = isTagged("a", idHex) - - override fun isTaggedAddressableNotes(idHexes: Set) = isAnyTagged("a", idHexes) - - override fun isTaggedHash(hashtag: String) = tags.any { it.size > 1 && it[0] == "t" && it[1].equals(hashtag, true) } - - override fun isTaggedGeoHash(hashtag: String) = tags.any { it.size > 1 && it[0] == "g" && it[1].startsWith(hashtag, true) } - - override fun isTaggedHashes(hashtags: Set) = tags.any { it.size > 1 && it[0] == "t" && it[1].lowercase() in hashtags } - - override fun isTaggedGeoHashes(hashtags: Set) = tags.any { it.size > 1 && it[0] == "g" && it[1].lowercase() in hashtags } - - override fun firstIsTaggedHashes(hashtags: Set) = tags.firstOrNull { it.size > 1 && it[0] == "t" && it[1].lowercase() in hashtags }?.getOrNull(1) - - override fun firstIsTaggedAddressableNote(addressableNotes: Set) = tags.firstOrNull { it.size > 1 && it[0] == "a" && it[1] in addressableNotes }?.getOrNull(1) - - override fun isTaggedAddressableKind(kind: Int): Boolean { - val kindStr = kind.toString() - return tags.any { it.size > 1 && it[0] == "a" && it[1].startsWith(kindStr) } - } - - override fun expiration() = - try { - tags.firstOrNull { it.size > 1 && it[0] == "expiration" }?.get(1)?.toLongOrNull() - } catch (_: Exception) { - null - } - - override fun isExpired() = (expiration() ?: Long.MAX_VALUE) < TimeUtils.now() - - override fun isExpirationBefore(time: Long) = (expiration() ?: Long.MAX_VALUE) < time - - override fun getTagOfAddressableKind(kind: Int): ATag? { - val kindStr = kind.toString() - val aTag = - tags.firstOrNull { it.size > 1 && it[0] == "a" && it[1].startsWith(kindStr) }?.getOrNull(1) - ?: return null - - return ATag.parse(aTag, null) - } - - override fun getPoWRank(): Int { - val commitedPoW = tags.firstOrNull { it.size > 2 && it[0] == "nonce" }?.get(2)?.toIntOrNull() - return PoWRank.getCommited(id, commitedPoW) - } - - override fun getGeoHash(): String? = - tags - .filter { it.size > 1 && it[0] == "g" } - .maxByOrNull { - it[1].length - }?.get(1) - ?.ifBlank { null } - - override fun getReward(): BigDecimal? = - try { - tags.firstOrNull { it.size > 1 && it[0] == "reward" }?.get(1)?.let { BigDecimal(it) } - } catch (e: Exception) { - null - } - - fun filterTags(startsWith: Array) = tags.remove(startsWith) - - open fun toNIP19(): String = - if (this is AddressableEvent) { - ATag(kind, pubKey, dTag(), null).toNAddr() - } else { - Nip19Bech32.createNEvent(id, pubKey, kind, null) - } - - fun toNostrUri(): String = "nostr:${toNIP19()}" - - fun hasCorrectIDHash(): Boolean { - if (id.isEmpty()) return false - return id.equals(generateId()) - } - - fun hasVerifiedSignature(): Boolean { - if (id.isEmpty() || sig.isEmpty()) return false - return 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 (!hasCorrectIDHash()) { - throw Exception( - """ - |Unexpected ID. - | Event: ${toJson()} - | Actual ID: $id - | Generated: ${generateId()} - """.trimIndent(), - ) - } - if (!hasVerifiedSignature()) { - throw Exception("""Bad signature!""") - } - } - - override fun hasValidSignature(): Boolean = - try { - hasCorrectIDHash() && hasVerifiedSignature() - } catch (e: Exception) { - Log.w("Event", "Event $id does not have a valid signature: ${toJson()}", e) - false - } - - fun generateId(): String = EventHasher.hashId(pubKey, createdAt, kind, tags, content) - - private class EventDeserializer : StdDeserializer(Event::class.java) { - override fun deserialize( - jp: JsonParser, - ctxt: DeserializationContext, - ): Event = fromJson(jp.codec.readTree(jp)) - } - - 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")?.asText()?.intern(), - pubKey = jsonObject.get("pubkey")?.asText()?.intern(), - createdAt = jsonObject.get("created_at")?.asLong(), - kind = jsonObject.get("kind")?.asInt(), - tags = - jsonObject.get("tags").toTypedArray { - it.toTypedArray { s -> if (s.isNull) "" else s.asText().intern() } - }, - content = jsonObject.get("content")?.asText(), - ) - } - } - - 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, 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, 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) - replace( - "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) - .enable(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS.mappedFeature()) - .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()) - .addDeserializer(BunkerMessage::class.java, BunkerMessage.BunkerMessageDeserializer()) - .addSerializer(BunkerRequest::class.java, BunkerRequest.BunkerRequestSerializer()) - .addDeserializer(BunkerRequest::class.java, BunkerRequest.BunkerRequestDeserializer()) - .addSerializer(BunkerResponse::class.java, BunkerResponse.BunkerResponseSerializer()) - .addDeserializer(BunkerResponse::class.java, BunkerResponse.BunkerResponseDeserializer()), - ) - - fun fromJson(jsonObject: JsonNode): Event = - 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").toTypedArray { - it.toTypedArray { s -> if (s.isNull) "" else s.asText().intern() } - }, - content = jsonObject.get("content").asText(), - sig = jsonObject.get("sig").asText(), - ) - - inline fun JsonNode.toTypedArray(transform: (JsonNode) -> R): Array = Array(size()) { transform(get(it)) } - - fun fromJson(json: String): Event = mapper.readValue(json, Event::class.java) - - fun toJson(event: Event): String = mapper.writeValueAsString(event) - - fun generateId( - pubKey: HexKey, - createdAt: Long, - kind: Int, - tags: Array>, - content: String, - ): HexKey = EventHasher.hashId(pubKey, createdAt, kind, tags, content) - - fun generateIdBytes( - pubKey: HexKey, - createdAt: Long, - kind: Int, - tags: Array>, - content: String, - ): ByteArray = EventHasher.hashIdBytes(pubKey, createdAt, kind, tags, content) - - fun create( - signer: NostrSigner, - kind: Int, - tags: Array> = emptyArray(), - content: String = "", - createdAt: Long = TimeUtils.now(), - onReady: (Event) -> Unit, - ) = signer.sign(createdAt, kind, tags, content, onReady) - } -} - -@Immutable -open class WrappedEvent( - id: HexKey, - @JsonProperty("pubkey") pubKey: HexKey, - @JsonProperty("created_at") createdAt: Long, - kind: Int, - tags: Array>, - content: String, - sig: HexKey, -) : Event(id, pubKey, createdAt, kind, tags, content, sig) { - @Transient var host: HostStub? = null // host event to broadcast when needed -} - -class HostStub( - val id: HexKey, - val pubKey: HexKey, - val kind: Int, -) - -@Immutable -interface AddressableEvent { - fun dTag(): String - - fun address(relayHint: String? = null): ATag - - fun addressTag(): String -} - -@Immutable -open class BaseAddressableEvent( - id: HexKey, - pubKey: HexKey, - createdAt: Long, - kind: Int, - tags: Array>, - content: String, - sig: HexKey, -) : Event(id, pubKey, createdAt, kind, tags, content, sig), - AddressableEvent { - override fun dTag() = tags.firstOrNull { it.size > 1 && it[0] == "d" }?.get(1) ?: "" - - override fun address(relayHint: String?) = ATag(kind, pubKey, dTag(), relayHint) - - /** - * Creates the tag in a memory effecient way (without creating the ATag class - */ - override fun addressTag() = ATag.assembleATag(kind, pubKey, dTag()) -} - -data class ZapSplitSetup( - val lnAddressOrPubKeyHex: String, - val relay: String?, - val weight: Double, - val isLnAddress: Boolean, -) - -interface RootScope diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/EventFactory.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/EventFactory.kt deleted file mode 100644 index b60be0cc3..000000000 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/EventFactory.kt +++ /dev/null @@ -1,169 +0,0 @@ -/** - * Copyright (c) 2024 Vitor Pamplona - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the - * Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -package com.vitorpamplona.quartz.events - -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.events.nip46.NostrConnectEvent - -class EventFactory { - companion object { - val factories: MutableMap>, String, HexKey) -> Event> = mutableMapOf() - - fun create( - id: String, - pubKey: String, - createdAt: Long, - kind: Int, - tags: Array>, - content: String, - sig: String, - ) = when (kind) { - AdvertisedRelayListEvent.KIND -> AdvertisedRelayListEvent(id, pubKey, createdAt, tags, content, sig) - AppDefinitionEvent.KIND -> AppDefinitionEvent(id, pubKey, createdAt, tags, content, sig) - AppRecommendationEvent.KIND -> AppRecommendationEvent(id, pubKey, createdAt, tags, content, sig) - AppSpecificDataEvent.KIND -> AppSpecificDataEvent(id, pubKey, createdAt, tags, content, sig) - AudioHeaderEvent.KIND -> AudioHeaderEvent(id, pubKey, createdAt, tags, content, sig) - AudioTrackEvent.KIND -> AudioTrackEvent(id, pubKey, createdAt, tags, content, sig) - BadgeAwardEvent.KIND -> BadgeAwardEvent(id, pubKey, createdAt, tags, content, sig) - BadgeDefinitionEvent.KIND -> BadgeDefinitionEvent(id, pubKey, createdAt, tags, content, sig) - BadgeProfilesEvent.KIND -> BadgeProfilesEvent(id, pubKey, createdAt, tags, content, sig) - BlossomServersEvent.KIND -> BlossomServersEvent(id, pubKey, createdAt, tags, content, sig) - BlossomAuthorizationEvent.KIND -> BlossomAuthorizationEvent(id, pubKey, createdAt, tags, content, sig) - BookmarkListEvent.KIND -> BookmarkListEvent(id, pubKey, createdAt, tags, content, sig) - CalendarDateSlotEvent.KIND -> CalendarDateSlotEvent(id, pubKey, createdAt, tags, content, sig) - CalendarEvent.KIND -> CalendarEvent(id, pubKey, createdAt, tags, content, sig) - CalendarTimeSlotEvent.KIND -> CalendarTimeSlotEvent(id, pubKey, createdAt, tags, content, sig) - CalendarRSVPEvent.KIND -> CalendarRSVPEvent(id, pubKey, createdAt, tags, content, sig) - ChannelCreateEvent.KIND -> ChannelCreateEvent(id, pubKey, createdAt, tags, content, sig) - ChannelHideMessageEvent.KIND -> ChannelHideMessageEvent(id, pubKey, createdAt, tags, content, sig) - ChannelListEvent.KIND -> ChannelListEvent(id, pubKey, createdAt, tags, content, sig) - ChannelMessageEvent.KIND -> ChannelMessageEvent(id, pubKey, createdAt, tags, content, sig) - ChannelMetadataEvent.KIND -> ChannelMetadataEvent(id, pubKey, createdAt, tags, content, sig) - ChannelMuteUserEvent.KIND -> ChannelMuteUserEvent(id, pubKey, createdAt, tags, content, sig) - ChatMessageEncryptedFileHeaderEvent.KIND -> { - if (id.isBlank()) { - ChatMessageEncryptedFileHeaderEvent( - Event.generateId(pubKey, createdAt, kind, tags, content), - pubKey, - createdAt, - tags, - content, - sig, - ) - } else { - ChatMessageEncryptedFileHeaderEvent(id, pubKey, createdAt, tags, content, sig) - } - } - ChatMessageEvent.KIND -> { - if (id.isBlank()) { - ChatMessageEvent( - Event.generateId(pubKey, createdAt, kind, tags, content), - pubKey, - createdAt, - tags, - content, - sig, - ) - } else { - ChatMessageEvent(id, pubKey, createdAt, tags, content, sig) - } - } - ChatMessageRelayListEvent.KIND -> ChatMessageRelayListEvent(id, pubKey, createdAt, tags, content, sig) - ClassifiedsEvent.KIND -> ClassifiedsEvent(id, pubKey, createdAt, tags, content, sig) - CommentEvent.KIND -> CommentEvent(id, pubKey, createdAt, tags, content, sig) - CommunityDefinitionEvent.KIND -> CommunityDefinitionEvent(id, pubKey, createdAt, tags, content, sig) - CommunityListEvent.KIND -> CommunityListEvent(id, pubKey, createdAt, tags, content, sig) - CommunityPostApprovalEvent.KIND -> CommunityPostApprovalEvent(id, pubKey, createdAt, tags, content, sig) - ContactListEvent.KIND -> ContactListEvent(id, pubKey, createdAt, tags, content, sig) - DeletionEvent.KIND -> DeletionEvent(id, pubKey, createdAt, tags, content, sig) - DraftEvent.KIND -> DraftEvent(id, pubKey, createdAt, tags, content, sig) - EmojiPackEvent.KIND -> EmojiPackEvent(id, pubKey, createdAt, tags, content, sig) - EmojiPackSelectionEvent.KIND -> EmojiPackSelectionEvent(id, pubKey, createdAt, tags, content, sig) - FileHeaderEvent.KIND -> FileHeaderEvent(id, pubKey, createdAt, tags, content, sig) - ProfileGalleryEntryEvent.KIND -> ProfileGalleryEntryEvent(id, pubKey, createdAt, tags, content, sig) - FileServersEvent.KIND -> FileServersEvent(id, pubKey, createdAt, tags, content, sig) - FileStorageEvent.KIND -> FileStorageEvent(id, pubKey, createdAt, tags, content, sig) - FileStorageHeaderEvent.KIND -> FileStorageHeaderEvent(id, pubKey, createdAt, tags, content, sig) - FhirResourceEvent.KIND -> FhirResourceEvent(id, pubKey, createdAt, tags, content, sig) - GenericRepostEvent.KIND -> GenericRepostEvent(id, pubKey, createdAt, tags, content, sig) - GiftWrapEvent.KIND -> GiftWrapEvent(id, pubKey, createdAt, tags, content, sig) - GitIssueEvent.KIND -> GitIssueEvent(id, pubKey, createdAt, tags, content, sig) - GitReplyEvent.KIND -> GitReplyEvent(id, pubKey, createdAt, tags, content, sig) - GitPatchEvent.KIND -> GitPatchEvent(id, pubKey, createdAt, tags, content, sig) - GitRepositoryEvent.KIND -> GitRepositoryEvent(id, pubKey, createdAt, tags, content, sig) - GoalEvent.KIND -> GoalEvent(id, pubKey, createdAt, tags, content, sig) - HighlightEvent.KIND -> HighlightEvent(id, pubKey, createdAt, tags, content, sig) - HTTPAuthorizationEvent.KIND -> HTTPAuthorizationEvent(id, pubKey, createdAt, tags, content, sig) - InteractiveStoryPrologueEvent.KIND -> InteractiveStoryPrologueEvent(id, pubKey, createdAt, tags, content, sig) - InteractiveStorySceneEvent.KIND -> InteractiveStorySceneEvent(id, pubKey, createdAt, tags, content, sig) - InteractiveStoryReadingStateEvent.KIND -> InteractiveStoryReadingStateEvent(id, pubKey, createdAt, tags, content, sig) - LiveActivitiesChatMessageEvent.KIND -> LiveActivitiesChatMessageEvent(id, pubKey, createdAt, tags, content, sig) - LiveActivitiesEvent.KIND -> LiveActivitiesEvent(id, pubKey, createdAt, tags, content, sig) - LnZapEvent.KIND -> LnZapEvent(id, pubKey, createdAt, tags, content, sig) - LnZapPaymentRequestEvent.KIND -> LnZapPaymentRequestEvent(id, pubKey, createdAt, tags, content, sig) - LnZapPaymentResponseEvent.KIND -> LnZapPaymentResponseEvent(id, pubKey, createdAt, tags, content, sig) - LnZapPrivateEvent.KIND -> LnZapPrivateEvent(id, pubKey, createdAt, tags, content, sig) - LnZapRequestEvent.KIND -> LnZapRequestEvent(id, pubKey, createdAt, tags, content, sig) - LongTextNoteEvent.KIND -> LongTextNoteEvent(id, pubKey, createdAt, tags, content, sig) - MetadataEvent.KIND -> MetadataEvent(id, pubKey, createdAt, tags, content, sig) - MuteListEvent.KIND -> MuteListEvent(id, pubKey, createdAt, tags, content, sig) - NNSEvent.KIND -> NNSEvent(id, pubKey, createdAt, tags, content, sig) - NostrConnectEvent.KIND -> NostrConnectEvent(id, pubKey, createdAt, tags, content, sig) - NIP90StatusEvent.KIND -> NIP90StatusEvent(id, pubKey, createdAt, tags, content, sig) - NIP90ContentDiscoveryRequestEvent.KIND -> NIP90ContentDiscoveryRequestEvent(id, pubKey, createdAt, tags, content, sig) - NIP90ContentDiscoveryResponseEvent.KIND -> NIP90ContentDiscoveryResponseEvent(id, pubKey, createdAt, tags, content, sig) - NIP90UserDiscoveryRequestEvent.KIND -> NIP90UserDiscoveryRequestEvent(id, pubKey, createdAt, tags, content, sig) - NIP90UserDiscoveryResponseEvent.KIND -> NIP90UserDiscoveryResponseEvent(id, pubKey, createdAt, tags, content, sig) - OtsEvent.KIND -> OtsEvent(id, pubKey, createdAt, tags, content, sig) - PeopleListEvent.KIND -> PeopleListEvent(id, pubKey, createdAt, tags, content, sig) - PictureEvent.KIND -> PictureEvent(id, pubKey, createdAt, tags, content, sig) - PinListEvent.KIND -> PinListEvent(id, pubKey, createdAt, tags, content, sig) - PollNoteEvent.KIND -> PollNoteEvent(id, pubKey, createdAt, tags, content, sig) - PrivateDmEvent.KIND -> PrivateDmEvent(id, pubKey, createdAt, tags, content, sig) - PrivateOutboxRelayListEvent.KIND -> PrivateOutboxRelayListEvent(id, pubKey, createdAt, tags, content, sig) - ReactionEvent.KIND -> ReactionEvent(id, pubKey, createdAt, tags, content, sig) - RecommendRelayEvent.KIND -> RecommendRelayEvent(id, pubKey, createdAt, tags, content, sig) - RelationshipStatusEvent.KIND -> RelationshipStatusEvent(id, pubKey, createdAt, tags, content, sig) - RelayAuthEvent.KIND -> RelayAuthEvent(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) - SealedGossipEvent.KIND -> SealedGossipEvent(id, pubKey, createdAt, tags, content, sig) - SearchRelayListEvent.KIND -> SearchRelayListEvent(id, pubKey, createdAt, tags, content, sig) - StatusEvent.KIND -> StatusEvent(id, pubKey, createdAt, tags, content, sig) - TextNoteEvent.KIND -> TextNoteEvent(id, pubKey, createdAt, tags, content, sig) - TextNoteModificationEvent.KIND -> TextNoteModificationEvent(id, pubKey, createdAt, tags, content, sig) - TorrentEvent.KIND -> TorrentEvent(id, pubKey, createdAt, tags, content, sig) - TorrentCommentEvent.KIND -> TorrentCommentEvent(id, pubKey, createdAt, tags, content, sig) - VideoHorizontalEvent.KIND -> VideoHorizontalEvent(id, pubKey, createdAt, tags, content, sig) - VideoVerticalEvent.KIND -> VideoVerticalEvent(id, pubKey, createdAt, tags, content, sig) - VideoViewEvent.KIND -> VideoViewEvent(id, pubKey, createdAt, tags, content, sig) - WikiNoteEvent.KIND -> WikiNoteEvent(id, pubKey, createdAt, tags, content, sig) - else -> { - factories[kind]?.let { - return it(id, pubKey, createdAt, tags, content, sig) - } - - Event(id, pubKey, createdAt, kind, tags, content, sig) - } - } - } -} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/EventInterface.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/EventInterface.kt deleted file mode 100644 index a014f8c6a..000000000 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/EventInterface.kt +++ /dev/null @@ -1,161 +0,0 @@ -/** - * Copyright (c) 2024 Vitor Pamplona - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the - * Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -package com.vitorpamplona.quartz.events - -import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.HexKey -import java.math.BigDecimal - -@Immutable -interface EventInterface { - fun isContentEncoded(): Boolean - - fun countMemory(): Long - - fun id(): HexKey - - fun pubKey(): HexKey - - fun createdAt(): Long - - fun kind(): Int - - fun tags(): Array> - - fun content(): String - - fun sig(): HexKey - - fun toJson(): String - - fun checkSignature() - - fun hasValidSignature(): Boolean - - fun isTagged( - key: String, - tag: String, - ): Boolean - - fun isAnyTagged( - key: String, - tags: Set, - ): Boolean - - fun isTaggedWord(word: String): Boolean - - fun isTaggedUser(idHex: String): Boolean - - fun isTaggedUsers(idHexes: Set): Boolean - - fun isTaggedEvent(idHex: String): Boolean - - fun isTaggedAddressableNote(idHex: String): Boolean - - fun isTaggedAddressableNotes(idHexes: Set): Boolean - - fun isTaggedHash(hashtag: String): Boolean - - fun isTaggedGeoHash(hashtag: String): Boolean - - fun isTaggedHashes(hashtags: Set): Boolean - - fun isTaggedGeoHashes(hashtags: Set): Boolean - - fun firstIsTaggedHashes(hashtags: Set): String? - - fun firstIsTaggedAddressableNote(addressableNotes: Set): String? - - fun isTaggedAddressableKind(kind: Int): Boolean - - fun getTagOfAddressableKind(kind: Int): ATag? - - fun expiration(): Long? - - fun hasHashtags(): Boolean - - fun hasGeohashes(): Boolean - - fun hashtags(): List - - fun geohashes(): List - - fun getReward(): BigDecimal? - - fun getPoWRank(): Int - - fun getGeoHash(): String? - - fun zapSplitSetup(): List - - fun isSensitive(): Boolean - - fun subject(): String? - - fun zapraiserAmount(): Long? - - fun hasAnyTaggedUser(): Boolean - - fun hasTagWithContent(tagName: String): Boolean - - fun forEachTaggedEvent(onEach: (eventId: HexKey) -> Unit) - - fun forEachHashTag(onEach: (eventId: HexKey) -> Unit) - - fun anyHashTag(onEach: (str: String) -> Boolean): Boolean - - fun mapTaggedEvent(map: (eventId: HexKey) -> R): List - - fun mapTaggedAddress(map: (address: String) -> R): List - - fun taggedAddresses(): List - - fun taggedUsers(): List - - fun taggedEvents(): List - - fun taggedUrls(): List - - fun firstTag(key: String): String? - - fun firstTagFor(vararg key: String): String? - - fun firstTaggedAddress(): ATag? - - fun firstTaggedUser(): HexKey? - - fun firstTaggedEvent(): HexKey? - - fun firstTaggedUrl(): String? - - fun firstTaggedK(): Int? - - fun taggedEmojis(): List - - fun matchTag1With(text: String): Boolean - - fun isExpired(): Boolean - - fun isExpirationBefore(time: Long): Boolean - - fun hasZapSplitSetup(): Boolean -} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/LnZapPaymentResponseEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/LnZapPaymentResponseEvent.kt deleted file mode 100644 index e9e1cc7ce..000000000 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/LnZapPaymentResponseEvent.kt +++ /dev/null @@ -1,190 +0,0 @@ -/** - * Copyright (c) 2024 Vitor Pamplona - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the - * Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -package com.vitorpamplona.quartz.events - -import android.util.Log -import androidx.compose.runtime.Immutable -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.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner -import com.vitorpamplona.quartz.utils.bytesUsedInMemory -import com.vitorpamplona.quartz.utils.pointerSizeInBytes - -@Immutable -class LnZapPaymentResponseEvent( - id: HexKey, - pubKey: HexKey, - createdAt: Long, - tags: Array>, - content: String, - sig: HexKey, -) : Event(id, pubKey, createdAt, KIND, tags, content, sig) { - // Once one of an app user decrypts the payment, all users else can see it. - @Transient private var response: Response? = null - - override fun countMemory(): Long = super.countMemory() + pointerSizeInBytes + (response?.countMemory() ?: 0) - - fun requestAuthor() = tags.firstOrNull { it.size > 1 && it[0] == "p" }?.get(1) - - fun requestId() = tags.firstOrNull { it.size > 1 && it[0] == "e" }?.get(1) - - fun talkingWith(oneSideHex: String): HexKey = if (pubKey == oneSideHex) requestAuthor() ?: pubKey else pubKey - - private fun plainContent( - signer: NostrSigner, - onReady: (String) -> Unit, - ) { - try { - signer.decrypt(content, talkingWith(signer.pubKey)) { content -> onReady(content) } - } catch (e: Exception) { - Log.w("PrivateDM", "Error decrypting the message ${e.message}") - } - } - - fun response( - signer: NostrSigner, - onReady: (Response) -> Unit, - ) { - response?.let { - onReady(it) - return - } - - try { - if (content.isNotEmpty()) { - plainContent(signer) { - mapper.readValue(it, Response::class.java)?.let { - response = it - onReady(it) - } - } - } - } catch (e: Exception) { - Log.w("LnZapPaymentResponseEvent", "Can't parse content as a payment response: $content", e) - } - } - - companion object { - const val KIND = 23195 - const val ALT = "Zap payment response" - } -} - -// RESPONSE OBJECTS -abstract class Response( - @JsonProperty("result_type") val resultType: String, -) { - abstract fun countMemory(): Long -} - -// PayInvoice Call - -class PayInvoiceSuccessResponse( - val result: PayInvoiceResultParams? = null, -) : Response("pay_invoice") { - class PayInvoiceResultParams( - val preimage: String, - ) { - fun countMemory(): Long = pointerSizeInBytes + preimage.bytesUsedInMemory() - } - - override fun countMemory(): Long = pointerSizeInBytes + (result?.countMemory() ?: 0) -} - -class PayInvoiceErrorResponse( - val error: PayInvoiceErrorParams? = null, -) : Response("pay_invoice") { - class PayInvoiceErrorParams( - val code: ErrorType?, - val message: String?, - ) { - fun countMemory(): Long = pointerSizeInBytes + pointerSizeInBytes + (message?.bytesUsedInMemory() ?: 0) - } - - override fun countMemory(): Long = pointerSizeInBytes + (error?.countMemory() ?: 0) - - enum class ErrorType { - @JsonProperty(value = "RATE_LIMITED") - RATE_LIMITED, - - // The client is sending commands too fast. It should retry in a few seconds. - @JsonProperty(value = "NOT_IMPLEMENTED") - NOT_IMPLEMENTED, - - // The command is not known or is intentionally not implemented. - @JsonProperty(value = "INSUFFICIENT_BALANCE") - INSUFFICIENT_BALANCE, - - // The wallet does not have enough funds to cover a fee reserve or the payment amount. - @JsonProperty(value = "QUOTA_EXCEEDED") - QUOTA_EXCEEDED, - - // The wallet has exceeded its spending quota. - @JsonProperty(value = "RESTRICTED") - RESTRICTED, - - // This public key is not allowed to do this operation. - @JsonProperty(value = "UNAUTHORIZED") - UNAUTHORIZED, - - // This public key has no wallet connected. - @JsonProperty(value = "INTERNAL") - INTERNAL, - - // An internal error. - @JsonProperty(value = "OTHER") - OTHER, // Other error. - } -} - -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") - val error = jsonObject.get("error") - if (result != null) { - return jp.codec.treeToValue(jsonObject, PayInvoiceSuccessResponse::class.java) - } - if (error != null) { - return jp.codec.treeToValue(jsonObject, PayInvoiceErrorResponse::class.java) - } - } else { - // tries to guess - if (jsonObject.get("result")?.get("preimage") != null) { - return jp.codec.treeToValue(jsonObject, PayInvoiceSuccessResponse::class.java) - } - if (jsonObject.get("error")?.get("code") != null) { - return jp.codec.treeToValue(jsonObject, PayInvoiceErrorResponse::class.java) - } - } - return null - } -} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/MetadataEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/MetadataEvent.kt deleted file mode 100644 index 03c75f878..000000000 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/MetadataEvent.kt +++ /dev/null @@ -1,293 +0,0 @@ -/** - * Copyright (c) 2024 Vitor Pamplona - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the - * Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -package com.vitorpamplona.quartz.events - -import android.util.Log -import androidx.compose.runtime.Stable -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.databind.node.ObjectNode -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner -import com.vitorpamplona.quartz.signers.NostrSignerSync -import com.vitorpamplona.quartz.utils.TimeUtils -import java.io.ByteArrayInputStream -import java.io.StringWriter - -@Stable -abstract class IdentityClaim( - val identity: String, - val proof: String, -) { - abstract fun toProofUrl(): String - - abstract fun platform(): String - - fun platformIdentity() = "${platform()}:$identity" - - companion object { - fun create( - platformIdentity: String, - proof: String, - ): IdentityClaim { - val (platform, identity) = platformIdentity.split(':') - - return when (platform.lowercase()) { - GitHubIdentity.platform -> GitHubIdentity(identity, proof) - TwitterIdentity.platform -> TwitterIdentity(identity, proof) - TelegramIdentity.platform -> TelegramIdentity(identity, proof) - MastodonIdentity.platform -> MastodonIdentity(identity, proof) - else -> throw IllegalArgumentException("Platform $platform not supported") - } - } - } -} - -class GitHubIdentity( - identity: String, - proof: String, -) : IdentityClaim(identity, proof) { - override fun toProofUrl() = "https://gist.github.com/$identity/$proof" - - override fun platform() = platform - - companion object { - val platform = "github" - - fun parseProofUrl(proofUrl: String): GitHubIdentity? { - return try { - if (proofUrl.isBlank()) return null - val path = proofUrl.removePrefix("https://gist.github.com/").split("?")[0].split("/") - - GitHubIdentity(path[0], path[1]) - } catch (e: Exception) { - null - } - } - } -} - -class TwitterIdentity( - identity: String, - proof: String, -) : IdentityClaim(identity, proof) { - override fun toProofUrl() = "https://x.com/$identity/status/$proof" - - override fun platform() = platform - - companion object { - val platform = "twitter" - - fun parseProofUrl(proofUrl: String): TwitterIdentity? { - return try { - if (proofUrl.isBlank()) return null - val path = proofUrl.removePrefix("https://x.com/").split("?")[0].split("/") - - TwitterIdentity(path[0], path[2]) - } catch (e: Exception) { - null - } - } - } -} - -class TelegramIdentity( - identity: String, - proof: String, -) : IdentityClaim(identity, proof) { - override fun toProofUrl() = "https://t.me/$proof" - - override fun platform() = platform - - companion object { - val platform = "telegram" - } -} - -class MastodonIdentity( - identity: String, - proof: String, -) : IdentityClaim(identity, proof) { - override fun toProofUrl() = "https://$identity/$proof" - - override fun platform() = platform - - companion object { - val platform = "mastodon" - - fun parseProofUrl(proofUrl: String): MastodonIdentity? { - return try { - if (proofUrl.isBlank()) return null - val path = proofUrl.removePrefix("https://").split("?")[0].split("/") - - return MastodonIdentity("${path[0]}/${path[1]}", path[2]) - } catch (e: Exception) { - null - } - } - } -} - -class MetadataEvent( - id: HexKey, - pubKey: HexKey, - createdAt: Long, - tags: Array>, - content: String, - sig: HexKey, -) : Event(id, pubKey, createdAt, KIND, tags, content, sig) { - fun contactMetaData() = - try { - mapper.readValue(content, UserMetadata::class.java) - } catch (e: Exception) { - // e.printStackTrace() - Log.w("MetadataEvent", "Content Parse Error: ${toNostrUri()} ${e.localizedMessage}") - null - } - - fun identityClaims() = - tags - .filter { it.firstOrNull() == "i" } - .mapNotNull { - try { - IdentityClaim.create(it[1], it[2]) - } catch (e: Exception) { - Log.e("MetadataEvent", "Can't parse identity [${it.joinToString { "," }}]", e) - null - } - } - - companion object { - const val KIND = 0 - - fun newUser( - name: String?, - signer: NostrSignerSync, - createdAt: Long = TimeUtils.now(), - ): MetadataEvent? { - // Tries to not delete any existing attribute that we do not work with. - val currentJson = ObjectMapper().createObjectNode() - - name?.let { addIfNotBlank(currentJson, "name", it.trim()) } - val writer = StringWriter() - ObjectMapper().writeValue(writer, currentJson) - - val tags = mutableListOf>() - - tags.add( - arrayOf("alt", "User profile for ${name ?: currentJson.get("name").asText() ?: ""}"), - ) - - return signer.sign(createdAt, KIND, tags.toTypedArray(), writer.buffer.toString()) - } - - fun updateFromPast( - latest: MetadataEvent?, - name: String?, - picture: String?, - banner: String?, - website: String?, - about: String?, - nip05: String?, - lnAddress: String?, - lnURL: String?, - pronouns: String?, - twitter: String?, - mastodon: String?, - github: String?, - signer: NostrSigner, - createdAt: Long = TimeUtils.now(), - onReady: (MetadataEvent) -> Unit, - ) { - // Tries to not delete any existing attribute that we do not work with. - val currentJson = - if (latest != null) { - ObjectMapper() - .readTree( - ByteArrayInputStream(latest.content.toByteArray(Charsets.UTF_8)), - ) as ObjectNode - } else { - ObjectMapper().createObjectNode() - } - - name?.let { addIfNotBlank(currentJson, "name", it.trim()) } - name?.let { addIfNotBlank(currentJson, "display_name", it.trim()) } - picture?.let { addIfNotBlank(currentJson, "picture", it.trim()) } - banner?.let { addIfNotBlank(currentJson, "banner", it.trim()) } - website?.let { addIfNotBlank(currentJson, "website", it.trim()) } - pronouns?.let { addIfNotBlank(currentJson, "pronouns", it.trim()) } - about?.let { addIfNotBlank(currentJson, "about", it.trim()) } - nip05?.let { addIfNotBlank(currentJson, "nip05", it.trim()) } - lnAddress?.let { addIfNotBlank(currentJson, "lud16", it.trim()) } - lnURL?.let { addIfNotBlank(currentJson, "lud06", it.trim()) } - - var claims = latest?.identityClaims() ?: emptyList() - - if (twitter?.isBlank() == true) { - // delete twitter - claims = claims.filter { it !is TwitterIdentity } - } - - if (github?.isBlank() == true) { - // delete github - claims = claims.filter { it !is GitHubIdentity } - } - - if (mastodon?.isBlank() == true) { - // delete mastodon - claims = claims.filter { it !is MastodonIdentity } - } - - // Updates while keeping other identities intact - val newClaims = - listOfNotNull( - twitter?.let { TwitterIdentity.parseProofUrl(it) }, - github?.let { GitHubIdentity.parseProofUrl(it) }, - mastodon?.let { MastodonIdentity.parseProofUrl(it) }, - ) + - claims.filter { it !is TwitterIdentity && it !is GitHubIdentity && it !is MastodonIdentity } - - val writer = StringWriter() - ObjectMapper().writeValue(writer, currentJson) - - val tags = mutableListOf>() - - tags.add( - arrayOf("alt", "User profile for ${name ?: currentJson.get("name").asText() ?: ""}"), - ) - - newClaims.forEach { tags.add(arrayOf("i", it.platformIdentity(), it.proof)) } - - signer.sign(createdAt, KIND, tags.toTypedArray(), writer.buffer.toString(), onReady) - } - - private fun addIfNotBlank( - currentJson: ObjectNode, - key: String, - value: String, - ) { - if (value.isBlank() || value == "null") { - currentJson.remove(key) - } else { - currentJson.put(key, value.trim()) - } - } - } -} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/AudioHeaderEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/audio/AudioHeaderEvent.kt similarity index 89% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/AudioHeaderEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/experimental/audio/AudioHeaderEvent.kt index 3ddc1aca7..78dec108d 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/AudioHeaderEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/audio/AudioHeaderEvent.kt @@ -18,12 +18,14 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.experimental.audio import androidx.compose.runtime.Immutable import com.fasterxml.jackson.module.kotlin.readValue -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -43,7 +45,7 @@ class AudioHeaderEvent( tags .firstOrNull { it.size > 1 && it[0] == WAVEFORM } ?.get(1) - ?.let { mapper.readValue>(it) } + ?.let { EventMapper.mapper.readValue>(it) } companion object { const val KIND = 1808 diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/AudioTrackEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/audio/AudioTrackEvent.kt similarity index 92% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/AudioTrackEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/experimental/audio/AudioTrackEvent.kt index e250a206c..3999b771a 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/AudioTrackEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/audio/AudioTrackEvent.kt @@ -18,11 +18,12 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.experimental.audio import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.BaseAddressableEvent +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.utils.TimeUtils @Immutable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/experimental/bounties/EventExt.kt b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/bounties/EventExt.kt new file mode 100644 index 000000000..94a4a603d --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/bounties/EventExt.kt @@ -0,0 +1,27 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.experimental.bounties + +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.core.firstMapTagged +import java.math.BigDecimal + +fun Event.getReward(): BigDecimal? = tags.firstMapTagged("reward") { runCatching { BigDecimal(it[1]) }.getOrNull() } diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/PrivateOutboxRelayListEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/edits/PrivateOutboxRelayListEvent.kt similarity index 91% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/PrivateOutboxRelayListEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/experimental/edits/PrivateOutboxRelayListEvent.kt index a26f54c05..7d7b14292 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/PrivateOutboxRelayListEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/edits/PrivateOutboxRelayListEvent.kt @@ -18,14 +18,17 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.experimental.edits import android.util.Log import androidx.compose.runtime.Immutable import com.fasterxml.jackson.module.kotlin.readValue -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.addressables.BaseAddressableEvent +import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip21UriScheme.toNostrUri import com.vitorpamplona.quartz.utils.TimeUtils import com.vitorpamplona.quartz.utils.bytesUsedInMemory import com.vitorpamplona.quartz.utils.pointerSizeInBytes @@ -84,7 +87,7 @@ class PrivateOutboxRelayListEvent( try { signer.nip44Decrypt(content, pubKey) { try { - privateTagsCache = mapper.readValue>>(it) + privateTagsCache = EventMapper.mapper.readValue>>(it) privateTagsCache?.let { onReady(it) } } catch (e: Throwable) { Log.w("PrivateOutboxRelayListEvent", "Error parsing the JSON: ${e.message}. Json `$it` from event `${toNostrUri()}`") @@ -109,7 +112,7 @@ class PrivateOutboxRelayListEvent( signer: NostrSigner, onReady: (String) -> Unit, ) { - val msg = mapper.writeValueAsString(privateTags) + val msg = EventMapper.mapper.writeValueAsString(privateTags) signer.nip44Encrypt( msg, diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/TextNoteModificationEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/edits/TextNoteModificationEvent.kt similarity index 89% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/TextNoteModificationEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/experimental/edits/TextNoteModificationEvent.kt index 0094c5983..0763a7a1b 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/TextNoteModificationEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/edits/TextNoteModificationEvent.kt @@ -18,11 +18,13 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.experimental.edits import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.events.firstTaggedEvent +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.utils.TimeUtils @Immutable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/Nip54InlineMetadata.kt b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/inlineMetadata/Nip54InlineMetadata.kt similarity index 95% rename from quartz/src/main/java/com/vitorpamplona/quartz/encoders/Nip54InlineMetadata.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/experimental/inlineMetadata/Nip54InlineMetadata.kt index d2bd7d9d5..b09f6fb99 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/Nip54InlineMetadata.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/inlineMetadata/Nip54InlineMetadata.kt @@ -18,8 +18,9 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.encoders +package com.vitorpamplona.quartz.experimental.inlineMetadata +import com.vitorpamplona.quartz.nip92IMeta.IMetaTag import java.net.URI import java.net.URLDecoder import java.net.URLEncoder diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/InteractiveStoryBaseEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/interactiveStories/InteractiveStoryBaseEvent.kt similarity index 81% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/InteractiveStoryBaseEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/experimental/interactiveStories/InteractiveStoryBaseEvent.kt index 4c865724d..f8bd76f18 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/InteractiveStoryBaseEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/interactiveStories/InteractiveStoryBaseEvent.kt @@ -18,12 +18,20 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.experimental.interactiveStories -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.IMetaTag -import com.vitorpamplona.quartz.encoders.Nip92MediaAttachments +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.addressables.BaseAddressableEvent +import com.vitorpamplona.quartz.nip01Core.core.firstTagValue +import com.vitorpamplona.quartz.nip01Core.geohash.geohashMipMap +import com.vitorpamplona.quartz.nip10Notes.findHashtags +import com.vitorpamplona.quartz.nip10Notes.findURLs +import com.vitorpamplona.quartz.nip19Bech32Entities.parse +import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiUrl +import com.vitorpamplona.quartz.nip57Zaps.ZapSplitSetup +import com.vitorpamplona.quartz.nip92IMeta.IMetaTag +import com.vitorpamplona.quartz.nip92IMeta.Nip92MediaAttachments open class InteractiveStoryBaseEvent( id: HexKey, @@ -34,11 +42,11 @@ open class InteractiveStoryBaseEvent( content: String, sig: HexKey, ) : BaseAddressableEvent(id, pubKey, createdAt, kind, tags, content, sig) { - fun title() = firstTag("title") + fun title() = tags.firstTagValue("title") - fun summary() = firstTag("summary") + fun summary() = tags.firstTagValue("summary") - fun image() = firstTag("image") + fun image() = tags.firstTagValue("image") fun options() = tags diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/InteractiveStoryPrologueEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/interactiveStories/InteractiveStoryPrologueEvent.kt similarity index 87% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/InteractiveStoryPrologueEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/experimental/interactiveStories/InteractiveStoryPrologueEvent.kt index f75f19a6e..90ce99821 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/InteractiveStoryPrologueEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/interactiveStories/InteractiveStoryPrologueEvent.kt @@ -18,12 +18,14 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.experimental.interactiveStories -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.IMetaTag -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip22Comments.RootScope +import com.vitorpamplona.quartz.nip57Zaps.ZapSplitSetup +import com.vitorpamplona.quartz.nip92IMeta.IMetaTag import com.vitorpamplona.quartz.utils.TimeUtils class InteractiveStoryPrologueEvent( diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/InteractiveStoryReadingStateEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/interactiveStories/InteractiveStoryReadingStateEvent.kt similarity index 84% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/InteractiveStoryReadingStateEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/experimental/interactiveStories/InteractiveStoryReadingStateEvent.kt index 0c0228554..29d525d40 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/InteractiveStoryReadingStateEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/interactiveStories/InteractiveStoryReadingStateEvent.kt @@ -18,12 +18,16 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.experimental.interactiveStories import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.addressables.BaseAddressableEvent +import com.vitorpamplona.quartz.nip01Core.core.firstTag +import com.vitorpamplona.quartz.nip01Core.core.firstTagValue +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip19Bech32Entities.parse import com.vitorpamplona.quartz.utils.TimeUtils import com.vitorpamplona.quartz.utils.removeTrailingNullsAndEmptyOthers @@ -36,23 +40,17 @@ class InteractiveStoryReadingStateEvent( content: String, sig: HexKey, ) : BaseAddressableEvent(id, pubKey, createdAt, KIND, tags, content, sig) { - fun title() = firstTag("title") + fun title() = tags.firstTagValue("title") - fun summary() = firstTag("summary") + fun summary() = tags.firstTagValue("summary") - fun image() = firstTag("image") + fun image() = tags.firstTagValue("image") - fun status() = firstTag("status") + fun status() = tags.firstTagValue("status") - fun root() = - tags.firstOrNull { it.size > 1 && it[0] == "A" }?.let { - ATag.parse(it[1], it.getOrNull(2)) - } + fun root() = tags.firstTag("A")?.let { ATag.parse(it[1], it.getOrNull(2)) } - fun currentScene() = - tags.firstOrNull { it.size > 1 && it[0] == "a" }?.let { - ATag.parse(it[1], it.getOrNull(2)) - } + fun currentScene() = tags.firstTag("a")?.let { ATag.parse(it[1], it.getOrNull(2)) } companion object { const val KIND = 30298 diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/InteractiveStorySceneEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/interactiveStories/InteractiveStorySceneEvent.kt similarity index 87% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/InteractiveStorySceneEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/experimental/interactiveStories/InteractiveStorySceneEvent.kt index 45807eeee..6b5d6b710 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/InteractiveStorySceneEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/interactiveStories/InteractiveStorySceneEvent.kt @@ -18,12 +18,14 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.experimental.interactiveStories -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.IMetaTag -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip22Comments.RootScope +import com.vitorpamplona.quartz.nip57Zaps.ZapSplitSetup +import com.vitorpamplona.quartz.nip92IMeta.IMetaTag import com.vitorpamplona.quartz.utils.TimeUtils class InteractiveStorySceneEvent( diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/FhirResourceEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/medical/FhirResourceEvent.kt similarity index 89% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/FhirResourceEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/experimental/medical/FhirResourceEvent.kt index 923fb47a7..abac11259 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/FhirResourceEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/medical/FhirResourceEvent.kt @@ -18,11 +18,12 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.experimental.medical import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.utils.TimeUtils @Immutable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/FileStorageEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/nip95/FileStorageEvent.kt similarity index 92% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/FileStorageEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/experimental/nip95/FileStorageEvent.kt index e3adef3fb..f154fb8b8 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/FileStorageEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/nip95/FileStorageEvent.kt @@ -18,12 +18,13 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.experimental.nip95 import android.util.Log import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.utils.TimeUtils import java.util.Base64 diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/FileStorageHeaderEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/nip95/FileStorageHeaderEvent.kt similarity index 92% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/FileStorageHeaderEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/experimental/nip95/FileStorageHeaderEvent.kt index 2b3185b3a..735191fb8 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/FileStorageHeaderEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/nip95/FileStorageHeaderEvent.kt @@ -18,12 +18,14 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.experimental.nip95 import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.Dimension -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip94FileMetadata.Dimension +import com.vitorpamplona.quartz.nip94FileMetadata.FileHeaderEvent import com.vitorpamplona.quartz.utils.TimeUtils @Immutable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/NNSEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/nns/NNSEvent.kt similarity index 89% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/NNSEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/experimental/nns/NNSEvent.kt index 73223548d..0c8c40dd0 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/NNSEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/nns/NNSEvent.kt @@ -18,11 +18,12 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.experimental.nns import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.BaseAddressableEvent +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.utils.TimeUtils @Immutable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/GalleryListEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/profileGallery/GalleryListEvent.kt similarity index 95% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/GalleryListEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/experimental/profileGallery/GalleryListEvent.kt index 97f5da251..4064b3e35 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/GalleryListEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/profileGallery/GalleryListEvent.kt @@ -18,12 +18,13 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.experimental.profileGallery import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip51Lists.GeneralListEvent import com.vitorpamplona.quartz.utils.TimeUtils @Immutable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/ProfileGalleryEntryEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/profileGallery/ProfileGalleryEntryEvent.kt similarity index 94% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/ProfileGalleryEntryEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/experimental/profileGallery/ProfileGalleryEntryEvent.kt index 5024b5115..5f30d48f8 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/ProfileGalleryEntryEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/profileGallery/ProfileGalleryEntryEvent.kt @@ -18,12 +18,13 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.experimental.profileGallery import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.Dimension -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip94FileMetadata.Dimension import com.vitorpamplona.quartz.utils.TimeUtils @Immutable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/RelationshipStatusEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/relationshipStatus/RelationshipStatusEvent.kt similarity index 92% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/RelationshipStatusEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/experimental/relationshipStatus/RelationshipStatusEvent.kt index 6dd91de9d..d1fe449fa 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/RelationshipStatusEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/relationshipStatus/RelationshipStatusEvent.kt @@ -18,11 +18,12 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.experimental.relationshipStatus import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEvent import com.vitorpamplona.quartz.utils.TimeUtils @Immutable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/PollNoteEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/zapPolls/PollNoteEvent.kt similarity index 91% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/PollNoteEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/experimental/zapPolls/PollNoteEvent.kt index cb95c5d1f..194666a7e 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/PollNoteEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/zapPolls/PollNoteEvent.kt @@ -18,14 +18,18 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.experimental.zapPolls import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.IMetaTag -import com.vitorpamplona.quartz.encoders.Nip92MediaAttachments -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.geohash.geohashMipMap +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip10Notes.BaseTextNoteEvent +import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiUrl +import com.vitorpamplona.quartz.nip57Zaps.ZapSplitSetup +import com.vitorpamplona.quartz.nip92IMeta.IMetaTag +import com.vitorpamplona.quartz.nip92IMeta.Nip92MediaAttachments import com.vitorpamplona.quartz.utils.TimeUtils const val POLL_OPTION = "poll_option" diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/LnInvoiceUtil.kt b/quartz/src/main/java/com/vitorpamplona/quartz/lightning/LnInvoiceUtil.kt similarity index 99% rename from quartz/src/main/java/com/vitorpamplona/quartz/encoders/LnInvoiceUtil.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/lightning/LnInvoiceUtil.kt index eb4d0b234..5b0cfd9a5 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/LnInvoiceUtil.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/lightning/LnInvoiceUtil.kt @@ -18,7 +18,7 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.encoders +package com.vitorpamplona.quartz.lightning import java.math.BigDecimal import java.util.Locale diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/LnWithdrawalUtil.kt b/quartz/src/main/java/com/vitorpamplona/quartz/lightning/LnWithdrawalUtil.kt similarity index 97% rename from quartz/src/main/java/com/vitorpamplona/quartz/encoders/LnWithdrawalUtil.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/lightning/LnWithdrawalUtil.kt index e56cc00bf..26babd9af 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/LnWithdrawalUtil.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/lightning/LnWithdrawalUtil.kt @@ -18,7 +18,7 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.encoders +package com.vitorpamplona.quartz.lightning import java.util.regex.Pattern diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/Lud06.kt b/quartz/src/main/java/com/vitorpamplona/quartz/lightning/Lud06.kt similarity index 95% rename from quartz/src/main/java/com/vitorpamplona/quartz/encoders/Lud06.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/lightning/Lud06.kt index e8c4e021d..a8ec27343 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/Lud06.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/lightning/Lud06.kt @@ -18,9 +18,10 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.encoders +package com.vitorpamplona.quartz.lightning import android.util.Log +import com.vitorpamplona.quartz.nip19Bech32Entities.bech32.Bech32 import java.util.regex.Pattern class Lud06 { diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/EventExt.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/EventExt.kt new file mode 100644 index 000000000..b88ff7653 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/EventExt.kt @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip01Core + +import android.util.Log +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.crypto.Hex +import com.vitorpamplona.quartz.nip01Core.core.Event + +fun Event.generateId(): String = EventHasher.hashId(pubKey, createdAt, kind, tags, content) + +fun Event.hasCorrectIDHash(): Boolean { + if (id.isEmpty()) return false + return id == generateId() +} + +fun Event.hasVerifiedSignature(): Boolean { + if (id.isEmpty() || sig.isEmpty()) return false + return 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. */ +fun Event.checkSignature() { + if (!hasCorrectIDHash()) { + throw Exception( + """ + |Unexpected ID. + | Event: ${toJson()} + | Actual ID: $id + | Generated: ${generateId()} + """.trimIndent(), + ) + } + if (!hasVerifiedSignature()) { + throw Exception("""Bad signature!""") + } +} + +fun Event.hasValidSignature(): Boolean = + try { + hasCorrectIDHash() && hasVerifiedSignature() + } catch (e: Exception) { + Log.w("Event", "Event $id does not have a valid signature: ${toJson()}", e) + false + } diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/EventFactory.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/EventFactory.kt new file mode 100644 index 000000000..a9656f32d --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/EventFactory.kt @@ -0,0 +1,262 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip01Core + +import com.vitorpamplona.quartz.blossom.BlossomAuthorizationEvent +import com.vitorpamplona.quartz.blossom.BlossomServersEvent +import com.vitorpamplona.quartz.experimental.audio.AudioHeaderEvent +import com.vitorpamplona.quartz.experimental.audio.AudioTrackEvent +import com.vitorpamplona.quartz.experimental.edits.PrivateOutboxRelayListEvent +import com.vitorpamplona.quartz.experimental.edits.TextNoteModificationEvent +import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStoryPrologueEvent +import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStoryReadingStateEvent +import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStorySceneEvent +import com.vitorpamplona.quartz.experimental.medical.FhirResourceEvent +import com.vitorpamplona.quartz.experimental.nip95.FileStorageEvent +import com.vitorpamplona.quartz.experimental.nip95.FileStorageHeaderEvent +import com.vitorpamplona.quartz.experimental.nns.NNSEvent +import com.vitorpamplona.quartz.experimental.profileGallery.ProfileGalleryEntryEvent +import com.vitorpamplona.quartz.experimental.relationshipStatus.RelationshipStatusEvent +import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent +import com.vitorpamplona.quartz.nip03Timestamp.OtsEvent +import com.vitorpamplona.quartz.nip04Dm.PrivateDmEvent +import com.vitorpamplona.quartz.nip09Deletions.DeletionEvent +import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent +import com.vitorpamplona.quartz.nip17Dm.ChatMessageEncryptedFileHeaderEvent +import com.vitorpamplona.quartz.nip17Dm.ChatMessageEvent +import com.vitorpamplona.quartz.nip17Dm.ChatMessageRelayListEvent +import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent +import com.vitorpamplona.quartz.nip18Reposts.RepostEvent +import com.vitorpamplona.quartz.nip22Comments.CommentEvent +import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent +import com.vitorpamplona.quartz.nip25Reactions.ReactionEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelCreateEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelHideMessageEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelListEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelMessageEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelMetadataEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelMuteUserEvent +import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiPackEvent +import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiPackSelectionEvent +import com.vitorpamplona.quartz.nip34Git.GitIssueEvent +import com.vitorpamplona.quartz.nip34Git.GitPatchEvent +import com.vitorpamplona.quartz.nip34Git.GitReplyEvent +import com.vitorpamplona.quartz.nip34Git.GitRepositoryEvent +import com.vitorpamplona.quartz.nip35Torrents.TorrentCommentEvent +import com.vitorpamplona.quartz.nip35Torrents.TorrentEvent +import com.vitorpamplona.quartz.nip37Drafts.DraftEvent +import com.vitorpamplona.quartz.nip38UserStatus.StatusEvent +import com.vitorpamplona.quartz.nip42RelayAuth.RelayAuthEvent +import com.vitorpamplona.quartz.nip47WalletConnect.LnZapPaymentRequestEvent +import com.vitorpamplona.quartz.nip47WalletConnect.LnZapPaymentResponseEvent +import com.vitorpamplona.quartz.nip50Search.SearchRelayListEvent +import com.vitorpamplona.quartz.nip51Lists.BookmarkListEvent +import com.vitorpamplona.quartz.nip51Lists.MuteListEvent +import com.vitorpamplona.quartz.nip51Lists.PeopleListEvent +import com.vitorpamplona.quartz.nip51Lists.PinListEvent +import com.vitorpamplona.quartz.nip51Lists.RelaySetEvent +import com.vitorpamplona.quartz.nip52Calendar.CalendarDateSlotEvent +import com.vitorpamplona.quartz.nip52Calendar.CalendarEvent +import com.vitorpamplona.quartz.nip52Calendar.CalendarRSVPEvent +import com.vitorpamplona.quartz.nip52Calendar.CalendarTimeSlotEvent +import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesChatMessageEvent +import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesEvent +import com.vitorpamplona.quartz.nip54Wiki.WikiNoteEvent +import com.vitorpamplona.quartz.nip56Reports.ReportEvent +import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent +import com.vitorpamplona.quartz.nip57Zaps.LnZapPrivateEvent +import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent +import com.vitorpamplona.quartz.nip58Badges.BadgeAwardEvent +import com.vitorpamplona.quartz.nip58Badges.BadgeDefinitionEvent +import com.vitorpamplona.quartz.nip58Badges.BadgeProfilesEvent +import com.vitorpamplona.quartz.nip59Giftwrap.GiftWrapEvent +import com.vitorpamplona.quartz.nip59Giftwrap.SealedGossipEvent +import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent +import com.vitorpamplona.quartz.nip68Picture.PictureEvent +import com.vitorpamplona.quartz.nip71Video.VideoHorizontalEvent +import com.vitorpamplona.quartz.nip71Video.VideoVerticalEvent +import com.vitorpamplona.quartz.nip71Video.VideoViewEvent +import com.vitorpamplona.quartz.nip72ModCommunities.CommunityDefinitionEvent +import com.vitorpamplona.quartz.nip72ModCommunities.CommunityListEvent +import com.vitorpamplona.quartz.nip72ModCommunities.CommunityPostApprovalEvent +import com.vitorpamplona.quartz.nip75ZapGoals.GoalEvent +import com.vitorpamplona.quartz.nip78AppData.AppSpecificDataEvent +import com.vitorpamplona.quartz.nip84Highlights.HighlightEvent +import com.vitorpamplona.quartz.nip89AppHandlers.AppDefinitionEvent +import com.vitorpamplona.quartz.nip89AppHandlers.AppRecommendationEvent +import com.vitorpamplona.quartz.nip90Dvms.NIP90ContentDiscoveryRequestEvent +import com.vitorpamplona.quartz.nip90Dvms.NIP90ContentDiscoveryResponseEvent +import com.vitorpamplona.quartz.nip90Dvms.NIP90StatusEvent +import com.vitorpamplona.quartz.nip90Dvms.NIP90UserDiscoveryRequestEvent +import com.vitorpamplona.quartz.nip90Dvms.NIP90UserDiscoveryResponseEvent +import com.vitorpamplona.quartz.nip94FileMetadata.FileHeaderEvent +import com.vitorpamplona.quartz.nip96FileStorage.FileServersEvent +import com.vitorpamplona.quartz.nip98HttpAuth.HTTPAuthorizationEvent +import com.vitorpamplona.quartz.nip99Classifieds.ClassifiedsEvent + +class EventFactory { + companion object { + val factories: MutableMap>, String, HexKey) -> Event> = mutableMapOf() + + fun create( + id: String, + pubKey: String, + createdAt: Long, + kind: Int, + tags: Array>, + content: String, + sig: String, + ): Event = + when (kind) { + AdvertisedRelayListEvent.KIND -> AdvertisedRelayListEvent(id, pubKey, createdAt, tags, content, sig) + AppDefinitionEvent.KIND -> AppDefinitionEvent(id, pubKey, createdAt, tags, content, sig) + AppRecommendationEvent.KIND -> AppRecommendationEvent(id, pubKey, createdAt, tags, content, sig) + AppSpecificDataEvent.KIND -> AppSpecificDataEvent(id, pubKey, createdAt, tags, content, sig) + AudioHeaderEvent.KIND -> AudioHeaderEvent(id, pubKey, createdAt, tags, content, sig) + AudioTrackEvent.KIND -> AudioTrackEvent(id, pubKey, createdAt, tags, content, sig) + BadgeAwardEvent.KIND -> BadgeAwardEvent(id, pubKey, createdAt, tags, content, sig) + BadgeDefinitionEvent.KIND -> BadgeDefinitionEvent(id, pubKey, createdAt, tags, content, sig) + BadgeProfilesEvent.KIND -> BadgeProfilesEvent(id, pubKey, createdAt, tags, content, sig) + BlossomServersEvent.KIND -> BlossomServersEvent(id, pubKey, createdAt, tags, content, sig) + BlossomAuthorizationEvent.KIND -> BlossomAuthorizationEvent(id, pubKey, createdAt, tags, content, sig) + BookmarkListEvent.KIND -> BookmarkListEvent(id, pubKey, createdAt, tags, content, sig) + CalendarDateSlotEvent.KIND -> CalendarDateSlotEvent(id, pubKey, createdAt, tags, content, sig) + CalendarEvent.KIND -> CalendarEvent(id, pubKey, createdAt, tags, content, sig) + CalendarTimeSlotEvent.KIND -> CalendarTimeSlotEvent(id, pubKey, createdAt, tags, content, sig) + CalendarRSVPEvent.KIND -> CalendarRSVPEvent(id, pubKey, createdAt, tags, content, sig) + ChannelCreateEvent.KIND -> ChannelCreateEvent(id, pubKey, createdAt, tags, content, sig) + ChannelHideMessageEvent.KIND -> ChannelHideMessageEvent(id, pubKey, createdAt, tags, content, sig) + ChannelListEvent.KIND -> ChannelListEvent(id, pubKey, createdAt, tags, content, sig) + ChannelMessageEvent.KIND -> ChannelMessageEvent(id, pubKey, createdAt, tags, content, sig) + ChannelMetadataEvent.KIND -> ChannelMetadataEvent(id, pubKey, createdAt, tags, content, sig) + ChannelMuteUserEvent.KIND -> ChannelMuteUserEvent(id, pubKey, createdAt, tags, content, sig) + ChatMessageEncryptedFileHeaderEvent.KIND -> { + if (id.isBlank()) { + ChatMessageEncryptedFileHeaderEvent( + Event.generateId(pubKey, createdAt, kind, tags, content), + pubKey, + createdAt, + tags, + content, + sig, + ) + } else { + ChatMessageEncryptedFileHeaderEvent(id, pubKey, createdAt, tags, content, sig) + } + } + ChatMessageEvent.KIND -> { + if (id.isBlank()) { + ChatMessageEvent( + Event.generateId(pubKey, createdAt, kind, tags, content), + pubKey, + createdAt, + tags, + content, + sig, + ) + } else { + ChatMessageEvent(id, pubKey, createdAt, tags, content, sig) + } + } + ChatMessageRelayListEvent.KIND -> ChatMessageRelayListEvent(id, pubKey, createdAt, tags, content, sig) + ClassifiedsEvent.KIND -> ClassifiedsEvent(id, pubKey, createdAt, tags, content, sig) + CommentEvent.KIND -> CommentEvent(id, pubKey, createdAt, tags, content, sig) + CommunityDefinitionEvent.KIND -> CommunityDefinitionEvent(id, pubKey, createdAt, tags, content, sig) + CommunityListEvent.KIND -> CommunityListEvent(id, pubKey, createdAt, tags, content, sig) + CommunityPostApprovalEvent.KIND -> CommunityPostApprovalEvent(id, pubKey, createdAt, tags, content, sig) + ContactListEvent.KIND -> ContactListEvent(id, pubKey, createdAt, tags, content, sig) + DeletionEvent.KIND -> DeletionEvent(id, pubKey, createdAt, tags, content, sig) + DraftEvent.KIND -> DraftEvent(id, pubKey, createdAt, tags, content, sig) + EmojiPackEvent.KIND -> EmojiPackEvent(id, pubKey, createdAt, tags, content, sig) + EmojiPackSelectionEvent.KIND -> EmojiPackSelectionEvent(id, pubKey, createdAt, tags, content, sig) + FileHeaderEvent.KIND -> FileHeaderEvent(id, pubKey, createdAt, tags, content, sig) + ProfileGalleryEntryEvent.KIND -> ProfileGalleryEntryEvent(id, pubKey, createdAt, tags, content, sig) + FileServersEvent.KIND -> FileServersEvent(id, pubKey, createdAt, tags, content, sig) + FileStorageEvent.KIND -> FileStorageEvent(id, pubKey, createdAt, tags, content, sig) + FileStorageHeaderEvent.KIND -> FileStorageHeaderEvent(id, pubKey, createdAt, tags, content, sig) + FhirResourceEvent.KIND -> FhirResourceEvent(id, pubKey, createdAt, tags, content, sig) + GenericRepostEvent.KIND -> GenericRepostEvent(id, pubKey, createdAt, tags, content, sig) + GiftWrapEvent.KIND -> GiftWrapEvent(id, pubKey, createdAt, tags, content, sig) + GitIssueEvent.KIND -> GitIssueEvent(id, pubKey, createdAt, tags, content, sig) + GitReplyEvent.KIND -> GitReplyEvent(id, pubKey, createdAt, tags, content, sig) + GitPatchEvent.KIND -> GitPatchEvent(id, pubKey, createdAt, tags, content, sig) + GitRepositoryEvent.KIND -> GitRepositoryEvent(id, pubKey, createdAt, tags, content, sig) + GoalEvent.KIND -> GoalEvent(id, pubKey, createdAt, tags, content, sig) + HighlightEvent.KIND -> HighlightEvent(id, pubKey, createdAt, tags, content, sig) + HTTPAuthorizationEvent.KIND -> HTTPAuthorizationEvent(id, pubKey, createdAt, tags, content, sig) + InteractiveStoryPrologueEvent.KIND -> InteractiveStoryPrologueEvent(id, pubKey, createdAt, tags, content, sig) + InteractiveStorySceneEvent.KIND -> InteractiveStorySceneEvent(id, pubKey, createdAt, tags, content, sig) + InteractiveStoryReadingStateEvent.KIND -> InteractiveStoryReadingStateEvent(id, pubKey, createdAt, tags, content, sig) + LiveActivitiesChatMessageEvent.KIND -> LiveActivitiesChatMessageEvent(id, pubKey, createdAt, tags, content, sig) + LiveActivitiesEvent.KIND -> LiveActivitiesEvent(id, pubKey, createdAt, tags, content, sig) + LnZapEvent.KIND -> LnZapEvent(id, pubKey, createdAt, tags, content, sig) + LnZapPaymentRequestEvent.KIND -> LnZapPaymentRequestEvent(id, pubKey, createdAt, tags, content, sig) + LnZapPaymentResponseEvent.KIND -> LnZapPaymentResponseEvent(id, pubKey, createdAt, tags, content, sig) + LnZapPrivateEvent.KIND -> LnZapPrivateEvent(id, pubKey, createdAt, tags, content, sig) + LnZapRequestEvent.KIND -> LnZapRequestEvent(id, pubKey, createdAt, tags, content, sig) + LongTextNoteEvent.KIND -> LongTextNoteEvent(id, pubKey, createdAt, tags, content, sig) + MetadataEvent.KIND -> MetadataEvent(id, pubKey, createdAt, tags, content, sig) + MuteListEvent.KIND -> MuteListEvent(id, pubKey, createdAt, tags, content, sig) + NNSEvent.KIND -> NNSEvent(id, pubKey, createdAt, tags, content, sig) + com.vitorpamplona.quartz.nip46RemoteSigner.NostrConnectEvent.KIND -> + com.vitorpamplona.quartz.nip46RemoteSigner + .NostrConnectEvent(id, pubKey, createdAt, tags, content, sig) + NIP90StatusEvent.KIND -> NIP90StatusEvent(id, pubKey, createdAt, tags, content, sig) + NIP90ContentDiscoveryRequestEvent.KIND -> NIP90ContentDiscoveryRequestEvent(id, pubKey, createdAt, tags, content, sig) + NIP90ContentDiscoveryResponseEvent.KIND -> NIP90ContentDiscoveryResponseEvent(id, pubKey, createdAt, tags, content, sig) + NIP90UserDiscoveryRequestEvent.KIND -> NIP90UserDiscoveryRequestEvent(id, pubKey, createdAt, tags, content, sig) + NIP90UserDiscoveryResponseEvent.KIND -> NIP90UserDiscoveryResponseEvent(id, pubKey, createdAt, tags, content, sig) + OtsEvent.KIND -> OtsEvent(id, pubKey, createdAt, tags, content, sig) + PeopleListEvent.KIND -> PeopleListEvent(id, pubKey, createdAt, tags, content, sig) + PictureEvent.KIND -> PictureEvent(id, pubKey, createdAt, tags, content, sig) + PinListEvent.KIND -> PinListEvent(id, pubKey, createdAt, tags, content, sig) + PollNoteEvent.KIND -> PollNoteEvent(id, pubKey, createdAt, tags, content, sig) + PrivateDmEvent.KIND -> PrivateDmEvent(id, pubKey, createdAt, tags, content, sig) + PrivateOutboxRelayListEvent.KIND -> PrivateOutboxRelayListEvent(id, pubKey, createdAt, tags, content, sig) + ReactionEvent.KIND -> ReactionEvent(id, pubKey, createdAt, tags, content, sig) + RelationshipStatusEvent.KIND -> RelationshipStatusEvent(id, pubKey, createdAt, tags, content, sig) + RelayAuthEvent.KIND -> RelayAuthEvent(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) + SealedGossipEvent.KIND -> SealedGossipEvent(id, pubKey, createdAt, tags, content, sig) + SearchRelayListEvent.KIND -> SearchRelayListEvent(id, pubKey, createdAt, tags, content, sig) + StatusEvent.KIND -> StatusEvent(id, pubKey, createdAt, tags, content, sig) + TextNoteEvent.KIND -> TextNoteEvent(id, pubKey, createdAt, tags, content, sig) + TextNoteModificationEvent.KIND -> TextNoteModificationEvent(id, pubKey, createdAt, tags, content, sig) + TorrentEvent.KIND -> TorrentEvent(id, pubKey, createdAt, tags, content, sig) + TorrentCommentEvent.KIND -> TorrentCommentEvent(id, pubKey, createdAt, tags, content, sig) + VideoHorizontalEvent.KIND -> VideoHorizontalEvent(id, pubKey, createdAt, tags, content, sig) + VideoVerticalEvent.KIND -> VideoVerticalEvent(id, pubKey, createdAt, tags, content, sig) + VideoViewEvent.KIND -> VideoViewEvent(id, pubKey, createdAt, tags, content, sig) + WikiNoteEvent.KIND -> WikiNoteEvent(id, pubKey, createdAt, tags, content, sig) + else -> { + factories[kind]?.let { + return it(id, pubKey, createdAt, tags, content, sig) + } + + Event(id, pubKey, createdAt, kind, tags, content, sig) + } + } + } +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip01/EventHasher.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/EventHasher.kt similarity index 91% rename from quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip01/EventHasher.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/EventHasher.kt index 9a22013f9..c0cf7602f 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip01/EventHasher.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/EventHasher.kt @@ -18,13 +18,11 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.crypto.nip01 +package com.vitorpamplona.quartz.nip01Core import com.fasterxml.jackson.databind.node.JsonNodeFactory import com.vitorpamplona.quartz.crypto.sha256Hash -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.toHexKey -import com.vitorpamplona.quartz.events.Event.Companion.mapper +import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper class EventHasher { companion object { @@ -54,7 +52,7 @@ class EventHasher { add(content) } - return mapper.writeValueAsString(rawEvent) + return EventMapper.toJson(rawEvent) } fun hashIdBytes( diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/EventHint.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/EventHint.kt similarity index 88% rename from quartz/src/main/java/com/vitorpamplona/quartz/encoders/EventHint.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/EventHint.kt index 2f185a621..e6860dca0 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/EventHint.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/EventHint.kt @@ -18,10 +18,11 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.encoders +package com.vitorpamplona.quartz.nip01Core import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NEvent import com.vitorpamplona.quartz.utils.bytesUsedInMemory import com.vitorpamplona.quartz.utils.pointerSizeInBytes @@ -40,9 +41,7 @@ data class EventHint( event.countMemory() + (relay?.bytesUsedInMemory() ?: 0) - fun toNEvent(): String = Nip19Bech32.createNEvent(event.id, event.pubKey, event.kind, relay) - - fun toNPub(): String = Nip19Bech32.createNPub(event.id) + fun toNEvent(): String = NEvent.create(event.id, event.pubKey, event.kind, relay) fun toTagArray(tag: String) = listOfNotNull(tag, event.id, relay, event.pubKey).toTypedArray() diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/HexKey.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/HexKey.kt new file mode 100644 index 000000000..31ba61f34 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/HexKey.kt @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip01Core + +import com.vitorpamplona.quartz.crypto.Hex + +/** Makes the distinction between String and Hex * */ +typealias HexKey = String + +fun ByteArray.toHexKey(): HexKey = Hex.encode(this) + +fun HexKey.hexToByteArray(): ByteArray = Hex.decode(this) diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/MetadataEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/MetadataEvent.kt new file mode 100644 index 000000000..98968d258 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/MetadataEvent.kt @@ -0,0 +1,142 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip01Core + +import android.util.Log +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.databind.node.ObjectNode +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerSync +import com.vitorpamplona.quartz.nip21UriScheme.toNostrUri +import com.vitorpamplona.quartz.nip39ExtIdentities.updateClaims +import com.vitorpamplona.quartz.utils.TimeUtils +import java.io.ByteArrayInputStream +import java.io.StringWriter + +class MetadataEvent( + id: HexKey, + pubKey: HexKey, + createdAt: Long, + tags: Array>, + content: String, + sig: HexKey, +) : Event(id, pubKey, createdAt, KIND, tags, content, sig) { + fun contactMetaData() = + try { + EventMapper.mapper.readValue(content, UserMetadata::class.java) + } catch (e: Exception) { + // e.printStackTrace() + Log.w("MetadataEvent", "Content Parse Error: ${toNostrUri()} ${e.localizedMessage}") + null + } + + companion object { + const val KIND = 0 + + fun newUser( + name: String?, + signer: NostrSignerSync, + createdAt: Long = TimeUtils.now(), + ): MetadataEvent? { + // Tries to not delete any existing attribute that we do not work with. + val currentJson = ObjectMapper().createObjectNode() + + name?.let { addIfNotBlank(currentJson, "name", it.trim()) } + val writer = StringWriter() + ObjectMapper().writeValue(writer, currentJson) + + val tags = mutableListOf>() + + tags.add( + arrayOf("alt", "User profile for ${name ?: currentJson.get("name").asText() ?: ""}"), + ) + + return signer.sign(createdAt, KIND, tags.toTypedArray(), writer.buffer.toString()) + } + + fun updateFromPast( + latest: MetadataEvent?, + name: String?, + picture: String?, + banner: String?, + website: String?, + about: String?, + nip05: String?, + lnAddress: String?, + lnURL: String?, + pronouns: String?, + twitter: String?, + mastodon: String?, + github: String?, + signer: NostrSigner, + createdAt: Long = TimeUtils.now(), + onReady: (MetadataEvent) -> Unit, + ) { + // Tries to not delete any existing attribute that we do not work with. + val currentJson = + if (latest != null) { + ObjectMapper() + .readTree( + ByteArrayInputStream(latest.content.toByteArray(Charsets.UTF_8)), + ) as ObjectNode + } else { + ObjectMapper().createObjectNode() + } + + name?.let { addIfNotBlank(currentJson, "name", it.trim()) } + name?.let { addIfNotBlank(currentJson, "display_name", it.trim()) } + picture?.let { addIfNotBlank(currentJson, "picture", it.trim()) } + banner?.let { addIfNotBlank(currentJson, "banner", it.trim()) } + website?.let { addIfNotBlank(currentJson, "website", it.trim()) } + pronouns?.let { addIfNotBlank(currentJson, "pronouns", it.trim()) } + about?.let { addIfNotBlank(currentJson, "about", it.trim()) } + nip05?.let { addIfNotBlank(currentJson, "nip05", it.trim()) } + lnAddress?.let { addIfNotBlank(currentJson, "lud16", it.trim()) } + lnURL?.let { addIfNotBlank(currentJson, "lud06", it.trim()) } + + val writer = StringWriter() + ObjectMapper().writeValue(writer, currentJson) + + val tags = mutableListOf>() + tags.add(arrayOf("alt", "User profile for ${name ?: currentJson.get("name").asText() ?: ""}")) + + latest?.updateClaims(twitter, github, mastodon)?.forEach { + tags.add(it) + } + + signer.sign(createdAt, KIND, tags.toTypedArray(), writer.buffer.toString(), onReady) + } + + private fun addIfNotBlank( + currentJson: ObjectNode, + key: String, + value: String, + ) { + if (value.isBlank() || value == "null") { + currentJson.remove(key) + } else { + currentJson.put(key, value.trim()) + } + } + } +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip01/Nip01.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/Nip01.kt similarity index 90% rename from quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip01/Nip01.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/Nip01.kt index 0c3923ea0..2ea196654 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip01/Nip01.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/Nip01.kt @@ -18,7 +18,7 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.crypto.nip01 +package com.vitorpamplona.quartz.nip01Core import com.vitorpamplona.quartz.crypto.CryptoUtils import com.vitorpamplona.quartz.crypto.nextBytes @@ -40,8 +40,8 @@ class Nip01( fun sign( data: ByteArray, privKey: ByteArray, - auxrand32: ByteArray? = random.nextBytes(32), - ): ByteArray = secp256k1.signSchnorr(data, privKey, auxrand32) + nonce: ByteArray? = random.nextBytes(32), + ): ByteArray = secp256k1.signSchnorr(data, privKey, nonce) fun signDeterministic( data: ByteArray, @@ -59,6 +59,6 @@ class Nip01( fun signString( message: String, privKey: ByteArray, - auxrand32: ByteArray = random.nextBytes(32), - ): ByteArray = sign(CryptoUtils.sha256(message.toByteArray()), privKey, auxrand32) + nonce: ByteArray = random.nextBytes(32), + ): ByteArray = sign(CryptoUtils.sha256(message.toByteArray()), privKey, nonce) } diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/UserMetadata.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/UserMetadata.kt new file mode 100644 index 000000000..6fe44d511 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/UserMetadata.kt @@ -0,0 +1,100 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip01Core + +import androidx.compose.runtime.Stable +import com.fasterxml.jackson.annotation.JsonProperty +import com.vitorpamplona.quartz.nip02FollowList.ImmutableListOfLists + +@Stable +class UserMetadata { + var name: String? = null + + @Deprecated("Use name instead", replaceWith = ReplaceWith("name")) + var username: String? = null + + @JsonProperty("display_name") + var displayName: String? = null + var picture: String? = null + var banner: String? = null + var website: String? = null + var about: String? = null + var bot: Boolean? = null + var pronouns: 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 + + @Transient + var tags: ImmutableListOfLists? = null + + fun anyName(): String? = displayName ?: name ?: username + + fun anyNameStartsWith(prefix: String): Boolean = + listOfNotNull(name, username, displayName, nip05, lud06, lud16).any { + it.contains(prefix, true) + } + + fun lnAddress(): String? = lud16 ?: lud06 + + fun bestName(): String? = displayName ?: name ?: username + + fun nip05(): String? = nip05 + + fun profilePicture(): String? = picture + + fun cleanBlankNames() { + if (pronouns == "null") pronouns = null + + if (picture?.isNotEmpty() == true) picture = picture?.trim() + if (nip05?.isNotEmpty() == true) nip05 = nip05?.trim() + if (displayName?.isNotEmpty() == true) displayName = displayName?.trim() + if (name?.isNotEmpty() == true) name = name?.trim() + if (username?.isNotEmpty() == true) username = username?.trim() + if (lud06?.isNotEmpty() == true) lud06 = lud06?.trim() + if (lud16?.isNotEmpty() == true) lud16 = lud16?.trim() + if (pronouns?.isNotEmpty() == true) pronouns = pronouns?.trim() + + if (banner?.isNotEmpty() == true) banner = banner?.trim() + if (website?.isNotEmpty() == true) website = website?.trim() + if (domain?.isNotEmpty() == true) domain = domain?.trim() + + if (picture?.isBlank() == true) picture = null + if (nip05?.isBlank() == true) nip05 = null + if (displayName?.isBlank() == true) displayName = null + if (name?.isBlank() == true) name = null + if (username?.isBlank() == true) username = null + if (lud06?.isBlank() == true) lud06 = null + if (lud16?.isBlank() == true) lud16 = null + + if (banner?.isBlank() == true) banner = null + if (website?.isBlank() == true) website = null + if (domain?.isBlank() == true) domain = null + if (pronouns?.isBlank() == true) pronouns = null + } +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/addressables/ATag.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/addressables/ATag.kt new file mode 100644 index 000000000..ff1ba7425 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/addressables/ATag.kt @@ -0,0 +1,65 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip01Core.addressables + +import androidx.compose.runtime.Immutable +import com.vitorpamplona.quartz.utils.bytesUsedInMemory +import com.vitorpamplona.quartz.utils.pointerSizeInBytes +import com.vitorpamplona.quartz.utils.removeTrailingNullsAndEmptyOthers + +@Immutable +data class ATag( + val kind: Int, + val pubKeyHex: String, + val dTag: String, +) { + var relay: String? = null + + constructor( + kind: Int, + pubKeyHex: String, + dTag: String, + relayHint: String?, + ) : this(kind, pubKeyHex, dTag) { + this.relay = relayHint + } + + fun countMemory(): Long = + 5 * pointerSizeInBytes + // 7 fields, 4 bytes each reference (32bit) + 8L + // kind + pubKeyHex.bytesUsedInMemory() + + dTag.bytesUsedInMemory() + + (relay?.bytesUsedInMemory() ?: 0) + + fun toTag() = assembleATag(kind, pubKeyHex, dTag) + + fun toATagArray() = removeTrailingNullsAndEmptyOthers("a", toTag(), relay) + + fun toQTagArray() = removeTrailingNullsAndEmptyOthers("q", toTag(), relay) + + companion object { + fun assembleATag( + kind: Int, + pubKeyHex: String, + dTag: String, + ) = "$kind:$pubKeyHex:$dTag" + } +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/addressables/AddressableEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/addressables/AddressableEvent.kt new file mode 100644 index 000000000..671f308d5 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/addressables/AddressableEvent.kt @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip01Core.addressables + +import androidx.compose.runtime.Immutable + +@Immutable +interface AddressableEvent { + fun dTag(): String + + fun address(relayHint: String? = null): ATag + + fun addressTag(): String +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/RecommendRelayEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/addressables/BaseAddressableEvent.kt similarity index 64% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/RecommendRelayEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/addressables/BaseAddressableEvent.kt index e217c86a1..df266260d 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/RecommendRelayEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/addressables/BaseAddressableEvent.kt @@ -18,36 +18,29 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip01Core.addressables import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner -import com.vitorpamplona.quartz.utils.TimeUtils -import java.net.URI +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event @Immutable -class RecommendRelayEvent( +open class BaseAddressableEvent( id: HexKey, pubKey: HexKey, createdAt: Long, + kind: Int, tags: Array>, content: String, sig: HexKey, -) : Event(id, pubKey, createdAt, KIND, tags, content, sig) { - fun relay() = URI.create(content.trim()) +) : Event(id, pubKey, createdAt, kind, tags, content, sig), + AddressableEvent { + override fun dTag() = tags.firstOrNull { it.size > 1 && it[0] == "d" }?.get(1) ?: "" - companion object { - const val KIND = 2 + override fun address(relayHint: String?) = ATag(kind, pubKey, dTag(), relayHint) - fun create( - relay: URI, - signer: NostrSigner, - createdAt: Long = TimeUtils.now(), - onReady: (RecommendRelayEvent) -> Unit, - ) { - val content = relay.toString() - signer.sign(createdAt, KIND, emptyArray(), content, onReady) - } - } + /** + * Creates the tag in a memory efficient way (without creating the ATag class + */ + override fun addressTag() = ATag.assembleATag(kind, pubKey, dTag()) } diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/addressables/EventExt.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/addressables/EventExt.kt new file mode 100644 index 000000000..450a0ca5f --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/addressables/EventExt.kt @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip01Core.addressables + +import com.vitorpamplona.quartz.nip01Core.core.Event + +fun Event.mapTaggedAddress(map: (address: String) -> R) = tags.mapTaggedAddress(map) + +fun Event.firstIsTaggedAddressableNote(addressableNotes: Set) = tags.firstIsTaggedAddressableNote(addressableNotes) + +fun Event.isTaggedAddressableNote(idHex: String) = tags.isTaggedAddressableNote(idHex) + +fun Event.isTaggedAddressableNotes(idHexes: Set) = tags.isTaggedAddressableNotes(idHexes) + +fun Event.isTaggedAddressableKind(kind: Int) = tags.isTaggedAddressableKind(kind) + +fun Event.getTagOfAddressableKind(kind: Int) = tags.getTagOfAddressableKind(kind) + +fun Event.taggedAddresses() = tags.taggedAddresses() + +fun Event.firstTaggedAddress() = tags.firstTaggedAddress() diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/addressables/TagArrayExt.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/addressables/TagArrayExt.kt new file mode 100644 index 000000000..3927dfd0c --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/addressables/TagArrayExt.kt @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip01Core.addressables + +import com.vitorpamplona.quartz.nip01Core.core.TagArray +import com.vitorpamplona.quartz.nip01Core.core.firstMapTagged +import com.vitorpamplona.quartz.nip01Core.core.isAnyTagged +import com.vitorpamplona.quartz.nip01Core.core.isTagged +import com.vitorpamplona.quartz.nip01Core.core.mapTagged +import com.vitorpamplona.quartz.nip01Core.core.mapValueTagged +import com.vitorpamplona.quartz.nip19Bech32Entities.parse + +fun TagArray.mapTaggedAddress(map: (address: String) -> R) = this.mapValueTagged("a", map) + +fun TagArray.firstIsTaggedAddressableNote(addressableNotes: Set) = + this + .firstOrNull { it.size > 1 && it[0] == "a" && it[1] in addressableNotes } + ?.getOrNull(1) + +fun TagArray.isTaggedAddressableNote(idHex: String) = this.isTagged("a", idHex) + +fun TagArray.isTaggedAddressableNotes(idHexes: Set) = this.isAnyTagged("a", idHexes) + +fun TagArray.isTaggedAddressableKind(kind: Int): Boolean { + val kindStr = kind.toString() + return this.any { it.size > 1 && it[0] == "a" && it[1].startsWith(kindStr) } +} + +fun TagArray.getTagOfAddressableKind(kind: Int): ATag? { + val kindStr = kind.toString() + val aTag = + this + .firstOrNull { it.size > 1 && it[0] == "a" && it[1].startsWith(kindStr) } + ?.getOrNull(1) + ?: return null + + return ATag.parse(aTag, null) +} + +fun TagArray.taggedAddresses() = this.mapTagged("a") { ATag.parse(it[1], it.getOrNull(2)) } + +fun TagArray.firstTaggedAddress() = this.firstMapTagged("a") { ATag.parse(it[1], it.getOrNull(2)) } diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/core/Event.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/core/Event.kt new file mode 100644 index 000000000..6a0ce3c60 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/core/Event.kt @@ -0,0 +1,87 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip01Core.core + +import androidx.compose.runtime.Immutable +import com.fasterxml.jackson.annotation.JsonProperty +import com.vitorpamplona.quartz.nip01Core.EventHasher +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.jackson.EventManualSerializer +import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.utils.bytesUsedInMemory +import com.vitorpamplona.quartz.utils.pointerSizeInBytes + +@Immutable +open class Event( + val id: HexKey, + @JsonProperty("pubkey") val pubKey: HexKey, + @JsonProperty("created_at") val createdAt: Long, + val kind: Int, + val tags: TagArray, + val content: String, + val sig: HexKey, +) { + open fun isContentEncoded() = false + + open fun countMemory(): Long = + 7 * pointerSizeInBytes + // 7 fields, 4 bytes each reference (32bit) + 12L + // createdAt + kind + id.bytesUsedInMemory() + + pubKey.bytesUsedInMemory() + + tags.sumOf { pointerSizeInBytes + it.sumOf { pointerSizeInBytes + it.bytesUsedInMemory() } } + + content.bytesUsedInMemory() + + sig.bytesUsedInMemory() + + fun toJson(): String = EventManualSerializer.toJson(id, pubKey, createdAt, kind, tags, content, sig) + + companion object { + fun fromJson(json: String): Event = EventMapper.fromJson(json) + + fun toJson(event: Event): String = EventMapper.toJson(event) + + fun generateId( + pubKey: HexKey, + createdAt: Long, + kind: Int, + tags: Array>, + content: String, + ): HexKey = EventHasher.hashId(pubKey, createdAt, kind, tags, content) + + fun generateIdBytes( + pubKey: HexKey, + createdAt: Long, + kind: Int, + tags: Array>, + content: String, + ): ByteArray = EventHasher.hashIdBytes(pubKey, createdAt, kind, tags, content) + + fun create( + signer: NostrSigner, + kind: Int, + tags: Array> = emptyArray(), + content: String = "", + createdAt: Long = TimeUtils.now(), + onReady: (Event) -> Unit, + ) = signer.sign(createdAt, kind, tags, content, onReady) + } +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/core/TagArray.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/core/TagArray.kt new file mode 100644 index 000000000..5b304441d --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/core/TagArray.kt @@ -0,0 +1,122 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip01Core.core + +import com.vitorpamplona.quartz.nip01Core.HexKey + +typealias TagArray = Array> + +fun TagArray.forEachTagged( + tagName: String, + onEach: (eventId: HexKey) -> Unit, +) = this.forEach { + if (it.size > 1 && it[0] == tagName) { + onEach(it[1]) + } +} + +fun TagArray.anyTagged( + tagName: String, + onEach: (tagValue: String) -> Boolean, +) = this.any { + if (it.size > 1 && it[0] == tagName) { + onEach(it[1]) + } else { + false + } +} + +fun TagArray.anyTagged(tagName: String) = this.any { it.size > 0 && it[0] == tagName } + +fun TagArray.anyTagWithValueStartingWithIgnoreCase( + tagName: String, + valuePrefix: String, +): Boolean = this.any { it.size > 1 && it[0] == tagName && it[1].startsWith(valuePrefix, true) } + +fun TagArray.hasTagWithContent(tagName: String) = this.any { it.size > 1 && it[0] == tagName } + +fun TagArray.mapValueTagged( + tagName: String, + map: (tagValue: String) -> R, +) = this.mapNotNull { + if (it.size > 1 && it[0] == tagName) { + map(it[1]) + } else { + null + } +} + +fun TagArray.mapTagged( + tagName: String, + map: (tagValue: Array) -> R, +) = this.mapNotNull { + if (it.size > 1 && it[0] == tagName) { + map(it) + } else { + null + } +} + +fun TagArray.mapValues(tagName: String) = + this.mapNotNull { + if (it.size > 1 && it[0] == tagName) { + it[1] + } else { + null + } + } + +fun TagArray.firstMapTagged( + tagName: String, + map: (tagValue: Array) -> R, +) = this.firstNotNullOfOrNull { + if (it.size > 1 && it[0] == tagName) { + map(it) + } else { + null + } +} + +fun TagArray.filterByTag(tagName: String) = this.filter { it.size > 0 && it[0] == tagName } + +fun TagArray.filterByTagWithValue(tagName: String) = this.filter { it.size > 1 && it[0] == tagName } + +fun TagArray.firstTag(key: String) = this.firstOrNull { it.size > 1 && it[0] == key } + +fun TagArray.firstTagValue(key: String) = this.firstOrNull { it.size > 1 && it[0] == key }?.let { it[1] } + +fun TagArray.firstTagValueAsInt(key: String) = this.firstOrNull { it.size > 1 && it[0] == key }?.let { it[1].toIntOrNull() } + +fun TagArray.firstTagValueAsLong(key: String) = this.firstOrNull { it.size > 1 && it[0] == key }?.let { it[1].toLongOrNull() } + +fun TagArray.firstTagValueFor(vararg key: String) = this.firstOrNull { it.size > 1 && it[0] in key }?.let { it[1] } + +fun TagArray.isTagged( + key: String, + tag: String, +) = this.any { it.size > 1 && it[0] == key && it[1] == tag } + +fun TagArray.isAnyTagged( + key: String, + tags: Set, +) = this.any { it.size > 1 && it[0] == key && it[1] in tags } + +fun TagArray.matchTag1With(text: String) = this.any { it.size > 1 && it[1].contains(text, true) } diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/events/EventExt.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/events/EventExt.kt new file mode 100644 index 000000000..2bf14ade3 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/events/EventExt.kt @@ -0,0 +1,34 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip01Core.events + +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event + +fun Event.forEachTaggedEvent(onEach: (eventId: HexKey) -> Unit) = tags.forEachTaggedEvent(onEach) + +fun Event.mapTaggedEvent(map: (eventId: HexKey) -> R) = tags.mapTaggedEvent(map) + +fun Event.taggedEvents() = tags.taggedEvents() + +fun Event.firstTaggedEvent() = tags.firstTaggedEvent() + +fun Event.isTaggedEvent(idHex: String) = tags.isTaggedEvent(idHex) diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/events/TagArrayExt.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/events/TagArrayExt.kt new file mode 100644 index 000000000..ac0dff378 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/events/TagArrayExt.kt @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip01Core.events + +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.TagArray +import com.vitorpamplona.quartz.nip01Core.core.firstTagValue +import com.vitorpamplona.quartz.nip01Core.core.forEachTagged +import com.vitorpamplona.quartz.nip01Core.core.isTagged +import com.vitorpamplona.quartz.nip01Core.core.mapValueTagged +import com.vitorpamplona.quartz.nip01Core.core.mapValues + +fun TagArray.forEachTaggedEvent(onEach: (eventId: HexKey) -> Unit) = this.forEachTagged("e", onEach) + +fun TagArray.mapTaggedEvent(map: (eventId: HexKey) -> R) = this.mapValueTagged("e", map) + +fun TagArray.taggedEvents() = this.mapValues("e") + +fun TagArray.firstTaggedEvent() = this.firstTagValue("e") + +fun TagArray.isTaggedEvent(idHex: String) = this.isTagged("e", idHex) diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/Nip01Serializer.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/experimental/Nip01Serializer.kt similarity index 98% rename from quartz/src/main/java/com/vitorpamplona/quartz/encoders/Nip01Serializer.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/experimental/Nip01Serializer.kt index ea9607733..e4b89fbc0 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/Nip01Serializer.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/experimental/Nip01Serializer.kt @@ -18,9 +18,9 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.encoders +package com.vitorpamplona.quartz.nip01Core.experimental -import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.nip01Core.core.Event import java.nio.ByteBuffer import java.nio.CharBuffer import java.nio.charset.CodingErrorAction diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/geohash/EventExt.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/geohash/EventExt.kt new file mode 100644 index 000000000..64b24727b --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/geohash/EventExt.kt @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip01Core.geohash + +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip22Comments.CommentEvent + +fun Event.hasGeohashes() = + if (this is CommentEvent) { + this.hasGeohashes() + } else { + tags.hasGeohashes() + } + +fun Event.isTaggedGeoHashes(hashtags: Set) = + if (this is CommentEvent) { + this.isTaggedGeoHashes(hashtags) + } else { + tags.isTaggedGeoHashes(hashtags) + } + +fun Event.isTaggedGeoHash(hashtag: String) = + if (this is CommentEvent) { + this.isTaggedGeoHash(hashtag) + } else { + tags.isTaggedGeoHash(hashtag) + } + +fun Event.geohashes() = + if (this is CommentEvent) { + geohashes() + } else { + tags.geohashes() + } + +fun Event.getGeoHash(): String? = + if (this is CommentEvent) { + getGeoHash() + } else { + tags.getGeoHash() + } diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/geohash/GeoHash.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/geohash/GeoHash.kt new file mode 100644 index 000000000..d430ba9bf --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/geohash/GeoHash.kt @@ -0,0 +1,29 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip01Core.geohash + +fun geohashMipMap(geohash: String): Array> = + geohash.indices + .asSequence() + .map { arrayOf("g", geohash.substring(0, it + 1)) } + .toList() + .reversed() + .toTypedArray() diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/geohash/TagArrayExt.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/geohash/TagArrayExt.kt new file mode 100644 index 000000000..cebd4a401 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/geohash/TagArrayExt.kt @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip01Core.geohash + +import com.vitorpamplona.quartz.nip01Core.core.TagArray +import com.vitorpamplona.quartz.nip01Core.core.anyTagWithValueStartingWithIgnoreCase +import com.vitorpamplona.quartz.nip01Core.core.hasTagWithContent +import com.vitorpamplona.quartz.nip01Core.core.isAnyTagged +import com.vitorpamplona.quartz.nip01Core.core.mapValues + +fun TagArray.hasGeohashes() = this.hasTagWithContent("g") + +fun TagArray.isTaggedGeoHashes(hashtags: Set) = this.isAnyTagged("g", hashtags) + +fun TagArray.isTaggedGeoHash(hashtag: String) = this.anyTagWithValueStartingWithIgnoreCase("g", hashtag) + +fun TagArray.geohashes() = this.mapValues("g") + +fun TagArray.getGeoHash(): String? = geohashes().maxByOrNull { it.length }?.ifBlank { null } diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/hashtags/EventExt.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/hashtags/EventExt.kt new file mode 100644 index 000000000..2f3762ce4 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/hashtags/EventExt.kt @@ -0,0 +1,38 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip01Core.hashtags + +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event + +fun Event.forEachHashTag(onEach: (eventId: HexKey) -> Unit) = tags.forEachHashTag(onEach) + +fun Event.anyHashTag(onEach: (str: String) -> Boolean) = tags.anyHashTag(onEach) + +fun Event.hasHashtags() = tags.hasHashtags() + +fun Event.hashtags() = tags.hashtags() + +fun Event.isTaggedHash(hashtag: String) = tags.isTaggedHash(hashtag) + +fun Event.isTaggedHashes(hashtags: Set) = tags.isTaggedHashes(hashtags) + +fun Event.firstIsTaggedHashes(hashtags: Set) = tags.firstIsTaggedHashes(hashtags) diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/hashtags/TagArrayExt.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/hashtags/TagArrayExt.kt new file mode 100644 index 000000000..f10a75d50 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/hashtags/TagArrayExt.kt @@ -0,0 +1,42 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip01Core.hashtags + +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.TagArray +import com.vitorpamplona.quartz.nip01Core.core.anyTagged +import com.vitorpamplona.quartz.nip01Core.core.forEachTagged +import com.vitorpamplona.quartz.nip01Core.core.hasTagWithContent +import com.vitorpamplona.quartz.nip01Core.core.mapValues + +fun TagArray.forEachHashTag(onEach: (eventId: HexKey) -> Unit) = this.forEachTagged("t", onEach) + +fun TagArray.anyHashTag(onEach: (str: String) -> Boolean) = this.anyTagged("t", onEach) + +fun TagArray.hasHashtags() = this.hasTagWithContent("t") + +fun TagArray.hashtags() = this.mapValues("t") + +fun TagArray.isTaggedHash(hashtag: String) = this.any { it.size > 1 && it[0] == "t" && it[1].equals(hashtag, true) } + +fun TagArray.isTaggedHashes(hashtags: Set) = this.any { it.size > 1 && it[0] == "t" && it[1].lowercase() in hashtags } + +fun TagArray.firstIsTaggedHashes(hashtags: Set) = this.firstOrNull { it.size > 1 && it[0] == "t" && it[1].lowercase() in hashtags }?.getOrNull(1) diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/jackson/EventDeserializer.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/jackson/EventDeserializer.kt new file mode 100644 index 000000000..527b4b339 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/jackson/EventDeserializer.kt @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip01Core.jackson + +import com.fasterxml.jackson.core.JsonParser +import com.fasterxml.jackson.databind.DeserializationContext +import com.fasterxml.jackson.databind.deser.std.StdDeserializer +import com.vitorpamplona.quartz.nip01Core.core.Event + +class EventDeserializer : StdDeserializer(Event::class.java) { + override fun deserialize( + jp: JsonParser, + ctxt: DeserializationContext, + ): Event = EventManualDeserializer.fromJson(jp.codec.readTree(jp)) +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/jackson/EventManualDeserializer.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/jackson/EventManualDeserializer.kt new file mode 100644 index 000000000..f39fc00cf --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/jackson/EventManualDeserializer.kt @@ -0,0 +1,43 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip01Core.jackson + +import com.fasterxml.jackson.databind.JsonNode +import com.vitorpamplona.quartz.nip01Core.EventFactory +import com.vitorpamplona.quartz.nip01Core.core.Event + +class EventManualDeserializer { + companion object { + fun fromJson(jsonObject: JsonNode): Event = + 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").toTypedArray { + it.toTypedArray { s -> if (s.isNull) "" else s.asText().intern() } + }, + content = jsonObject.get("content").asText(), + sig = jsonObject.get("sig").asText(), + ) + } +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/jackson/EventManualSerializer.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/jackson/EventManualSerializer.kt new file mode 100644 index 000000000..528a3c5f1 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/jackson/EventManualSerializer.kt @@ -0,0 +1,62 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip01Core.jackson + +import com.fasterxml.jackson.databind.node.JsonNodeFactory +import com.vitorpamplona.quartz.nip01Core.HexKey + +class EventManualSerializer { + companion object { + fun toJson( + id: HexKey, + pubKey: HexKey, + createdAt: Long, + kind: Int, + tags: Array>, + content: String, + sig: String, + ): String { + val factory = JsonNodeFactory.instance + + val obj = + factory.objectNode().apply { + put("id", id) + put("pubkey", pubKey) + put("created_at", createdAt) + put("kind", kind) + replace( + "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) + } + + return EventMapper.mapper.writeValueAsString(obj) + } + } +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/jackson/EventMapper.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/jackson/EventMapper.kt new file mode 100644 index 000000000..25f97c895 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/jackson/EventMapper.kt @@ -0,0 +1,73 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip01Core.jackson + +import com.fasterxml.jackson.core.json.JsonReadFeature +import com.fasterxml.jackson.databind.DeserializationFeature +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.module.SimpleModule +import com.fasterxml.jackson.databind.node.ArrayNode +import com.fasterxml.jackson.databind.node.ObjectNode +import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerMessage +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequest +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponse +import com.vitorpamplona.quartz.nip47WalletConnect.Request +import com.vitorpamplona.quartz.nip47WalletConnect.RequestDeserializer +import com.vitorpamplona.quartz.nip47WalletConnect.Response +import com.vitorpamplona.quartz.nip47WalletConnect.ResponseDeserializer +import com.vitorpamplona.quartz.nip59Giftwrap.Gossip +import com.vitorpamplona.quartz.nip59Giftwrap.GossipDeserializer +import com.vitorpamplona.quartz.nip59Giftwrap.GossipSerializer + +class EventMapper { + companion object { + val mapper = + jacksonObjectMapper() + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + .enable(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS.mappedFeature()) + .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()) + .addDeserializer(BunkerMessage::class.java, BunkerMessage.BunkerMessageDeserializer()) + .addSerializer(BunkerRequest::class.java, BunkerRequest.BunkerRequestSerializer()) + .addDeserializer(BunkerRequest::class.java, BunkerRequest.BunkerRequestDeserializer()) + .addSerializer(BunkerResponse::class.java, BunkerResponse.BunkerResponseSerializer()) + .addDeserializer(BunkerResponse::class.java, BunkerResponse.BunkerResponseDeserializer()), + ) + + fun fromJson(json: String): Event = mapper.readValue(json, Event::class.java) + + fun fromJson(json: JsonNode): Event = EventManualDeserializer.fromJson(json) + + fun toJson(event: Event): String = mapper.writeValueAsString(event) + + fun toJson(event: ArrayNode?): String = mapper.writeValueAsString(event) + + fun toJson(event: ObjectNode?): String = mapper.writeValueAsString(event) + } +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/jackson/EventSerializer.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/jackson/EventSerializer.kt new file mode 100644 index 000000000..33f3ab70d --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/jackson/EventSerializer.kt @@ -0,0 +1,46 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip01Core.jackson + +import com.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.databind.SerializerProvider +import com.fasterxml.jackson.databind.ser.std.StdSerializer +import com.vitorpamplona.quartz.nip01Core.core.Event + +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, 0, tag.size) } + gen.writeEndArray() + gen.writeStringField("content", event.content) + gen.writeStringField("sig", event.sig) + gen.writeEndObject() + } +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/jackson/JacksonExt.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/jackson/JacksonExt.kt new file mode 100644 index 000000000..d6ddaeb77 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/jackson/JacksonExt.kt @@ -0,0 +1,25 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip01Core.jackson + +import com.fasterxml.jackson.databind.JsonNode + +inline fun JsonNode.toTypedArray(transform: (JsonNode) -> R): Array = Array(size()) { transform(get(it)) } diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/people/EventExt.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/people/EventExt.kt new file mode 100644 index 000000000..44356cb51 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/people/EventExt.kt @@ -0,0 +1,38 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip01Core.people + +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.core.firstTagValue +import com.vitorpamplona.quartz.nip01Core.core.hasTagWithContent +import com.vitorpamplona.quartz.nip01Core.core.isAnyTagged +import com.vitorpamplona.quartz.nip01Core.core.isTagged +import com.vitorpamplona.quartz.nip01Core.core.mapValues + +fun Event.isTaggedUser(idHex: String) = tags.isTagged("p", idHex) + +fun Event.isTaggedUsers(idHexes: Set) = tags.isAnyTagged("p", idHexes) + +fun Event.taggedUsers() = tags.mapValues("p") + +fun Event.firstTaggedUser() = tags.firstTagValue("p") + +fun Event.hasAnyTaggedUser() = tags.hasTagWithContent("p") diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/people/TagArrayExt.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/people/TagArrayExt.kt new file mode 100644 index 000000000..754b7189d --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/people/TagArrayExt.kt @@ -0,0 +1,38 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip01Core.people + +import com.vitorpamplona.quartz.nip01Core.core.TagArray +import com.vitorpamplona.quartz.nip01Core.core.firstTagValue +import com.vitorpamplona.quartz.nip01Core.core.hasTagWithContent +import com.vitorpamplona.quartz.nip01Core.core.isAnyTagged +import com.vitorpamplona.quartz.nip01Core.core.isTagged +import com.vitorpamplona.quartz.nip01Core.core.mapValues + +fun TagArray.isTaggedUser(idHex: String) = this.isTagged("p", idHex) + +fun TagArray.isTaggedUsers(idHexes: Set) = this.isAnyTagged("p", idHexes) + +fun TagArray.taggedUsers() = this.mapValues("p") + +fun TagArray.firstTaggedUser() = this.firstTagValue("p") + +fun TagArray.hasAnyTaggedUser() = this.hasTagWithContent("p") diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/signers/NostrSigner.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/signers/NostrSigner.kt similarity index 88% rename from quartz/src/main/java/com/vitorpamplona/quartz/signers/NostrSigner.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/signers/NostrSigner.kt index a5df0763f..d6039b0c6 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/signers/NostrSigner.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/signers/NostrSigner.kt @@ -18,14 +18,14 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.signers +package com.vitorpamplona.quartz.nip01Core.signers -import com.vitorpamplona.quartz.crypto.nip04.Nip04 -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.events.Event -import com.vitorpamplona.quartz.events.EventFactory -import com.vitorpamplona.quartz.events.LnZapPrivateEvent -import com.vitorpamplona.quartz.events.LnZapRequestEvent +import com.vitorpamplona.quartz.nip01Core.EventFactory +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip04Dm.Nip04 +import com.vitorpamplona.quartz.nip57Zaps.LnZapPrivateEvent +import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent abstract class NostrSigner( val pubKey: HexKey, diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/signers/NostrSignerInternal.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/signers/NostrSignerInternal.kt similarity index 89% rename from quartz/src/main/java/com/vitorpamplona/quartz/signers/NostrSignerInternal.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/signers/NostrSignerInternal.kt index c6668a563..2d44683d5 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/signers/NostrSignerInternal.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/signers/NostrSignerInternal.kt @@ -18,14 +18,14 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.signers +package com.vitorpamplona.quartz.nip01Core.signers import com.vitorpamplona.quartz.crypto.KeyPair -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.toHexKey -import com.vitorpamplona.quartz.events.Event -import com.vitorpamplona.quartz.events.LnZapPrivateEvent -import com.vitorpamplona.quartz.events.LnZapRequestEvent +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.toHexKey +import com.vitorpamplona.quartz.nip57Zaps.LnZapPrivateEvent +import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent class NostrSignerInternal( val keyPair: KeyPair, diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/signers/NostrSignerSync.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/signers/NostrSignerSync.kt similarity index 91% rename from quartz/src/main/java/com/vitorpamplona/quartz/signers/NostrSignerSync.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/signers/NostrSignerSync.kt index 32c214e7f..fcb0cb616 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/signers/NostrSignerSync.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/signers/NostrSignerSync.kt @@ -18,18 +18,19 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.signers +package com.vitorpamplona.quartz.nip01Core.signers import android.util.Log import com.vitorpamplona.quartz.crypto.CryptoUtils import com.vitorpamplona.quartz.crypto.KeyPair -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.hexToByteArray -import com.vitorpamplona.quartz.encoders.toHexKey -import com.vitorpamplona.quartz.events.Event -import com.vitorpamplona.quartz.events.EventFactory -import com.vitorpamplona.quartz.events.LnZapPrivateEvent -import com.vitorpamplona.quartz.events.LnZapRequestEvent +import com.vitorpamplona.quartz.nip01Core.EventFactory +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.hexToByteArray +import com.vitorpamplona.quartz.nip01Core.toHexKey +import com.vitorpamplona.quartz.nip57Zaps.LnZapPrivateEvent +import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent +import com.vitorpamplona.quartz.nip57Zaps.PrivateZapEncryption class NostrSignerSync( val keyPair: KeyPair, @@ -153,7 +154,7 @@ class NostrSignerSync( val idToGeneratePrivateKey = zappedEvent ?: userHex val encryptionPrivateKey = - LnZapRequestEvent.createEncryptionPrivateKey( + PrivateZapEncryption.createEncryptionPrivateKey( keyPair.privKey.toHexKey(), idToGeneratePrivateKey, createdAt, @@ -165,7 +166,7 @@ class NostrSignerSync( val noteJson = privateEvent.toJson() val encryptedContent = - LnZapRequestEvent.encryptPrivateZapMessage( + PrivateZapEncryption.encryptPrivateZapMessage( noteJson, encryptionPrivateKey, userHex.hexToByteArray(), @@ -195,13 +196,13 @@ class NostrSignerSync( val altPubkeyToUse = recipientPK val altPrivateKeyToUse = if (recipientPost != null) { - LnZapRequestEvent.createEncryptionPrivateKey( + PrivateZapEncryption.createEncryptionPrivateKey( keyPair.privKey.toHexKey(), recipientPost, event.createdAt, ) } else if (recipientPK != null) { - LnZapRequestEvent.createEncryptionPrivateKey( + PrivateZapEncryption.createEncryptionPrivateKey( keyPair.privKey.toHexKey(), recipientPK, event.createdAt, diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/ContactListEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip02FollowList/ContactListEvent.kt similarity index 80% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/ContactListEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip02FollowList/ContactListEvent.kt index cbdf74a31..15f614cf1 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/ContactListEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip02FollowList/ContactListEvent.kt @@ -18,19 +18,27 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip02FollowList import android.util.Log import androidx.compose.runtime.Immutable import androidx.compose.runtime.Stable -import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.module.kotlin.readValue -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.decodePublicKey -import com.vitorpamplona.quartz.encoders.toHexKey -import com.vitorpamplona.quartz.signers.NostrSigner -import com.vitorpamplona.quartz.signers.NostrSignerSync +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.addressables.isTaggedAddressableNote +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.events.isTaggedEvent +import com.vitorpamplona.quartz.nip01Core.geohash.isTaggedGeoHash +import com.vitorpamplona.quartz.nip01Core.hashtags.hashtags +import com.vitorpamplona.quartz.nip01Core.hashtags.isTaggedHash +import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper +import com.vitorpamplona.quartz.nip01Core.people.isTaggedUser +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerSync +import com.vitorpamplona.quartz.nip01Core.toHexKey +import com.vitorpamplona.quartz.nip19Bech32Entities.decodePublicKey +import com.vitorpamplona.quartz.nip19Bech32Entities.parse import com.vitorpamplona.quartz.utils.TimeUtils @Immutable data class Contact( @@ -83,8 +91,6 @@ class ContactListEvent( fun countFollowTags() = tags.count { it.size > 1 && it[0] == "t" } - fun unverifiedFollowGeohashSet() = tags.filter { it.size > 1 && it[0] == "g" }.mapNotNull { it.getOrNull(1) } - fun follows() = tags.mapNotNull { try { @@ -104,7 +110,7 @@ class ContactListEvent( fun relays(): Map? = try { if (content.isNotEmpty()) { - mapper.readValue>(content) + EventMapper.mapper.readValue>(content) } else { null } @@ -131,7 +137,7 @@ class ContactListEvent( ): ContactListEvent? { val content = if (relayUse != null) { - mapper.writeValueAsString(relayUse) + EventMapper.mapper.writeValueAsString(relayUse) } else { "" } @@ -162,7 +168,7 @@ class ContactListEvent( ) { val content = if (relayUse != null) { - mapper.writeValueAsString(relayUse) + EventMapper.mapper.writeValueAsString(relayUse) } else { "" } @@ -382,7 +388,7 @@ class ContactListEvent( ) { val content = if (relayUse != null) { - mapper.writeValueAsString(relayUse) + EventMapper.mapper.writeValueAsString(relayUse) } else { "" } @@ -420,81 +426,6 @@ class ContactListEvent( ) } -@Stable -class UserMetadata { - var name: String? = null - - @Deprecated("Use name instead", replaceWith = ReplaceWith("name")) - var username: String? = null - - @JsonProperty("display_name") - var displayName: String? = null - var picture: String? = null - var banner: String? = null - var website: String? = null - var about: String? = null - var bot: Boolean? = null - var pronouns: 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 - - @Transient - var tags: ImmutableListOfLists? = null - - fun anyName(): String? = displayName ?: name ?: username - - fun anyNameStartsWith(prefix: String): Boolean = - listOfNotNull(name, username, displayName, nip05, lud06, lud16).any { - it.contains(prefix, true) - } - - fun lnAddress(): String? = lud16 ?: lud06 - - fun bestName(): String? = displayName ?: name ?: username - - fun nip05(): String? = nip05 - - fun profilePicture(): String? = picture - - fun cleanBlankNames() { - if (pronouns == "null") pronouns = null - - if (picture?.isNotEmpty() == true) picture = picture?.trim() - if (nip05?.isNotEmpty() == true) nip05 = nip05?.trim() - if (displayName?.isNotEmpty() == true) displayName = displayName?.trim() - if (name?.isNotEmpty() == true) name = name?.trim() - if (username?.isNotEmpty() == true) username = username?.trim() - if (lud06?.isNotEmpty() == true) lud06 = lud06?.trim() - if (lud16?.isNotEmpty() == true) lud16 = lud16?.trim() - if (pronouns?.isNotEmpty() == true) pronouns = pronouns?.trim() - - if (banner?.isNotEmpty() == true) banner = banner?.trim() - if (website?.isNotEmpty() == true) website = website?.trim() - if (domain?.isNotEmpty() == true) domain = domain?.trim() - - if (picture?.isBlank() == true) picture = null - if (nip05?.isBlank() == true) nip05 = null - if (displayName?.isBlank() == true) displayName = null - if (name?.isBlank() == true) name = null - if (username?.isBlank() == true) username = null - if (lud06?.isBlank() == true) lud06 = null - if (lud16?.isBlank() == true) lud16 = null - - if (banner?.isBlank() == true) banner = null - if (website?.isBlank() == true) website = null - if (domain?.isBlank() == true) domain = null - if (pronouns?.isBlank() == true) pronouns = null - } -} - @Stable class ImmutableListOfLists( val lists: Array>, ) diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/OtsEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/OtsEvent.kt similarity index 81% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/OtsEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/OtsEvent.kt index bcb715ae8..4f012cc2f 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/OtsEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/OtsEvent.kt @@ -18,46 +18,27 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip03Timestamp import android.util.Log import androidx.compose.runtime.Immutable -import androidx.compose.runtime.Stable -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.hexToByteArray -import com.vitorpamplona.quartz.ots.BlockstreamExplorer -import com.vitorpamplona.quartz.ots.CalendarPureJavaBuilder -import com.vitorpamplona.quartz.ots.DetachedTimestampFile -import com.vitorpamplona.quartz.ots.Hash -import com.vitorpamplona.quartz.ots.OpenTimestamps -import com.vitorpamplona.quartz.ots.VerifyResult -import com.vitorpamplona.quartz.ots.exceptions.UrlException -import com.vitorpamplona.quartz.ots.op.OpSHA256 -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.hexToByteArray +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip03Timestamp.ots.BlockstreamExplorer +import com.vitorpamplona.quartz.nip03Timestamp.ots.CalendarPureJavaBuilder +import com.vitorpamplona.quartz.nip03Timestamp.ots.DetachedTimestampFile +import com.vitorpamplona.quartz.nip03Timestamp.ots.Hash +import com.vitorpamplona.quartz.nip03Timestamp.ots.OpenTimestamps +import com.vitorpamplona.quartz.nip03Timestamp.ots.VerifyResult +import com.vitorpamplona.quartz.nip03Timestamp.ots.exceptions.UrlException +import com.vitorpamplona.quartz.nip03Timestamp.ots.op.OpSHA256 import com.vitorpamplona.quartz.utils.TimeUtils import com.vitorpamplona.quartz.utils.pointerSizeInBytes import kotlinx.coroutines.CancellationException import java.util.Base64 -@Immutable -sealed class VerificationState { - @Immutable object NotStarted : VerificationState() - - @Stable - class Verified( - val verifiedTime: Long, - ) : VerificationState() - - @Immutable class Error( - val errorMessage: String, - ) : VerificationState() - - @Immutable class NetworkError( - val errorMessage: String, - val time: Long = TimeUtils.now(), - ) : VerificationState() -} - @Immutable class OtsEvent( id: HexKey, @@ -110,13 +91,25 @@ class OtsEvent( const val KIND = 1040 const val ALT = "Opentimestamps Attestation" - var otsInstance = OpenTimestamps(BlockstreamExplorer(), CalendarPureJavaBuilder()) + var otsInstance = + OpenTimestamps( + BlockstreamExplorer(), + CalendarPureJavaBuilder(), + ) fun stamp(eventId: HexKey): String { - val hash = Hash(eventId.hexToByteArray(), OpSHA256._TAG) + val hash = + Hash( + eventId.hexToByteArray(), + OpSHA256._TAG, + ) val file = DetachedTimestampFile.from(hash) val timestamp = otsInstance.stamp(file) - val detachedToSerialize = DetachedTimestampFile(hash.getOp(), timestamp) + val detachedToSerialize = + DetachedTimestampFile( + hash.getOp(), + timestamp, + ) return Base64.getEncoder().encodeToString(detachedToSerialize.serialize()) } diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/VerificationState.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/VerificationState.kt new file mode 100644 index 000000000..26b560821 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/VerificationState.kt @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip03Timestamp + +import androidx.compose.runtime.Immutable +import androidx.compose.runtime.Stable +import com.vitorpamplona.quartz.utils.TimeUtils + +@Immutable +sealed class VerificationState { + @Immutable + object NotStarted : VerificationState() + + @Stable + class Verified( + val verifiedTime: Long, + ) : VerificationState() + + @Immutable + class Error( + val errorMessage: String, + ) : VerificationState() + + @Immutable + class NetworkError( + val errorMessage: String, + val time: Long = TimeUtils.now(), + ) : VerificationState() +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/BitcoinExplorer.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/BitcoinExplorer.java similarity index 91% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/BitcoinExplorer.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/BitcoinExplorer.java index 5a5bbd811..37a7de152 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/BitcoinExplorer.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/BitcoinExplorer.java @@ -1,4 +1,4 @@ -package com.vitorpamplona.quartz.ots; +package com.vitorpamplona.quartz.nip03Timestamp.ots; public interface BitcoinExplorer { /** diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/BlockHeader.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/BlockHeader.java similarity index 97% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/BlockHeader.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/BlockHeader.java index 3d0983d1f..c13deba43 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/BlockHeader.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/BlockHeader.java @@ -1,4 +1,4 @@ -package com.vitorpamplona.quartz.ots; +package com.vitorpamplona.quartz.nip03Timestamp.ots; public class BlockHeader { diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/BlockstreamExplorer.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/BlockstreamExplorer.java similarity index 88% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/BlockstreamExplorer.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/BlockstreamExplorer.java index 01c84254f..d08821446 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/BlockstreamExplorer.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/BlockstreamExplorer.java @@ -1,13 +1,15 @@ -package com.vitorpamplona.quartz.ots; +package com.vitorpamplona.quartz.nip03Timestamp.ots; import android.util.Log; import com.fasterxml.jackson.databind.JsonNode; -import com.vitorpamplona.quartz.ots.http.Request; -import com.vitorpamplona.quartz.ots.http.Response; +import com.vitorpamplona.quartz.nip03Timestamp.ots.http.Request; +import com.vitorpamplona.quartz.nip03Timestamp.ots.http.Response; import java.net.URL; -import java.util.concurrent.*; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; public class BlockstreamExplorer implements BitcoinExplorer { private static final String esploraUrl = "https://blockstream.info/api"; diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/Calendar.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/Calendar.java similarity index 88% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/Calendar.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/Calendar.java index 27c870d8a..1784a78de 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/Calendar.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/Calendar.java @@ -1,11 +1,11 @@ -package com.vitorpamplona.quartz.ots; +package com.vitorpamplona.quartz.nip03Timestamp.ots; -import com.vitorpamplona.quartz.ots.exceptions.CommitmentNotFoundException; -import com.vitorpamplona.quartz.ots.exceptions.DeserializationException; -import com.vitorpamplona.quartz.ots.exceptions.ExceededSizeException; -import com.vitorpamplona.quartz.ots.exceptions.UrlException; -import com.vitorpamplona.quartz.ots.http.Request; -import com.vitorpamplona.quartz.ots.http.Response; +import com.vitorpamplona.quartz.nip03Timestamp.ots.exceptions.CommitmentNotFoundException; +import com.vitorpamplona.quartz.nip03Timestamp.ots.exceptions.DeserializationException; +import com.vitorpamplona.quartz.nip03Timestamp.ots.exceptions.ExceededSizeException; +import com.vitorpamplona.quartz.nip03Timestamp.ots.exceptions.UrlException; +import com.vitorpamplona.quartz.nip03Timestamp.ots.http.Request; +import com.vitorpamplona.quartz.nip03Timestamp.ots.http.Response; import java.net.URL; import java.util.HashMap; diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/CalendarAsyncSubmit.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/CalendarAsyncSubmit.java similarity index 89% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/CalendarAsyncSubmit.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/CalendarAsyncSubmit.java index 08b69a261..e6b84a00f 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/CalendarAsyncSubmit.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/CalendarAsyncSubmit.java @@ -1,9 +1,7 @@ -package com.vitorpamplona.quartz.ots; +package com.vitorpamplona.quartz.nip03Timestamp.ots; -import android.util.Log; - -import com.vitorpamplona.quartz.ots.http.Request; -import com.vitorpamplona.quartz.ots.http.Response; +import com.vitorpamplona.quartz.nip03Timestamp.ots.http.Request; +import com.vitorpamplona.quartz.nip03Timestamp.ots.http.Response; import java.net.URL; import java.util.HashMap; diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/CalendarBuilder.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/CalendarBuilder.java similarity index 75% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/CalendarBuilder.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/CalendarBuilder.java index f630401e4..1dd68ed8c 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/CalendarBuilder.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/CalendarBuilder.java @@ -1,4 +1,4 @@ -package com.vitorpamplona.quartz.ots; +package com.vitorpamplona.quartz.nip03Timestamp.ots; public interface CalendarBuilder { public ICalendar newSyncCalendar(String url); diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/CalendarPureJavaBuilder.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/CalendarPureJavaBuilder.java similarity index 84% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/CalendarPureJavaBuilder.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/CalendarPureJavaBuilder.java index d75b65b4c..85ff8b2c5 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/CalendarPureJavaBuilder.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/CalendarPureJavaBuilder.java @@ -1,4 +1,4 @@ -package com.vitorpamplona.quartz.ots; +package com.vitorpamplona.quartz.nip03Timestamp.ots; public class CalendarPureJavaBuilder implements CalendarBuilder { public ICalendar newSyncCalendar(String url) { diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/DetachedTimestampFile.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/DetachedTimestampFile.java similarity index 96% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/DetachedTimestampFile.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/DetachedTimestampFile.java index 1b212316d..2bc8d50e0 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/DetachedTimestampFile.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/DetachedTimestampFile.java @@ -1,9 +1,9 @@ -package com.vitorpamplona.quartz.ots; +package com.vitorpamplona.quartz.nip03Timestamp.ots; -import com.vitorpamplona.quartz.ots.exceptions.DeserializationException; -import com.vitorpamplona.quartz.ots.op.Op; -import com.vitorpamplona.quartz.ots.op.OpCrypto; -import com.vitorpamplona.quartz.ots.op.OpSHA256; +import com.vitorpamplona.quartz.nip03Timestamp.ots.exceptions.DeserializationException; +import com.vitorpamplona.quartz.nip03Timestamp.ots.op.Op; +import com.vitorpamplona.quartz.nip03Timestamp.ots.op.OpCrypto; +import com.vitorpamplona.quartz.nip03Timestamp.ots.op.OpSHA256; import java.io.File; import java.io.IOException; diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/Hash.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/Hash.java similarity index 92% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/Hash.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/Hash.java index 4d1375f5f..785e4ab83 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/Hash.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/Hash.java @@ -1,11 +1,11 @@ -package com.vitorpamplona.quartz.ots; +package com.vitorpamplona.quartz.nip03Timestamp.ots; -import com.vitorpamplona.quartz.ots.op.OpCrypto; -import com.vitorpamplona.quartz.ots.op.OpKECCAK256; -import com.vitorpamplona.quartz.ots.op.OpRIPEMD160; -import com.vitorpamplona.quartz.ots.op.OpSHA1; -import com.vitorpamplona.quartz.ots.op.OpSHA256; -import com.vitorpamplona.quartz.encoders.Hex; +import com.vitorpamplona.quartz.crypto.Hex; +import com.vitorpamplona.quartz.nip03Timestamp.ots.op.OpCrypto; +import com.vitorpamplona.quartz.nip03Timestamp.ots.op.OpKECCAK256; +import com.vitorpamplona.quartz.nip03Timestamp.ots.op.OpRIPEMD160; +import com.vitorpamplona.quartz.nip03Timestamp.ots.op.OpSHA1; +import com.vitorpamplona.quartz.nip03Timestamp.ots.op.OpSHA256; import java.io.File; import java.io.IOException; diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/ICalendar.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/ICalendar.java new file mode 100644 index 000000000..75a546583 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/ICalendar.java @@ -0,0 +1,13 @@ +package com.vitorpamplona.quartz.nip03Timestamp.ots; + +import com.vitorpamplona.quartz.nip03Timestamp.ots.exceptions.CommitmentNotFoundException; +import com.vitorpamplona.quartz.nip03Timestamp.ots.exceptions.DeserializationException; +import com.vitorpamplona.quartz.nip03Timestamp.ots.exceptions.ExceededSizeException; +import com.vitorpamplona.quartz.nip03Timestamp.ots.exceptions.UrlException; + +public interface ICalendar { + Timestamp submit(byte[] digest) + throws ExceededSizeException, UrlException, DeserializationException; + + Timestamp getTimestamp(byte[] commitment) throws DeserializationException, ExceededSizeException, CommitmentNotFoundException, UrlException; +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/ICalendarAsyncSubmit.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/ICalendarAsyncSubmit.java similarity index 79% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/ICalendarAsyncSubmit.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/ICalendarAsyncSubmit.java index 9dd821150..22e785c2b 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/ICalendarAsyncSubmit.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/ICalendarAsyncSubmit.java @@ -1,4 +1,4 @@ -package com.vitorpamplona.quartz.ots; +package com.vitorpamplona.quartz.nip03Timestamp.ots; import java.util.Optional; import java.util.concurrent.Callable; diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/Merkle.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/Merkle.java similarity index 92% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/Merkle.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/Merkle.java index 59222c5e4..df129fbab 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/Merkle.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/Merkle.java @@ -1,8 +1,8 @@ -package com.vitorpamplona.quartz.ots; +package com.vitorpamplona.quartz.nip03Timestamp.ots; -import com.vitorpamplona.quartz.ots.op.OpAppend; -import com.vitorpamplona.quartz.ots.op.OpPrepend; -import com.vitorpamplona.quartz.ots.op.OpSHA256; +import com.vitorpamplona.quartz.nip03Timestamp.ots.op.OpAppend; +import com.vitorpamplona.quartz.nip03Timestamp.ots.op.OpPrepend; +import com.vitorpamplona.quartz.nip03Timestamp.ots.op.OpSHA256; import java.util.ArrayList; import java.util.List; diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/OpenTimestamps.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/OpenTimestamps.java similarity index 95% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/OpenTimestamps.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/OpenTimestamps.java index 3118c99a0..95b7418bc 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/OpenTimestamps.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/OpenTimestamps.java @@ -1,17 +1,17 @@ -package com.vitorpamplona.quartz.ots; +package com.vitorpamplona.quartz.nip03Timestamp.ots; import android.util.Log; -import com.vitorpamplona.quartz.ots.attestation.BitcoinBlockHeaderAttestation; -import com.vitorpamplona.quartz.ots.attestation.EthereumBlockHeaderAttestation; -import com.vitorpamplona.quartz.ots.attestation.LitecoinBlockHeaderAttestation; -import com.vitorpamplona.quartz.ots.attestation.PendingAttestation; -import com.vitorpamplona.quartz.ots.attestation.TimeAttestation; -import com.vitorpamplona.quartz.encoders.Hex; -import com.vitorpamplona.quartz.ots.exceptions.VerificationException; -import com.vitorpamplona.quartz.ots.op.OpAppend; -import com.vitorpamplona.quartz.ots.op.OpCrypto; -import com.vitorpamplona.quartz.ots.op.OpSHA256; +import com.vitorpamplona.quartz.crypto.Hex; +import com.vitorpamplona.quartz.nip03Timestamp.ots.attestation.BitcoinBlockHeaderAttestation; +import com.vitorpamplona.quartz.nip03Timestamp.ots.attestation.EthereumBlockHeaderAttestation; +import com.vitorpamplona.quartz.nip03Timestamp.ots.attestation.LitecoinBlockHeaderAttestation; +import com.vitorpamplona.quartz.nip03Timestamp.ots.attestation.PendingAttestation; +import com.vitorpamplona.quartz.nip03Timestamp.ots.attestation.TimeAttestation; +import com.vitorpamplona.quartz.nip03Timestamp.ots.exceptions.VerificationException; +import com.vitorpamplona.quartz.nip03Timestamp.ots.op.OpAppend; +import com.vitorpamplona.quartz.nip03Timestamp.ots.op.OpCrypto; +import com.vitorpamplona.quartz.nip03Timestamp.ots.op.OpSHA256; import java.io.IOException; import java.nio.charset.StandardCharsets; diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/README.md b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/README.md similarity index 100% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/README.md rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/README.md diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/StreamDeserializationContext.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/StreamDeserializationContext.java similarity index 94% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/StreamDeserializationContext.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/StreamDeserializationContext.java index b566d816f..96e1b0679 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/StreamDeserializationContext.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/StreamDeserializationContext.java @@ -1,8 +1,8 @@ -package com.vitorpamplona.quartz.ots; +package com.vitorpamplona.quartz.nip03Timestamp.ots; + +import com.vitorpamplona.quartz.nip03Timestamp.ots.exceptions.DeserializationException; -import com.vitorpamplona.quartz.ots.exceptions.DeserializationException; import java.util.Arrays; -import java.util.logging.Logger; public class StreamDeserializationContext { diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/StreamSerializationContext.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/StreamSerializationContext.java similarity index 96% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/StreamSerializationContext.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/StreamSerializationContext.java index 87368bda8..a95b4229a 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/StreamSerializationContext.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/StreamSerializationContext.java @@ -1,9 +1,8 @@ -package com.vitorpamplona.quartz.ots; +package com.vitorpamplona.quartz.nip03Timestamp.ots; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.logging.Logger; public class StreamSerializationContext { diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/Timestamp.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/Timestamp.java similarity index 96% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/Timestamp.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/Timestamp.java index f9f7d03c6..a93de02ec 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/Timestamp.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/Timestamp.java @@ -1,15 +1,24 @@ -package com.vitorpamplona.quartz.ots; +package com.vitorpamplona.quartz.nip03Timestamp.ots; -import com.vitorpamplona.quartz.ots.attestation.BitcoinBlockHeaderAttestation; -import com.vitorpamplona.quartz.ots.attestation.TimeAttestation; -import com.vitorpamplona.quartz.encoders.Hex; -import com.vitorpamplona.quartz.ots.exceptions.DeserializationException; -import com.vitorpamplona.quartz.ots.op.Op; -import com.vitorpamplona.quartz.ots.op.OpBinary; -import com.vitorpamplona.quartz.ots.op.OpSHA256; +import com.vitorpamplona.quartz.crypto.Hex; +import com.vitorpamplona.quartz.nip03Timestamp.ots.attestation.BitcoinBlockHeaderAttestation; +import com.vitorpamplona.quartz.nip03Timestamp.ots.attestation.TimeAttestation; +import com.vitorpamplona.quartz.nip03Timestamp.ots.exceptions.DeserializationException; +import com.vitorpamplona.quartz.nip03Timestamp.ots.op.Op; +import com.vitorpamplona.quartz.nip03Timestamp.ots.op.OpBinary; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; import java.util.Map.Entry; +import java.util.Set; +import java.util.TreeMap; /** * Proof that one or more attestations commit to a message. diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/Utils.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/Utils.java similarity index 99% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/Utils.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/Utils.java index 85cb300e8..97ea90f9c 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/Utils.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/Utils.java @@ -1,4 +1,4 @@ -package com.vitorpamplona.quartz.ots; +package com.vitorpamplona.quartz.nip03Timestamp.ots; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/VerifyResult.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/VerifyResult.java similarity index 96% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/VerifyResult.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/VerifyResult.java index 8288779d1..4f777de1f 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/VerifyResult.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/VerifyResult.java @@ -1,4 +1,4 @@ -package com.vitorpamplona.quartz.ots; +package com.vitorpamplona.quartz.nip03Timestamp.ots; import java.text.DateFormatSymbols; import java.text.SimpleDateFormat; diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/attestation/BitcoinBlockHeaderAttestation.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/attestation/BitcoinBlockHeaderAttestation.java similarity index 90% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/attestation/BitcoinBlockHeaderAttestation.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/attestation/BitcoinBlockHeaderAttestation.java index 55acbefe6..abb74bd9f 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/attestation/BitcoinBlockHeaderAttestation.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/attestation/BitcoinBlockHeaderAttestation.java @@ -1,13 +1,12 @@ -package com.vitorpamplona.quartz.ots.attestation; +package com.vitorpamplona.quartz.nip03Timestamp.ots.attestation; -import com.vitorpamplona.quartz.ots.BlockHeader; -import com.vitorpamplona.quartz.ots.StreamDeserializationContext; -import com.vitorpamplona.quartz.ots.StreamSerializationContext; -import com.vitorpamplona.quartz.ots.Utils; -import com.vitorpamplona.quartz.ots.exceptions.VerificationException; +import com.vitorpamplona.quartz.nip03Timestamp.ots.BlockHeader; +import com.vitorpamplona.quartz.nip03Timestamp.ots.StreamDeserializationContext; +import com.vitorpamplona.quartz.nip03Timestamp.ots.StreamSerializationContext; +import com.vitorpamplona.quartz.nip03Timestamp.ots.Utils; +import com.vitorpamplona.quartz.nip03Timestamp.ots.exceptions.VerificationException; import java.util.Arrays; -import java.util.logging.Logger; /** * Bitcoin Block Header Attestation. diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/attestation/EthereumBlockHeaderAttestation.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/attestation/EthereumBlockHeaderAttestation.java similarity index 87% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/attestation/EthereumBlockHeaderAttestation.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/attestation/EthereumBlockHeaderAttestation.java index bce68c9a8..e0d514275 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/attestation/EthereumBlockHeaderAttestation.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/attestation/EthereumBlockHeaderAttestation.java @@ -1,11 +1,9 @@ -package com.vitorpamplona.quartz.ots.attestation; +package com.vitorpamplona.quartz.nip03Timestamp.ots.attestation; -import com.vitorpamplona.quartz.ots.StreamDeserializationContext; -import com.vitorpamplona.quartz.ots.StreamSerializationContext; -import com.vitorpamplona.quartz.ots.Utils; +import com.vitorpamplona.quartz.nip03Timestamp.ots.StreamDeserializationContext; +import com.vitorpamplona.quartz.nip03Timestamp.ots.StreamSerializationContext; import java.util.Arrays; -import java.util.logging.Logger; /** * Ethereum Block Header Attestation. diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/attestation/LitecoinBlockHeaderAttestation.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/attestation/LitecoinBlockHeaderAttestation.java similarity index 85% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/attestation/LitecoinBlockHeaderAttestation.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/attestation/LitecoinBlockHeaderAttestation.java index 548d88e24..dc7c22f28 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/attestation/LitecoinBlockHeaderAttestation.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/attestation/LitecoinBlockHeaderAttestation.java @@ -1,13 +1,12 @@ -package com.vitorpamplona.quartz.ots.attestation; +package com.vitorpamplona.quartz.nip03Timestamp.ots.attestation; -import com.vitorpamplona.quartz.ots.BlockHeader; -import com.vitorpamplona.quartz.ots.StreamDeserializationContext; -import com.vitorpamplona.quartz.ots.StreamSerializationContext; -import com.vitorpamplona.quartz.ots.Utils; -import com.vitorpamplona.quartz.ots.exceptions.VerificationException; +import com.vitorpamplona.quartz.nip03Timestamp.ots.BlockHeader; +import com.vitorpamplona.quartz.nip03Timestamp.ots.StreamDeserializationContext; +import com.vitorpamplona.quartz.nip03Timestamp.ots.StreamSerializationContext; +import com.vitorpamplona.quartz.nip03Timestamp.ots.Utils; +import com.vitorpamplona.quartz.nip03Timestamp.ots.exceptions.VerificationException; import java.util.Arrays; -import java.util.logging.Logger; /** * Litecoin Block Header Attestation. diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/attestation/PendingAttestation.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/attestation/PendingAttestation.java similarity index 91% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/attestation/PendingAttestation.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/attestation/PendingAttestation.java index 5e9a44390..93c0e26e6 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/attestation/PendingAttestation.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/attestation/PendingAttestation.java @@ -1,15 +1,14 @@ -package com.vitorpamplona.quartz.ots.attestation; +package com.vitorpamplona.quartz.nip03Timestamp.ots.attestation; import android.util.Log; -import com.vitorpamplona.quartz.ots.StreamDeserializationContext; -import com.vitorpamplona.quartz.ots.StreamSerializationContext; -import com.vitorpamplona.quartz.ots.Utils; +import com.vitorpamplona.quartz.nip03Timestamp.ots.StreamDeserializationContext; +import com.vitorpamplona.quartz.nip03Timestamp.ots.StreamSerializationContext; +import com.vitorpamplona.quartz.nip03Timestamp.ots.Utils; +import com.vitorpamplona.quartz.nip03Timestamp.ots.exceptions.DeserializationException; -import com.vitorpamplona.quartz.ots.exceptions.DeserializationException; import java.nio.charset.StandardCharsets; import java.util.Arrays; -import java.util.logging.Logger; /** * Pending attestations. diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/attestation/TimeAttestation.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/attestation/TimeAttestation.java similarity index 84% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/attestation/TimeAttestation.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/attestation/TimeAttestation.java index 39325530c..2f511f8b5 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/attestation/TimeAttestation.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/attestation/TimeAttestation.java @@ -1,15 +1,15 @@ -package com.vitorpamplona.quartz.ots.attestation; +package com.vitorpamplona.quartz.nip03Timestamp.ots.attestation; -import com.vitorpamplona.quartz.ots.StreamDeserializationContext; -import com.vitorpamplona.quartz.ots.StreamSerializationContext; -import com.vitorpamplona.quartz.ots.Utils; +import com.vitorpamplona.quartz.nip03Timestamp.ots.StreamDeserializationContext; +import com.vitorpamplona.quartz.nip03Timestamp.ots.StreamSerializationContext; +import com.vitorpamplona.quartz.nip03Timestamp.ots.Timestamp; +import com.vitorpamplona.quartz.nip03Timestamp.ots.Utils; +import com.vitorpamplona.quartz.nip03Timestamp.ots.exceptions.DeserializationException; -import com.vitorpamplona.quartz.ots.exceptions.DeserializationException; import java.util.Arrays; -import java.util.logging.Logger; /** - * Class representing {@link com.vitorpamplona.quartz.ots.Timestamp} signature verification + * Class representing {@link Timestamp} signature verification */ public abstract class TimeAttestation implements Comparable { diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/attestation/UnknownAttestation.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/attestation/UnknownAttestation.java similarity index 82% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/attestation/UnknownAttestation.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/attestation/UnknownAttestation.java index 6baf6879a..2f726a2d1 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/attestation/UnknownAttestation.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/attestation/UnknownAttestation.java @@ -1,12 +1,11 @@ -package com.vitorpamplona.quartz.ots.attestation; +package com.vitorpamplona.quartz.nip03Timestamp.ots.attestation; -import com.vitorpamplona.quartz.ots.StreamDeserializationContext; -import com.vitorpamplona.quartz.ots.StreamSerializationContext; -import com.vitorpamplona.quartz.ots.Utils; +import com.vitorpamplona.quartz.nip03Timestamp.ots.StreamDeserializationContext; +import com.vitorpamplona.quartz.nip03Timestamp.ots.StreamSerializationContext; +import com.vitorpamplona.quartz.nip03Timestamp.ots.Utils; +import com.vitorpamplona.quartz.nip03Timestamp.ots.exceptions.DeserializationException; -import com.vitorpamplona.quartz.ots.exceptions.DeserializationException; import java.util.Arrays; -import java.util.logging.Logger; /** * Placeholder for attestations that don't support diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/crypto/Digest.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/crypto/Digest.java similarity index 95% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/crypto/Digest.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/crypto/Digest.java index c0c3bd7f2..03f47a14a 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/crypto/Digest.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/crypto/Digest.java @@ -1,4 +1,4 @@ -package com.vitorpamplona.quartz.ots.crypto; +package com.vitorpamplona.quartz.nip03Timestamp.ots.crypto; /** * Message digest interface diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/crypto/ExtendedDigest.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/crypto/ExtendedDigest.java similarity index 82% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/crypto/ExtendedDigest.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/crypto/ExtendedDigest.java index df08f1191..ed3b81563 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/crypto/ExtendedDigest.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/crypto/ExtendedDigest.java @@ -1,4 +1,4 @@ -package com.vitorpamplona.quartz.ots.crypto; +package com.vitorpamplona.quartz.nip03Timestamp.ots.crypto; public interface ExtendedDigest extends Digest { /** diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/crypto/GeneralDigest.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/crypto/GeneralDigest.java similarity index 98% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/crypto/GeneralDigest.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/crypto/GeneralDigest.java index 021eb4675..284d03653 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/crypto/GeneralDigest.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/crypto/GeneralDigest.java @@ -1,4 +1,4 @@ -package com.vitorpamplona.quartz.ots.crypto; +package com.vitorpamplona.quartz.nip03Timestamp.ots.crypto; /** * Base implementation of MD4 family style digest as outlined in diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/crypto/KeccakDigest.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/crypto/KeccakDigest.java similarity index 99% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/crypto/KeccakDigest.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/crypto/KeccakDigest.java index 6053f72dc..cd669e1ef 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/crypto/KeccakDigest.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/crypto/KeccakDigest.java @@ -1,6 +1,6 @@ -package com.vitorpamplona.quartz.ots.crypto; +package com.vitorpamplona.quartz.nip03Timestamp.ots.crypto; -import com.vitorpamplona.quartz.ots.Utils; +import com.vitorpamplona.quartz.nip03Timestamp.ots.Utils; /** * Implementation of Keccak based on following KeccakNISTInterface.c from http://keccak.noekeon.org/ diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/crypto/Memoable.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/crypto/Memoable.java similarity index 94% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/crypto/Memoable.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/crypto/Memoable.java index 062b836a3..59b8154a8 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/crypto/Memoable.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/crypto/Memoable.java @@ -1,4 +1,4 @@ -package com.vitorpamplona.quartz.ots.crypto; +package com.vitorpamplona.quartz.nip03Timestamp.ots.crypto; /** * Interface for Memoable objects. Memoable objects allow the taking of a snapshot of their internal state diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/crypto/Pack.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/crypto/Pack.java similarity index 99% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/crypto/Pack.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/crypto/Pack.java index 17c839703..7fe7a0ce3 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/crypto/Pack.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/crypto/Pack.java @@ -1,4 +1,4 @@ -package com.vitorpamplona.quartz.ots.crypto; +package com.vitorpamplona.quartz.nip03Timestamp.ots.crypto; /** * Utility methods for converting byte arrays into ints and longs, and back again. diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/crypto/RIPEMD160Digest.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/crypto/RIPEMD160Digest.java similarity index 99% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/crypto/RIPEMD160Digest.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/crypto/RIPEMD160Digest.java index 51dfc8a69..d50e65ab6 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/crypto/RIPEMD160Digest.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/crypto/RIPEMD160Digest.java @@ -1,4 +1,4 @@ -package com.vitorpamplona.quartz.ots.crypto; +package com.vitorpamplona.quartz.nip03Timestamp.ots.crypto; /** * Implementation of RIPEMD diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/exceptions/CommitmentNotFoundException.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/exceptions/CommitmentNotFoundException.java similarity index 70% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/exceptions/CommitmentNotFoundException.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/exceptions/CommitmentNotFoundException.java index 14e3fd457..47af42bf2 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/exceptions/CommitmentNotFoundException.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/exceptions/CommitmentNotFoundException.java @@ -1,4 +1,4 @@ -package com.vitorpamplona.quartz.ots.exceptions; +package com.vitorpamplona.quartz.nip03Timestamp.ots.exceptions; public class CommitmentNotFoundException extends Exception { public CommitmentNotFoundException(String message) { diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/exceptions/DeserializationException.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/exceptions/DeserializationException.java similarity index 69% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/exceptions/DeserializationException.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/exceptions/DeserializationException.java index 76da9998b..2b5d46265 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/exceptions/DeserializationException.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/exceptions/DeserializationException.java @@ -1,4 +1,4 @@ -package com.vitorpamplona.quartz.ots.exceptions; +package com.vitorpamplona.quartz.nip03Timestamp.ots.exceptions; public class DeserializationException extends Exception { public DeserializationException(String message) { diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/exceptions/ExceededSizeException.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/exceptions/ExceededSizeException.java similarity index 67% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/exceptions/ExceededSizeException.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/exceptions/ExceededSizeException.java index 5a921de9d..7c2269a45 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/exceptions/ExceededSizeException.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/exceptions/ExceededSizeException.java @@ -1,4 +1,4 @@ -package com.vitorpamplona.quartz.ots.exceptions; +package com.vitorpamplona.quartz.nip03Timestamp.ots.exceptions; public class ExceededSizeException extends Exception { public ExceededSizeException(String message) { diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/exceptions/UrlException.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/exceptions/UrlException.java similarity index 65% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/exceptions/UrlException.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/exceptions/UrlException.java index a3d56c192..d5a195505 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/exceptions/UrlException.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/exceptions/UrlException.java @@ -1,4 +1,4 @@ -package com.vitorpamplona.quartz.ots.exceptions; +package com.vitorpamplona.quartz.nip03Timestamp.ots.exceptions; public class UrlException extends Exception { public UrlException(String message) { diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/exceptions/VerificationException.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/exceptions/VerificationException.java similarity index 68% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/exceptions/VerificationException.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/exceptions/VerificationException.java index 7d53dfedb..39e24656a 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/exceptions/VerificationException.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/exceptions/VerificationException.java @@ -1,4 +1,4 @@ -package com.vitorpamplona.quartz.ots.exceptions; +package com.vitorpamplona.quartz.nip03Timestamp.ots.exceptions; public class VerificationException extends Exception { public VerificationException(String message) { diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/http/Request.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/http/Request.java similarity index 96% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/http/Request.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/http/Request.java index 0df2db21d..c2dd66c76 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/http/Request.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/http/Request.java @@ -1,13 +1,11 @@ -package com.vitorpamplona.quartz.ots.http; +package com.vitorpamplona.quartz.nip03Timestamp.ots.http; import android.util.Log; import java.io.DataOutputStream; import java.io.InputStream; -import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.URL; -import java.net.URLEncoder; import java.util.Map; import java.util.concurrent.BlockingQueue; import java.util.concurrent.Callable; diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/http/Response.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/http/Response.java similarity index 96% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/http/Response.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/http/Response.java index adb378f38..d03a08c03 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/http/Response.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/http/Response.java @@ -1,4 +1,4 @@ -package com.vitorpamplona.quartz.ots.http; +package com.vitorpamplona.quartz.nip03Timestamp.ots.http; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.json.JsonMapper; diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/op/Op.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/op/Op.java similarity index 94% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/op/Op.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/op/Op.java index 9dc7700a3..eccb53ec6 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/op/Op.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/op/Op.java @@ -1,12 +1,10 @@ -package com.vitorpamplona.quartz.ots.op; +package com.vitorpamplona.quartz.nip03Timestamp.ots.op; import android.util.Log; -import com.vitorpamplona.quartz.ots.StreamDeserializationContext; -import com.vitorpamplona.quartz.ots.StreamSerializationContext; - -import com.vitorpamplona.quartz.ots.exceptions.DeserializationException; -import java.util.logging.Logger; +import com.vitorpamplona.quartz.nip03Timestamp.ots.StreamDeserializationContext; +import com.vitorpamplona.quartz.nip03Timestamp.ots.StreamSerializationContext; +import com.vitorpamplona.quartz.nip03Timestamp.ots.exceptions.DeserializationException; /** * Operations are the edges in the timestamp tree, with each operation taking a message and zero or more arguments to produce a result. diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/op/OpAppend.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/op/OpAppend.java similarity index 79% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/op/OpAppend.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/op/OpAppend.java index 0b81fe726..e1631278a 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/op/OpAppend.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/op/OpAppend.java @@ -1,11 +1,10 @@ -package com.vitorpamplona.quartz.ots.op; +package com.vitorpamplona.quartz.nip03Timestamp.ots.op; -import com.vitorpamplona.quartz.ots.StreamDeserializationContext; -import com.vitorpamplona.quartz.ots.Utils; +import com.vitorpamplona.quartz.nip03Timestamp.ots.StreamDeserializationContext; +import com.vitorpamplona.quartz.nip03Timestamp.ots.Utils; +import com.vitorpamplona.quartz.nip03Timestamp.ots.exceptions.DeserializationException; -import com.vitorpamplona.quartz.ots.exceptions.DeserializationException; import java.util.Arrays; -import java.util.logging.Logger; /** * Append a suffix to a message. diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/op/OpBinary.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/op/OpBinary.java similarity index 80% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/op/OpBinary.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/op/OpBinary.java index 217337e50..435fff1cc 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/op/OpBinary.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/op/OpBinary.java @@ -1,13 +1,13 @@ -package com.vitorpamplona.quartz.ots.op; +package com.vitorpamplona.quartz.nip03Timestamp.ots.op; import android.util.Log; -import com.vitorpamplona.quartz.encoders.Hex; -import com.vitorpamplona.quartz.ots.StreamDeserializationContext; -import com.vitorpamplona.quartz.ots.StreamSerializationContext; -import com.vitorpamplona.quartz.ots.Utils; +import com.vitorpamplona.quartz.crypto.Hex; +import com.vitorpamplona.quartz.nip03Timestamp.ots.StreamDeserializationContext; +import com.vitorpamplona.quartz.nip03Timestamp.ots.StreamSerializationContext; +import com.vitorpamplona.quartz.nip03Timestamp.ots.Utils; +import com.vitorpamplona.quartz.nip03Timestamp.ots.exceptions.DeserializationException; -import com.vitorpamplona.quartz.ots.exceptions.DeserializationException; import java.util.Arrays; /** diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/op/OpCrypto.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/op/OpCrypto.java similarity index 95% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/op/OpCrypto.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/op/OpCrypto.java index 28e6b1aaa..4ba85d345 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/op/OpCrypto.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/op/OpCrypto.java @@ -1,8 +1,8 @@ -package com.vitorpamplona.quartz.ots.op; +package com.vitorpamplona.quartz.nip03Timestamp.ots.op; import android.util.Log; -import com.vitorpamplona.quartz.ots.StreamDeserializationContext; +import com.vitorpamplona.quartz.nip03Timestamp.ots.StreamDeserializationContext; import java.io.File; import java.io.FileInputStream; diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/op/OpKECCAK256.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/op/OpKECCAK256.java similarity index 83% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/op/OpKECCAK256.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/op/OpKECCAK256.java index c77582759..47e2185d4 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/op/OpKECCAK256.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/op/OpKECCAK256.java @@ -1,10 +1,7 @@ -package com.vitorpamplona.quartz.ots.op; +package com.vitorpamplona.quartz.nip03Timestamp.ots.op; -import com.vitorpamplona.quartz.ots.StreamDeserializationContext; -import com.vitorpamplona.quartz.ots.Utils; -import com.vitorpamplona.quartz.ots.crypto.KeccakDigest; - -import java.util.logging.Logger; +import com.vitorpamplona.quartz.nip03Timestamp.ots.StreamDeserializationContext; +import com.vitorpamplona.quartz.nip03Timestamp.ots.crypto.KeccakDigest; /** * Cryptographic Keccak256 operation. diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/op/OpPrepend.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/op/OpPrepend.java similarity index 79% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/op/OpPrepend.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/op/OpPrepend.java index 89c3d89e5..510749f89 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/op/OpPrepend.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/op/OpPrepend.java @@ -1,11 +1,10 @@ -package com.vitorpamplona.quartz.ots.op; +package com.vitorpamplona.quartz.nip03Timestamp.ots.op; -import com.vitorpamplona.quartz.ots.StreamDeserializationContext; -import com.vitorpamplona.quartz.ots.Utils; +import com.vitorpamplona.quartz.nip03Timestamp.ots.StreamDeserializationContext; +import com.vitorpamplona.quartz.nip03Timestamp.ots.Utils; +import com.vitorpamplona.quartz.nip03Timestamp.ots.exceptions.DeserializationException; -import com.vitorpamplona.quartz.ots.exceptions.DeserializationException; import java.util.Arrays; -import java.util.logging.Logger; /** * Prepend a prefix to a message. diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/op/OpRIPEMD160.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/op/OpRIPEMD160.java similarity index 83% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/op/OpRIPEMD160.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/op/OpRIPEMD160.java index cf89834fd..4ef69398c 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/op/OpRIPEMD160.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/op/OpRIPEMD160.java @@ -1,10 +1,7 @@ -package com.vitorpamplona.quartz.ots.op; +package com.vitorpamplona.quartz.nip03Timestamp.ots.op; -import com.vitorpamplona.quartz.ots.StreamDeserializationContext; -import com.vitorpamplona.quartz.ots.Utils; -import com.vitorpamplona.quartz.ots.crypto.RIPEMD160Digest; - -import java.util.logging.Logger; +import com.vitorpamplona.quartz.nip03Timestamp.ots.StreamDeserializationContext; +import com.vitorpamplona.quartz.nip03Timestamp.ots.crypto.RIPEMD160Digest; /** * Cryptographic RIPEMD160 operation. diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/op/OpSHA1.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/op/OpSHA1.java similarity index 88% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/op/OpSHA1.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/op/OpSHA1.java index 0a8080090..055705677 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/op/OpSHA1.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/op/OpSHA1.java @@ -1,9 +1,6 @@ -package com.vitorpamplona.quartz.ots.op; +package com.vitorpamplona.quartz.nip03Timestamp.ots.op; -import com.vitorpamplona.quartz.ots.StreamDeserializationContext; -import com.vitorpamplona.quartz.ots.Utils; - -import java.util.logging.Logger; +import com.vitorpamplona.quartz.nip03Timestamp.ots.StreamDeserializationContext; /** * Cryptographic SHA1 operation. diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/op/OpSHA256.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/op/OpSHA256.java similarity index 85% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/op/OpSHA256.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/op/OpSHA256.java index 892713a46..c5772c2e3 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/op/OpSHA256.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/op/OpSHA256.java @@ -1,9 +1,6 @@ -package com.vitorpamplona.quartz.ots.op; +package com.vitorpamplona.quartz.nip03Timestamp.ots.op; -import com.vitorpamplona.quartz.ots.StreamDeserializationContext; -import com.vitorpamplona.quartz.ots.Utils; - -import java.util.logging.Logger; +import com.vitorpamplona.quartz.nip03Timestamp.ots.StreamDeserializationContext; /** * Cryptographic SHA256 operation. diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/op/OpUnary.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/op/OpUnary.java similarity index 83% rename from quartz/src/main/java/com/vitorpamplona/quartz/ots/op/OpUnary.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/op/OpUnary.java index d1b5894e1..458a75b31 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/op/OpUnary.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip03Timestamp/ots/op/OpUnary.java @@ -1,11 +1,8 @@ -package com.vitorpamplona.quartz.ots.op; +package com.vitorpamplona.quartz.nip03Timestamp.ots.op; import android.util.Log; -import com.vitorpamplona.quartz.ots.StreamDeserializationContext; -import com.vitorpamplona.quartz.ots.Utils; - -import java.util.logging.Logger; +import com.vitorpamplona.quartz.nip03Timestamp.ots.StreamDeserializationContext; /** * Operations that act on a single message. diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip04/Nip04.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip04Dm/Nip04.kt similarity index 97% rename from quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip04/Nip04.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip04Dm/Nip04.kt index 6c6b8e8d3..5dd80229a 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip04/Nip04.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip04Dm/Nip04.kt @@ -18,11 +18,11 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.crypto.nip04 +package com.vitorpamplona.quartz.nip04Dm import android.util.Log -import com.vitorpamplona.quartz.crypto.SharedKeyCache -import com.vitorpamplona.quartz.encoders.Hex +import com.vitorpamplona.quartz.crypto.Hex +import com.vitorpamplona.quartz.nip44Encryption.SharedKeyCache import fr.acinq.secp256k1.Secp256k1 import java.security.SecureRandom import java.util.Base64 diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/PrivateDmEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip04Dm/PrivateDmEvent.kt similarity index 90% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/PrivateDmEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip04Dm/PrivateDmEvent.kt index cdaf38d46..12e3d1878 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/PrivateDmEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip04Dm/PrivateDmEvent.kt @@ -18,15 +18,19 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip04Dm import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.Hex -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.HexValidator -import com.vitorpamplona.quartz.encoders.IMetaTag -import com.vitorpamplona.quartz.encoders.Nip54InlineMetadata -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.crypto.Hex +import com.vitorpamplona.quartz.experimental.inlineMetadata.Nip54InlineMetadata +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.geohash.geohashMipMap +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip17Dm.ChatroomKey +import com.vitorpamplona.quartz.nip17Dm.ChatroomKeyable +import com.vitorpamplona.quartz.nip57Zaps.ZapSplitSetup +import com.vitorpamplona.quartz.nip92IMeta.IMetaTag import com.vitorpamplona.quartz.utils.TimeUtils import com.vitorpamplona.quartz.utils.bytesUsedInMemory import com.vitorpamplona.quartz.utils.pointerSizeInBytes @@ -61,7 +65,7 @@ class PrivateDmEvent( fun verifiedRecipientPubKey(): HexKey? { val recipient = recipientPubKey() - return if (HexValidator.isHex(recipient)) { + return if (Hex.isHex(recipient)) { recipient } else { null @@ -171,11 +175,3 @@ class PrivateDmEvent( } } } - -fun geohashMipMap(geohash: String): Array> = - geohash.indices - .asSequence() - .map { arrayOf("g", geohash.substring(0, it + 1)) } - .toList() - .reversed() - .toTypedArray() diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip06/Bip32SeedDerivation.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip06KeyDerivation/Bip32SeedDerivation.kt similarity index 98% rename from quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip06/Bip32SeedDerivation.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip06KeyDerivation/Bip32SeedDerivation.kt index 8c7bbeed5..88fc1dcdc 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip06/Bip32SeedDerivation.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip06KeyDerivation/Bip32SeedDerivation.kt @@ -18,7 +18,7 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.crypto.nip06 +package com.vitorpamplona.quartz.nip06KeyDerivation import fr.acinq.secp256k1.Secp256k1 import javax.crypto.Mac diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip06/Bip39KeyPath.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip06KeyDerivation/Bip39KeyPath.kt similarity index 88% rename from quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip06/Bip39KeyPath.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip06KeyDerivation/Bip39KeyPath.kt index e6b84ed8b..35bb41ded 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip06/Bip39KeyPath.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip06KeyDerivation/Bip39KeyPath.kt @@ -18,7 +18,7 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.crypto.nip06 +package com.vitorpamplona.quartz.nip06KeyDerivation class KeyPath( val path: List, @@ -43,7 +43,14 @@ class KeyPath( val empty: KeyPath = KeyPath(listOf()) fun computePath(path: String): List { - fun toNumber(value: String): Long = if (value.last() == '\'' || value.last() == 'h') Hardener.hardened(value.dropLast(1).toLong()) else value.toLong() + fun toNumber(value: String): Long = + if (value.last() == '\'' || value.last() == 'h') { + Hardener.hardened( + value.dropLast(1).toLong(), + ) + } else { + value.toLong() + } val path1 = path.removePrefix("m").removePrefix("/") return if (path1.isEmpty()) { diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip06/Bip39Mnemonics.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip06KeyDerivation/Bip39Mnemonics.kt similarity index 99% rename from quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip06/Bip39Mnemonics.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip06KeyDerivation/Bip39Mnemonics.kt index a040f1287..006f68b42 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip06/Bip39Mnemonics.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip06KeyDerivation/Bip39Mnemonics.kt @@ -18,10 +18,10 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.crypto.nip06 +package com.vitorpamplona.quartz.nip06KeyDerivation -import com.vitorpamplona.quartz.crypto.nip49.PBKDF import com.vitorpamplona.quartz.crypto.sha256Hash +import com.vitorpamplona.quartz.nip49PrivKeyEnc.PBKDF // CODE FROM: https://github.com/ACINQ/bitcoin-kmp/ diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip06/Nip06.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip06KeyDerivation/Nip06.kt similarity index 97% rename from quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip06/Nip06.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip06KeyDerivation/Nip06.kt index 8bb79e827..f1b405901 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip06/Nip06.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip06KeyDerivation/Nip06.kt @@ -18,7 +18,7 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.crypto.nip06 +package com.vitorpamplona.quartz.nip06KeyDerivation import fr.acinq.secp256k1.Secp256k1 diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/DeletionEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip09Deletions/DeletionEvent.kt similarity index 88% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/DeletionEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip09Deletions/DeletionEvent.kt index fb23c4281..4fe954c8e 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/DeletionEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip09Deletions/DeletionEvent.kt @@ -18,11 +18,15 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip09Deletions import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.AddressableEvent +import com.vitorpamplona.quartz.nip01Core.addressables.taggedAddresses +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.events.taggedEvents +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.utils.TimeUtils @Immutable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/BaseTextNoteEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip10Notes/BaseTextNoteEvent.kt similarity index 83% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/BaseTextNoteEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip10Notes/BaseTextNoteEvent.kt index a0ed55bb3..061ad2f26 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/BaseTextNoteEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip10Notes/BaseTextNoteEvent.kt @@ -18,14 +18,27 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip10Notes import android.util.Log import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.Nip19Bech32 -import com.vitorpamplona.quartz.encoders.Nip19Bech32.nip19regex +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.addressables.taggedAddresses +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.people.taggedUsers +import com.vitorpamplona.quartz.nip19Bech32Entities.Nip19Parser +import com.vitorpamplona.quartz.nip19Bech32Entities.Nip19Parser.nip19regex +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NAddress +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NEmbed +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NEvent +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NProfile +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NPub +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.Note +import com.vitorpamplona.quartz.nip19Bech32Entities.parse +import com.vitorpamplona.quartz.nip19Bech32Entities.parseAtag +import com.vitorpamplona.quartz.nip54Wiki.WikiNoteEvent +import com.vitorpamplona.quartz.nip72ModCommunities.CommunityDefinitionEvent import java.util.regex.Pattern val tagSearch = Pattern.compile("(?:\\s|\\A)\\#\\[([0-9]+)\\]") @@ -118,13 +131,13 @@ open class BaseTextNoteEvent( try { if (type != null) { - val parsed = Nip19Bech32.parseComponents(type, key, additionalChars)?.entity + val parsed = Nip19Parser.parseComponents(type, key, additionalChars)?.entity if (parsed != null) { - if (parsed is Nip19Bech32.NProfile) { + if (parsed is NProfile) { returningList.add(parsed.hex) } - if (parsed is Nip19Bech32.NPub) { + if (parsed is NPub) { returningList.add(parsed.hex) } } @@ -166,14 +179,14 @@ open class BaseTextNoteEvent( val additionalChars = matcher2.group(4) // additional chars if (type != null) { - val parsed = Nip19Bech32.parseComponents(type, key, additionalChars)?.entity + val parsed = Nip19Parser.parseComponents(type, key, additionalChars)?.entity if (parsed != null) { when (parsed) { - is Nip19Bech32.NEvent -> citations.add(parsed.hex) - is Nip19Bech32.NAddress -> citations.add(parsed.atag) - is Nip19Bech32.Note -> citations.add(parsed.hex) - is Nip19Bech32.NEmbed -> citations.add(parsed.event.id) + is NEvent -> citations.add(parsed.hex) + is NAddress -> citations.add(parsed.aTag()) + is Note -> citations.add(parsed.hex) + is NEmbed -> citations.add(parsed.event.id) } } } diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/ETag.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip10Notes/ETag.kt similarity index 80% rename from quartz/src/main/java/com/vitorpamplona/quartz/encoders/ETag.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip10Notes/ETag.kt index 00f84e2c5..2510f7ee3 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/ETag.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip10Notes/ETag.kt @@ -18,10 +18,14 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.encoders +package com.vitorpamplona.quartz.nip10Notes import android.util.Log import androidx.compose.runtime.Immutable +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip19Bech32Entities.Nip19Parser +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NEvent +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.Note import com.vitorpamplona.quartz.utils.bytesUsedInMemory import com.vitorpamplona.quartz.utils.pointerSizeInBytes import com.vitorpamplona.quartz.utils.removeTrailingNullsAndEmptyOthers @@ -43,7 +47,7 @@ data class ETag( eventId.bytesUsedInMemory() + (relay?.bytesUsedInMemory() ?: 0) - fun toNEvent(): String = Nip19Bech32.createNEvent(eventId, authorPubKeyHex, null, relay) + fun toNEvent(): String = NEvent.create(eventId, authorPubKeyHex, null, relay) fun toETagArray() = removeTrailingNullsAndEmptyOthers("e", eventId, relay, authorPubKeyHex) @@ -52,11 +56,11 @@ data class ETag( companion object { fun parseNIP19(nevent: String): ETag? { try { - val parsed = Nip19Bech32.uriToRoute(nevent)?.entity + val parsed = Nip19Parser.uriToRoute(nevent)?.entity return when (parsed) { - is Nip19Bech32.Note -> ETag(parsed.hex) - is Nip19Bech32.NEvent -> ETag(parsed.hex, parsed.author, parsed.relay.firstOrNull()) + is Note -> ETag(parsed.hex) + is NEvent -> ETag(parsed.hex, parsed.author, parsed.relay.firstOrNull()) else -> null } } catch (e: Throwable) { diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/PTag.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip10Notes/PTag.kt similarity index 69% rename from quartz/src/main/java/com/vitorpamplona/quartz/encoders/PTag.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip10Notes/PTag.kt index c1304b5c9..b951c96e6 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/PTag.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip10Notes/PTag.kt @@ -18,10 +18,13 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.encoders +package com.vitorpamplona.quartz.nip10Notes -import android.util.Log import androidx.compose.runtime.Immutable +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.hexToByteArray +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NProfile +import com.vitorpamplona.quartz.nip19Bech32Entities.toNpub import com.vitorpamplona.quartz.utils.bytesUsedInMemory import com.vitorpamplona.quartz.utils.pointerSizeInBytes import com.vitorpamplona.quartz.utils.removeTrailingNullsAndEmptyOthers @@ -41,26 +44,9 @@ data class PTag( pubKeyHex.bytesUsedInMemory() + (relay?.bytesUsedInMemory() ?: 0) - fun toNProfile(): String = Nip19Bech32.createNProfile(pubKeyHex, relay?.let { listOf(it) } ?: emptyList()) + fun toNProfile(): String = NProfile.create(pubKeyHex, relay?.let { listOf(it) } ?: emptyList()) - fun toNPub(): String = Nip19Bech32.createNPub(pubKeyHex) + fun toNPub(): String = pubKeyHex.hexToByteArray().toNpub() fun toPTagArray() = removeTrailingNullsAndEmptyOthers("p", pubKeyHex, relay) - - companion object { - fun parseNAddr(nprofile: String): PTag? { - try { - val parsed = Nip19Bech32.uriToRoute(nprofile)?.entity - - return when (parsed) { - is Nip19Bech32.NPub -> PTag(parsed.hex) - is Nip19Bech32.NProfile -> PTag(parsed.hex, parsed.relay.firstOrNull()) - else -> null - } - } catch (e: Throwable) { - Log.w("PTag", "Issue trying to Decode NIP19 $this: ${e.message}") - return null - } - } - } } diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/TextNoteEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip10Notes/TextNoteEvent.kt similarity index 91% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/TextNoteEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip10Notes/TextNoteEvent.kt index 0ed34f369..e088c8973 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/TextNoteEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip10Notes/TextNoteEvent.kt @@ -18,16 +18,21 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip10Notes import androidx.compose.runtime.Immutable import com.linkedin.urls.detection.UrlDetector import com.linkedin.urls.detection.UrlDetectorOptions -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.IMetaTag -import com.vitorpamplona.quartz.encoders.Nip92MediaAttachments -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.addressables.AddressableEvent +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.geohash.geohashMipMap +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiUrl +import com.vitorpamplona.quartz.nip57Zaps.ZapSplitSetup +import com.vitorpamplona.quartz.nip92IMeta.IMetaTag +import com.vitorpamplona.quartz.nip92IMeta.Nip92MediaAttachments import com.vitorpamplona.quartz.utils.TimeUtils @Immutable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/Nip11RelayInformation.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip11RelayInfo/Nip11RelayInformation.kt similarity index 98% rename from quartz/src/main/java/com/vitorpamplona/quartz/encoders/Nip11RelayInformation.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip11RelayInfo/Nip11RelayInformation.kt index c2258dad6..95ed42153 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/Nip11RelayInformation.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip11RelayInfo/Nip11RelayInformation.kt @@ -18,7 +18,7 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.encoders +package com.vitorpamplona.quartz.nip11RelayInfo import androidx.compose.runtime.Stable import com.fasterxml.jackson.databind.DeserializationFeature diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip13Pow/EventExt.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip13Pow/EventExt.kt new file mode 100644 index 000000000..562e2a328 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip13Pow/EventExt.kt @@ -0,0 +1,28 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip13Pow + +import com.vitorpamplona.quartz.nip01Core.core.Event + +fun Event.getPoWRank(): Int { + val commitedPoW = tags.firstOrNull { it.size > 2 && it[0] == "nonce" }?.get(2)?.toIntOrNull() + return PoWRank.getCommited(id, commitedPoW) +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/PoWRank.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip13Pow/PoWRank.kt similarity index 98% rename from quartz/src/main/java/com/vitorpamplona/quartz/encoders/PoWRank.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip13Pow/PoWRank.kt index fd4a3a9a2..1eac8885b 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/PoWRank.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip13Pow/PoWRank.kt @@ -18,7 +18,7 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.encoders +package com.vitorpamplona.quartz.nip13Pow class PoWRank { companion object { diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip14Subject/EventExt.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip14Subject/EventExt.kt new file mode 100644 index 000000000..3901c34b4 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip14Subject/EventExt.kt @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip14Subject + +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.core.firstTagValue + +fun Event.subject() = tags.firstTagValue("subject") diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip17/AESGCM.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip17Dm/AESGCM.kt similarity index 89% rename from quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip17/AESGCM.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip17Dm/AESGCM.kt index bea2684d0..04000c7ae 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip17/AESGCM.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip17Dm/AESGCM.kt @@ -18,22 +18,14 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.crypto.nip17 +package com.vitorpamplona.quartz.nip17Dm import com.vitorpamplona.quartz.crypto.CryptoUtils -import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.nip01Core.toHexKey import javax.crypto.Cipher import javax.crypto.spec.GCMParameterSpec import javax.crypto.spec.SecretKeySpec -interface NostrCipher { - fun name(): String - - fun encrypt(bytesToEncrypt: ByteArray): ByteArray - - fun decrypt(bytesToDecrypt: ByteArray): ByteArray -} - class AESGCM( val keyBytes: ByteArray = CryptoUtils.random(32), val nonce: ByteArray = CryptoUtils.random(16), diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/ChatMessageEncryptedFileHeaderEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip17Dm/ChatMessageEncryptedFileHeaderEvent.kt similarity index 94% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/ChatMessageEncryptedFileHeaderEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip17Dm/ChatMessageEncryptedFileHeaderEvent.kt index fd5dcabb7..78fd264b0 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/ChatMessageEncryptedFileHeaderEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip17Dm/ChatMessageEncryptedFileHeaderEvent.kt @@ -18,14 +18,15 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip17Dm import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.Dimension -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.hexToByteArray -import com.vitorpamplona.quartz.encoders.toHexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.hexToByteArray +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.toHexKey +import com.vitorpamplona.quartz.nip59Giftwrap.WrappedEvent +import com.vitorpamplona.quartz.nip94FileMetadata.Dimension import com.vitorpamplona.quartz.utils.TimeUtils import kotlinx.collections.immutable.toImmutableSet diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/ChatMessageEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip17Dm/ChatMessageEvent.kt similarity index 89% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/ChatMessageEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip17Dm/ChatMessageEvent.kt index 1af3a6b6e..6c84fd466 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/ChatMessageEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip17Dm/ChatMessageEvent.kt @@ -18,14 +18,17 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip17Dm import androidx.compose.runtime.Immutable -import androidx.compose.runtime.Stable -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.IMetaTag -import com.vitorpamplona.quartz.encoders.Nip92MediaAttachments -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.geohash.geohashMipMap +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiUrl +import com.vitorpamplona.quartz.nip57Zaps.ZapSplitSetup +import com.vitorpamplona.quartz.nip59Giftwrap.WrappedEvent +import com.vitorpamplona.quartz.nip92IMeta.IMetaTag +import com.vitorpamplona.quartz.nip92IMeta.Nip92MediaAttachments import com.vitorpamplona.quartz.utils.TimeUtils import kotlinx.collections.immutable.toImmutableSet @@ -115,16 +118,3 @@ class ChatMessageEvent( } } } - -interface NIP17Group { - fun groupMembers(): Set -} - -interface ChatroomKeyable { - fun chatroomKey(toRemove: HexKey): ChatroomKey -} - -@Stable -data class ChatroomKey( - val users: Set, -) diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/ChatMessageRelayListEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip17Dm/ChatMessageRelayListEvent.kt similarity index 91% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/ChatMessageRelayListEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip17Dm/ChatMessageRelayListEvent.kt index 26965bd4f..677780d46 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/ChatMessageRelayListEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip17Dm/ChatMessageRelayListEvent.kt @@ -18,13 +18,14 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip17Dm import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner -import com.vitorpamplona.quartz.signers.NostrSignerSync +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.addressables.BaseAddressableEvent +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerSync import com.vitorpamplona.quartz.utils.TimeUtils @Immutable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip17Dm/ChatroomKey.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip17Dm/ChatroomKey.kt new file mode 100644 index 000000000..fbd6d98d8 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip17Dm/ChatroomKey.kt @@ -0,0 +1,29 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip17Dm + +import androidx.compose.runtime.Stable +import com.vitorpamplona.quartz.nip01Core.HexKey + +@Stable +data class ChatroomKey( + val users: Set, +) diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip17Dm/ChatroomKeyable.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip17Dm/ChatroomKeyable.kt new file mode 100644 index 000000000..1d5ddf635 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip17Dm/ChatroomKeyable.kt @@ -0,0 +1,27 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip17Dm + +import com.vitorpamplona.quartz.nip01Core.HexKey + +interface ChatroomKeyable { + fun chatroomKey(toRemove: HexKey): ChatroomKey +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/NIP17Factory.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip17Dm/NIP17Factory.kt similarity index 91% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/NIP17Factory.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip17Dm/NIP17Factory.kt index 7f2715d29..2b08a0e2b 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/NIP17Factory.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip17Dm/NIP17Factory.kt @@ -18,12 +18,18 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip17Dm -import com.vitorpamplona.quartz.encoders.Dimension -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.IMetaTag -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip25Reactions.ReactionEvent +import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiUrl +import com.vitorpamplona.quartz.nip57Zaps.ZapSplitSetup +import com.vitorpamplona.quartz.nip59Giftwrap.GiftWrapEvent +import com.vitorpamplona.quartz.nip59Giftwrap.SealedGossipEvent +import com.vitorpamplona.quartz.nip92IMeta.IMetaTag +import com.vitorpamplona.quartz.nip94FileMetadata.Dimension class NIP17Factory { data class Result( @@ -184,7 +190,7 @@ class NIP17Factory { fun createReactionWithinGroup( content: String, - originalNote: EventInterface, + originalNote: Event, to: List, signer: NostrSigner, onReady: (Result) -> Unit, @@ -209,7 +215,7 @@ class NIP17Factory { fun createReactionWithinGroup( emojiUrl: EmojiUrl, - originalNote: EventInterface, + originalNote: Event, to: List, signer: NostrSigner, onReady: (Result) -> Unit, diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip17Dm/NIP17Group.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip17Dm/NIP17Group.kt new file mode 100644 index 000000000..e49b925ee --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip17Dm/NIP17Group.kt @@ -0,0 +1,27 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip17Dm + +import com.vitorpamplona.quartz.nip01Core.HexKey + +interface NIP17Group { + fun groupMembers(): Set +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip17Dm/NostrCipher.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip17Dm/NostrCipher.kt new file mode 100644 index 000000000..6a90da014 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip17Dm/NostrCipher.kt @@ -0,0 +1,29 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip17Dm + +interface NostrCipher { + fun name(): String + + fun encrypt(bytesToEncrypt: ByteArray): ByteArray + + fun decrypt(bytesToDecrypt: ByteArray): ByteArray +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/GenericRepostEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip18Reposts/GenericRepostEvent.kt similarity index 83% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/GenericRepostEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip18Reposts/GenericRepostEvent.kt index 0609f4739..8f644f1a1 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/GenericRepostEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip18Reposts/GenericRepostEvent.kt @@ -18,11 +18,13 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip18Reposts import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.AddressableEvent +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -50,7 +52,7 @@ class GenericRepostEvent( const val ALT = "Generic repost" fun create( - boostedPost: EventInterface, + boostedPost: Event, signer: NostrSigner, createdAt: Long = TimeUtils.now(), onReady: (GenericRepostEvent) -> Unit, @@ -59,15 +61,15 @@ class GenericRepostEvent( val tags = mutableListOf( - arrayOf("e", boostedPost.id()), - arrayOf("p", boostedPost.pubKey()), + arrayOf("e", boostedPost.id), + arrayOf("p", boostedPost.pubKey), ) if (boostedPost is AddressableEvent) { tags.add(arrayOf("a", boostedPost.address().toTag())) } - tags.add(arrayOf("k", "${boostedPost.kind()}")) + tags.add(arrayOf("k", "${boostedPost.kind}")) tags.add(arrayOf("alt", ALT)) signer.sign(createdAt, KIND, tags.toTypedArray(), content, onReady) diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/RepostEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip18Reposts/RepostEvent.kt similarity index 80% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/RepostEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip18Reposts/RepostEvent.kt index 056182829..d6de50e7c 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/RepostEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip18Reposts/RepostEvent.kt @@ -18,11 +18,15 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip18Reposts import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.AddressableEvent +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.events.taggedEvents +import com.vitorpamplona.quartz.nip01Core.people.taggedUsers +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -50,15 +54,15 @@ class RepostEvent( const val ALT = "Repost event" fun create( - boostedPost: EventInterface, + boostedPost: Event, signer: NostrSigner, createdAt: Long = TimeUtils.now(), onReady: (RepostEvent) -> Unit, ) { val content = boostedPost.toJson() - val replyToPost = arrayOf("e", boostedPost.id()) - val replyToAuthor = arrayOf("p", boostedPost.pubKey()) + val replyToPost = arrayOf("e", boostedPost.id) + val replyToAuthor = arrayOf("p", boostedPost.pubKey) var tags: Array> = arrayOf(replyToPost, replyToAuthor) diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/ATagExt.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/ATagExt.kt new file mode 100644 index 000000000..451a93bad --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/ATagExt.kt @@ -0,0 +1,66 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip19Bech32Entities + +import android.util.Log +import com.vitorpamplona.quartz.crypto.Hex +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NAddress + +fun ATag.Companion.isATag(key: String): Boolean = key.startsWith("naddr1") || key.contains(":") + +fun ATag.Companion.parse( + address: String, + relay: String?, +): ATag? = + if (address.startsWith("naddr") || address.startsWith("nostr:naddr")) { + parseNAddr(address) + } else { + parseAtag(address, relay) + } + +fun ATag.Companion.parseAtag( + atag: String, + relay: String?, +): ATag? = + try { + val parts = atag.split(":", limit = 3) + Hex.decode(parts[1]) + ATag(parts[0].toInt(), parts[1], parts[2], relay) + } catch (t: Throwable) { + Log.w("ATag", "Error parsing A Tag: $atag: ${t.message}") + null + } + +fun ATag.Companion.parseAtagUnckecked(atag: String): ATag? = + try { + val parts = atag.split(":") + ATag(parts[0].toInt(), parts[1], parts[2], null) + } catch (t: Throwable) { + null + } + +fun ATag.toNAddr(overrideRelay: String? = relay): String = NAddress.create(kind, pubKeyHex, dTag, overrideRelay ?: relay) + +fun ATag.Companion.parseNAddr(naddr: String) = + NAddress.parse(naddr)?.let { result -> + ATag(result.kind, result.author, result.dTag, result.relay.firstOrNull()) + } diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/ByteArrayExt.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/ByteArrayExt.kt new file mode 100644 index 000000000..525e2d81f --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/ByteArrayExt.kt @@ -0,0 +1,40 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip19Bech32Entities + +import com.vitorpamplona.quartz.nip19Bech32Entities.bech32.Bech32 + +fun ByteArray.toNsec() = Bech32.encodeBytes(hrp = "nsec", this, Bech32.Encoding.Bech32) + +fun ByteArray.toNpub() = Bech32.encodeBytes(hrp = "npub", this, Bech32.Encoding.Bech32) + +@Deprecated("Prefer nevent1 instead") +fun ByteArray.toNote() = Bech32.encodeBytes(hrp = "note", this, Bech32.Encoding.Bech32) + +fun ByteArray.toNEvent() = Bech32.encodeBytes(hrp = "nevent", this, Bech32.Encoding.Bech32) + +fun ByteArray.toNProfile() = Bech32.encodeBytes(hrp = "nprofile", this, Bech32.Encoding.Bech32) + +fun ByteArray.toNAddress() = Bech32.encodeBytes(hrp = "naddr", this, Bech32.Encoding.Bech32) + +fun ByteArray.toLnUrl() = Bech32.encodeBytes(hrp = "lnurl", this, Bech32.Encoding.Bech32) + +fun ByteArray.toNEmbed() = Bech32.encodeBytes(hrp = "nembed", this, Bech32.Encoding.Bech32) diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/EventExt.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/EventExt.kt new file mode 100644 index 000000000..d45baed00 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/EventExt.kt @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip19Bech32Entities + +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.addressables.AddressableEvent +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NEvent + +fun Event.toNIP19(): String = + if (this is AddressableEvent) { + ATag(kind, pubKey, dTag(), null).toNAddr() + } else { + NEvent.create(id, pubKey, kind, null) + } diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/Nip19Parser.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/Nip19Parser.kt new file mode 100644 index 000000000..c6dd4935c --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/Nip19Parser.kt @@ -0,0 +1,194 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip19Bech32Entities + +import android.util.Log +import androidx.compose.runtime.Immutable +import com.vitorpamplona.quartz.crypto.Hex +import com.vitorpamplona.quartz.crypto.KeyPair +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.hexToByteArray +import com.vitorpamplona.quartz.nip01Core.toHexKey +import com.vitorpamplona.quartz.nip19Bech32Entities.bech32.bechToBytes +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.Entity +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NAddress +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NEmbed +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NEvent +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NProfile +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NPub +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NRelay +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NSec +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.Note +import kotlinx.coroutines.CancellationException +import java.util.regex.Pattern + +object Nip19Parser { + val nip19PlusNip46regex = + Pattern.compile( + "(nostr:)?@?(nsec1|npub1|nevent1|naddr1|note1|nprofile1|nrelay1|nembed1|ncryptsec1)([qpzry9x8gf2tvdw0s3jn54khce6mua7l]+)([\\S]*)", + Pattern.CASE_INSENSITIVE, + ) + + val nip19regex = + Pattern.compile( + "(nostr:)?@?(nsec1|npub1|nevent1|naddr1|note1|nprofile1|nrelay1|nembed1)([qpzry9x8gf2tvdw0s3jn54khce6mua7l]+)([\\S]*)", + Pattern.CASE_INSENSITIVE, + ) + + @Immutable + data class ParseReturn( + val entity: Entity, + val nip19raw: String, + val additionalChars: String? = null, + ) + + fun tryParseAndClean(uri: String?): String? { + if (uri == null) return null + + try { + val matcher = nip19PlusNip46regex.matcher(uri) + if (!matcher.find()) { + return null + } + + val type = matcher.group(2) // npub1 + val key = matcher.group(3) // bech32 + + return type + key + } catch (e: Throwable) { + Log.e("NIP19 Parser", "Issue trying to Decode NIP19 $uri: ${e.message}", e) + } + + return null + } + + fun uriToRoute(uri: String?): ParseReturn? { + if (uri == null) return null + + try { + val matcher = nip19regex.matcher(uri) + if (!matcher.find()) { + return null + } + + val type = matcher.group(2) // npub1 + val key = matcher.group(3) // bech32 + val additionalChars = matcher.group(4) // additional chars + + if (type == null) return null + + return parseComponents(type, key, additionalChars.ifEmpty { null }) + } catch (e: Throwable) { + Log.e("NIP19 Parser", "Issue trying to Decode NIP19 $uri: ${e.message}", e) + } + + return null + } + + fun parseComponents( + type: String, + key: String?, + additionalChars: String?, + ): ParseReturn? = + try { + val nip19 = (type + key) + val bytes = nip19.bechToBytes() + + when (type.lowercase()) { + "nsec1" -> NSec.parse(bytes) + "npub1" -> NPub.parse(bytes) + "note1" -> Note.parse(bytes) + "nprofile1" -> NProfile.parse(bytes) + "nevent1" -> NEvent.parse(bytes) + "nrelay1" -> NRelay.parse(bytes) + "naddr1" -> NAddress.parse(bytes) + "nembed1" -> NEmbed.parse(bytes) + else -> null + }?.let { + ParseReturn(it, nip19, additionalChars) + } + } catch (e: Throwable) { + Log.w("NIP19 Parser", "Issue trying to Decode NIP19 $key: ${e.message}", e) + null + } +} + +fun decodePublicKey(key: String): ByteArray = + when (val parsed = Nip19Parser.uriToRoute(key)?.entity) { + is NSec -> KeyPair(privKey = key.bechToBytes()).pubKey + is NPub -> parsed.hex.hexToByteArray() + is NProfile -> parsed.hex.hexToByteArray() + else -> Hex.decode(key) // crashes on purpose + } + +fun decodePrivateKeyAsHexOrNull(key: String): HexKey? = + try { + when (val parsed = Nip19Parser.uriToRoute(key)?.entity) { + is NSec -> parsed.hex + is NPub -> null + is NProfile -> null + is Note -> null + is NEvent -> null + is NEmbed -> null + is NRelay -> null + is NAddress -> null + else -> Hex.decode(key).toHexKey() + } + } catch (e: Exception) { + if (e is CancellationException) throw e + null + } + +fun decodePublicKeyAsHexOrNull(key: String): HexKey? = + try { + when (val parsed = Nip19Parser.uriToRoute(key)?.entity) { + is NSec -> KeyPair(privKey = key.bechToBytes()).pubKey.toHexKey() + is NPub -> parsed.hex + is NProfile -> parsed.hex + is Note -> null + is NEvent -> null + is NEmbed -> null + is NRelay -> null + is NAddress -> null + else -> Hex.decode(key).toHexKey() + } + } catch (e: Exception) { + if (e is CancellationException) throw e + null + } + +fun decodeEventIdAsHexOrNull(key: String): HexKey? = + try { + when (val parsed = Nip19Parser.uriToRoute(key)?.entity) { + is NSec -> null + is NPub -> null + is NProfile -> null + is Note -> parsed.hex + is NEvent -> parsed.hex + is NAddress -> parsed.aTag() + is NEmbed -> null + is NRelay -> null + else -> Hex.decode(key).toHexKey() + } + } catch (e: Exception) { + if (e is CancellationException) throw e + null + } diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/TlvBuilderExt.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/TlvBuilderExt.kt new file mode 100644 index 000000000..91248880e --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/TlvBuilderExt.kt @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip19Bech32Entities.TlvTypes +import com.vitorpamplona.quartz.nip19Bech32Entities.tlv.TlvBuilder + +fun TlvBuilder.addString( + type: TlvTypes, + string: String, +) = addString(type.id, string) + +fun TlvBuilder.addHex( + type: TlvTypes, + key: HexKey, +) = addHex(type.id, key) + +fun TlvBuilder.addInt( + type: TlvTypes, + data: Int, +) = addInt(type.id, data) + +fun TlvBuilder.addStringIfNotNull( + type: TlvTypes, + data: String?, +) = addStringIfNotNull(type.id, data) + +fun TlvBuilder.addHexIfNotNull( + type: TlvTypes, + data: HexKey?, +) = addHexIfNotNull(type.id, data) + +fun TlvBuilder.addIntIfNotNull( + type: TlvTypes, + data: Int?, +) = addIntIfNotNull(type.id, data) diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/TlvTypes.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/TlvTypes.kt new file mode 100644 index 000000000..436fa4721 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/TlvTypes.kt @@ -0,0 +1,40 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip19Bech32Entities + +import com.vitorpamplona.quartz.nip19Bech32Entities.tlv.Tlv + +enum class TlvTypes( + val id: Byte, +) { + SPECIAL(0), + RELAY(1), + AUTHOR(2), + KIND(3), +} + +fun Tlv.firstAsInt(type: TlvTypes) = firstAsInt(type.id) + +fun Tlv.firstAsHex(type: TlvTypes) = firstAsHex(type.id) + +fun Tlv.firstAsString(type: TlvTypes) = firstAsString(type.id) + +fun Tlv.asStringList(type: TlvTypes) = asStringList(type.id) diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/Bech32Util.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/bech32/Bech32Util.kt similarity index 99% rename from quartz/src/main/java/com/vitorpamplona/quartz/encoders/Bech32Util.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/bech32/Bech32Util.kt index 643da6a5e..97365ce7a 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/Bech32Util.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/bech32/Bech32Util.kt @@ -18,7 +18,7 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.encoders +package com.vitorpamplona.quartz.nip19Bech32Entities.bech32 /* * Copyright 2020 ACINQ SAS diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/entities/Entity.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/entities/Entity.kt new file mode 100644 index 000000000..27a4907bc --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/entities/Entity.kt @@ -0,0 +1,23 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip19Bech32Entities.entities + +interface Entity diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/entities/NAddress.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/entities/NAddress.kt new file mode 100644 index 000000000..d9b428aa0 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/entities/NAddress.kt @@ -0,0 +1,89 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip19Bech32Entities.entities + +import addHex +import addInt +import addString +import addStringIfNotNull +import android.util.Log +import androidx.compose.runtime.Immutable +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip19Bech32Entities.TlvTypes +import com.vitorpamplona.quartz.nip19Bech32Entities.bech32.bechToBytes +import com.vitorpamplona.quartz.nip19Bech32Entities.tlv.Tlv +import com.vitorpamplona.quartz.nip19Bech32Entities.tlv.TlvBuilder +import com.vitorpamplona.quartz.nip19Bech32Entities.toNAddress + +@Immutable +data class NAddress( + val kind: Int, + val author: String, + val dTag: String, + val relay: List, +) : Entity { + fun aTag(): String = ATag.assembleATag(kind, author, dTag) + + companion object { + fun parse(naddr: String): NAddress? { + try { + val key = naddr.removePrefix("nostr:") + + if (key.startsWith("naddr")) { + return parse(key.bechToBytes()) + } + } catch (e: Throwable) { + Log.w("NAddress", "Issue trying to Decode NIP19 $this: ${e.message}") + // e.printStackTrace() + } + + return null + } + + fun parse(bytes: ByteArray): NAddress? { + if (bytes.isEmpty()) return null + + val tlv = Tlv.parse(bytes) + + val d = tlv.firstAsString(TlvTypes.SPECIAL.id) ?: "" + val relay = tlv.asStringList(TlvTypes.RELAY.id) ?: emptyList() + val author = tlv.firstAsHex(TlvTypes.AUTHOR.id) ?: return null + val kind = tlv.firstAsInt(TlvTypes.KIND.id) ?: return null + + return NAddress(kind, author, d, relay) + } + + fun create( + kind: Int, + pubKeyHex: String, + dTag: String, + relay: String?, + ): String = + TlvBuilder() + .apply { + addString(TlvTypes.SPECIAL, dTag) + addStringIfNotNull(TlvTypes.RELAY, relay) + addHex(TlvTypes.AUTHOR, pubKeyHex) + addInt(TlvTypes.KIND, kind) + }.build() + .toNAddress() + } +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/entities/NEmbed.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/entities/NEmbed.kt new file mode 100644 index 000000000..2f547fe7d --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/entities/NEmbed.kt @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip19Bech32Entities.entities + +import androidx.compose.runtime.Immutable +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip19Bech32Entities.toNEmbed +import java.io.ByteArrayOutputStream +import java.util.zip.GZIPInputStream +import java.util.zip.GZIPOutputStream + +@Immutable +data class NEmbed( + val event: Event, +) : Entity { + companion object { + fun parse(bytes: ByteArray): NEmbed? { + if (bytes.isEmpty()) return null + return NEmbed(Event.fromJson(ungzip(bytes))) + } + + fun create(event: Event): String = gzip(event.toJson()).toNEmbed() + + fun gzip(content: String): ByteArray { + val bos = ByteArrayOutputStream() + GZIPOutputStream(bos).bufferedWriter(Charsets.UTF_8).use { it.write(content) } + val array = bos.toByteArray() + return array + } + + fun ungzip(content: ByteArray): String = GZIPInputStream(content.inputStream()).bufferedReader(Charsets.UTF_8).use { it.readText() } + } +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/entities/NEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/entities/NEvent.kt new file mode 100644 index 000000000..71e68d199 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/entities/NEvent.kt @@ -0,0 +1,73 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip19Bech32Entities.entities + +import addHex +import addHexIfNotNull +import addIntIfNotNull +import addStringIfNotNull +import androidx.compose.runtime.Immutable +import com.vitorpamplona.quartz.nip19Bech32Entities.TlvTypes +import com.vitorpamplona.quartz.nip19Bech32Entities.asStringList +import com.vitorpamplona.quartz.nip19Bech32Entities.firstAsHex +import com.vitorpamplona.quartz.nip19Bech32Entities.tlv.Tlv +import com.vitorpamplona.quartz.nip19Bech32Entities.tlv.TlvBuilder +import com.vitorpamplona.quartz.nip19Bech32Entities.toNEvent + +@Immutable +data class NEvent( + val hex: String, + val relay: List, + val author: String?, + val kind: Int?, +) : Entity { + companion object { + fun parse(bytes: ByteArray): NEvent? { + if (bytes.isEmpty()) return null + + val tlv = Tlv.parse(bytes) + + val hex = tlv.firstAsHex(TlvTypes.SPECIAL) ?: return null + val relay = tlv.asStringList(TlvTypes.RELAY) ?: emptyList() + val author = tlv.firstAsHex(TlvTypes.AUTHOR) + val kind = tlv.firstAsInt(TlvTypes.KIND.id) + + if (hex.isBlank()) return null + + return NEvent(hex, relay, author, kind) + } + + fun create( + idHex: String, + author: String?, + kind: Int?, + relay: String?, + ): String = + TlvBuilder() + .apply { + addHex(TlvTypes.SPECIAL, idHex) + addStringIfNotNull(TlvTypes.RELAY, relay) + addHexIfNotNull(TlvTypes.AUTHOR, author) + addIntIfNotNull(TlvTypes.KIND, kind) + }.build() + .toNEvent() + } +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/entities/NProfile.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/entities/NProfile.kt new file mode 100644 index 000000000..b5149e337 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/entities/NProfile.kt @@ -0,0 +1,65 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip19Bech32Entities.entities + +import addHex +import addStringIfNotNull +import androidx.compose.runtime.Immutable +import com.vitorpamplona.quartz.nip19Bech32Entities.TlvTypes +import com.vitorpamplona.quartz.nip19Bech32Entities.asStringList +import com.vitorpamplona.quartz.nip19Bech32Entities.firstAsHex +import com.vitorpamplona.quartz.nip19Bech32Entities.tlv.Tlv +import com.vitorpamplona.quartz.nip19Bech32Entities.tlv.TlvBuilder +import com.vitorpamplona.quartz.nip19Bech32Entities.toNProfile + +@Immutable +data class NProfile( + val hex: String, + val relay: List, +) : Entity { + companion object { + fun parse(bytes: ByteArray): NProfile? { + if (bytes.isEmpty()) return null + + val tlv = Tlv.parse(bytes) + + val hex = tlv.firstAsHex(TlvTypes.SPECIAL) ?: return null + val relay = tlv.asStringList(TlvTypes.RELAY) ?: emptyList() + + if (hex.isBlank()) return null + + return NProfile(hex, relay) + } + + fun create( + authorPubKeyHex: String, + relay: List, + ): String = + TlvBuilder() + .apply { + addHex(TlvTypes.SPECIAL, authorPubKeyHex) + relay.forEach { + addStringIfNotNull(TlvTypes.RELAY, it) + } + }.build() + .toNProfile() + } +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/entities/NPub.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/entities/NPub.kt new file mode 100644 index 000000000..1acf7dc71 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/entities/NPub.kt @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip19Bech32Entities.entities + +import androidx.compose.runtime.Immutable +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.hexToByteArray +import com.vitorpamplona.quartz.nip01Core.toHexKey +import com.vitorpamplona.quartz.nip19Bech32Entities.toNpub + +@Immutable +data class NPub( + val hex: String, +) : Entity { + companion object { + fun parse(bytes: ByteArray): NPub? { + if (bytes.isEmpty()) return null + return NPub(bytes.toHexKey()) + } + + fun create(authorPubKeyHex: HexKey): String = authorPubKeyHex.hexToByteArray().toNpub() + } +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/entities/NRelay.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/entities/NRelay.kt new file mode 100644 index 000000000..45cf9f787 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/entities/NRelay.kt @@ -0,0 +1,40 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip19Bech32Entities.entities + +import androidx.compose.runtime.Immutable +import com.vitorpamplona.quartz.nip19Bech32Entities.TlvTypes +import com.vitorpamplona.quartz.nip19Bech32Entities.tlv.Tlv + +@Immutable +data class NRelay( + val relay: List, +) : Entity { + companion object { + fun parse(bytes: ByteArray): NRelay? { + if (bytes.isEmpty()) return null + + val relayUrl = Tlv.parse(bytes).asStringList(TlvTypes.SPECIAL.id) ?: return null + + return NRelay(relayUrl) + } + } +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/entities/NSec.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/entities/NSec.kt new file mode 100644 index 000000000..c99c3af6e --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/entities/NSec.kt @@ -0,0 +1,36 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip19Bech32Entities.entities + +import androidx.compose.runtime.Immutable +import com.vitorpamplona.quartz.nip01Core.toHexKey + +@Immutable +data class NSec( + val hex: String, +) : Entity { + companion object { + fun parse(bytes: ByteArray): NSec? { + if (bytes.isEmpty()) return null + return NSec(bytes.toHexKey()) + } + } +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/entities/Note.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/entities/Note.kt new file mode 100644 index 000000000..deb4afe60 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/entities/Note.kt @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip19Bech32Entities.entities + +import androidx.compose.runtime.Immutable +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.hexToByteArray +import com.vitorpamplona.quartz.nip01Core.toHexKey +import com.vitorpamplona.quartz.nip19Bech32Entities.toNote + +@Immutable +data class Note( + val hex: String, +) : Entity { + companion object { + fun parse(bytes: ByteArray): Note? { + if (bytes.isEmpty()) return null + return Note(bytes.toHexKey()) + } + + fun create(eventId: HexKey): String = eventId.hexToByteArray().toNote() + } +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/Tlv.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/tlv/Tlv.kt similarity index 68% rename from quartz/src/main/java/com/vitorpamplona/quartz/encoders/Tlv.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/tlv/Tlv.kt index 284a99f1f..24877a8ef 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/Tlv.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/tlv/Tlv.kt @@ -18,67 +18,12 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.encoders +package com.vitorpamplona.quartz.nip19Bech32Entities.tlv -import java.io.ByteArrayOutputStream +import com.vitorpamplona.quartz.nip01Core.toHexKey import java.nio.ByteBuffer import java.nio.ByteOrder -class TlvBuilder { - val outputStream = ByteArrayOutputStream() - - private fun add( - type: Byte, - byteArray: ByteArray, - ) { - outputStream.write(byteArrayOf(type, byteArray.size.toByte())) - outputStream.write(byteArray) - } - - 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.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 build(): ByteArray = outputStream.toByteArray() -} - -fun Int.to32BitByteArray(): ByteArray { - val bytes = ByteArray(4) - (0..3).forEach { bytes[3 - it] = ((this ushr (8 * it)) and 0xFFFF).toByte() } - return bytes -} - -fun ByteArray.toInt32(): Int? { - if (size != 4) return null - return ByteBuffer.wrap(this, 0, 4).order(ByteOrder.BIG_ENDIAN).int -} - class Tlv( val data: Map>, ) { @@ -116,3 +61,8 @@ class Tlv( } } } + +fun ByteArray.toInt32(): Int? { + if (size != 4) return null + return ByteBuffer.wrap(this, 0, 4).order(ByteOrder.BIG_ENDIAN).int +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/tlv/TlvBuilder.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/tlv/TlvBuilder.kt new file mode 100644 index 000000000..60cfedd81 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32Entities/tlv/TlvBuilder.kt @@ -0,0 +1,75 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip19Bech32Entities.tlv + +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.hexToByteArray +import java.io.ByteArrayOutputStream + +class TlvBuilder { + val outputStream = ByteArrayOutputStream() + + private fun add( + type: Byte, + byteArray: ByteArray, + ) { + outputStream.write(byteArrayOf(type, byteArray.size.toByte())) + outputStream.write(byteArray) + } + + 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.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 build(): ByteArray = outputStream.toByteArray() +} + +fun Int.to32BitByteArray(): ByteArray { + val bytes = ByteArray(4) + (0..3).forEach { bytes[3 - it] = ((this ushr (8 * it)) and 0xFFFF).toByte() } + return bytes +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip21UriScheme/EventExt.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip21UriScheme/EventExt.kt new file mode 100644 index 000000000..cb0057c08 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip21UriScheme/EventExt.kt @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip21UriScheme + +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip19Bech32Entities.toNIP19 + +fun Event.toNostrUri(): String = "nostr:${toNIP19()}" diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/CommentEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip22Comments/CommentEvent.kt similarity index 86% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/CommentEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip22Comments/CommentEvent.kt index 7481019f8..9d0a5756b 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/CommentEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip22Comments/CommentEvent.kt @@ -18,17 +18,26 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip22Comments import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.ETag -import com.vitorpamplona.quartz.encoders.EventHint -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.IMetaTag -import com.vitorpamplona.quartz.encoders.Nip92MediaAttachments -import com.vitorpamplona.quartz.encoders.PTag -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.EventHint +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.addressables.AddressableEvent +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.geohash.geohashMipMap +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip10Notes.BaseTextNoteEvent +import com.vitorpamplona.quartz.nip10Notes.ETag +import com.vitorpamplona.quartz.nip10Notes.PTag +import com.vitorpamplona.quartz.nip10Notes.findHashtags +import com.vitorpamplona.quartz.nip10Notes.findURLs +import com.vitorpamplona.quartz.nip19Bech32Entities.parseAtag +import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiUrl +import com.vitorpamplona.quartz.nip57Zaps.ZapSplitSetup +import com.vitorpamplona.quartz.nip92IMeta.IMetaTag +import com.vitorpamplona.quartz.nip92IMeta.Nip92MediaAttachments import com.vitorpamplona.quartz.utils.TimeUtils import com.vitorpamplona.quartz.utils.removeTrailingNullsAndEmptyOthers @@ -56,15 +65,15 @@ class CommentEvent( private fun getGeoHashList() = tags.filter { isGeohashTag(it) } - override fun hasGeohashes() = tags.any { isGeohashTag(it) } + fun hasGeohashes() = tags.any { isGeohashTag(it) } - override fun geohashes() = getGeoHashList().map { it[1].drop(4).lowercase() } + fun geohashes() = getGeoHashList().map { it[1].drop(4).lowercase() } - override fun getGeoHash(): String? = geohashes().maxByOrNull { it.length } + fun getGeoHash(): String? = geohashes().maxByOrNull { it.length } - override fun isTaggedGeoHash(hashtag: String) = tags.any { isGeohashTag(it) && it[1].endsWith(hashtag, true) } + fun isTaggedGeoHash(hashtag: String) = tags.any { isGeohashTag(it) && it[1].endsWith(hashtag, true) } - override fun isTaggedGeoHashes(hashtags: Set) = geohashes().any { it in hashtags } + fun isTaggedGeoHashes(hashtags: Set) = geohashes().any { it in hashtags } override fun markedReplyTos(): List = tags.filter { it.size > 1 && it[0] == "e" }.map { it[1] } + tags.filter { it.size > 1 && it[0] == "E" }.map { it[1] } diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip22Comments/RootScope.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip22Comments/RootScope.kt new file mode 100644 index 000000000..de9c13c9e --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip22Comments/RootScope.kt @@ -0,0 +1,23 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip22Comments + +interface RootScope diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/LongTextNoteEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip23LongContent/LongTextNoteEvent.kt similarity index 87% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/LongTextNoteEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip23LongContent/LongTextNoteEvent.kt index b06909e27..00f7b0a9e 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/LongTextNoteEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip23LongContent/LongTextNoteEvent.kt @@ -18,12 +18,15 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip23LongContent import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.addressables.AddressableEvent +import com.vitorpamplona.quartz.nip01Core.hashtags.hashtags +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip10Notes.BaseTextNoteEvent import com.vitorpamplona.quartz.utils.TimeUtils @Immutable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/ReactionEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip25Reactions/ReactionEvent.kt similarity index 81% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/ReactionEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip25Reactions/ReactionEvent.kt index 6073a9abb..ed8ed0148 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/ReactionEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip25Reactions/ReactionEvent.kt @@ -18,11 +18,14 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip25Reactions import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.AddressableEvent +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiUrl import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -42,14 +45,14 @@ class ReactionEvent( const val KIND = 7 fun createWarning( - originalNote: EventInterface, + originalNote: Event, signer: NostrSigner, createdAt: Long = TimeUtils.now(), onReady: (ReactionEvent) -> Unit, ) = create("\u26A0\uFE0F", originalNote, signer, createdAt, onReady) fun createLike( - originalNote: EventInterface, + originalNote: Event, signer: NostrSigner, createdAt: Long = TimeUtils.now(), onReady: (ReactionEvent) -> Unit, @@ -57,16 +60,16 @@ class ReactionEvent( fun create( content: String, - originalNote: EventInterface, + originalNote: Event, signer: NostrSigner, createdAt: Long = TimeUtils.now(), onReady: (ReactionEvent) -> Unit, ) { var tags = listOf( - arrayOf("e", originalNote.id()), - arrayOf("p", originalNote.pubKey()), - arrayOf("k", originalNote.kind().toString()), + arrayOf("e", originalNote.id), + arrayOf("p", originalNote.pubKey), + arrayOf("k", originalNote.kind.toString()), ) if (originalNote is AddressableEvent) { tags = tags + listOf(arrayOf("a", originalNote.address().toTag())) @@ -77,7 +80,7 @@ class ReactionEvent( fun create( emojiUrl: EmojiUrl, - originalNote: EventInterface, + originalNote: Event, signer: NostrSigner, createdAt: Long = TimeUtils.now(), onReady: (ReactionEvent) -> Unit, @@ -86,8 +89,8 @@ class ReactionEvent( var tags = arrayOf( - arrayOf("e", originalNote.id()), - arrayOf("p", originalNote.pubKey()), + arrayOf("e", originalNote.id), + arrayOf("p", originalNote.pubKey), arrayOf("emoji", emojiUrl.code, emojiUrl.url), ) diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/ChannelCreateEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip28PublicChat/ChannelCreateEvent.kt similarity index 88% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/ChannelCreateEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip28PublicChat/ChannelCreateEvent.kt index f3dad8aec..078c1a9cf 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/ChannelCreateEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip28PublicChat/ChannelCreateEvent.kt @@ -18,13 +18,15 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip28PublicChat import android.util.Log import androidx.compose.runtime.Immutable import com.fasterxml.jackson.module.kotlin.readValue -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -38,7 +40,7 @@ class ChannelCreateEvent( ) : Event(id, pubKey, createdAt, KIND, tags, content, sig) { fun channelInfo(): ChannelData = try { - mapper.readValue(content) + EventMapper.mapper.readValue(content) } catch (e: Exception) { Log.e("ChannelMetadataEvent", "Can't parse channel info $content", e) ChannelData(null, null, null) @@ -74,7 +76,7 @@ class ChannelCreateEvent( val content = try { if (channelInfo != null) { - mapper.writeValueAsString(channelInfo) + EventMapper.mapper.writeValueAsString(channelInfo) } else { "" } diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/ChannelHideMessageEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip28PublicChat/ChannelHideMessageEvent.kt similarity index 91% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/ChannelHideMessageEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip28PublicChat/ChannelHideMessageEvent.kt index 7d0207c24..099661155 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/ChannelHideMessageEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip28PublicChat/ChannelHideMessageEvent.kt @@ -18,11 +18,12 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip28PublicChat import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.utils.TimeUtils @Immutable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/ChannelListEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip28PublicChat/ChannelListEvent.kt similarity index 97% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/ChannelListEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip28PublicChat/ChannelListEvent.kt index 3943c76b0..56465959d 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/ChannelListEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip28PublicChat/ChannelListEvent.kt @@ -18,11 +18,12 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip28PublicChat import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip51Lists.GeneralListEvent import com.vitorpamplona.quartz.utils.TimeUtils import com.vitorpamplona.quartz.utils.bytesUsedInMemory import com.vitorpamplona.quartz.utils.pointerSizeInBytes diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/ChannelMessageEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip28PublicChat/ChannelMessageEvent.kt similarity index 88% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/ChannelMessageEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip28PublicChat/ChannelMessageEvent.kt index 38da37023..e2e08a3a4 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/ChannelMessageEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip28PublicChat/ChannelMessageEvent.kt @@ -18,13 +18,17 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip28PublicChat import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.IMetaTag -import com.vitorpamplona.quartz.encoders.Nip92MediaAttachments -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.geohash.geohashMipMap +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip10Notes.BaseTextNoteEvent +import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiUrl +import com.vitorpamplona.quartz.nip57Zaps.ZapSplitSetup +import com.vitorpamplona.quartz.nip92IMeta.IMetaTag +import com.vitorpamplona.quartz.nip92IMeta.Nip92MediaAttachments import com.vitorpamplona.quartz.utils.TimeUtils @Immutable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/ChannelMetadataEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip28PublicChat/ChannelMetadataEvent.kt similarity index 87% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/ChannelMetadataEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip28PublicChat/ChannelMetadataEvent.kt index 269016804..ae566f5a9 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/ChannelMetadataEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip28PublicChat/ChannelMetadataEvent.kt @@ -18,12 +18,14 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip28PublicChat import android.util.Log import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -40,7 +42,7 @@ class ChannelMetadataEvent( fun channelInfo() = try { - mapper.readValue(content, ChannelCreateEvent.ChannelData::class.java) + EventMapper.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) @@ -81,7 +83,7 @@ class ChannelMetadataEvent( ) { val content = if (newChannelInfo != null) { - mapper.writeValueAsString(newChannelInfo) + EventMapper.mapper.writeValueAsString(newChannelInfo) } else { "" } diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/ChannelMuteUserEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip28PublicChat/ChannelMuteUserEvent.kt similarity index 91% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/ChannelMuteUserEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip28PublicChat/ChannelMuteUserEvent.kt index d69522340..9bae646b2 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/ChannelMuteUserEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip28PublicChat/ChannelMuteUserEvent.kt @@ -18,11 +18,12 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip28PublicChat import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.utils.TimeUtils @Immutable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/Nip30CustomEmoji.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip30CustomEmoji/CustomEmoji.kt similarity index 97% rename from quartz/src/main/java/com/vitorpamplona/quartz/encoders/Nip30CustomEmoji.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip30CustomEmoji/CustomEmoji.kt index de5823ab9..d8fb3323a 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/Nip30CustomEmoji.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip30CustomEmoji/CustomEmoji.kt @@ -18,15 +18,15 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.encoders +package com.vitorpamplona.quartz.nip30CustomEmoji import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.events.ImmutableListOfLists +import com.vitorpamplona.quartz.nip02FollowList.ImmutableListOfLists import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList import java.util.regex.Pattern -class Nip30CustomEmoji { +class CustomEmoji { companion object { val customEmojiPattern: Pattern = Pattern.compile("\\:([A-Za-z0-9_\\-]+)\\:", Pattern.CASE_INSENSITIVE) diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/EmojiPackEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip30CustomEmoji/EmojiPackEvent.kt similarity index 92% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/EmojiPackEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip30CustomEmoji/EmojiPackEvent.kt index 887f24416..7ee535e93 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/EmojiPackEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip30CustomEmoji/EmojiPackEvent.kt @@ -18,11 +18,12 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip30CustomEmoji import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip51Lists.GeneralListEvent import com.vitorpamplona.quartz.utils.TimeUtils @Immutable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/EmojiPackSelectionEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip30CustomEmoji/EmojiPackSelectionEvent.kt similarity index 73% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/EmojiPackSelectionEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip30CustomEmoji/EmojiPackSelectionEvent.kt index ab758aa34..0e6ca4c4c 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/EmojiPackSelectionEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip30CustomEmoji/EmojiPackSelectionEvent.kt @@ -18,12 +18,14 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip30CustomEmoji import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.addressables.BaseAddressableEvent +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -42,9 +44,20 @@ class EmojiPackSelectionEvent( const val FIXED_D_TAG = "" const val ALT = "Emoji selection" - fun createAddressATag(pubKey: HexKey): ATag = ATag(KIND, pubKey, AdvertisedRelayListEvent.FIXED_D_TAG, null) + fun createAddressATag(pubKey: HexKey): ATag = + ATag( + KIND, + pubKey, + AdvertisedRelayListEvent.FIXED_D_TAG, + null, + ) - fun createAddressTag(pubKey: HexKey): String = ATag.assembleATag(KIND, pubKey, AdvertisedRelayListEvent.FIXED_D_TAG) + fun createAddressTag(pubKey: HexKey): String = + ATag.assembleATag( + KIND, + pubKey, + AdvertisedRelayListEvent.FIXED_D_TAG, + ) fun create( listOfEmojiPacks: List?, diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip30CustomEmoji/EventExt.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip30CustomEmoji/EventExt.kt new file mode 100644 index 000000000..bf48b06ef --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip30CustomEmoji/EventExt.kt @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip30CustomEmoji + +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.core.mapTagged + +fun Event.taggedEmojis() = tags.mapTagged("emoji") { EmojiUrl.parse(it) } diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/GitIssueEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip34Git/GitIssueEvent.kt similarity index 88% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/GitIssueEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip34Git/GitIssueEvent.kt index 2c1752ffe..529d4e0ec 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/GitIssueEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip34Git/GitIssueEvent.kt @@ -18,12 +18,14 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip34Git import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip10Notes.BaseTextNoteEvent +import com.vitorpamplona.quartz.nip19Bech32Entities.parse import com.vitorpamplona.quartz.utils.TimeUtils @Immutable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/GitPatchEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip34Git/GitPatchEvent.kt similarity index 90% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/GitPatchEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip34Git/GitPatchEvent.kt index 4c5a04ce8..c47c44050 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/GitPatchEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip34Git/GitPatchEvent.kt @@ -18,12 +18,14 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip34Git import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip19Bech32Entities.parse import com.vitorpamplona.quartz.utils.TimeUtils @Immutable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/GitReplyEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip34Git/GitReplyEvent.kt similarity index 86% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/GitReplyEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip34Git/GitReplyEvent.kt index 3b40d605f..4b26d6f8c 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/GitReplyEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip34Git/GitReplyEvent.kt @@ -18,14 +18,24 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip34Git import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.IMetaTag -import com.vitorpamplona.quartz.encoders.Nip92MediaAttachments -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.addressables.AddressableEvent +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.geohash.geohashMipMap +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip10Notes.BaseTextNoteEvent +import com.vitorpamplona.quartz.nip10Notes.findHashtags +import com.vitorpamplona.quartz.nip10Notes.findURLs +import com.vitorpamplona.quartz.nip10Notes.positionalMarkedTags +import com.vitorpamplona.quartz.nip19Bech32Entities.parse +import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiUrl +import com.vitorpamplona.quartz.nip57Zaps.ZapSplitSetup +import com.vitorpamplona.quartz.nip92IMeta.IMetaTag +import com.vitorpamplona.quartz.nip92IMeta.Nip92MediaAttachments import com.vitorpamplona.quartz.utils.TimeUtils @Immutable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/GitRepositoryEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip34Git/GitRepositoryEvent.kt similarity index 90% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/GitRepositoryEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip34Git/GitRepositoryEvent.kt index f610dc7e2..a20bc9d36 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/GitRepositoryEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip34Git/GitRepositoryEvent.kt @@ -18,11 +18,12 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip34Git import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.BaseAddressableEvent +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.utils.TimeUtils @Immutable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/TorrentCommentEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip35Torrents/TorrentCommentEvent.kt similarity index 85% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/TorrentCommentEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip35Torrents/TorrentCommentEvent.kt index 1513be3e6..b5898496d 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/TorrentCommentEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip35Torrents/TorrentCommentEvent.kt @@ -18,14 +18,23 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip35Torrents import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.IMetaTag -import com.vitorpamplona.quartz.encoders.Nip92MediaAttachments -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.addressables.AddressableEvent +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.geohash.geohashMipMap +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip10Notes.BaseTextNoteEvent +import com.vitorpamplona.quartz.nip10Notes.findHashtags +import com.vitorpamplona.quartz.nip10Notes.findURLs +import com.vitorpamplona.quartz.nip10Notes.positionalMarkedTags +import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiUrl +import com.vitorpamplona.quartz.nip57Zaps.ZapSplitSetup +import com.vitorpamplona.quartz.nip92IMeta.IMetaTag +import com.vitorpamplona.quartz.nip92IMeta.Nip92MediaAttachments import com.vitorpamplona.quartz.utils.TimeUtils @Immutable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/TorrentEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip35Torrents/TorrentEvent.kt similarity index 89% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/TorrentEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip35Torrents/TorrentEvent.kt index 9c6a1291e..3c1eb40e3 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/TorrentEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip35Torrents/TorrentEvent.kt @@ -18,12 +18,15 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip35Torrents import android.net.Uri import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.core.firstTagValue +import com.vitorpamplona.quartz.nip01Core.core.mapValues +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -35,13 +38,13 @@ class TorrentEvent( content: String, sig: HexKey, ) : Event(id, pubKey, createdAt, KIND, tags, content, sig) { - fun title() = firstTag("title") + fun title() = tags.firstTagValue("title") - fun btih() = firstTag("btih") + fun btih() = tags.firstTagValue("btih") - fun x() = firstTag("x") + fun x() = tags.firstTagValue("x") - fun trackers() = tags.filter { it.size > 1 && it[0] == "tracker" }.map { it[1] } + fun trackers() = tags.mapValues("tracker") fun files() = tags.filter { it.size > 1 && it[0] == "file" }.map { TorrentFile(it[1], it.getOrNull(2)?.toLongOrNull()) } @@ -120,9 +123,3 @@ class TorrentEvent( } } } - -@Immutable -class TorrentFile( - val fileName: String, - val bytes: Long?, -) diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip35Torrents/TorrentFile.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip35Torrents/TorrentFile.kt new file mode 100644 index 000000000..7b346585e --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip35Torrents/TorrentFile.kt @@ -0,0 +1,29 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip35Torrents + +import androidx.compose.runtime.Immutable + +@Immutable +class TorrentFile( + val fileName: String, + val bytes: Long?, +) diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip36SensitiveContent/EventExt.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip36SensitiveContent/EventExt.kt new file mode 100644 index 000000000..8e506b86f --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip36SensitiveContent/EventExt.kt @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip36SensitiveContent + +import com.vitorpamplona.quartz.nip01Core.core.Event + +fun Event.isSensitive() = tags.any { (it.size > 0 && it[0] == "content-warning") } + +fun Event.isSensitiveOrNSFW() = + tags.any { + (it.size > 0 && it[0] == "content-warning") || + (it.size > 1 && it[0] == "t" && (it[1].equals("nsfw", true) || it[1].equals("nude", true))) + } diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/DraftEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip37Drafts/DraftEvent.kt similarity index 88% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/DraftEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip37Drafts/DraftEvent.kt index 3285ae1a4..8b3a92c70 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/DraftEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip37Drafts/DraftEvent.kt @@ -18,12 +18,22 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip37Drafts import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStoryBaseEvent +import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.addressables.BaseAddressableEvent +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent +import com.vitorpamplona.quartz.nip22Comments.CommentEvent +import com.vitorpamplona.quartz.nip28PublicChat.ChannelMessageEvent +import com.vitorpamplona.quartz.nip34Git.GitReplyEvent +import com.vitorpamplona.quartz.nip35Torrents.TorrentCommentEvent +import com.vitorpamplona.quartz.nip53LiveActivities.LiveActivitiesChatMessageEvent import com.vitorpamplona.quartz.utils.TimeUtils import com.vitorpamplona.quartz.utils.pointerSizeInBytes @@ -125,7 +135,7 @@ class DraftEvent( onReady: (DraftEvent) -> Unit, ) { val tagsWithMarkers = - originalNote.tags().filter { + originalNote.tags.filter { it.size > 3 && (it[0] == "e" || it[0] == "a") && (it[3] == "root" || it[3] == "reply") } @@ -192,7 +202,7 @@ class DraftEvent( onReady: (DraftEvent) -> Unit, ) { val tagsWithMarkers = - originalNote.tags().filter { + originalNote.tags.filter { it.size > 3 && (it[0] == "e" || it[0] == "a") && (it[3] == "root" || it[3] == "reply") } @@ -219,7 +229,7 @@ class DraftEvent( onReady: (DraftEvent) -> Unit, ) { val tagsWithMarkers = - originalNote.tags().filter { + originalNote.tags.filter { it.size > 3 && (it[0] == "e" || it[0] == "a") && (it[3] == "root" || it[3] == "reply") } diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/StatusEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip38UserStatus/StatusEvent.kt similarity index 88% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/StatusEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip38UserStatus/StatusEvent.kt index aa897e286..1e162061d 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/StatusEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip38UserStatus/StatusEvent.kt @@ -18,11 +18,13 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip38UserStatus import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.BaseAddressableEvent +import com.vitorpamplona.quartz.nip01Core.core.firstTagValue +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -34,6 +36,8 @@ class StatusEvent( content: String, sig: HexKey, ) : BaseAddressableEvent(id, pubKey, createdAt, KIND, tags, content, sig) { + fun firstTaggedUrl() = tags.firstTagValue("r") + companion object { const val KIND = 30315 diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip39ExtIdentities/EventExt.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip39ExtIdentities/EventExt.kt new file mode 100644 index 000000000..522659624 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip39ExtIdentities/EventExt.kt @@ -0,0 +1,72 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip39ExtIdentities + +import android.util.Log +import com.vitorpamplona.quartz.nip01Core.MetadataEvent +import com.vitorpamplona.quartz.nip01Core.core.TagArray +import com.vitorpamplona.quartz.nip01Core.core.mapTagged + +fun MetadataEvent.identityClaims() = + tags.mapTagged("i") { + try { + IdentityClaim.create(it[1], it[2]) + } catch (e: Exception) { + Log.e("MetadataEvent", "Can't parse identity [${it.joinToString { "," }}]", e) + null + } + } + +fun MetadataEvent.updateClaims( + twitter: String?, + mastodon: String?, + github: String?, +): TagArray { + var claims = identityClaims() + + // null leave as is. blank deletes it. + if (twitter != null) { + // delete twitter + claims = claims.filter { it !is TwitterIdentity } + if (twitter.isNotBlank()) { + TwitterIdentity.parseProofUrl(twitter)?.let { claims = claims + it } + } + } + + // null leave as is. blank deletes it. + if (github != null) { + // delete github + claims = claims.filter { it !is GitHubIdentity } + if (github.isNotBlank()) { + GitHubIdentity.parseProofUrl(github)?.let { claims = claims + it } + } + } + + // null leave as is. blank deletes it. + if (mastodon != null) { + claims = claims.filter { it !is MastodonIdentity } + if (mastodon.isNotBlank()) { + MastodonIdentity.parseProofUrl(mastodon)?.let { claims = claims + it } + } + } + + return claims.map { arrayOf("i", it.platformIdentity(), it.proof) }.toTypedArray() +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip39ExtIdentities/GitHubIdentity.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip39ExtIdentities/GitHubIdentity.kt new file mode 100644 index 000000000..522dc88f4 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip39ExtIdentities/GitHubIdentity.kt @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip39ExtIdentities + +class GitHubIdentity( + identity: String, + proof: String, +) : IdentityClaim(identity, proof) { + override fun toProofUrl() = "https://gist.github.com/$identity/$proof" + + override fun platform() = platform + + companion object { + val platform = "github" + + fun parseProofUrl(proofUrl: String): GitHubIdentity? { + return try { + if (proofUrl.isBlank()) return null + val path = proofUrl.removePrefix("https://gist.github.com/").split("?")[0].split("/") + + GitHubIdentity(path[0], path[1]) + } catch (e: Exception) { + null + } + } + } +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip39ExtIdentities/IdentityClaim.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip39ExtIdentities/IdentityClaim.kt new file mode 100644 index 000000000..cfe30c135 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip39ExtIdentities/IdentityClaim.kt @@ -0,0 +1,52 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip39ExtIdentities + +import androidx.compose.runtime.Stable + +@Stable +abstract class IdentityClaim( + val identity: String, + val proof: String, +) { + abstract fun toProofUrl(): String + + abstract fun platform(): String + + fun platformIdentity() = "${platform()}:$identity" + + companion object { + fun create( + platformIdentity: String, + proof: String, + ): IdentityClaim { + val (platform, identity) = platformIdentity.split(':') + + return when (platform.lowercase()) { + GitHubIdentity.platform -> GitHubIdentity(identity, proof) + TwitterIdentity.platform -> TwitterIdentity(identity, proof) + TelegramIdentity.platform -> TelegramIdentity(identity, proof) + MastodonIdentity.platform -> MastodonIdentity(identity, proof) + else -> throw IllegalArgumentException("Platform $platform not supported") + } + } + } +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip39ExtIdentities/MastodonIdentity.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip39ExtIdentities/MastodonIdentity.kt new file mode 100644 index 000000000..59975daf8 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip39ExtIdentities/MastodonIdentity.kt @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip39ExtIdentities + +class MastodonIdentity( + identity: String, + proof: String, +) : IdentityClaim(identity, proof) { + override fun toProofUrl() = "https://$identity/$proof" + + override fun platform() = platform + + companion object { + val platform = "mastodon" + + fun parseProofUrl(proofUrl: String): MastodonIdentity? { + return try { + if (proofUrl.isBlank()) return null + val path = proofUrl.removePrefix("https://").split("?")[0].split("/") + + return MastodonIdentity("${path[0]}/${path[1]}", path[2]) + } catch (e: Exception) { + null + } + } + } +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip39ExtIdentities/TelegramIdentity.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip39ExtIdentities/TelegramIdentity.kt new file mode 100644 index 000000000..0dff28a8f --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip39ExtIdentities/TelegramIdentity.kt @@ -0,0 +1,34 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip39ExtIdentities + +class TelegramIdentity( + identity: String, + proof: String, +) : IdentityClaim(identity, proof) { + override fun toProofUrl() = "https://t.me/$proof" + + override fun platform() = platform + + companion object { + val platform = "telegram" + } +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip39ExtIdentities/TwitterIdentity.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip39ExtIdentities/TwitterIdentity.kt new file mode 100644 index 000000000..0f87cf517 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip39ExtIdentities/TwitterIdentity.kt @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip39ExtIdentities + +class TwitterIdentity( + identity: String, + proof: String, +) : IdentityClaim(identity, proof) { + override fun toProofUrl() = "https://x.com/$identity/status/$proof" + + override fun platform() = platform + + companion object { + val platform = "twitter" + + fun parseProofUrl(proofUrl: String): TwitterIdentity? { + return try { + if (proofUrl.isBlank()) return null + val path = proofUrl.removePrefix("https://x.com/").split("?")[0].split("/") + + TwitterIdentity(path[0], path[2]) + } catch (e: Exception) { + null + } + } + } +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip40Expiration/EventExt.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip40Expiration/EventExt.kt new file mode 100644 index 000000000..67eba274d --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip40Expiration/EventExt.kt @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip40Expiration + +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.utils.TimeUtils + +fun Event.expiration() = + try { + tags.firstOrNull { it.size > 1 && it[0] == "expiration" }?.get(1)?.toLongOrNull() + } catch (_: Exception) { + null + } + +fun Event.isExpired() = (expiration() ?: Long.MAX_VALUE) < TimeUtils.now() + +fun Event.isExpirationBefore(time: Long) = (expiration() ?: Long.MAX_VALUE) < time diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/RelayAuthEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip42RelayAuth/RelayAuthEvent.kt similarity index 92% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/RelayAuthEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip42RelayAuth/RelayAuthEvent.kt index 15f40f0da..c835c0502 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/RelayAuthEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip42RelayAuth/RelayAuthEvent.kt @@ -18,11 +18,12 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip42RelayAuth import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.utils.TimeUtils @Immutable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip44/Nip44.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip44Encryption/Nip44.kt similarity index 94% rename from quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip44/Nip44.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip44Encryption/Nip44.kt index b0acc1548..c7018bac6 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip44/Nip44.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip44Encryption/Nip44.kt @@ -18,10 +18,10 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.crypto.nip44 +package com.vitorpamplona.quartz.nip44Encryption -import com.vitorpamplona.quartz.crypto.nip04.Nip04 -import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper +import com.vitorpamplona.quartz.nip04Dm.Nip04 import fr.acinq.secp256k1.Secp256k1 import java.security.SecureRandom import java.util.Base64 @@ -85,7 +85,7 @@ class Nip44( privateKey: ByteArray, pubKey: ByteArray, ): String? { - val info = Event.mapper.readValue(json, EncryptedInfoString::class.java) + val info = EventMapper.mapper.readValue(json, EncryptedInfoString::class.java) return when (info.v) { Nip04.EncryptedInfo.V -> { diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip44/Nip44v1.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip44Encryption/Nip44v1.kt similarity index 96% rename from quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip44/Nip44v1.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip44Encryption/Nip44v1.kt index 513bac5dd..e03527a47 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip44/Nip44v1.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip44Encryption/Nip44v1.kt @@ -18,14 +18,14 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.crypto.nip44 +package com.vitorpamplona.quartz.nip44Encryption import android.util.Log import com.goterl.lazysodium.SodiumAndroid import com.goterl.lazysodium.utils.Key -import com.vitorpamplona.quartz.crypto.SharedKeyCache +import com.vitorpamplona.quartz.crypto.Hex import com.vitorpamplona.quartz.crypto.sha256Hash -import com.vitorpamplona.quartz.encoders.Hex +import com.vitorpamplona.quartz.nip44Encryption.crypto.cryptoStreamXChaCha20Xor import fr.acinq.secp256k1.Secp256k1 import java.security.SecureRandom import java.util.Base64 diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip44/Nip44v2.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip44Encryption/Nip44v2.kt similarity index 97% rename from quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip44/Nip44v2.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip44Encryption/Nip44v2.kt index 54cbf1c40..1fab13b24 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip44/Nip44v2.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip44Encryption/Nip44v2.kt @@ -18,14 +18,14 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.crypto.nip44 +package com.vitorpamplona.quartz.nip44Encryption import android.util.Log import com.goterl.lazysodium.LazySodiumAndroid import com.goterl.lazysodium.SodiumAndroid -import com.vitorpamplona.quartz.crypto.SharedKeyCache -import com.vitorpamplona.quartz.encoders.Hex -import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.crypto.Hex +import com.vitorpamplona.quartz.nip01Core.toHexKey +import com.vitorpamplona.quartz.nip44Encryption.crypto.Hkdf import fr.acinq.secp256k1.Secp256k1 import java.nio.ByteBuffer import java.nio.ByteOrder diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/crypto/SharedKeyCache.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip44Encryption/SharedKeyCache.kt similarity index 97% rename from quartz/src/main/java/com/vitorpamplona/quartz/crypto/SharedKeyCache.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip44Encryption/SharedKeyCache.kt index 810c8925c..159afd3c9 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/crypto/SharedKeyCache.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip44Encryption/SharedKeyCache.kt @@ -18,7 +18,7 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.crypto +package com.vitorpamplona.quartz.nip44Encryption import android.util.LruCache diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip44/Hkdf.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip44Encryption/crypto/Hkdf.kt similarity index 97% rename from quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip44/Hkdf.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip44Encryption/crypto/Hkdf.kt index 258670df1..e52d18eb8 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip44/Hkdf.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip44Encryption/crypto/Hkdf.kt @@ -18,7 +18,7 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.crypto.nip44 +package com.vitorpamplona.quartz.nip44Encryption.crypto import java.nio.ByteBuffer import javax.crypto.Mac diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip44/SodiumUtils.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip44Encryption/crypto/SodiumUtils.kt similarity index 98% rename from quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip44/SodiumUtils.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip44Encryption/crypto/SodiumUtils.kt index 9961e4b1f..2cc0c902f 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip44/SodiumUtils.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip44Encryption/crypto/SodiumUtils.kt @@ -18,7 +18,7 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.crypto.nip44 +package com.vitorpamplona.quartz.nip44Encryption.crypto import com.goterl.lazysodium.SodiumAndroid import com.goterl.lazysodium.utils.Key diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerMessage.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerMessage.kt similarity index 97% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerMessage.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerMessage.kt index 4d5b145f5..5134a79ee 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerMessage.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerMessage.kt @@ -18,7 +18,7 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events.nip46 +package com.vitorpamplona.quartz.nip46RemoteSigner import com.fasterxml.jackson.core.JsonParser import com.fasterxml.jackson.databind.DeserializationContext diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerRequest.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerRequest.kt similarity index 97% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerRequest.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerRequest.kt index 9425b8fa6..71a54f872 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerRequest.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerRequest.kt @@ -18,7 +18,7 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events.nip46 +package com.vitorpamplona.quartz.nip46RemoteSigner import com.fasterxml.jackson.core.JsonGenerator import com.fasterxml.jackson.core.JsonParser @@ -27,7 +27,7 @@ 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.ser.std.StdSerializer -import com.vitorpamplona.quartz.events.Event.Companion.toTypedArray +import com.vitorpamplona.quartz.nip01Core.jackson.toTypedArray import com.vitorpamplona.quartz.utils.bytesUsedInMemory import com.vitorpamplona.quartz.utils.pointerSizeInBytes diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerRequestConnect.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerRequestConnect.kt similarity index 94% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerRequestConnect.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerRequestConnect.kt index 531f40386..e2b41c7e6 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerRequestConnect.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerRequestConnect.kt @@ -18,9 +18,9 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events.nip46 +package com.vitorpamplona.quartz.nip46RemoteSigner -import com.vitorpamplona.quartz.encoders.HexKey +import com.vitorpamplona.quartz.nip01Core.HexKey import java.util.UUID class BunkerRequestConnect( diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerRequestGetPublicKey.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerRequestGetPublicKey.kt similarity index 96% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerRequestGetPublicKey.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerRequestGetPublicKey.kt index 19610c5aa..27864bcfe 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerRequestGetPublicKey.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerRequestGetPublicKey.kt @@ -18,7 +18,7 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events.nip46 +package com.vitorpamplona.quartz.nip46RemoteSigner import java.util.UUID diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerRequestGetRelays.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerRequestGetRelays.kt similarity index 96% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerRequestGetRelays.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerRequestGetRelays.kt index 704d88c39..9bb7530a5 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerRequestGetRelays.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerRequestGetRelays.kt @@ -18,7 +18,7 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events.nip46 +package com.vitorpamplona.quartz.nip46RemoteSigner import java.util.UUID diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerRequestNip04Decrypt.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerRequestNip04Decrypt.kt similarity index 94% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerRequestNip04Decrypt.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerRequestNip04Decrypt.kt index af7b90f94..20bf478a6 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerRequestNip04Decrypt.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerRequestNip04Decrypt.kt @@ -18,9 +18,9 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events.nip46 +package com.vitorpamplona.quartz.nip46RemoteSigner -import com.vitorpamplona.quartz.encoders.HexKey +import com.vitorpamplona.quartz.nip01Core.HexKey import java.util.UUID class BunkerRequestNip04Decrypt( diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerRequestNip04Encrypt.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerRequestNip04Encrypt.kt similarity index 94% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerRequestNip04Encrypt.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerRequestNip04Encrypt.kt index eed216c91..ee4107730 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerRequestNip04Encrypt.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerRequestNip04Encrypt.kt @@ -18,9 +18,9 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events.nip46 +package com.vitorpamplona.quartz.nip46RemoteSigner -import com.vitorpamplona.quartz.encoders.HexKey +import com.vitorpamplona.quartz.nip01Core.HexKey import java.util.UUID class BunkerRequestNip04Encrypt( diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerRequestNip44Decrypt.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerRequestNip44Decrypt.kt similarity index 94% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerRequestNip44Decrypt.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerRequestNip44Decrypt.kt index 85416bd92..0769163c5 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerRequestNip44Decrypt.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerRequestNip44Decrypt.kt @@ -18,9 +18,9 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events.nip46 +package com.vitorpamplona.quartz.nip46RemoteSigner -import com.vitorpamplona.quartz.encoders.HexKey +import com.vitorpamplona.quartz.nip01Core.HexKey import java.util.UUID class BunkerRequestNip44Decrypt( diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerRequestNip44Encrypt.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerRequestNip44Encrypt.kt similarity index 94% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerRequestNip44Encrypt.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerRequestNip44Encrypt.kt index 3009f66ad..8f7064808 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerRequestNip44Encrypt.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerRequestNip44Encrypt.kt @@ -18,9 +18,9 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events.nip46 +package com.vitorpamplona.quartz.nip46RemoteSigner -import com.vitorpamplona.quartz.encoders.HexKey +import com.vitorpamplona.quartz.nip01Core.HexKey import java.util.UUID class BunkerRequestNip44Encrypt( diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerRequestPing.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerRequestPing.kt similarity index 96% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerRequestPing.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerRequestPing.kt index 3ad3d0c43..49c45fbb8 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerRequestPing.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerRequestPing.kt @@ -18,7 +18,7 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events.nip46 +package com.vitorpamplona.quartz.nip46RemoteSigner import java.util.UUID diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerRequestSign.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerRequestSign.kt similarity index 93% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerRequestSign.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerRequestSign.kt index 0f4d94012..e00c07af5 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerRequestSign.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerRequestSign.kt @@ -18,9 +18,9 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events.nip46 +package com.vitorpamplona.quartz.nip46RemoteSigner -import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.nip01Core.core.Event import java.util.UUID class BunkerRequestSign( diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerResponse.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerResponse.kt similarity index 89% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerResponse.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerResponse.kt index a25cf8755..b922e08e7 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerResponse.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerResponse.kt @@ -18,7 +18,7 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events.nip46 +package com.vitorpamplona.quartz.nip46RemoteSigner import com.fasterxml.jackson.core.JsonGenerator import com.fasterxml.jackson.core.JsonParser @@ -27,7 +27,7 @@ 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.ser.std.StdSerializer -import com.vitorpamplona.quartz.encoders.HexValidator +import com.vitorpamplona.quartz.crypto.Hex import com.vitorpamplona.quartz.utils.bytesUsedInMemory import com.vitorpamplona.quartz.utils.pointerSizeInBytes @@ -54,7 +54,8 @@ open class BunkerResponse( val error = jsonObject.get("error")?.asText() if (error != null) { - return BunkerResponseError.parse(id, result, error) + return com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponseError + .parse(id, result, error) } if (result != null) { @@ -62,13 +63,14 @@ open class BunkerResponse( BunkerResponseAck.RESULT -> return BunkerResponseAck.parse(id, result, error) BunkerResponsePong.RESULT -> return BunkerResponsePong.parse(id, result, error) else -> { - if (result.length == 64 && HexValidator.isHex(result)) { + if (result.length == 64 && Hex.isHex(result)) { return BunkerResponsePublicKey.parse(id, result) } if (result.get(0) == '{') { try { - return BunkerResponseEvent.parse(id, result) + return com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponseEvent + .parse(id, result) } catch (_: Exception) { } diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerResponseAck.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerResponseAck.kt similarity index 96% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerResponseAck.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerResponseAck.kt index 9d5e0edf2..686b85e8c 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerResponseAck.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerResponseAck.kt @@ -18,7 +18,7 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events.nip46 +package com.vitorpamplona.quartz.nip46RemoteSigner import java.util.UUID diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerResponseDecrypt.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerResponseDecrypt.kt similarity index 96% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerResponseDecrypt.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerResponseDecrypt.kt index 0cea12bbc..f3a3afcc4 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerResponseDecrypt.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerResponseDecrypt.kt @@ -18,7 +18,7 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events.nip46 +package com.vitorpamplona.quartz.nip46RemoteSigner import java.util.UUID diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerResponseEncrypt.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerResponseEncrypt.kt similarity index 96% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerResponseEncrypt.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerResponseEncrypt.kt index 1b9d2b3fc..3323627c6 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerResponseEncrypt.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerResponseEncrypt.kt @@ -18,7 +18,7 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events.nip46 +package com.vitorpamplona.quartz.nip46RemoteSigner import java.util.UUID diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerResponseError.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerResponseError.kt similarity index 85% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerResponseError.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerResponseError.kt index 97eb55c8b..a335e9041 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerResponseError.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerResponseError.kt @@ -18,19 +18,20 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events.nip46 +package com.vitorpamplona.quartz.nip46RemoteSigner import java.util.UUID class BunkerResponseError( id: String = UUID.randomUUID().toString(), error: String, -) : BunkerResponse(id, null, error) { +) : com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponse(id, null, error) { companion object { fun parse( id: String, result: String? = null, error: String, - ) = BunkerResponseError(id, error) + ) = com.vitorpamplona.quartz.nip46RemoteSigner + .BunkerResponseError(id, error) } } diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerResponseEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerResponseEvent.kt similarity index 81% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerResponseEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerResponseEvent.kt index de24f00d7..b59be9055 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerResponseEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerResponseEvent.kt @@ -18,20 +18,21 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events.nip46 +package com.vitorpamplona.quartz.nip46RemoteSigner -import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.nip01Core.core.Event import java.util.UUID class BunkerResponseEvent( id: String = UUID.randomUUID().toString(), val event: Event, -) : BunkerResponse(id, event.toJson(), null) { +) : com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponse(id, event.toJson(), null) { companion object { fun parse( id: String, result: String, error: String? = null, - ) = BunkerResponseEvent(id, Event.fromJson(result)) + ) = com.vitorpamplona.quartz.nip46RemoteSigner + .BunkerResponseEvent(id, Event.fromJson(result)) } } diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerResponseGetRelays.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerResponseGetRelays.kt similarity index 78% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerResponseGetRelays.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerResponseGetRelays.kt index adea55b72..50a507b11 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerResponseGetRelays.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerResponseGetRelays.kt @@ -18,22 +18,22 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events.nip46 +package com.vitorpamplona.quartz.nip46RemoteSigner import com.fasterxml.jackson.core.type.TypeReference -import com.vitorpamplona.quartz.events.ContactListEvent.ReadWrite -import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper +import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent.ReadWrite import java.util.UUID class BunkerResponseGetRelays( id: String = UUID.randomUUID().toString(), val relays: Map, -) : BunkerResponse(id, Event.mapper.writeValueAsString(relays), null) { +) : BunkerResponse(id, EventMapper.mapper.writeValueAsString(relays), null) { companion object { fun parse( id: String, result: String, error: String? = null, - ) = BunkerResponseGetRelays(id, Event.mapper.readValue(result, object : TypeReference>() {})) + ) = BunkerResponseGetRelays(id, EventMapper.mapper.readValue(result, object : TypeReference>() {})) } } diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerResponsePong.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerResponsePong.kt similarity index 96% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerResponsePong.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerResponsePong.kt index 70380a99f..1f1de7508 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerResponsePong.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerResponsePong.kt @@ -18,7 +18,7 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events.nip46 +package com.vitorpamplona.quartz.nip46RemoteSigner import java.util.UUID diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerResponsePublicKey.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerResponsePublicKey.kt similarity index 93% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerResponsePublicKey.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerResponsePublicKey.kt index 3794de71e..bbd4a9969 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/BunkerResponsePublicKey.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/BunkerResponsePublicKey.kt @@ -18,9 +18,9 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events.nip46 +package com.vitorpamplona.quartz.nip46RemoteSigner -import com.vitorpamplona.quartz.encoders.HexKey +import com.vitorpamplona.quartz.nip01Core.HexKey import java.util.UUID class BunkerResponsePublicKey( diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/NostrConnectEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/NostrConnectEvent.kt similarity index 63% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/NostrConnectEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/NostrConnectEvent.kt index a65e67a3b..751e03fb7 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/nip46/NostrConnectEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip46RemoteSigner/NostrConnectEvent.kt @@ -18,14 +18,14 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events.nip46 +package com.vitorpamplona.quartz.nip46RemoteSigner import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.Hex -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.HexValidator -import com.vitorpamplona.quartz.events.Event -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.crypto.Hex +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.utils.TimeUtils import com.vitorpamplona.quartz.utils.pointerSizeInBytes @@ -37,8 +37,16 @@ class NostrConnectEvent( tags: Array>, content: String, sig: HexKey, -) : Event(id, pubKey, createdAt, KIND, tags, content, sig) { - @Transient private var decryptedContent: Map = mapOf() +) : Event( + id, + pubKey, + createdAt, + com.vitorpamplona.quartz.nip46RemoteSigner.NostrConnectEvent.Companion.KIND, + tags, + content, + sig, + ) { + @Transient private var decryptedContent: Map = mapOf() override fun countMemory(): Long = super.countMemory() + @@ -52,7 +60,7 @@ class NostrConnectEvent( fun verifiedRecipientPubKey(): HexKey? { val recipient = recipientPubKey() - return if (HexValidator.isHex(recipient)) { + return if (Hex.isHex(recipient)) { recipient } else { null @@ -63,7 +71,7 @@ class NostrConnectEvent( fun plainContent( signer: NostrSigner, - onReady: (BunkerMessage) -> Unit, + onReady: (com.vitorpamplona.quartz.nip46RemoteSigner.BunkerMessage) -> Unit, ) { decryptedContent[signer.pubKey]?.let { onReady(it) @@ -72,7 +80,7 @@ class NostrConnectEvent( // decrypts using NIP-04 or NIP-44 signer.decrypt(content, talkingWith(signer.pubKey)) { retVal -> - val content = Event.mapper.readValue(retVal, BunkerMessage::class.java) + val content = EventMapper.mapper.readValue(retVal, com.vitorpamplona.quartz.nip46RemoteSigner.BunkerMessage::class.java) decryptedContent = decryptedContent + Pair(signer.pubKey, content) @@ -85,23 +93,35 @@ class NostrConnectEvent( const val ALT = "Nostr Connect Event" fun create( - message: BunkerMessage, + message: com.vitorpamplona.quartz.nip46RemoteSigner.BunkerMessage, remoteKey: HexKey, signer: NostrSigner, createdAt: Long = TimeUtils.now(), - onReady: (NostrConnectEvent) -> Unit, + onReady: (com.vitorpamplona.quartz.nip46RemoteSigner.NostrConnectEvent) -> Unit, ) { val tags = arrayOf( - arrayOf("alt", ALT), + arrayOf("alt", com.vitorpamplona.quartz.nip46RemoteSigner.NostrConnectEvent.Companion.ALT), arrayOf("p", remoteKey), ) - signer.sign(createdAt, KIND, tags, "", onReady) + signer.sign( + createdAt, + com.vitorpamplona.quartz.nip46RemoteSigner.NostrConnectEvent.Companion.KIND, + tags, + "", + onReady, + ) - val encrypted = mapper.writeValueAsString(message) + val encrypted = EventMapper.mapper.writeValueAsString(message) signer.nip44Encrypt(encrypted, remoteKey) { content -> - signer.sign(createdAt, KIND, tags, content, onReady) + signer.sign( + createdAt, + com.vitorpamplona.quartz.nip46RemoteSigner.NostrConnectEvent.Companion.KIND, + tags, + content, + onReady, + ) } } } diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/LnZapPaymentRequestEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip47WalletConnect/LnZapPaymentRequestEvent.kt similarity index 70% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/LnZapPaymentRequestEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip47WalletConnect/LnZapPaymentRequestEvent.kt index cd7ed54ff..08073ce4d 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/LnZapPaymentRequestEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip47WalletConnect/LnZapPaymentRequestEvent.kt @@ -18,16 +18,14 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip47WalletConnect import android.util.Log import androidx.compose.runtime.Immutable -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.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.utils.TimeUtils import com.vitorpamplona.quartz.utils.bytesUsedInMemory import com.vitorpamplona.quartz.utils.pointerSizeInBytes @@ -63,7 +61,7 @@ class LnZapPaymentRequestEvent( try { signer.decrypt(content, talkingWith(signer.pubKey)) { jsonText -> - val payInvoiceMethod = mapper.readValue(jsonText, Request::class.java) + val payInvoiceMethod = EventMapper.mapper.readValue(jsonText, Request::class.java) lnInvoice = (payInvoiceMethod as? PayInvoiceMethod)?.params?.invoice @@ -85,7 +83,7 @@ class LnZapPaymentRequestEvent( createdAt: Long = TimeUtils.now(), onReady: (LnZapPaymentRequestEvent) -> Unit, ) { - val serializedRequest = mapper.writeValueAsString(PayInvoiceMethod.create(lnInvoice)) + val serializedRequest = EventMapper.mapper.writeValueAsString(PayInvoiceMethod.create(lnInvoice)) val tags = arrayOf(arrayOf("p", walletServicePubkey), arrayOf("alt", ALT)) @@ -98,37 +96,3 @@ class LnZapPaymentRequestEvent( } } } - -// REQUEST OBJECTS - -abstract class Request( - var method: String? = null, -) - -// PayInvoice Call -class PayInvoiceParams( - var invoice: String? = null, -) - -class PayInvoiceMethod( - var params: PayInvoiceParams? = null, -) : Request("pay_invoice") { - companion object { - fun create(bolt11: String): PayInvoiceMethod = PayInvoiceMethod(PayInvoiceParams(bolt11)) - } -} - -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 jp.codec.treeToValue(jsonObject, PayInvoiceMethod::class.java) - } - return null - } -} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip47WalletConnect/LnZapPaymentResponseEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip47WalletConnect/LnZapPaymentResponseEvent.kt new file mode 100644 index 000000000..a033e25cc --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip47WalletConnect/LnZapPaymentResponseEvent.kt @@ -0,0 +1,89 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip47WalletConnect + +import android.util.Log +import androidx.compose.runtime.Immutable +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.utils.pointerSizeInBytes + +@Immutable +class LnZapPaymentResponseEvent( + id: HexKey, + pubKey: HexKey, + createdAt: Long, + tags: Array>, + content: String, + sig: HexKey, +) : Event(id, pubKey, createdAt, KIND, tags, content, sig) { + // Once one of an app user decrypts the payment, all users else can see it. + @Transient private var response: Response? = null + + override fun countMemory(): Long = super.countMemory() + pointerSizeInBytes + (response?.countMemory() ?: 0) + + fun requestAuthor() = tags.firstOrNull { it.size > 1 && it[0] == "p" }?.get(1) + + fun requestId() = tags.firstOrNull { it.size > 1 && it[0] == "e" }?.get(1) + + fun talkingWith(oneSideHex: String): HexKey = if (pubKey == oneSideHex) requestAuthor() ?: pubKey else pubKey + + private fun plainContent( + signer: NostrSigner, + onReady: (String) -> Unit, + ) { + try { + signer.decrypt(content, talkingWith(signer.pubKey)) { content -> onReady(content) } + } catch (e: Exception) { + Log.w("PrivateDM", "Error decrypting the message ${e.message}") + } + } + + fun response( + signer: NostrSigner, + onReady: (Response) -> Unit, + ) { + response?.let { + onReady(it) + return + } + + try { + if (content.isNotEmpty()) { + plainContent(signer) { + EventMapper.mapper.readValue(it, Response::class.java)?.let { + response = it + onReady(it) + } + } + } + } catch (e: Exception) { + Log.w("LnZapPaymentResponseEvent", "Can't parse content as a payment response: $content", e) + } + } + + companion object { + const val KIND = 23195 + const val ALT = "Zap payment response" + } +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/Nip47WalletConnect.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip47WalletConnect/Nip47WalletConnect.kt similarity index 91% rename from quartz/src/main/java/com/vitorpamplona/quartz/encoders/Nip47WalletConnect.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip47WalletConnect/Nip47WalletConnect.kt index 7916615f8..5197cd69f 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/Nip47WalletConnect.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip47WalletConnect/Nip47WalletConnect.kt @@ -18,9 +18,12 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.encoders +package com.vitorpamplona.quartz.nip47WalletConnect import android.net.Uri +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.toHexKey +import com.vitorpamplona.quartz.nip19Bech32Entities.decodePublicKey import kotlinx.coroutines.CancellationException // Rename to the corect nip number when ready. diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip47WalletConnect/Request.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip47WalletConnect/Request.kt new file mode 100644 index 000000000..afab8cb37 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip47WalletConnect/Request.kt @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip47WalletConnect + +// REQUEST OBJECTS +abstract class Request( + var method: String? = null, +) + +// PayInvoice Call +class PayInvoiceParams( + var invoice: String? = null, +) + +class PayInvoiceMethod( + var params: PayInvoiceParams? = null, +) : Request("pay_invoice") { + companion object { + fun create(bolt11: String): PayInvoiceMethod = PayInvoiceMethod(PayInvoiceParams(bolt11)) + } +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip47WalletConnect/RequestDeserializer.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip47WalletConnect/RequestDeserializer.kt new file mode 100644 index 000000000..a4d511f47 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip47WalletConnect/RequestDeserializer.kt @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip47WalletConnect + +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 + +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 jp.codec.treeToValue(jsonObject, PayInvoiceMethod::class.java) + } + return null + } +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip47WalletConnect/Response.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip47WalletConnect/Response.kt new file mode 100644 index 000000000..85c10c4b5 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip47WalletConnect/Response.kt @@ -0,0 +1,92 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip47WalletConnect + +import com.fasterxml.jackson.annotation.JsonProperty +import com.vitorpamplona.quartz.utils.bytesUsedInMemory +import com.vitorpamplona.quartz.utils.pointerSizeInBytes + +// RESPONSE OBJECTS +abstract class Response( + @JsonProperty("result_type") val resultType: String, +) { + abstract fun countMemory(): Long +} + +// PayInvoice Call + +class PayInvoiceSuccessResponse( + val result: PayInvoiceResultParams? = null, +) : Response("pay_invoice") { + class PayInvoiceResultParams( + val preimage: String, + ) { + fun countMemory(): Long = pointerSizeInBytes + preimage.bytesUsedInMemory() + } + + override fun countMemory(): Long = pointerSizeInBytes + (result?.countMemory() ?: 0) +} + +class PayInvoiceErrorResponse( + val error: PayInvoiceErrorParams? = null, +) : Response("pay_invoice") { + class PayInvoiceErrorParams( + val code: ErrorType?, + val message: String?, + ) { + fun countMemory(): Long = pointerSizeInBytes + pointerSizeInBytes + (message?.bytesUsedInMemory() ?: 0) + } + + override fun countMemory(): Long = pointerSizeInBytes + (error?.countMemory() ?: 0) + + enum class ErrorType { + @JsonProperty(value = "RATE_LIMITED") + RATE_LIMITED, + + // The client is sending commands too fast. It should retry in a few seconds. + @JsonProperty(value = "NOT_IMPLEMENTED") + NOT_IMPLEMENTED, + + // The command is not known or is intentionally not implemented. + @JsonProperty(value = "INSUFFICIENT_BALANCE") + INSUFFICIENT_BALANCE, + + // The wallet does not have enough funds to cover a fee reserve or the payment amount. + @JsonProperty(value = "QUOTA_EXCEEDED") + QUOTA_EXCEEDED, + + // The wallet has exceeded its spending quota. + @JsonProperty(value = "RESTRICTED") + RESTRICTED, + + // This public key is not allowed to do this operation. + @JsonProperty(value = "UNAUTHORIZED") + UNAUTHORIZED, + + // This public key has no wallet connected. + @JsonProperty(value = "INTERNAL") + INTERNAL, + + // An internal error. + @JsonProperty(value = "OTHER") + OTHER, // Other error. + } +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip47WalletConnect/ResponseDeserializer.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip47WalletConnect/ResponseDeserializer.kt new file mode 100644 index 000000000..2b53eef7b --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip47WalletConnect/ResponseDeserializer.kt @@ -0,0 +1,56 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip47WalletConnect + +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 + +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") + val error = jsonObject.get("error") + if (result != null) { + return jp.codec.treeToValue(jsonObject, PayInvoiceSuccessResponse::class.java) + } + if (error != null) { + return jp.codec.treeToValue(jsonObject, PayInvoiceErrorResponse::class.java) + } + } else { + // tries to guess + if (jsonObject.get("result")?.get("preimage") != null) { + return jp.codec.treeToValue(jsonObject, PayInvoiceSuccessResponse::class.java) + } + if (jsonObject.get("error")?.get("code") != null) { + return jp.codec.treeToValue(jsonObject, PayInvoiceErrorResponse::class.java) + } + } + return null + } +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip49/Nip49.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip49PrivKeyEnc/Nip49.kt similarity index 94% rename from quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip49/Nip49.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip49PrivKeyEnc/Nip49.kt index 70a19252b..f6671fc5c 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip49/Nip49.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip49PrivKeyEnc/Nip49.kt @@ -18,16 +18,16 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.crypto.nip49 +package com.vitorpamplona.quartz.nip49PrivKeyEnc import android.util.Log import com.goterl.lazysodium.LazySodiumAndroid import com.goterl.lazysodium.SodiumAndroid -import com.vitorpamplona.quartz.encoders.Bech32 -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.bechToBytes -import com.vitorpamplona.quartz.encoders.hexToByteArray -import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.hexToByteArray +import com.vitorpamplona.quartz.nip01Core.toHexKey +import com.vitorpamplona.quartz.nip19Bech32Entities.bech32.Bech32 +import com.vitorpamplona.quartz.nip19Bech32Entities.bech32.bechToBytes import fr.acinq.secp256k1.Secp256k1 import java.security.SecureRandom import java.text.Normalizer diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip49/PBKDF.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip49PrivKeyEnc/PBKDF.java similarity index 98% rename from quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip49/PBKDF.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip49PrivKeyEnc/PBKDF.java index 6b7adfacd..5c2300431 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip49/PBKDF.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip49PrivKeyEnc/PBKDF.java @@ -1,11 +1,13 @@ // Copyright (C) 2011 - Will Glozer. All rights reserved. -package com.vitorpamplona.quartz.crypto.nip49; +package com.vitorpamplona.quartz.nip49PrivKeyEnc; + +import static java.lang.System.arraycopy; + +import java.security.GeneralSecurityException; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; -import java.security.GeneralSecurityException; -import static java.lang.System.arraycopy; /** * An implementation of the Password-Based Key Derivation Function as specified diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip49/SCrypt.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip49PrivKeyEnc/SCrypt.java similarity index 99% rename from quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip49/SCrypt.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip49PrivKeyEnc/SCrypt.java index bd5c89610..c0b4ed236 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip49/SCrypt.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip49PrivKeyEnc/SCrypt.java @@ -1,13 +1,14 @@ // Copyright (C) 2011 - Will Glozer. All rights reserved. -package com.vitorpamplona.quartz.crypto.nip49; - -import javax.crypto.Mac; -import java.security.GeneralSecurityException; +package com.vitorpamplona.quartz.nip49PrivKeyEnc; import static java.lang.Integer.MAX_VALUE; import static java.lang.System.arraycopy; +import java.security.GeneralSecurityException; + +import javax.crypto.Mac; + /** * An implementation of the scrypt * key derivation function. This class will attempt to load a native library diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip49/SecretKeyOrEmptySpec.java b/quartz/src/main/java/com/vitorpamplona/quartz/nip49PrivKeyEnc/SecretKeyOrEmptySpec.java similarity index 98% rename from quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip49/SecretKeyOrEmptySpec.java rename to quartz/src/main/java/com/vitorpamplona/quartz/nip49PrivKeyEnc/SecretKeyOrEmptySpec.java index d4e347c28..5b6e83a8e 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip49/SecretKeyOrEmptySpec.java +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip49PrivKeyEnc/SecretKeyOrEmptySpec.java @@ -23,12 +23,14 @@ * questions. */ -package com.vitorpamplona.quartz.crypto.nip49; +package com.vitorpamplona.quartz.nip49PrivKeyEnc; import java.security.MessageDigest; import java.security.spec.KeySpec; import java.util.Locale; + import javax.crypto.SecretKey; +import javax.crypto.spec.DESKeySpec; /** * This class specifies a secret key in a provider-independent fashion. diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/SearchRelayListEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip50Search/SearchRelayListEvent.kt similarity index 91% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/SearchRelayListEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip50Search/SearchRelayListEvent.kt index 1c93aa251..757bda953 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/SearchRelayListEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip50Search/SearchRelayListEvent.kt @@ -18,13 +18,14 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip50Search import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner -import com.vitorpamplona.quartz.signers.NostrSignerSync +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.addressables.BaseAddressableEvent +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerSync import com.vitorpamplona.quartz.utils.TimeUtils @Immutable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/BookmarkListEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip51Lists/BookmarkListEvent.kt similarity index 97% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/BookmarkListEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip51Lists/BookmarkListEvent.kt index ccd2392be..ca81e54dc 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/BookmarkListEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip51Lists/BookmarkListEvent.kt @@ -18,12 +18,12 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip51Lists import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.utils.TimeUtils @Immutable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/GeneralListEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip51Lists/GeneralListEvent.kt similarity index 88% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/GeneralListEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip51Lists/GeneralListEvent.kt index b6e0adcfa..5d675fe61 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/GeneralListEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip51Lists/GeneralListEvent.kt @@ -18,15 +18,20 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip51Lists import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.core.isTagged +import com.vitorpamplona.quartz.nip01Core.events.taggedEvents +import com.vitorpamplona.quartz.nip01Core.geohash.geohashes +import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper +import com.vitorpamplona.quartz.nip01Core.people.taggedUsers +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip19Bech32Entities.parse import kotlinx.collections.immutable.ImmutableSet import kotlinx.collections.immutable.toImmutableSet -import java.util.HashSet @Immutable abstract class GeneralListEvent( @@ -76,7 +81,7 @@ abstract class GeneralListEvent( ) } } else { - onReady(isTagged(key, tag)) + onReady(tags.isTagged(key, tag)) } fun privateTagsOrEmpty( @@ -115,7 +120,7 @@ abstract class GeneralListEvent( fun filterHashtags(tags: Array>): List = tags.filter { it.size > 1 && it[0] == "t" }.map { it[1] } - fun filterGeohashes(tags: Array>): List = tags.filter { it.size > 1 && it[0] == "g" }.map { it[1] } + fun filterGeohashes(tags: Array>): List = tags.geohashes() fun filterEvents(tags: Array>): List = tags.filter { it.size > 1 && it[0] == "e" }.map { it[1] } @@ -150,7 +155,7 @@ abstract class GeneralListEvent( signer: NostrSigner, onReady: (String) -> Unit, ) { - val msg = mapper.writeValueAsString(privateTags) + val msg = EventMapper.mapper.writeValueAsString(privateTags) signer.nip04Encrypt( msg, diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/MuteListEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip51Lists/MuteListEvent.kt similarity index 98% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/MuteListEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip51Lists/MuteListEvent.kt index a945a9294..81b6b3b50 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/MuteListEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip51Lists/MuteListEvent.kt @@ -18,11 +18,11 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip51Lists import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.utils.TimeUtils import com.vitorpamplona.quartz.utils.bytesUsedInMemory import com.vitorpamplona.quartz.utils.pointerSizeInBytes diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/PeopleListEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip51Lists/PeopleListEvent.kt similarity index 98% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/PeopleListEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip51Lists/PeopleListEvent.kt index 066822565..10db84c0f 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/PeopleListEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip51Lists/PeopleListEvent.kt @@ -18,11 +18,11 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip51Lists import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.utils.TimeUtils import com.vitorpamplona.quartz.utils.bytesUsedInMemory import com.vitorpamplona.quartz.utils.pointerSizeInBytes diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/PinListEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip51Lists/PinListEvent.kt similarity index 89% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/PinListEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip51Lists/PinListEvent.kt index 185df6818..acd8b4a21 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/PinListEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip51Lists/PinListEvent.kt @@ -18,11 +18,12 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip51Lists import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.BaseAddressableEvent +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.utils.TimeUtils @Immutable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/PrivateTagArrayEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip51Lists/PrivateTagArrayEvent.kt similarity index 95% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/PrivateTagArrayEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip51Lists/PrivateTagArrayEvent.kt index 37532e39a..7da137940 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/PrivateTagArrayEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip51Lists/PrivateTagArrayEvent.kt @@ -18,17 +18,17 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip51Lists import android.util.Log import androidx.compose.runtime.Immutable import com.fasterxml.jackson.module.kotlin.readValue -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.BaseAddressableEvent +import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.utils.bytesUsedInMemory import com.vitorpamplona.quartz.utils.pointerSizeInBytes -import com.vitorpamplona.quartz.utils.remove -import com.vitorpamplona.quartz.utils.replaceAll @Immutable abstract class PrivateTagArrayEvent( @@ -66,7 +66,7 @@ abstract class PrivateTagArrayEvent( try { signer.decrypt(content, pubKey) { - privateTagsCache = mapper.readValue>>(it) + privateTagsCache = EventMapper.mapper.readValue>>(it) privateTagsCache?.let { onReady(it) } } } catch (e: Throwable) { @@ -263,7 +263,7 @@ abstract class PrivateTagArrayEvent( signer: NostrSigner, onReady: (String) -> Unit, ) = signer.nip04Encrypt( - if (privateTags.isNullOrEmpty()) "" else mapper.writeValueAsString(privateTags), + if (privateTags.isNullOrEmpty()) "" else EventMapper.mapper.writeValueAsString(privateTags), signer.pubKey, onReady, ) diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/RelaySetEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip51Lists/RelaySetEvent.kt similarity index 90% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/RelaySetEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip51Lists/RelaySetEvent.kt index a75dae2c9..604f5e9e5 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/RelaySetEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip51Lists/RelaySetEvent.kt @@ -18,11 +18,12 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip51Lists import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.BaseAddressableEvent +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.utils.TimeUtils @Immutable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip51Lists/TagArrayExt.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip51Lists/TagArrayExt.kt new file mode 100644 index 000000000..06ac817dd --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip51Lists/TagArrayExt.kt @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip51Lists + +import com.vitorpamplona.quartz.nip01Core.core.TagArray +import com.vitorpamplona.quartz.utils.startsWith + +inline fun TagArray.filterToArray(predicate: (Array) -> Boolean): TagArray = filterTo(ArrayList(), predicate).toTypedArray() + +inline fun TagArray.remove(predicate: (Array) -> Boolean): TagArray = filterNotTo(ArrayList(this.size), predicate).toTypedArray() + +inline fun TagArray.remove(startsWith: Array): TagArray = filterNotTo(ArrayList(this.size), { it.startsWith(startsWith) }).toTypedArray() + +inline fun TagArray.replaceAll( + startsWith: Array, + newElement: Array, +): TagArray = filterNotTo(ArrayList(this.size), { it.startsWith(startsWith) }).plusElement(newElement).toTypedArray() diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/CalendarDateSlotEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip52Calendar/CalendarDateSlotEvent.kt similarity index 81% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/CalendarDateSlotEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip52Calendar/CalendarDateSlotEvent.kt index 4adbf7908..900bc305a 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/CalendarDateSlotEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip52Calendar/CalendarDateSlotEvent.kt @@ -18,11 +18,13 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip52Calendar import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.BaseAddressableEvent +import com.vitorpamplona.quartz.nip01Core.core.firstTagValue +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -34,11 +36,11 @@ class CalendarDateSlotEvent( content: String, sig: HexKey, ) : BaseAddressableEvent(id, pubKey, createdAt, KIND, tags, content, sig) { - fun location() = tags.firstOrNull { it.size > 1 && it[0] == "location" }?.get(1) + fun location() = tags.firstTagValue("location") - fun start() = tags.firstOrNull { it.size > 1 && it[0] == "start" }?.get(1) + fun start() = tags.firstTagValue("start") - fun end() = tags.firstOrNull { it.size > 1 && it[0] == "end" }?.get(1) + fun end() = tags.firstTagValue("end") // ["start", ""], // ["end", ""], diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/CalendarEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip52Calendar/CalendarEvent.kt similarity index 88% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/CalendarEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip52Calendar/CalendarEvent.kt index 68095789c..c789748de 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/CalendarEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip52Calendar/CalendarEvent.kt @@ -18,11 +18,12 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip52Calendar import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.BaseAddressableEvent +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.utils.TimeUtils @Immutable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/CalendarRSVPEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip52Calendar/CalendarRSVPEvent.kt similarity index 82% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/CalendarRSVPEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip52Calendar/CalendarRSVPEvent.kt index fe83c6d5b..2524dd2df 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/CalendarRSVPEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip52Calendar/CalendarRSVPEvent.kt @@ -18,11 +18,13 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip52Calendar import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.BaseAddressableEvent +import com.vitorpamplona.quartz.nip01Core.core.firstTagValue +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -34,11 +36,11 @@ class CalendarRSVPEvent( content: String, sig: HexKey, ) : BaseAddressableEvent(id, pubKey, createdAt, KIND, tags, content, sig) { - fun status() = tags.firstOrNull { it.size > 1 && it[0] == "location" }?.get(1) + fun location() = tags.firstTagValue("location") - fun start() = tags.firstOrNull { it.size > 1 && it[0] == "start" }?.get(1) + fun start() = tags.firstTagValue("start") - fun end() = tags.firstOrNull { it.size > 1 && it[0] == "end" }?.get(1) + fun end() = tags.firstTagValue("end") // ["L", "status"], // ["l", "", "status"], diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/CalendarTimeSlotEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip52Calendar/CalendarTimeSlotEvent.kt similarity index 76% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/CalendarTimeSlotEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip52Calendar/CalendarTimeSlotEvent.kt index 4ecf31c4f..d72cae70d 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/CalendarTimeSlotEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip52Calendar/CalendarTimeSlotEvent.kt @@ -18,11 +18,14 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip52Calendar import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.BaseAddressableEvent +import com.vitorpamplona.quartz.nip01Core.core.firstTagValue +import com.vitorpamplona.quartz.nip01Core.core.firstTagValueAsLong +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -34,15 +37,15 @@ class CalendarTimeSlotEvent( content: String, sig: HexKey, ) : BaseAddressableEvent(id, pubKey, createdAt, KIND, tags, content, sig) { - fun location() = tags.firstOrNull { it.size > 1 && it[0] == "location" }?.get(1) + fun location() = tags.firstTagValue("location") - fun start() = tags.firstOrNull { it.size > 1 && it[0] == "start" }?.get(1)?.toLongOrNull() + fun start() = tags.firstTagValueAsLong("start") - fun end() = tags.firstOrNull { it.size > 1 && it[0] == "end" }?.get(1)?.toLongOrNull() + fun end() = tags.firstTagValueAsLong("end") - fun startTmz() = tags.firstOrNull { it.size > 1 && it[0] == "start_tzid" }?.get(1)?.toLongOrNull() + fun startTmz() = tags.firstTagValueAsLong("start_tzid") - fun endTmz() = tags.firstOrNull { it.size > 1 && it[0] == "end_tzid" }?.get(1)?.toLongOrNull() + fun endTmz() = tags.firstTagValueAsLong("end_tzid") // ["start", ""], // ["end", ""], diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/LiveActivitiesChatMessageEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip53LiveActivities/LiveActivitiesChatMessageEvent.kt similarity index 83% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/LiveActivitiesChatMessageEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip53LiveActivities/LiveActivitiesChatMessageEvent.kt index afee128cb..fc6952829 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/LiveActivitiesChatMessageEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip53LiveActivities/LiveActivitiesChatMessageEvent.kt @@ -18,14 +18,19 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip53LiveActivities import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.IMetaTag -import com.vitorpamplona.quartz.encoders.Nip92MediaAttachments -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.geohash.geohashMipMap +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip10Notes.BaseTextNoteEvent +import com.vitorpamplona.quartz.nip19Bech32Entities.parse +import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiUrl +import com.vitorpamplona.quartz.nip57Zaps.ZapSplitSetup +import com.vitorpamplona.quartz.nip92IMeta.IMetaTag +import com.vitorpamplona.quartz.nip92IMeta.Nip92MediaAttachments import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -41,15 +46,12 @@ class LiveActivitiesChatMessageEvent( tags.firstOrNull { it.size > 3 && it[0] == "a" && it[3] == "root" } ?: tags.firstOrNull { it.size > 1 && it[0] == "a" } - private fun activityHex() = innerActivity()?.let { it.getOrNull(1) } + private fun activityHex() = innerActivity()?.getOrNull(1) fun activity() = innerActivity()?.let { if (it.size > 1) { - val aTagValue = it[1] - val relay = it.getOrNull(2) - - ATag.parse(aTagValue, relay) + ATag.parse(it[1], it.getOrNull(2)) } else { null } diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/LiveActivitiesEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip53LiveActivities/LiveActivitiesEvent.kt similarity index 92% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/LiveActivitiesEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip53LiveActivities/LiveActivitiesEvent.kt index 564c94200..7755588c0 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/LiveActivitiesEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip53LiveActivities/LiveActivitiesEvent.kt @@ -18,11 +18,13 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip53LiveActivities import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.experimental.audio.Participant +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.BaseAddressableEvent +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.utils.TimeUtils @Immutable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/WikiNoteEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip54Wiki/WikiNoteEvent.kt similarity index 87% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/WikiNoteEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip54Wiki/WikiNoteEvent.kt index b6cc81eea..91ae637ce 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/WikiNoteEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip54Wiki/WikiNoteEvent.kt @@ -18,12 +18,15 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip54Wiki import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.addressables.AddressableEvent +import com.vitorpamplona.quartz.nip01Core.hashtags.hashtags +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip10Notes.BaseTextNoteEvent import com.vitorpamplona.quartz.utils.TimeUtils @Immutable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/signers/ExternalSignerLauncher.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip55AndroidSigner/ExternalSignerLauncher.kt similarity index 97% rename from quartz/src/main/java/com/vitorpamplona/quartz/signers/ExternalSignerLauncher.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip55AndroidSigner/ExternalSignerLauncher.kt index 61209c1bc..35f86d37c 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/signers/ExternalSignerLauncher.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip55AndroidSigner/ExternalSignerLauncher.kt @@ -18,7 +18,7 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.signers +package com.vitorpamplona.quartz.nip55AndroidSigner import android.content.ContentResolver import android.content.Intent @@ -34,9 +34,9 @@ import com.fasterxml.jackson.databind.deser.std.StdDeserializer import com.fasterxml.jackson.databind.module.SimpleModule import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import com.fasterxml.jackson.module.kotlin.readValue -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.events.EventInterface -import com.vitorpamplona.quartz.events.LnZapRequestEvent +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent enum class SignerType { SIGN_EVENT, @@ -240,12 +240,12 @@ class ExternalSignerLauncher( } fun openSigner( - event: EventInterface, + event: Event, onReady: (String) -> Unit, ) { getDataFromResolver( SignerType.SIGN_EVENT, - arrayOf(event.toJson(), event.pubKey()), + arrayOf(event.toJson(), event.pubKey), ).fold( onFailure = { }, onSuccess = { @@ -254,7 +254,7 @@ class ExternalSignerLauncher( event.toJson(), SignerType.SIGN_EVENT, "", - event.id(), + event.id, onReady, ) } else { diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/signers/NostrSignerExternal.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip55AndroidSigner/NostrSignerExternal.kt similarity index 92% rename from quartz/src/main/java/com/vitorpamplona/quartz/signers/NostrSignerExternal.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip55AndroidSigner/NostrSignerExternal.kt index 2124ed201..11b10f548 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/signers/NostrSignerExternal.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip55AndroidSigner/NostrSignerExternal.kt @@ -18,15 +18,16 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.signers +package com.vitorpamplona.quartz.nip55AndroidSigner import android.util.Log import com.goterl.lazysodium.BuildConfig -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.events.Event -import com.vitorpamplona.quartz.events.EventFactory -import com.vitorpamplona.quartz.events.LnZapPrivateEvent -import com.vitorpamplona.quartz.events.LnZapRequestEvent +import com.vitorpamplona.quartz.nip01Core.EventFactory +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip57Zaps.LnZapPrivateEvent +import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent class NostrSignerExternal( pubKey: HexKey, diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/ReportEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip56Reports/ReportEvent.kt similarity index 91% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/ReportEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip56Reports/ReportEvent.kt index 119b3d89b..0068a164d 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/ReportEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip56Reports/ReportEvent.kt @@ -18,11 +18,13 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip56Reports import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.AddressableEvent +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.utils.TimeUtils @Immutable data class ReportedKey( @@ -84,15 +86,15 @@ class ReportEvent( const val KIND = 1984 fun create( - reportedPost: EventInterface, + reportedPost: Event, type: ReportType, signer: NostrSigner, content: String = "", createdAt: Long = TimeUtils.now(), onReady: (ReportEvent) -> Unit, ) { - val reportPostTag = arrayOf("e", reportedPost.id(), type.name.lowercase()) - val reportAuthorTag = arrayOf("p", reportedPost.pubKey(), type.name.lowercase()) + val reportPostTag = arrayOf("e", reportedPost.id, type.name.lowercase()) + val reportAuthorTag = arrayOf("p", reportedPost.pubKey, type.name.lowercase()) var tags: Array> = arrayOf(reportPostTag, reportAuthorTag) diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip57Zaps/EventExt.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip57Zaps/EventExt.kt new file mode 100644 index 000000000..b0fcd5f14 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip57Zaps/EventExt.kt @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip57Zaps + +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.core.firstTagValueAsLong +import com.vitorpamplona.quartz.nip01Core.core.hasTagWithContent +import com.vitorpamplona.quartz.nip01Core.core.mapTagged + +fun Event.hasZapSplitSetup() = tags.hasTagWithContent("zap") + +fun Event.zapSplitSetup(): List = + tags.mapTagged("zap") { + val isLnAddress = it[0].contains("@") || it[0].startsWith("LNURL", true) + val weight = if (isLnAddress) 1.0 else (it.getOrNull(3)?.toDoubleOrNull() ?: 0.0) + + if (weight > 0) { + ZapSplitSetup( + it[1], + it.getOrNull(2), + weight, + isLnAddress, + ) + } else { + null + } + } + +fun Event.zapraiserAmount() = tags.firstTagValueAsLong("zapraiser") diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/LnZapEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip57Zaps/LnZapEvent.kt similarity index 92% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/LnZapEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip57Zaps/LnZapEvent.kt index 568fc4d87..016580a17 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/LnZapEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip57Zaps/LnZapEvent.kt @@ -18,12 +18,14 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip57Zaps import android.util.Log import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.LnInvoiceUtil +import com.vitorpamplona.quartz.experimental.zapPolls.POLL_OPTION +import com.vitorpamplona.quartz.lightning.LnInvoiceUtil +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.utils.pointerSizeInBytes @Immutable @@ -82,12 +84,10 @@ class LnZapEvent( null } - override fun zappedRequestAuthor(): String? = zapRequest?.pubKey() + override fun zappedRequestAuthor(): String? = zapRequest?.pubKey override fun amount() = amount - override fun content(): String = content - fun lnInvoice() = tags.firstOrNull { it.size > 1 && it[0] == "bolt11" }?.get(1) private fun description() = tags.firstOrNull { it.size > 1 && it[0] == "description" }?.get(1) diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/LnZapEventInterface.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip57Zaps/LnZapEventInterface.kt similarity index 91% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/LnZapEventInterface.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip57Zaps/LnZapEventInterface.kt index f7fce1fd2..9510d1464 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/LnZapEventInterface.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip57Zaps/LnZapEventInterface.kt @@ -18,13 +18,14 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip57Zaps import androidx.compose.runtime.Immutable +import com.vitorpamplona.quartz.nip01Core.core.Event import java.math.BigDecimal @Immutable -interface LnZapEventInterface : EventInterface { +interface LnZapEventInterface { fun zappedPost(): List fun zappedPollOption(): Int? diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/LnZapPrivateEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip57Zaps/LnZapPrivateEvent.kt similarity index 88% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/LnZapPrivateEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip57Zaps/LnZapPrivateEvent.kt index 7b3851448..bf95cad91 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/LnZapPrivateEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip57Zaps/LnZapPrivateEvent.kt @@ -18,12 +18,13 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip57Zaps import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner -import com.vitorpamplona.quartz.signers.NostrSignerSync +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerSync import com.vitorpamplona.quartz.utils.TimeUtils @Immutable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/LnZapRequestEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip57Zaps/LnZapRequestEvent.kt similarity index 60% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/LnZapRequestEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip57Zaps/LnZapRequestEvent.kt index ee3096b0e..c0004e6e2 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/LnZapRequestEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip57Zaps/LnZapRequestEvent.kt @@ -18,24 +18,20 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip57Zaps import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.crypto.CryptoUtils import com.vitorpamplona.quartz.crypto.KeyPair -import com.vitorpamplona.quartz.encoders.Bech32 -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.hexToByteArray -import com.vitorpamplona.quartz.signers.NostrSigner -import com.vitorpamplona.quartz.signers.NostrSignerInternal +import com.vitorpamplona.quartz.experimental.zapPolls.POLL_OPTION +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.AddressableEvent +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.core.mapValues +import com.vitorpamplona.quartz.nip01Core.hexToByteArray +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerInternal import com.vitorpamplona.quartz.utils.TimeUtils import com.vitorpamplona.quartz.utils.pointerSizeInBytes -import java.nio.charset.Charset -import java.security.SecureRandom -import javax.crypto.BadPaddingException -import javax.crypto.Cipher -import javax.crypto.spec.IvParameterSpec -import javax.crypto.spec.SecretKeySpec @Immutable class LnZapRequestEvent( @@ -50,9 +46,9 @@ class LnZapRequestEvent( override fun countMemory(): Long = super.countMemory() + pointerSizeInBytes + (privateZapEvent?.countMemory() ?: 0) - fun zappedPost() = tags.filter { it.size > 1 && it[0] == "e" }.map { it[1] } + fun zappedPost() = tags.mapValues("e") - fun zappedAuthor() = tags.filter { it.size > 1 && it[0] == "p" }.map { it[1] } + fun zappedAuthor() = tags.mapValues("p") fun isPrivateZap() = tags.any { t -> t.size >= 2 && t[0] == "anon" && t[1].isNotBlank() } @@ -65,7 +61,7 @@ class LnZapRequestEvent( val encnote = anonTag[1] if (encnote.isNotBlank()) { try { - val note = decryptPrivateZapMessage(encnote, loggedInUserPrivKey, pubKey.hexToByteArray()) + val note = PrivateZapEncryption.decryptPrivateZapMessage(encnote, loggedInUserPrivKey, pubKey.hexToByteArray()) val decryptedEvent = fromJson(note) if (decryptedEvent.kind == 9733) { return decryptedEvent as LnZapPrivateEvent @@ -101,7 +97,7 @@ class LnZapRequestEvent( const val ALT = "Zap request" fun create( - originalNote: EventInterface, + originalNote: Event, relays: Set, signer: NostrSigner, pollOption: Int?, @@ -115,8 +111,8 @@ class LnZapRequestEvent( var tags = listOf( - arrayOf("e", originalNote.id()), - arrayOf("p", toUserPubHex ?: originalNote.pubKey()), + arrayOf("e", originalNote.id), + arrayOf("p", toUserPubHex ?: originalNote.pubKey), arrayOf("relays") + relays, arrayOf("alt", ALT), ) @@ -165,72 +161,5 @@ class LnZapRequestEvent( signer.sign(createdAt, KIND, tags, message, onReady) } } - - fun createEncryptionPrivateKey( - privkey: String, - id: String, - createdAt: Long, - ): ByteArray { - val str = privkey + id + createdAt.toString() - val strbyte = str.toByteArray(Charset.forName("utf-8")) - return CryptoUtils.sha256(strbyte) - } - - fun encryptPrivateZapMessage( - msg: String, - privkey: ByteArray, - pubkey: ByteArray, - ): String { - val sharedSecret = CryptoUtils.getSharedSecretNIP04(privkey, pubkey) - val iv = ByteArray(16) - SecureRandom().nextBytes(iv) - - val keySpec = SecretKeySpec(sharedSecret, "AES") - val ivSpec = IvParameterSpec(iv) - - val utf8message = msg.toByteArray(Charset.forName("utf-8")) - val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding") - cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec) - val encryptedMsg = cipher.doFinal(utf8message) - - val encryptedMsgBech32 = - Bech32.encode("pzap", Bech32.eight2five(encryptedMsg), Bech32.Encoding.Bech32) - val ivBech32 = Bech32.encode("iv", Bech32.eight2five(iv), Bech32.Encoding.Bech32) - - return encryptedMsgBech32 + "_" + ivBech32 - } - - private fun decryptPrivateZapMessage( - msg: String, - privkey: ByteArray, - pubkey: ByteArray, - ): String { - val sharedSecret = CryptoUtils.getSharedSecretNIP04(privkey, pubkey) - if (sharedSecret.size != 16 && sharedSecret.size != 32) { - throw IllegalArgumentException("Invalid shared secret size") - } - val parts = msg.split("_") - if (parts.size != 2) { - throw IllegalArgumentException("Invalid message format") - } - val iv = parts[1].run { Bech32.decode(this).second } - 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), - ), - ) - - try { - val decryptedMsgBytes = cipher.doFinal(encryptedBytes) - return String(decryptedMsgBytes) - } catch (ex: BadPaddingException) { - throw IllegalArgumentException("Bad padding: ${ex.message}") - } - } } } diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip57Zaps/PrivateZapEncryption.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip57Zaps/PrivateZapEncryption.kt new file mode 100644 index 000000000..42317afb3 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip57Zaps/PrivateZapEncryption.kt @@ -0,0 +1,101 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip57Zaps + +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.nip19Bech32Entities.bech32.Bech32 +import java.nio.charset.Charset +import java.security.SecureRandom +import javax.crypto.BadPaddingException +import javax.crypto.Cipher +import javax.crypto.spec.IvParameterSpec +import javax.crypto.spec.SecretKeySpec + +class PrivateZapEncryption { + companion object { + fun createEncryptionPrivateKey( + privkey: String, + id: String, + createdAt: Long, + ): ByteArray { + val str = privkey + id + createdAt.toString() + val strbyte = str.toByteArray(Charset.forName("utf-8")) + return CryptoUtils.sha256(strbyte) + } + + fun encryptPrivateZapMessage( + msg: String, + privkey: ByteArray, + pubkey: ByteArray, + ): String { + val sharedSecret = CryptoUtils.getSharedSecretNIP04(privkey, pubkey) + val iv = ByteArray(16) + SecureRandom().nextBytes(iv) + + val keySpec = SecretKeySpec(sharedSecret, "AES") + val ivSpec = IvParameterSpec(iv) + + val utf8message = msg.toByteArray(Charset.forName("utf-8")) + val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding") + cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec) + val encryptedMsg = cipher.doFinal(utf8message) + + val encryptedMsgBech32 = + Bech32.encode("pzap", Bech32.eight2five(encryptedMsg), Bech32.Encoding.Bech32) + val ivBech32 = Bech32.encode("iv", Bech32.eight2five(iv), Bech32.Encoding.Bech32) + + return encryptedMsgBech32 + "_" + ivBech32 + } + + fun decryptPrivateZapMessage( + msg: String, + privkey: ByteArray, + pubkey: ByteArray, + ): String { + val sharedSecret = CryptoUtils.getSharedSecretNIP04(privkey, pubkey) + if (sharedSecret.size != 16 && sharedSecret.size != 32) { + throw IllegalArgumentException("Invalid shared secret size") + } + val parts = msg.split("_") + if (parts.size != 2) { + throw IllegalArgumentException("Invalid message format") + } + val iv = parts[1].run { Bech32.decode(this).second } + 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), + ), + ) + + try { + val decryptedMsgBytes = cipher.doFinal(encryptedBytes) + return String(decryptedMsgBytes) + } catch (ex: BadPaddingException) { + throw IllegalArgumentException("Bad padding: ${ex.message}") + } + } + } +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip57Zaps/ZapSplitSetup.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip57Zaps/ZapSplitSetup.kt new file mode 100644 index 000000000..cabb611a0 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip57Zaps/ZapSplitSetup.kt @@ -0,0 +1,28 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip57Zaps + +data class ZapSplitSetup( + val lnAddressOrPubKeyHex: String, + val relay: String?, + val weight: Double, + val isLnAddress: Boolean, +) diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/BadgeAwardEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip58Badges/BadgeAwardEvent.kt similarity index 84% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/BadgeAwardEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip58Badges/BadgeAwardEvent.kt index a4ebdb3d0..da70b1626 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/BadgeAwardEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip58Badges/BadgeAwardEvent.kt @@ -18,10 +18,13 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip58Badges import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.HexKey +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.taggedAddresses +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.people.taggedUsers @Immutable class BadgeAwardEvent( diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/BadgeDefinitionEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip58Badges/BadgeDefinitionEvent.kt similarity index 91% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/BadgeDefinitionEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip58Badges/BadgeDefinitionEvent.kt index 41d76d2d8..a84556073 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/BadgeDefinitionEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip58Badges/BadgeDefinitionEvent.kt @@ -18,10 +18,11 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip58Badges import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.HexKey +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.BaseAddressableEvent @Immutable class BadgeDefinitionEvent( diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/BadgeProfilesEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip58Badges/BadgeProfilesEvent.kt similarity index 83% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/BadgeProfilesEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip58Badges/BadgeProfilesEvent.kt index e939c5857..7219e2d9c 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/BadgeProfilesEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip58Badges/BadgeProfilesEvent.kt @@ -18,11 +18,14 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip58Badges import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.HexKey +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.addressables.BaseAddressableEvent +import com.vitorpamplona.quartz.nip01Core.addressables.taggedAddresses +import com.vitorpamplona.quartz.nip01Core.events.taggedEvents @Immutable class BadgeProfilesEvent( diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/GiftWrapEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip59Giftwrap/GiftWrapEvent.kt similarity index 88% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/GiftWrapEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip59Giftwrap/GiftWrapEvent.kt index 5cd3334eb..a72c74c5d 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/GiftWrapEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip59Giftwrap/GiftWrapEvent.kt @@ -18,14 +18,17 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip59Giftwrap import android.util.Log import androidx.compose.runtime.Immutable import com.vitorpamplona.quartz.crypto.KeyPair -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner -import com.vitorpamplona.quartz.signers.NostrSignerInternal +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.core.firstTagValue +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerInternal +import com.vitorpamplona.quartz.nip21UriScheme.toNostrUri import com.vitorpamplona.quartz.utils.TimeUtils import com.vitorpamplona.quartz.utils.bytesUsedInMemory import com.vitorpamplona.quartz.utils.pointerSizeInBytes @@ -108,7 +111,7 @@ class GiftWrapEvent( signer.nip44Decrypt(content, pubKey, onReady) } - fun recipientPubKey() = tags.firstOrNull { it.size > 1 && it[0] == "p" }?.get(1) + fun recipientPubKey() = tags.firstTagValue("p") companion object { const val KIND = 1059 @@ -121,7 +124,7 @@ class GiftWrapEvent( onReady: (GiftWrapEvent) -> Unit, ) { val signer = NostrSignerInternal(KeyPair()) // GiftWrap is always a random key - val serializedContent = toJson(event) + val serializedContent = event.toJson() val tags = arrayOf(arrayOf("p", recipientPubKey)) signer.nip44Encrypt(serializedContent, recipientPubKey) { content -> diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip59Giftwrap/Gossip.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip59Giftwrap/Gossip.kt new file mode 100644 index 000000000..ce0d99db3 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip59Giftwrap/Gossip.kt @@ -0,0 +1,56 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip59Giftwrap + +import com.fasterxml.jackson.annotation.JsonProperty +import com.vitorpamplona.quartz.nip01Core.EventFactory +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper + +class Gossip( + val id: HexKey?, + @JsonProperty("pubkey") val pubKey: HexKey?, + @JsonProperty("created_at") val createdAt: Long?, + val kind: Int?, + val tags: Array>?, + val content: String?, +) { + fun mergeWith(event: SealedGossipEvent): Event { + val newPubKey = event.pubKey // forces to be the pubkey of the seal to make sure impersonators don't impersonate + val newCreatedAt = if (createdAt != null && createdAt > 1000) createdAt else event.createdAt + val newKind = kind ?: -1 + val newTags = (tags ?: emptyArray()).plus(event.tags) + val newContent = content ?: "" + val newID = id?.ifBlank { null } ?: Event.generateId(newPubKey, newCreatedAt, newKind, newTags, newContent) + val sig = "" + + return EventFactory.create(newID, newPubKey, newCreatedAt, newKind, newTags, newContent, sig) + } + + companion object { + fun fromJson(json: String): Gossip = EventMapper.mapper.readValue(json, Gossip::class.java) + + fun toJson(event: Gossip): String = EventMapper.mapper.writeValueAsString(event) + + fun create(event: Event): Gossip = Gossip(event.id, event.pubKey, event.createdAt, event.kind, event.tags, event.content) + } +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip59Giftwrap/GossipDeserializer.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip59Giftwrap/GossipDeserializer.kt new file mode 100644 index 000000000..85667c468 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip59Giftwrap/GossipDeserializer.kt @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip59Giftwrap + +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.nip01Core.jackson.toTypedArray + +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")?.asText()?.intern(), + pubKey = jsonObject.get("pubkey")?.asText()?.intern(), + createdAt = jsonObject.get("created_at")?.asLong(), + kind = jsonObject.get("kind")?.asInt(), + tags = + jsonObject.get("tags").toTypedArray { + it.toTypedArray { s -> if (s.isNull) "" else s.asText().intern() } + }, + content = jsonObject.get("content")?.asText(), + ) + } +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip59Giftwrap/GossipSerializer.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip59Giftwrap/GossipSerializer.kt new file mode 100644 index 000000000..7ef8d6a70 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip59Giftwrap/GossipSerializer.kt @@ -0,0 +1,46 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip59Giftwrap + +import com.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.databind.SerializerProvider +import com.fasterxml.jackson.databind.ser.std.StdSerializer + +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, 0, tag.size) } + gen.writeEndArray() + } + event.content?.let { gen.writeStringField("content", it) } + gen.writeEndObject() + } +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip59Giftwrap/HostStub.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip59Giftwrap/HostStub.kt new file mode 100644 index 000000000..2cf83aa1b --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip59Giftwrap/HostStub.kt @@ -0,0 +1,29 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip59Giftwrap + +import com.vitorpamplona.quartz.nip01Core.HexKey + +class HostStub( + val id: HexKey, + val pubKey: HexKey, + val kind: Int, +) diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/SealedGossipEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip59Giftwrap/SealedGossipEvent.kt similarity index 74% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/SealedGossipEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip59Giftwrap/SealedGossipEvent.kt index 12dad5195..1479356c2 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/SealedGossipEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip59Giftwrap/SealedGossipEvent.kt @@ -18,13 +18,13 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip59Giftwrap import android.util.Log import androidx.compose.runtime.Immutable -import com.fasterxml.jackson.annotation.JsonProperty -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.utils.TimeUtils import com.vitorpamplona.quartz.utils.bytesUsedInMemory import com.vitorpamplona.quartz.utils.pointerSizeInBytes @@ -134,34 +134,3 @@ class SealedGossipEvent( } } } - -class Gossip( - val id: HexKey?, - @JsonProperty("pubkey") val pubKey: HexKey?, - @JsonProperty("created_at") val createdAt: Long?, - val kind: Int?, - val tags: Array>?, - val content: String?, -) { - fun mergeWith(event: SealedGossipEvent): Event { - val newPubKey = event.pubKey // forces to be the pubkey of the seal to make sure impersonators don't impersonate - val newCreatedAt = if (createdAt != null && createdAt > 1000) createdAt else event.createdAt - val newKind = kind ?: -1 - val newTags = (tags ?: emptyArray()).plus(event.tags) - val newContent = content ?: "" - val newID = - id?.ifBlank { null } - ?: Event.generateId(newPubKey, newCreatedAt, newKind, newTags, newContent) - val sig = "" - - 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 = Gossip(event.id, event.pubKey, event.createdAt, event.kind, event.tags, event.content) - } -} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip59Giftwrap/WrappedEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip59Giftwrap/WrappedEvent.kt new file mode 100644 index 000000000..1c653a447 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip59Giftwrap/WrappedEvent.kt @@ -0,0 +1,38 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip59Giftwrap + +import androidx.compose.runtime.Immutable +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event + +@Immutable +open class WrappedEvent( + id: HexKey, + pubKey: HexKey, + createdAt: Long, + kind: Int, + tags: Array>, + content: String, + sig: HexKey, +) : Event(id, pubKey, createdAt, kind, tags, content, sig) { + @Transient var host: HostStub? = null // host event to broadcast when needed +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/AdvertisedRelayListEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip65RelayList/AdvertisedRelayListEvent.kt similarity index 91% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/AdvertisedRelayListEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip65RelayList/AdvertisedRelayListEvent.kt index 614660fda..b7214a788 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/AdvertisedRelayListEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip65RelayList/AdvertisedRelayListEvent.kt @@ -18,13 +18,14 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip65RelayList import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner -import com.vitorpamplona.quartz.signers.NostrSignerSync +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.addressables.BaseAddressableEvent +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerSync import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -101,7 +102,7 @@ class AdvertisedRelayListEvent( earlierVersion.tags .filter { it[0] != "r" } .plus( - relays.map(::createRelayTag), + relays.map(Companion::createRelayTag), ).toTypedArray() signer.sign(createdAt, KIND, tags, earlierVersion.content, onReady) @@ -125,7 +126,7 @@ class AdvertisedRelayListEvent( fun createTagArray(relays: List): Array> = relays - .map(::createRelayTag) + .map(Companion::createRelayTag) .plusElement(arrayOf("alt", ALT)) .toTypedArray() diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/utils/RelayListRecommendationProcessor.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip65RelayList/RelayListRecommendationProcessor.kt similarity index 96% rename from quartz/src/main/java/com/vitorpamplona/quartz/utils/RelayListRecommendationProcessor.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip65RelayList/RelayListRecommendationProcessor.kt index fabf96931..2566987ef 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/utils/RelayListRecommendationProcessor.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip65RelayList/RelayListRecommendationProcessor.kt @@ -18,11 +18,9 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.utils +package com.vitorpamplona.quartz.nip65RelayList -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.RelayUrlFormatter -import com.vitorpamplona.quartz.events.AdvertisedRelayListEvent +import com.vitorpamplona.quartz.nip01Core.HexKey class RelayListRecommendationProcessor { companion object { @@ -62,11 +60,11 @@ class RelayListRecommendationProcessor { event.writeRelays().forEach { relayUrl -> if (!RelayUrlFormatter.isLocalHost(relayUrl) && (hasOnionConnection || !RelayUrlFormatter.isOnion(relayUrl))) { RelayUrlFormatter.normalizeOrNull(relayUrl)?.let { normRelayUrl -> - val set = validWriteRelayUrls[event.pubKey()] + val set = validWriteRelayUrls[event.pubKey] if (set != null) { set.add(normRelayUrl) } else { - validWriteRelayUrls[event.pubKey()] = mutableSetOf(normRelayUrl) + validWriteRelayUrls[event.pubKey] = mutableSetOf(normRelayUrl) } } } diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/RelayUrlFormatter.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip65RelayList/RelayUrlFormatter.kt similarity index 98% rename from quartz/src/main/java/com/vitorpamplona/quartz/encoders/RelayUrlFormatter.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip65RelayList/RelayUrlFormatter.kt index 3b5b92e62..aab438aaf 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/RelayUrlFormatter.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip65RelayList/RelayUrlFormatter.kt @@ -18,7 +18,7 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.encoders +package com.vitorpamplona.quartz.nip65RelayList import org.czeal.rfc3986.URIReference diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/PictureEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip68Picture/PictureEvent.kt similarity index 92% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/PictureEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip68Picture/PictureEvent.kt index 97ac47063..e6fcc5b83 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/PictureEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip68Picture/PictureEvent.kt @@ -18,16 +18,22 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip68Picture import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.Dimension -import com.vitorpamplona.quartz.encoders.ETag -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.Nip92MediaAttachments.Companion.IMETA -import com.vitorpamplona.quartz.encoders.PTag -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.geohash.geohashMipMap +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip10Notes.ETag +import com.vitorpamplona.quartz.nip10Notes.PTag +import com.vitorpamplona.quartz.nip10Notes.findHashtags +import com.vitorpamplona.quartz.nip10Notes.findURLs +import com.vitorpamplona.quartz.nip22Comments.RootScope +import com.vitorpamplona.quartz.nip57Zaps.ZapSplitSetup +import com.vitorpamplona.quartz.nip92IMeta.Nip92MediaAttachments.Companion.IMETA +import com.vitorpamplona.quartz.nip94FileMetadata.Dimension import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -250,7 +256,15 @@ class PictureMeta( val fallback = mutableListOf() val annotations = mutableListOf() - if (tagArray.size == 2 && tagArray[1].contains(URL) && (tagArray[1].contains(BLUR_HASH) || tagArray[1].contains(FILE_SIZE))) { + if (tagArray.size == 2 && + tagArray[1].contains(URL) && + ( + tagArray[1].contains(BLUR_HASH) || + tagArray[1].contains( + FILE_SIZE, + ) + ) + ) { // hack to fix pablo's bug val keys = setOf(URL, MIME_TYPE, BLUR_HASH, DIMENSION, ALT, HASH, FILE_SIZE, FALLBACK, ANNOTATIONS) var keyNextValue: String? = null diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/VideoEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip71Video/VideoEvent.kt similarity index 94% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/VideoEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip71Video/VideoEvent.kt index dab687808..053d584a6 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/VideoEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip71Video/VideoEvent.kt @@ -18,13 +18,16 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip71Video import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.Dimension -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.Nip92MediaAttachments.Companion.IMETA -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.BaseAddressableEvent +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip22Comments.RootScope +import com.vitorpamplona.quartz.nip92IMeta.Nip92MediaAttachments.Companion.IMETA +import com.vitorpamplona.quartz.nip94FileMetadata.Dimension +import com.vitorpamplona.quartz.nip94FileMetadata.FileHeaderEvent import com.vitorpamplona.quartz.utils.TimeUtils @Immutable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/VideoHorizontalEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip71Video/VideoHorizontalEvent.kt similarity index 91% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/VideoHorizontalEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip71Video/VideoHorizontalEvent.kt index f9a5c38dd..3b26329b0 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/VideoHorizontalEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip71Video/VideoHorizontalEvent.kt @@ -18,12 +18,13 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip71Video import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.Dimension -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip22Comments.RootScope +import com.vitorpamplona.quartz.nip94FileMetadata.Dimension import com.vitorpamplona.quartz.utils.TimeUtils import java.util.UUID diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/VideoVerticalEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip71Video/VideoVerticalEvent.kt similarity index 91% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/VideoVerticalEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip71Video/VideoVerticalEvent.kt index 5abc2a128..62c1771bd 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/VideoVerticalEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip71Video/VideoVerticalEvent.kt @@ -18,12 +18,13 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip71Video import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.Dimension -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip22Comments.RootScope +import com.vitorpamplona.quartz.nip94FileMetadata.Dimension import com.vitorpamplona.quartz.utils.TimeUtils import java.util.UUID diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/VideoViewEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip71Video/VideoViewEvent.kt similarity index 90% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/VideoViewEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip71Video/VideoViewEvent.kt index 2254924a2..119c78160 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/VideoViewEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip71Video/VideoViewEvent.kt @@ -18,12 +18,13 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip71Video import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.addressables.BaseAddressableEvent +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.utils.TimeUtils @Immutable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/CommunityDefinitionEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip72ModCommunities/CommunityDefinitionEvent.kt similarity index 88% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/CommunityDefinitionEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip72ModCommunities/CommunityDefinitionEvent.kt index 38a72b2a0..4251ce4a2 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/CommunityDefinitionEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip72ModCommunities/CommunityDefinitionEvent.kt @@ -18,11 +18,13 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip72ModCommunities import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.experimental.audio.Participant +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.BaseAddressableEvent +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.utils.TimeUtils @Immutable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/CommunityListEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip72ModCommunities/CommunityListEvent.kt similarity index 96% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/CommunityListEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip72ModCommunities/CommunityListEvent.kt index f8e0d3dae..d1a26062e 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/CommunityListEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip72ModCommunities/CommunityListEvent.kt @@ -18,12 +18,14 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip72ModCommunities import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip19Bech32Entities.parseAtag +import com.vitorpamplona.quartz.nip51Lists.GeneralListEvent import com.vitorpamplona.quartz.utils.TimeUtils import com.vitorpamplona.quartz.utils.pointerSizeInBytes import kotlinx.collections.immutable.ImmutableSet diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/CommunityPostApprovalEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip72ModCommunities/CommunityPostApprovalEvent.kt similarity index 87% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/CommunityPostApprovalEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip72ModCommunities/CommunityPostApprovalEvent.kt index 90ef3030b..e1a7b479c 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/CommunityPostApprovalEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip72ModCommunities/CommunityPostApprovalEvent.kt @@ -18,13 +18,15 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip72ModCommunities import android.util.Log import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip19Bech32Entities.parse import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -84,9 +86,9 @@ class CommunityPostApprovalEvent( val content = approvedPost.toJson() val communities = arrayOf("a", community.address().toTag()) - val replyToPost = arrayOf("e", approvedPost.id()) - val replyToAuthor = arrayOf("p", approvedPost.pubKey()) - val innerKind = arrayOf("k", "${approvedPost.kind()}") + val replyToPost = arrayOf("e", approvedPost.id) + val replyToAuthor = arrayOf("p", approvedPost.pubKey) + val innerKind = arrayOf("k", "${approvedPost.kind}") val alt = arrayOf("alt", ALT) val tags: Array> = diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/GoalEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip75ZapGoals/GoalEvent.kt similarity index 89% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/GoalEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip75ZapGoals/GoalEvent.kt index 1ee839c04..7ae869bc9 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/GoalEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip75ZapGoals/GoalEvent.kt @@ -18,11 +18,14 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip75ZapGoals import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.AddressableEvent +import com.vitorpamplona.quartz.nip01Core.addressables.BaseAddressableEvent +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.utils.TimeUtils @Immutable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/AppSpecificDataEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip78AppData/AppSpecificDataEvent.kt similarity index 89% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/AppSpecificDataEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip78AppData/AppSpecificDataEvent.kt index 59ce91c3c..3ea2141e5 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/AppSpecificDataEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip78AppData/AppSpecificDataEvent.kt @@ -18,11 +18,12 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip78AppData -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.addressables.BaseAddressableEvent +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.utils.TimeUtils class AppSpecificDataEvent( diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/HighlightEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip84Highlights/HighlightEvent.kt similarity index 75% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/HighlightEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip84Highlights/HighlightEvent.kt index 81d92b510..fd0db385a 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/HighlightEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip84Highlights/HighlightEvent.kt @@ -18,11 +18,17 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip84Highlights import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.firstTaggedAddress +import com.vitorpamplona.quartz.nip01Core.core.firstTagValue +import com.vitorpamplona.quartz.nip01Core.core.firstTagValueFor +import com.vitorpamplona.quartz.nip01Core.events.firstTaggedEvent +import com.vitorpamplona.quartz.nip01Core.people.firstTaggedUser +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip10Notes.BaseTextNoteEvent import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -34,13 +40,13 @@ class HighlightEvent( content: String, sig: HexKey, ) : BaseTextNoteEvent(id, pubKey, createdAt, KIND, tags, content, sig) { - fun inUrl() = firstTaggedUrl() + fun inUrl() = tags.firstTagValue("r") fun author() = firstTaggedUser() fun quote() = content - fun context() = firstTagFor("context") + fun context() = tags.firstTagValueFor("context") fun inPost() = firstTaggedAddress() diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip89AppHandlers/AppDefinitionEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip89AppHandlers/AppDefinitionEvent.kt new file mode 100644 index 000000000..28452da3d --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip89AppHandlers/AppDefinitionEvent.kt @@ -0,0 +1,93 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip89AppHandlers + +import android.util.Log +import androidx.compose.runtime.Immutable +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.UserMetadata +import com.vitorpamplona.quartz.nip01Core.addressables.BaseAddressableEvent +import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip21UriScheme.toNostrUri +import com.vitorpamplona.quartz.utils.TimeUtils +import java.io.ByteArrayInputStream + +@Immutable +class AppDefinitionEvent( + id: HexKey, + pubKey: HexKey, + createdAt: Long, + tags: Array>, + content: String, + sig: HexKey, +) : BaseAddressableEvent(id, pubKey, createdAt, KIND, tags, content, sig) { + override fun countMemory(): Long = super.countMemory() + (cachedMetadata?.countMemory() ?: 8L) + + @Transient private var cachedMetadata: AppMetadata? = null + + fun appMetaData() = + if (cachedMetadata != null) { + cachedMetadata + } else { + try { + val newMetadata = + EventMapper.mapper.readValue( + ByteArrayInputStream(content.toByteArray(Charsets.UTF_8)), + AppMetadata::class.java, + ) + + cachedMetadata = newMetadata + + newMetadata + } catch (e: Exception) { + e.printStackTrace() + Log.w("AppDefinitionEvent", "Content Parse Error: ${toNostrUri()} ${e.localizedMessage}") + null + } + } + + fun supportedKinds() = + tags + .filter { it.size > 1 && it[0] == "k" } + .mapNotNull { runCatching { it[1].toInt() }.getOrNull() } + + fun includeKind(kind: String) = tags.any { it.size > 1 && it[0] == "k" && it[1] == kind } + + fun publishedAt() = tags.firstOrNull { it.size > 1 && it[0] == "published_at" }?.get(1) + + companion object { + const val KIND = 31990 + + fun create( + details: UserMetadata, + signer: NostrSigner, + createdAt: Long = TimeUtils.now(), + onReady: (AppDefinitionEvent) -> Unit, + ) { + val tags = + arrayOf( + arrayOf("alt", "App definition event for ${details.name}"), + ) + signer.sign(createdAt, KIND, tags, "", onReady) + } + } +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/AppDefinitionEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip89AppHandlers/AppMetadata.kt similarity index 69% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/AppDefinitionEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip89AppHandlers/AppMetadata.kt index cce5b9fb5..d57d5825e 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/AppDefinitionEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip89AppHandlers/AppMetadata.kt @@ -18,18 +18,13 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip89AppHandlers -import android.util.Log -import androidx.compose.runtime.Immutable import androidx.compose.runtime.Stable import com.fasterxml.jackson.annotation.JsonProperty -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner -import com.vitorpamplona.quartz.utils.TimeUtils +import com.vitorpamplona.quartz.nip02FollowList.ImmutableListOfLists import com.vitorpamplona.quartz.utils.bytesUsedInMemory import com.vitorpamplona.quartz.utils.pointerSizeInBytes -import java.io.ByteArrayInputStream @Stable class AppMetadata { @@ -122,64 +117,3 @@ class AppMetadata { if (domain?.isBlank() == true) domain = null } } - -@Immutable -class AppDefinitionEvent( - id: HexKey, - pubKey: HexKey, - createdAt: Long, - tags: Array>, - content: String, - sig: HexKey, -) : BaseAddressableEvent(id, pubKey, createdAt, KIND, tags, content, sig) { - override fun countMemory(): Long = super.countMemory() + (cachedMetadata?.countMemory() ?: 8L) - - @Transient private var cachedMetadata: AppMetadata? = null - - fun appMetaData() = - if (cachedMetadata != null) { - cachedMetadata - } else { - try { - val newMetadata = - mapper.readValue( - ByteArrayInputStream(content.toByteArray(Charsets.UTF_8)), - AppMetadata::class.java, - ) - - cachedMetadata = newMetadata - - newMetadata - } catch (e: Exception) { - e.printStackTrace() - Log.w("AppDefinitionEvent", "Content Parse Error: ${toNostrUri()} ${e.localizedMessage}") - null - } - } - - fun supportedKinds() = - tags - .filter { it.size > 1 && it[0] == "k" } - .mapNotNull { runCatching { it[1].toInt() }.getOrNull() } - - fun includeKind(kind: String) = tags.any { it.size > 1 && it[0] == "k" && it[1] == kind } - - fun publishedAt() = tags.firstOrNull { it.size > 1 && it[0] == "published_at" }?.get(1) - - companion object { - const val KIND = 31990 - - fun create( - details: UserMetadata, - signer: NostrSigner, - createdAt: Long = TimeUtils.now(), - onReady: (AppDefinitionEvent) -> Unit, - ) { - val tags = - arrayOf( - arrayOf("alt", "App definition event for ${details.name}"), - ) - signer.sign(createdAt, KIND, tags, "", onReady) - } - } -} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/AppRecommendationEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip89AppHandlers/AppRecommendationEvent.kt similarity index 85% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/AppRecommendationEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip89AppHandlers/AppRecommendationEvent.kt index 6bc49b09d..0539f1aea 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/AppRecommendationEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip89AppHandlers/AppRecommendationEvent.kt @@ -18,12 +18,14 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip89AppHandlers import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.addressables.BaseAddressableEvent +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip19Bech32Entities.parse import com.vitorpamplona.quartz.utils.TimeUtils @Immutable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/NIP90ContentDiscoveryRequestEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip90Dvms/NIP90ContentDiscoveryRequestEvent.kt similarity index 91% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/NIP90ContentDiscoveryRequestEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip90Dvms/NIP90ContentDiscoveryRequestEvent.kt index b3bfd70a8..95b75a3a7 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/NIP90ContentDiscoveryRequestEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip90Dvms/NIP90ContentDiscoveryRequestEvent.kt @@ -18,12 +18,13 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip90Dvms import androidx.compose.runtime.Immutable import androidx.compose.runtime.Stable -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.utils.TimeUtils @Stable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/NIP90ContentDiscoveryResponseEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip90Dvms/NIP90ContentDiscoveryResponseEvent.kt similarity index 86% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/NIP90ContentDiscoveryResponseEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip90Dvms/NIP90ContentDiscoveryResponseEvent.kt index a2c1feb72..7e44fa3ed 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/NIP90ContentDiscoveryResponseEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip90Dvms/NIP90ContentDiscoveryResponseEvent.kt @@ -18,13 +18,16 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip90Dvms import android.util.Log import androidx.compose.runtime.Immutable import com.fasterxml.jackson.module.kotlin.readValue -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip89AppHandlers.AppRecommendationEvent import com.vitorpamplona.quartz.utils.TimeUtils import com.vitorpamplona.quartz.utils.bytesUsedInMemory import com.vitorpamplona.quartz.utils.pointerSizeInBytes @@ -55,7 +58,7 @@ class NIP90ContentDiscoveryResponseEvent( try { events = - mapper.readValue>>(content).mapNotNull { + EventMapper.mapper.readValue>>(content).mapNotNull { if (it.size > 1 && it[0] == "e") { it[1] } else { diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/NIP90StatusEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip90Dvms/NIP90StatusEvent.kt similarity index 91% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/NIP90StatusEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip90Dvms/NIP90StatusEvent.kt index a6cf48deb..f21ac8c6b 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/NIP90StatusEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip90Dvms/NIP90StatusEvent.kt @@ -18,11 +18,13 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip90Dvms import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip89AppHandlers.AppRecommendationEvent import com.vitorpamplona.quartz.utils.TimeUtils @Immutable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/NIP90UserDiscoveryRequestEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip90Dvms/NIP90UserDiscoveryRequestEvent.kt similarity index 87% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/NIP90UserDiscoveryRequestEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip90Dvms/NIP90UserDiscoveryRequestEvent.kt index 493cbf407..ec721fa7a 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/NIP90UserDiscoveryRequestEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip90Dvms/NIP90UserDiscoveryRequestEvent.kt @@ -18,11 +18,13 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip90Dvms import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip89AppHandlers.AppRecommendationEvent import com.vitorpamplona.quartz.utils.TimeUtils @Immutable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/NIP90UserDiscoveryResponseEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip90Dvms/NIP90UserDiscoveryResponseEvent.kt similarity index 87% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/NIP90UserDiscoveryResponseEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip90Dvms/NIP90UserDiscoveryResponseEvent.kt index f1978ca97..313793af1 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/NIP90UserDiscoveryResponseEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip90Dvms/NIP90UserDiscoveryResponseEvent.kt @@ -18,11 +18,13 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip90Dvms import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip89AppHandlers.AppRecommendationEvent import com.vitorpamplona.quartz.utils.TimeUtils @Immutable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip92IMeta/IMetaTag.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip92IMeta/IMetaTag.kt new file mode 100644 index 000000000..1c4ae17fc --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip92IMeta/IMetaTag.kt @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip92IMeta + +class IMetaTag( + val url: String, + val properties: Map, +) diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip92IMeta/IMetaTagBuilder.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip92IMeta/IMetaTagBuilder.kt new file mode 100644 index 000000000..6ce51c0bf --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip92IMeta/IMetaTagBuilder.kt @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip92IMeta + +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip94FileMetadata.Dimension +import com.vitorpamplona.quartz.nip94FileMetadata.FileHeaderEvent.Companion.ALT +import com.vitorpamplona.quartz.nip94FileMetadata.FileHeaderEvent.Companion.BLUR_HASH +import com.vitorpamplona.quartz.nip94FileMetadata.FileHeaderEvent.Companion.DIMENSION +import com.vitorpamplona.quartz.nip94FileMetadata.FileHeaderEvent.Companion.FILE_SIZE +import com.vitorpamplona.quartz.nip94FileMetadata.FileHeaderEvent.Companion.HASH +import com.vitorpamplona.quartz.nip94FileMetadata.FileHeaderEvent.Companion.MAGNET_URI +import com.vitorpamplona.quartz.nip94FileMetadata.FileHeaderEvent.Companion.MIME_TYPE +import com.vitorpamplona.quartz.nip94FileMetadata.FileHeaderEvent.Companion.ORIGINAL_HASH +import com.vitorpamplona.quartz.nip94FileMetadata.FileHeaderEvent.Companion.TORRENT_INFOHASH + +class IMetaTagBuilder( + val url: String, +) { + val properties = mutableMapOf() + + fun add( + key: String, + value: String, + ): IMetaTagBuilder { + properties.set(key, value) + return this + } + + fun magnet(uri: String) = add(MAGNET_URI, uri) + + fun mimeType(mime: String) = add(MIME_TYPE, mime) + + fun alt(alt: String) = add(ALT, alt) + + fun hash(hash: HexKey) = add(HASH, hash) + + fun size(size: Int) = add(FILE_SIZE, size.toString()) + + fun dims(dims: Dimension) = add(DIMENSION, dims.toString()) + + fun blurhash(blurhash: String) = add(BLUR_HASH, blurhash) + + fun originalHash(originalHash: String) = add(ORIGINAL_HASH, originalHash) + + fun torrent(uri: String) = add(TORRENT_INFOHASH, uri) + + fun sensitiveContent(reason: String) = add("content-warning", reason) + + fun build() = IMetaTag(url, properties) +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/Nip92MediaAttachments.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip92IMeta/Nip92MediaAttachments.kt similarity index 62% rename from quartz/src/main/java/com/vitorpamplona/quartz/encoders/Nip92MediaAttachments.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip92IMeta/Nip92MediaAttachments.kt index 52a13e456..821091951 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/Nip92MediaAttachments.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip92IMeta/Nip92MediaAttachments.kt @@ -18,58 +18,7 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.encoders - -import com.vitorpamplona.quartz.events.FileHeaderEvent.Companion.ALT -import com.vitorpamplona.quartz.events.FileHeaderEvent.Companion.BLUR_HASH -import com.vitorpamplona.quartz.events.FileHeaderEvent.Companion.DIMENSION -import com.vitorpamplona.quartz.events.FileHeaderEvent.Companion.FILE_SIZE -import com.vitorpamplona.quartz.events.FileHeaderEvent.Companion.HASH -import com.vitorpamplona.quartz.events.FileHeaderEvent.Companion.MAGNET_URI -import com.vitorpamplona.quartz.events.FileHeaderEvent.Companion.MIME_TYPE -import com.vitorpamplona.quartz.events.FileHeaderEvent.Companion.ORIGINAL_HASH -import com.vitorpamplona.quartz.events.FileHeaderEvent.Companion.TORRENT_INFOHASH - -class IMetaTag( - val url: String, - val properties: Map, -) - -class IMetaTagBuilder( - val url: String, -) { - val properties = mutableMapOf() - - fun add( - key: String, - value: String, - ): IMetaTagBuilder { - properties.set(key, value) - return this - } - - fun magnet(uri: String) = add(MAGNET_URI, uri) - - fun mimeType(mime: String) = add(MIME_TYPE, mime) - - fun alt(alt: String) = add(ALT, alt) - - fun hash(hash: HexKey) = add(HASH, hash) - - fun size(size: Int) = add(FILE_SIZE, size.toString()) - - fun dims(dims: Dimension) = add(DIMENSION, dims.toString()) - - fun blurhash(blurhash: String) = add(BLUR_HASH, blurhash) - - fun originalHash(originalHash: String) = add(ORIGINAL_HASH, originalHash) - - fun torrent(uri: String) = add(TORRENT_INFOHASH, uri) - - fun sensitiveContent(reason: String) = add("content-warning", reason) - - fun build() = IMetaTag(url, properties) -} +package com.vitorpamplona.quartz.nip92IMeta class Nip92MediaAttachments { companion object { diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/Dimension.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip94FileMetadata/Dimension.kt similarity index 97% rename from quartz/src/main/java/com/vitorpamplona/quartz/encoders/Dimension.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip94FileMetadata/Dimension.kt index 99bcbb980..3936ba330 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/Dimension.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip94FileMetadata/Dimension.kt @@ -18,7 +18,7 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.encoders +package com.vitorpamplona.quartz.nip94FileMetadata class Dimension( val width: Int, diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/FileHeaderEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip94FileMetadata/FileHeaderEvent.kt similarity index 96% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/FileHeaderEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip94FileMetadata/FileHeaderEvent.kt index ef136101a..65625a125 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/FileHeaderEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip94FileMetadata/FileHeaderEvent.kt @@ -18,12 +18,12 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip94FileMetadata import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.Dimension -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.utils.TimeUtils @Immutable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/FileServersEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip96FileStorage/FileServersEvent.kt similarity index 92% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/FileServersEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip96FileStorage/FileServersEvent.kt index 02cbc8e8c..a62894d22 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/FileServersEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip96FileStorage/FileServersEvent.kt @@ -18,12 +18,13 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip96FileStorage import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.addressables.BaseAddressableEvent +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.utils.TimeUtils @Immutable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/HttpUrlFormatter.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip96FileStorage/HttpUrlFormatter.kt similarity index 98% rename from quartz/src/main/java/com/vitorpamplona/quartz/encoders/HttpUrlFormatter.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip96FileStorage/HttpUrlFormatter.kt index 2e378683b..72671a3d7 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/HttpUrlFormatter.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip96FileStorage/HttpUrlFormatter.kt @@ -18,7 +18,7 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.encoders +package com.vitorpamplona.quartz.nip96FileStorage import org.czeal.rfc3986.URIReference diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/HTTPAuthorizationEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip98HttpAuth/HTTPAuthorizationEvent.kt similarity index 89% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/HTTPAuthorizationEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip98HttpAuth/HTTPAuthorizationEvent.kt index c51470ecd..c2aff2165 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/HTTPAuthorizationEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip98HttpAuth/HTTPAuthorizationEvent.kt @@ -18,13 +18,14 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip98HttpAuth import androidx.compose.runtime.Immutable import com.vitorpamplona.quartz.crypto.CryptoUtils -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.toHexKey -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.toHexKey import com.vitorpamplona.quartz.utils.TimeUtils @Immutable diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/ClassifiedsEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip99Classifieds/ClassifiedsEvent.kt similarity index 90% rename from quartz/src/main/java/com/vitorpamplona/quartz/events/ClassifiedsEvent.kt rename to quartz/src/main/java/com/vitorpamplona/quartz/nip99Classifieds/ClassifiedsEvent.kt index b9c4522a9..a6ff2bdf7 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/ClassifiedsEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip99Classifieds/ClassifiedsEvent.kt @@ -18,14 +18,20 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.events +package com.vitorpamplona.quartz.nip99Classifieds import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.encoders.ATag -import com.vitorpamplona.quartz.encoders.HexKey -import com.vitorpamplona.quartz.encoders.IMetaTag -import com.vitorpamplona.quartz.encoders.Nip92MediaAttachments -import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.HexKey +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.addressables.BaseAddressableEvent +import com.vitorpamplona.quartz.nip01Core.geohash.geohashMipMap +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip10Notes.findHashtags +import com.vitorpamplona.quartz.nip10Notes.findURLs +import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiUrl +import com.vitorpamplona.quartz.nip57Zaps.ZapSplitSetup +import com.vitorpamplona.quartz.nip92IMeta.IMetaTag +import com.vitorpamplona.quartz.nip92IMeta.Nip92MediaAttachments import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -104,7 +110,7 @@ class ClassifiedsEvent( price: Price?, location: String?, category: String?, - condition: ClassifiedsEvent.CONDITION?, + condition: CONDITION?, publishedAt: Long? = TimeUtils.now(), replyTos: List?, addresses: List?, @@ -203,9 +209,3 @@ class ClassifiedsEvent( } } } - -data class Price( - val amount: String, - val currency: String?, - val frequency: String?, -) diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip99Classifieds/Price.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip99Classifieds/Price.kt new file mode 100644 index 000000000..1c899002a --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip99Classifieds/Price.kt @@ -0,0 +1,27 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip99Classifieds + +data class Price( + val amount: String, + val currency: String?, + val frequency: String?, +) diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/ots/ICalendar.java b/quartz/src/main/java/com/vitorpamplona/quartz/ots/ICalendar.java deleted file mode 100644 index 5f04fa40b..000000000 --- a/quartz/src/main/java/com/vitorpamplona/quartz/ots/ICalendar.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.vitorpamplona.quartz.ots; - -import com.vitorpamplona.quartz.ots.exceptions.CommitmentNotFoundException; -import com.vitorpamplona.quartz.ots.exceptions.DeserializationException; -import com.vitorpamplona.quartz.ots.exceptions.ExceededSizeException; -import com.vitorpamplona.quartz.ots.exceptions.UrlException; - -public interface ICalendar { - Timestamp submit(byte[] digest) - throws ExceededSizeException, UrlException, DeserializationException; - - Timestamp getTimestamp(byte[] commitment) throws DeserializationException, ExceededSizeException, CommitmentNotFoundException, UrlException; -} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/utils/ArrayUtils.kt b/quartz/src/main/java/com/vitorpamplona/quartz/utils/ArrayUtils.kt index 3def1d85c..bba5bbfb4 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/utils/ArrayUtils.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/utils/ArrayUtils.kt @@ -37,14 +37,3 @@ fun Array.startsWith(startsWith: Array): Boolean { } return true } - -inline fun Array>.filterToArray(predicate: (Array) -> Boolean): Array> = filterTo(ArrayList(), predicate).toTypedArray() - -inline fun Array>.remove(predicate: (Array) -> Boolean): Array> = filterNotTo(ArrayList(this.size), predicate).toTypedArray() - -inline fun Array>.remove(startsWith: Array): Array> = filterNotTo(ArrayList(this.size), { it.startsWith(startsWith) }).toTypedArray() - -inline fun Array>.replaceAll( - startsWith: Array, - newElement: Array, -): Array> = filterNotTo(ArrayList(this.size), { it.startsWith(startsWith) }).plusElement(newElement).toTypedArray() diff --git a/quartz/src/test/java/com/vitorpamplona/quartz/encoders/Nip19Bech32Test.kt b/quartz/src/test/java/com/vitorpamplona/quartz/encoders/Nip19Bech32Test.kt deleted file mode 100644 index 5c9a0ecf6..000000000 --- a/quartz/src/test/java/com/vitorpamplona/quartz/encoders/Nip19Bech32Test.kt +++ /dev/null @@ -1,127 +0,0 @@ -/** - * Copyright (c) 2024 Vitor Pamplona - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the - * Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -package com.vitorpamplona.quartz.encoders - -import org.junit.Assert -import org.junit.Assert.assertNotNull -import org.junit.Test - -class Nip19Bech32Test { - @Test() - fun uri_to_route_null() { - val actual = Nip19Bech32.uriToRoute(null) - - Assert.assertEquals(null, actual) - } - - @Test() - fun uri_to_route_unknown() { - val actual = Nip19Bech32.uriToRoute("nostr:unknown") - - Assert.assertEquals(null, actual) - } - - @Test() - fun uri_to_route_npub() { - val actual = - Nip19Bech32.uriToRoute("nostr:npub1hv7k2s755n697sptva8vkh9jz40lzfzklnwj6ekewfmxp5crwdjs27007y") - - Assert.assertTrue(actual?.entity is Nip19Bech32.NPub) - Assert.assertEquals( - "bb3d6543d4a4f45f402b674ecb5cb2155ff12456fcdd2d66d9727660d3037365", - (actual?.entity as? Nip19Bech32.NPub)?.hex, - ) - } - - @Test() - fun uri_to_route_note() { - val result = - Nip19Bech32.uriToRoute("nostr:note1stqea6wmwezg9x6yyr6qkukw95ewtdukyaztycws65l8wppjmtpscawevv")?.entity as? Nip19Bech32.Note - - assertNotNull(result) - Assert.assertEquals( - "82c19ee9db7644829b4420f40b72ce2d32e5b7962744b261d0d53e770432dac3", - result?.hex, - ) - } - - @Test() - fun uri_to_route_nprofile() { - val actual = Nip19Bech32.uriToRoute("nostr:nprofile") - - Assert.assertEquals(null, actual) - } - - @Test() - fun uri_to_route_incomplete_nevent() { - val actual = Nip19Bech32.uriToRoute("nostr:nevent") - - Assert.assertEquals(null, actual) - } - - @Test() - fun uri_to_route_incomplete_nrelay() { - val actual = Nip19Bech32.uriToRoute("nostr:nrelay") - - Assert.assertEquals(null, actual) - } - - @Test() - fun uri_to_route_incomplete_naddr() { - val actual = Nip19Bech32.uriToRoute("nostr:naddr") - - Assert.assertEquals(null, actual) - } - - @Test() - fun uri_to_route_complete_nprofile_2() { - val actual = Nip19Bech32.uriToRoute("nostr:nprofile1qqsyvrp9u6p0mfur9dfdru3d853tx9mdjuhkphxuxgfwmryja7zsvhqpzamhxue69uhhv6t5daezumn0wd68yvfwvdhk6tcpz9mhxue69uhkummnw3ezuamfdejj7qgwwaehxw309ahx7uewd3hkctcscpyug") - - Assert.assertNotNull(actual) - Assert.assertTrue(actual?.entity is Nip19Bech32.NProfile) - Assert.assertEquals("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", (actual?.entity as? Nip19Bech32.NProfile)?.hex) - Assert.assertEquals("wss://vitor.nostr1.com/", (actual?.entity as? Nip19Bech32.NProfile)?.relay?.first()) - } - - @Test() - fun uri_to_route_complete_nprofile() { - val actual = Nip19Bech32.uriToRoute("nostr:nprofile1qy2hwumn8ghj7un9d3shjtnyv9kh2uewd9hj7qgwwaehxw309ahx7uewd3hkctcpr9mhxue69uhhyetvv9ujuumwdae8gtnnda3kjctv9uqzq9thu3vem5gvsc6f3l3uyz7c92h6lq56t9wws0zulzkrgc6nrvym5jfztf") - - Assert.assertTrue(actual?.entity is Nip19Bech32.NProfile) - Assert.assertEquals("1577e4599dd10c863498fe3c20bd82aafaf829a595ce83c5cf8ac3463531b09b", (actual?.entity as? Nip19Bech32.NProfile)?.hex) - } - - @Test() - fun uri_to_route_complete_nevent() { - val actual = Nip19Bech32.uriToRoute("nostr:nevent1qy2hwumn8ghj7un9d3shjtnyv9kh2uewd9hj7qgwwaehxw309ahx7uewd3hkctcpr9mhxue69uhhyetvv9ujuumwdae8gtnnda3kjctv9uq36amnwvaz7tmjv4kxz7fwvd5xjcmpvahhqmr9vfejucm0d5hsz9mhwden5te0wfjkccte9ec8y6tdv9kzumn9wshsz8thwden5te0dehhxarj9ekh2arfdeuhwctvd3jhgtnrdakj7qg3waehxw309ucngvpwvcmh5tnfduhszythwden5te0dehhxarj9emkjmn99uq3jamnwvaz7tmhv4kxxmmdv5hxummnw3ezuamfdejj7qpqvsup5xk3e2quedxjvn2gjppc0lqny5dmnr2ypc9tftwmdxta0yjqrd6n50") - - Assert.assertTrue(actual?.entity is Nip19Bech32.NEvent) - Assert.assertEquals("64381a1ad1ca81ccb4d264d48904387fc13251bb98d440e0ab4addb6997d7924", (actual?.entity as? Nip19Bech32.NEvent)?.hex) - } - - @Test() - fun uri_to_route_complete_naddr() { - val actual = Nip19Bech32.uriToRoute("nostr:naddr1qqyxzmt9w358jum5qyt8wumn8ghj7un9d3shjtnwdaehgu3wvfskueqzypd7v3r24z33cydnk3fmlrd0exe5dlej3506zxs05q4puerp765mzqcyqqq8scsq6mk7u") - - Assert.assertTrue(actual?.entity is Nip19Bech32.NAddress) - Assert.assertEquals("30818:5be6446aa8a31c11b3b453bf8dafc9b346ff328d1fa11a0fa02a1e6461f6a9b1:amethyst", (actual?.entity as? Nip19Bech32.NAddress)?.atag) - } -} diff --git a/quartz/src/test/java/com/vitorpamplona/quartz/encoders/Nip01SerializerTest.kt b/quartz/src/test/java/com/vitorpamplona/quartz/experimental/Nip01SerializerTest.kt similarity index 97% rename from quartz/src/test/java/com/vitorpamplona/quartz/encoders/Nip01SerializerTest.kt rename to quartz/src/test/java/com/vitorpamplona/quartz/experimental/Nip01SerializerTest.kt index b8539c5c4..1cbf3f465 100644 --- a/quartz/src/test/java/com/vitorpamplona/quartz/encoders/Nip01SerializerTest.kt +++ b/quartz/src/test/java/com/vitorpamplona/quartz/experimental/Nip01SerializerTest.kt @@ -18,11 +18,13 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.encoders +package com.vitorpamplona.quartz.experimental import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper -import com.vitorpamplona.quartz.crypto.nip01.EventHasher -import com.vitorpamplona.quartz.events.Event +import com.vitorpamplona.quartz.nip01Core.EventHasher +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.experimental.Nip01Serializer +import com.vitorpamplona.quartz.nip01Core.generateId import junit.framework.TestCase.assertEquals import org.junit.Test diff --git a/quartz/src/test/java/com/vitorpamplona/quartz/encoders/Lud06Test.kt b/quartz/src/test/java/com/vitorpamplona/quartz/lightning/Lud06Test.kt similarity index 97% rename from quartz/src/test/java/com/vitorpamplona/quartz/encoders/Lud06Test.kt rename to quartz/src/test/java/com/vitorpamplona/quartz/lightning/Lud06Test.kt index 541a1d3c7..4c925921b 100644 --- a/quartz/src/test/java/com/vitorpamplona/quartz/encoders/Lud06Test.kt +++ b/quartz/src/test/java/com/vitorpamplona/quartz/lightning/Lud06Test.kt @@ -18,7 +18,7 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.encoders +package com.vitorpamplona.quartz.lightning import org.junit.Assert.assertEquals import org.junit.Test diff --git a/quartz/src/test/java/com/vitorpamplona/quartz/encoders/NIP19ParserTest.kt b/quartz/src/test/java/com/vitorpamplona/quartz/nip19Bech32Entities/NIP19ParserTest.kt similarity index 67% rename from quartz/src/test/java/com/vitorpamplona/quartz/encoders/NIP19ParserTest.kt rename to quartz/src/test/java/com/vitorpamplona/quartz/nip19Bech32Entities/NIP19ParserTest.kt index bc5788e7d..b00f0a6ce 100644 --- a/quartz/src/test/java/com/vitorpamplona/quartz/encoders/NIP19ParserTest.kt +++ b/quartz/src/test/java/com/vitorpamplona/quartz/nip19Bech32Entities/NIP19ParserTest.kt @@ -18,50 +18,157 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.encoders +package com.vitorpamplona.quartz.nip19Bech32Entities +import com.vitorpamplona.quartz.nip01Core.addressables.ATag +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NAddress +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NEvent +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NProfile +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.NPub +import com.vitorpamplona.quartz.nip19Bech32Entities.entities.Note +import org.junit.Assert import org.junit.Assert.assertEquals import org.junit.Assert.assertNotNull import org.junit.Assert.assertTrue import org.junit.Test class NIP19ParserTest { + @Test() + fun uri_to_route_null() { + val actual = Nip19Parser.uriToRoute(null) + + Assert.assertEquals(null, actual) + } + + @Test() + fun uri_to_route_unknown() { + val actual = Nip19Parser.uriToRoute("nostr:unknown") + + Assert.assertEquals(null, actual) + } + + @Test() + fun uri_to_route_npub() { + val actual = + Nip19Parser.uriToRoute("nostr:npub1hv7k2s755n697sptva8vkh9jz40lzfzklnwj6ekewfmxp5crwdjs27007y") + + Assert.assertTrue(actual?.entity is NPub) + Assert.assertEquals( + "bb3d6543d4a4f45f402b674ecb5cb2155ff12456fcdd2d66d9727660d3037365", + (actual?.entity as? NPub)?.hex, + ) + } + + @Test() + fun uri_to_route_note() { + val result = + Nip19Parser.uriToRoute("nostr:note1stqea6wmwezg9x6yyr6qkukw95ewtdukyaztycws65l8wppjmtpscawevv")?.entity as? Note + + assertNotNull(result) + Assert.assertEquals( + "82c19ee9db7644829b4420f40b72ce2d32e5b7962744b261d0d53e770432dac3", + result?.hex, + ) + } + + @Test() + fun uri_to_route_nprofile() { + val actual = Nip19Parser.uriToRoute("nostr:nprofile") + + Assert.assertEquals(null, actual) + } + + @Test() + fun uri_to_route_incomplete_nevent() { + val actual = Nip19Parser.uriToRoute("nostr:nevent") + + Assert.assertEquals(null, actual) + } + + @Test() + fun uri_to_route_incomplete_nrelay() { + val actual = Nip19Parser.uriToRoute("nostr:nrelay") + + Assert.assertEquals(null, actual) + } + + @Test() + fun uri_to_route_incomplete_naddr() { + val actual = Nip19Parser.uriToRoute("nostr:naddr") + + Assert.assertEquals(null, actual) + } + + @Test() + fun uri_to_route_complete_nprofile_2() { + val actual = Nip19Parser.uriToRoute("nostr:nprofile1qqsyvrp9u6p0mfur9dfdru3d853tx9mdjuhkphxuxgfwmryja7zsvhqpzamhxue69uhhv6t5daezumn0wd68yvfwvdhk6tcpz9mhxue69uhkummnw3ezuamfdejj7qgwwaehxw309ahx7uewd3hkctcscpyug") + + Assert.assertNotNull(actual) + Assert.assertTrue(actual?.entity is NProfile) + Assert.assertEquals("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", (actual?.entity as? NProfile)?.hex) + Assert.assertEquals("wss://vitor.nostr1.com/", (actual?.entity as? NProfile)?.relay?.first()) + } + + @Test() + fun uri_to_route_complete_nprofile() { + val actual = Nip19Parser.uriToRoute("nostr:nprofile1qy2hwumn8ghj7un9d3shjtnyv9kh2uewd9hj7qgwwaehxw309ahx7uewd3hkctcpr9mhxue69uhhyetvv9ujuumwdae8gtnnda3kjctv9uqzq9thu3vem5gvsc6f3l3uyz7c92h6lq56t9wws0zulzkrgc6nrvym5jfztf") + + Assert.assertTrue(actual?.entity is NProfile) + Assert.assertEquals("1577e4599dd10c863498fe3c20bd82aafaf829a595ce83c5cf8ac3463531b09b", (actual?.entity as? NProfile)?.hex) + } + + @Test() + fun uri_to_route_complete_nevent() { + val actual = Nip19Parser.uriToRoute("nostr:nevent1qy2hwumn8ghj7un9d3shjtnyv9kh2uewd9hj7qgwwaehxw309ahx7uewd3hkctcpr9mhxue69uhhyetvv9ujuumwdae8gtnnda3kjctv9uq36amnwvaz7tmjv4kxz7fwvd5xjcmpvahhqmr9vfejucm0d5hsz9mhwden5te0wfjkccte9ec8y6tdv9kzumn9wshsz8thwden5te0dehhxarj9ekh2arfdeuhwctvd3jhgtnrdakj7qg3waehxw309ucngvpwvcmh5tnfduhszythwden5te0dehhxarj9emkjmn99uq3jamnwvaz7tmhv4kxxmmdv5hxummnw3ezuamfdejj7qpqvsup5xk3e2quedxjvn2gjppc0lqny5dmnr2ypc9tftwmdxta0yjqrd6n50") + + Assert.assertTrue(actual?.entity is NEvent) + Assert.assertEquals("64381a1ad1ca81ccb4d264d48904387fc13251bb98d440e0ab4addb6997d7924", (actual?.entity as? NEvent)?.hex) + } + + @Test() + fun uri_to_route_complete_naddr() { + val actual = Nip19Parser.uriToRoute("nostr:naddr1qqyxzmt9w358jum5qyt8wumn8ghj7un9d3shjtnwdaehgu3wvfskueqzypd7v3r24z33cydnk3fmlrd0exe5dlej3506zxs05q4puerp765mzqcyqqq8scsq6mk7u") + + Assert.assertTrue(actual?.entity is NAddress) + Assert.assertEquals("30818:5be6446aa8a31c11b3b453bf8dafc9b346ff328d1fa11a0fa02a1e6461f6a9b1:amethyst", (actual?.entity as? NAddress)?.aTag()) + } + @Test fun nAddrParser() { val result = - Nip19Bech32.uriToRoute( + Nip19Parser.uriToRoute( "nostr:naddr1qqqqygzxpsj7dqha57pjk5k37gkn6g4nzakewtmqmnwryyhd3jfwlpgxtspsgqqqw4rs3xyxus", ) assertEquals( "30023:460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c:", - (result?.entity as? Nip19Bech32.NAddress)?.atag, + (result?.entity as? NAddress)?.aTag(), ) } @Test fun nAddrParser2() { val result = - Nip19Bech32.uriToRoute( + Nip19Parser.uriToRoute( "nostr:naddr1qq8kwatfv3jj6amfwfjkwatpwfjqygxsm6lelvfda7qlg0tud9pfhduysy4vrexj65azqtdk4tr75j6xdspsgqqqw4rsg32ag8", ) assertEquals( "30023:d0debf9fb12def81f43d7c69429bb784812ac1e4d2d53a202db6aac7ea4b466c:guide-wireguard", - (result?.entity as? Nip19Bech32.NAddress)?.atag, + (result?.entity as? NAddress)?.aTag(), ) } @Test fun nAddrParse3() { val result = - Nip19Bech32.uriToRoute( + Nip19Parser.uriToRoute( "naddr1qqyrswtyv5mnjv3sqy28wumn8ghj7un9d3shjtnyv9kh2uewd9hsygx3uczxts4hwue9ayfn7ggq62anzstde2qs749pm9tx2csuthhpjvpsgqqqw4rs8pmj38", ) - assertTrue(result?.entity is Nip19Bech32.NAddress) + assertTrue(result?.entity is NAddress) assertEquals( "30023:d1e60465c2b777325e9133f2100d2bb31416dca810f54a1d95665621c5dee193:89de7920", - (result?.entity as? Nip19Bech32.NAddress)?.atag, + (result?.entity as? NAddress)?.aTag(), ) - assertEquals("wss://relay.damus.io", (result?.entity as? Nip19Bech32.NAddress)?.relay?.get(0)) + assertEquals("wss://relay.damus.io", (result?.entity as? NAddress)?.relay?.get(0)) } @Test @@ -132,15 +239,15 @@ class NIP19ParserTest { @Test fun nAddrParserPablo() { val result = - Nip19Bech32 + Nip19Parser .uriToRoute( "naddr1qq2hs7p30p6kcunxxamkgcnyd33xxve3veshyq3qyujphdcz69z6jafxpnldae3xtymdekfeatkt3r4qusr3w5krqspqxpqqqpaxjlg805f", - )?.entity as? Nip19Bech32.NAddress + )?.entity as? NAddress assertNotNull(result) assertEquals( "31337:27241bb702d145a975260cfedee6265936dcd939eaecb88ea0e4071752c30402:xx1xulrf7wdbdlbc31far", - result?.atag, + result?.aTag(), ) assertEquals(true, result?.relay?.isEmpty()) assertEquals("27241bb702d145a975260cfedee6265936dcd939eaecb88ea0e4071752c30402", result?.author) @@ -150,15 +257,15 @@ class NIP19ParserTest { @Test fun nAddrParserGizmo() { val result = - Nip19Bech32 + Nip19Parser .uriToRoute( "naddr1qpqrvvfnvccrzdryxgunzvtxvgukge34xfjnqdpcv9sk2desxgmrscesvserzd3h8ycrywphvg6nsvf58ycnqef3v5mnsvt98pjnqdfs8ypzq3huhccxt6h34eupz3jeynjgjgek8lel2f4adaea0svyk94a3njdqvzqqqr4gudhrkyk", - )?.entity as? Nip19Bech32.NAddress + )?.entity as? NAddress assertNotNull(result) assertEquals( "30023:46fcbe3065eaf1ae7811465924e48923363ff3f526bd6f73d7c184b16bd8ce4d:613f014d2911fb9df52e048aae70268c0d216790287b5814910e1e781e8e0509", - result?.atag, + result?.aTag(), ) assertEquals(true, result?.relay?.isEmpty()) assertEquals("46fcbe3065eaf1ae7811465924e48923363ff3f526bd6f73d7c184b16bd8ce4d", result?.author) @@ -168,15 +275,15 @@ class NIP19ParserTest { @Test fun nAddrParserGizmo2() { val result = - Nip19Bech32 + Nip19Parser .uriToRoute( "naddr1qq9rzd3h8y6nqwf5xyuqygzxljlrqe027xh8sy2xtyjwfzfrxcll8afxh4hh847psjckhkxwf5psgqqqw4rsty50fx", - )?.entity as? Nip19Bech32.NAddress + )?.entity as? NAddress assertNotNull(result) assertEquals( "30023:46fcbe3065eaf1ae7811465924e48923363ff3f526bd6f73d7c184b16bd8ce4d:1679509418", - result?.atag, + result?.aTag(), ) assertEquals(true, result?.relay?.isEmpty()) assertEquals("46fcbe3065eaf1ae7811465924e48923363ff3f526bd6f73d7c184b16bd8ce4d", result?.author) @@ -186,7 +293,7 @@ class NIP19ParserTest { @Test fun nEventParserCompleteTest() { val result = - Nip19Bech32.uriToRoute("nostr:nevent1qqsdw6xpk28tjnrajz4xhy2jqg0md8ywxj6997rsutjzxs0207tedjspz4mhxue69uhhyetvv9ujumn0wd68ytnzvuhsygx2crjrydvqdksffurc0fdsfc566pxtrg78afw0v8kursecwdqg9vpsgqqqqqqsnknas6")?.entity as? Nip19Bech32.NEvent + Nip19Parser.uriToRoute("nostr:nevent1qqsdw6xpk28tjnrajz4xhy2jqg0md8ywxj6997rsutjzxs0207tedjspz4mhxue69uhhyetvv9ujumn0wd68ytnzvuhsygx2crjrydvqdksffurc0fdsfc566pxtrg78afw0v8kursecwdqg9vpsgqqqqqqsnknas6")?.entity as? NEvent assertNotNull(result) assertEquals("d768c1b28eb94c7d90aa6b9152021fb69c8e34b452f870e2e42341ea7f9796ca", result?.hex) @@ -198,7 +305,7 @@ class NIP19ParserTest { @Test fun nEventParserTest() { val result = - Nip19Bech32.uriToRoute("nostr:nevent1qqs0tsw8hjacs4fppgdg7f5yhgwwfkyua4xcs3re9wwkpkk2qeu6mhql22rcy")?.entity as? Nip19Bech32.NEvent + Nip19Parser.uriToRoute("nostr:nevent1qqs0tsw8hjacs4fppgdg7f5yhgwwfkyua4xcs3re9wwkpkk2qeu6mhql22rcy")?.entity as? NEvent assertNotNull(result) assertEquals("f5c1c7bcbb8855210a1a8f2684ba1ce4d89ced4d8844792b9d60daca0679addc", result?.hex) @@ -210,7 +317,7 @@ class NIP19ParserTest { @Test fun nEventParser2Test() { val result = - Nip19Bech32.uriToRoute("nostr:nevent1qqsfvaa2w3nkw472lt2ezr6x5x347k8hht398vp7hrl6wrdjldry86sprfmhxue69uhhyetvv9ujuam9wd6x2unwvf6xxtnrdaks5myyah")?.entity as? Nip19Bech32.NEvent + Nip19Parser.uriToRoute("nostr:nevent1qqsfvaa2w3nkw472lt2ezr6x5x347k8hht398vp7hrl6wrdjldry86sprfmhxue69uhhyetvv9ujuam9wd6x2unwvf6xxtnrdaks5myyah")?.entity as? NEvent assertNotNull(result) assertEquals("9677aa74676757cafad5910f46a1a35f58f7bae253b03eb8ffa70db2fb4643ea", result?.hex) @@ -222,10 +329,10 @@ class NIP19ParserTest { @Test fun nEventParser() { val result = - Nip19Bech32 + Nip19Parser .uriToRoute( "nostr:nevent1qqstvrl6wftd8ht4g0vrp6m30tjs6pdxcvk977g769dcvlptkzu4ftqppamhxue69uhkummnw3ezumt0d5pzp78lz8r60568sd2a8dx3wnj6gume02gxaf92vx4fk67qv5kpagt6qvzqqqqqqygqr86c", - )?.entity as? Nip19Bech32.NEvent + )?.entity as? NEvent assertNotNull(result) assertEquals("b60ffa7256d3dd7543d830eb717ae50d05a6c32c5f791ed15b867c2bb0b954ac", result?.hex) @@ -237,10 +344,10 @@ class NIP19ParserTest { @Test fun nEventParser2() { val result = - Nip19Bech32 + Nip19Parser .uriToRoute( "nostr:nevent1qqsplpuwsgrrmq85rfup6w3w777rxmcmadu590emfx6z4msj2844euqpz3mhxue69uhhyetvv9ujuerpd46hxtnfdupzq3svyhng9ld8sv44950j957j9vchdktj7cxumsep9mvvjthc2pjuqvzqqqqqqye3a70w", - )?.entity as? Nip19Bech32.NEvent + )?.entity as? NEvent assertNotNull(result) assertEquals("1f878e82063d80f41a781d3a2ef7bc336f1beb7942bf3b49b42aee1251eb5cf0", result?.hex) @@ -252,10 +359,10 @@ class NIP19ParserTest { @Test fun nEventParser3() { val result = - Nip19Bech32 + Nip19Parser .uriToRoute( "nostr:nevent1qqsg6gechd3dhzx38n4z8a2lylzgsmmgeamhmtzz72m9ummsnf0xjfspsdmhxue69uhkummn9ekx7mpvwaehxw309ahx7um5wghx77r5wghxgetk93mhxue69uhhyetvv9ujumn0wd68ytnzvuk8wumn8ghj7mn0wd68ytn9d9h82mny0fmkzmn6d9njuumsv93k2trhwden5te0wfjkccte9ehx7um5wghxyctwvsk8wumn8ghj7un9d3shjtnyv9kh2uewd9hs3kqsdn", - )?.entity as? Nip19Bech32.NEvent + )?.entity as? NEvent assertNotNull(result) assertEquals("8d2338bb62db88d13cea23f55f27c4886f68cf777dac42f2b65e6f709a5e6926", result?.hex) @@ -268,10 +375,10 @@ class NIP19ParserTest { @Test fun nEventParserInvalidChecksum() { val result = - Nip19Bech32 + Nip19Parser .uriToRoute( "nostr:nevent1qqsyxq8v0730nz38dupnjzp5jegkyz4gu2ptwcps4v32hjnrap0q0espz3mhxue69uhhyetvv9ujuerpd46hxtnfdupzq3svyhng9ld8sv44950j957j9vchdktj7cxumsep9mvvjthc2pjuqvzqqqqqqyn3t9gj", - )?.entity as? Nip19Bech32.NEvent + )?.entity as? NEvent assertNotNull(result) assertEquals("4300ec7fa2f98a276f033908349651620aa8e282b76030ab22abca63e85e07e6", result?.hex) @@ -283,7 +390,7 @@ class NIP19ParserTest { @Test fun nEventFormatter() { val nevent = - Nip19Bech32.createNEvent( + NEvent.create( "f5c1c7bcbb8855210a1a8f2684ba1ce4d89ced4d8844792b9d60daca0679addc", null, null, @@ -295,7 +402,7 @@ class NIP19ParserTest { @Test fun nEventFormatterWithExtraInfo() { val nevent = - Nip19Bech32.createNEvent( + NEvent.create( "f5c1c7bcbb8855210a1a8f2684ba1ce4d89ced4d8844792b9d60daca0679addc", "7fa56f5d6962ab1e3cd424e758c3002b8665f7b0d8dcee9fe9e288d7751ac194", 40, @@ -310,7 +417,7 @@ class NIP19ParserTest { @Test fun nEventFormatterWithFullInfo() { val nevent = - Nip19Bech32.createNEvent( + NEvent.create( "1f878e82063d80f41a781d3a2ef7bc336f1beb7942bf3b49b42aee1251eb5cf0", "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", 1, diff --git a/quartz/src/test/java/com/vitorpamplona/quartz/encoders/TlvIntegerTest.kt b/quartz/src/test/java/com/vitorpamplona/quartz/nip19Bech32Entities/TlvIntegerTest.kt similarity index 92% rename from quartz/src/test/java/com/vitorpamplona/quartz/encoders/TlvIntegerTest.kt rename to quartz/src/test/java/com/vitorpamplona/quartz/nip19Bech32Entities/TlvIntegerTest.kt index db2a99c03..3d70da227 100644 --- a/quartz/src/test/java/com/vitorpamplona/quartz/encoders/TlvIntegerTest.kt +++ b/quartz/src/test/java/com/vitorpamplona/quartz/nip19Bech32Entities/TlvIntegerTest.kt @@ -18,8 +18,10 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.encoders +package com.vitorpamplona.quartz.nip19Bech32Entities +import com.vitorpamplona.quartz.nip19Bech32Entities.tlv.to32BitByteArray +import com.vitorpamplona.quartz.nip19Bech32Entities.tlv.toInt32 import org.junit.Assert import org.junit.Assert.assertEquals import org.junit.Test diff --git a/quartz/src/test/java/com/vitorpamplona/quartz/encoders/Nip30Test.kt b/quartz/src/test/java/com/vitorpamplona/quartz/nip30CustomEmoji/Nip30Test.kt similarity index 64% rename from quartz/src/test/java/com/vitorpamplona/quartz/encoders/Nip30Test.kt rename to quartz/src/test/java/com/vitorpamplona/quartz/nip30CustomEmoji/Nip30Test.kt index 7dcca987e..cf6aeca41 100644 --- a/quartz/src/test/java/com/vitorpamplona/quartz/encoders/Nip30Test.kt +++ b/quartz/src/test/java/com/vitorpamplona/quartz/nip30CustomEmoji/Nip30Test.kt @@ -18,9 +18,9 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.encoders +package com.vitorpamplona.quartz.nip30CustomEmoji -import com.vitorpamplona.quartz.events.ImmutableListOfLists +import com.vitorpamplona.quartz.nip02FollowList.ImmutableListOfLists import junit.framework.TestCase.assertEquals import junit.framework.TestCase.assertNull import org.junit.Test @@ -31,18 +31,18 @@ class Nip30Test { val tags = mapOf(":soapbox:" to "http://soapbox") val input = "Alex Gleason :soapbox:" - val result = Nip30CustomEmoji.assembleAnnotatedList(input, tags) + val result = CustomEmoji.assembleAnnotatedList(input, tags) assertEquals(2, result!!.size) assertEquals( "Alex Gleason ", - (result[0] as Nip30CustomEmoji.TextType).text, + (result[0] as CustomEmoji.TextType).text, ) assertEquals( "http://soapbox", - (result[1] as Nip30CustomEmoji.ImageUrlType).url, + (result[1] as CustomEmoji.ImageUrlType).url, ) } @@ -51,18 +51,18 @@ class Nip30Test { val tags = mapOf(":soapbox:" to "http://soapbox") val input = ":soapbox:Alex Gleason" - val result = Nip30CustomEmoji.assembleAnnotatedList(input, tags) + val result = CustomEmoji.assembleAnnotatedList(input, tags) assertEquals(2, result!!.size) assertEquals( "http://soapbox", - (result[0] as Nip30CustomEmoji.ImageUrlType).url, + (result[0] as CustomEmoji.ImageUrlType).url, ) assertEquals( "Alex Gleason", - (result[1] as Nip30CustomEmoji.TextType).text, + (result[1] as CustomEmoji.TextType).text, ) } @@ -76,23 +76,23 @@ class Nip30Test { ) val input = "Hello :gleasonator: \uD83D\uDE02 :ablobcatrainbow: :disputed: yolo" - val result = Nip30CustomEmoji.assembleAnnotatedList(input, tags) + val result = CustomEmoji.assembleAnnotatedList(input, tags) assertEquals(7, result!!.size) - assertEquals("Hello ", (result[0] as Nip30CustomEmoji.TextType).text) + assertEquals("Hello ", (result[0] as CustomEmoji.TextType).text) - assertEquals("http://gleasonator", (result[1] as Nip30CustomEmoji.ImageUrlType).url) + assertEquals("http://gleasonator", (result[1] as CustomEmoji.ImageUrlType).url) - assertEquals(" 😂 ", (result[2] as Nip30CustomEmoji.TextType).text) + assertEquals(" 😂 ", (result[2] as CustomEmoji.TextType).text) - assertEquals("http://ablobcatrainbow", (result[3] as Nip30CustomEmoji.ImageUrlType).url) + assertEquals("http://ablobcatrainbow", (result[3] as CustomEmoji.ImageUrlType).url) - assertEquals(" ", (result[4] as Nip30CustomEmoji.TextType).text) + assertEquals(" ", (result[4] as CustomEmoji.TextType).text) - assertEquals("http://disputed", (result[5] as Nip30CustomEmoji.ImageUrlType).url) + assertEquals("http://disputed", (result[5] as CustomEmoji.ImageUrlType).url) - assertEquals(" yolo", (result[6] as Nip30CustomEmoji.TextType).text) + assertEquals(" yolo", (result[6] as CustomEmoji.TextType).text) } @Test() @@ -100,7 +100,7 @@ class Nip30Test { val tags = emptyMap() val input = "hello vitor: how can I help:" - val result = Nip30CustomEmoji.assembleAnnotatedList(input, tags) + val result = CustomEmoji.assembleAnnotatedList(input, tags) assertNull(result) } @@ -110,15 +110,15 @@ class Nip30Test { val tags = mapOf(":vitor:" to "http://vitor") val input = "hello :vitor: how :can I help:" - val result = Nip30CustomEmoji.assembleAnnotatedList(input, tags) + val result = CustomEmoji.assembleAnnotatedList(input, tags) assertEquals(3, result!!.size) - assertEquals("hello ", (result[0] as Nip30CustomEmoji.TextType).text) + assertEquals("hello ", (result[0] as CustomEmoji.TextType).text) - assertEquals("http://vitor", (result[1] as Nip30CustomEmoji.ImageUrlType).url) + assertEquals("http://vitor", (result[1] as CustomEmoji.ImageUrlType).url) - assertEquals(" how :can I help:", (result[2] as Nip30CustomEmoji.TextType).text) + assertEquals(" how :can I help:", (result[2] as CustomEmoji.TextType).text) } @Test() @@ -126,13 +126,13 @@ class Nip30Test { val tags = mapOf(":x30EDE:" to "http://x30EDE", ":\uD883\uDEDE:" to "http://\uD883\uDEDE") val input = "\uD883\uDEDE\uD883\uDEDE麺の:x30EDE:。:\uD883\uDEDE:(Violation of NIP-30)" - val result = Nip30CustomEmoji.assembleAnnotatedList(input, tags) + val result = CustomEmoji.assembleAnnotatedList(input, tags) assertEquals(3, result!!.size) - assertEquals("\uD883\uDEDE\uD883\uDEDE麺の", (result[0] as Nip30CustomEmoji.TextType).text) - assertEquals("http://x30EDE", (result[1] as Nip30CustomEmoji.ImageUrlType).url) - assertEquals("。:\uD883\uDEDE:(Violation of NIP-30)", (result[2] as Nip30CustomEmoji.TextType).text) + assertEquals("\uD883\uDEDE\uD883\uDEDE麺の", (result[0] as CustomEmoji.TextType).text) + assertEquals("http://x30EDE", (result[1] as CustomEmoji.ImageUrlType).url) + assertEquals("。:\uD883\uDEDE:(Violation of NIP-30)", (result[2] as CustomEmoji.TextType).text) } @Test() @@ -150,19 +150,19 @@ class Nip30Test { "#ioメシヨソイゲーム\n" + "https://misskey.io/play/9g3qza4jow" - val result = Nip30CustomEmoji.assembleAnnotatedList(input, ImmutableListOfLists(tags)) + val result = CustomEmoji.assembleAnnotatedList(input, ImmutableListOfLists(tags)) assertEquals(9, result!!.size) var i = 0 - assertEquals("\u200B", (result[i++] as Nip30CustomEmoji.TextType).text) - assertEquals("https://media.misskeyusercontent.com/emoji/_ri.png", (result[i++] as Nip30CustomEmoji.ImageUrlType).url) - assertEquals("\u200B\u200B", (result[i++] as Nip30CustomEmoji.TextType).text) - assertEquals("https://media.misskeyusercontent.com/emoji/_ri.png", (result[i++] as Nip30CustomEmoji.ImageUrlType).url) - assertEquals("\u200Bはベイクドモチョチョ\u200B", (result[i++] as Nip30CustomEmoji.TextType).text) - assertEquals("https://media.misskeyusercontent.com/emoji/petthex_japanesecake.gif", (result[i++] as Nip30CustomEmoji.ImageUrlType).url) - assertEquals("\u200Bを食べました\u200B", (result[i++] as Nip30CustomEmoji.TextType).text) - assertEquals("https://media.misskeyusercontent.com/misskey/f6294900-f678-43cc-bc36-3ee5deeca4c2.gif", (result[i++] as Nip30CustomEmoji.ImageUrlType).url) - assertEquals("\u200B\n#ioメシヨソイゲーム\nhttps://misskey.io/play/9g3qza4jow", (result[i] as Nip30CustomEmoji.TextType).text) + assertEquals("\u200B", (result[i++] as CustomEmoji.TextType).text) + assertEquals("https://media.misskeyusercontent.com/emoji/_ri.png", (result[i++] as CustomEmoji.ImageUrlType).url) + assertEquals("\u200B\u200B", (result[i++] as CustomEmoji.TextType).text) + assertEquals("https://media.misskeyusercontent.com/emoji/_ri.png", (result[i++] as CustomEmoji.ImageUrlType).url) + assertEquals("\u200Bはベイクドモチョチョ\u200B", (result[i++] as CustomEmoji.TextType).text) + assertEquals("https://media.misskeyusercontent.com/emoji/petthex_japanesecake.gif", (result[i++] as CustomEmoji.ImageUrlType).url) + assertEquals("\u200Bを食べました\u200B", (result[i++] as CustomEmoji.TextType).text) + assertEquals("https://media.misskeyusercontent.com/misskey/f6294900-f678-43cc-bc36-3ee5deeca4c2.gif", (result[i++] as CustomEmoji.ImageUrlType).url) + assertEquals("\u200B\n#ioメシヨソイゲーム\nhttps://misskey.io/play/9g3qza4jow", (result[i] as CustomEmoji.TextType).text) } } diff --git a/quartz/src/test/java/com/vitorpamplona/quartz/utils/RelayListRecommendationProcessorTest.kt b/quartz/src/test/java/com/vitorpamplona/quartz/nip65RelayList/RelayListRecommendationProcessorTest.kt similarity index 98% rename from quartz/src/test/java/com/vitorpamplona/quartz/utils/RelayListRecommendationProcessorTest.kt rename to quartz/src/test/java/com/vitorpamplona/quartz/nip65RelayList/RelayListRecommendationProcessorTest.kt index 91fdbc4a3..3590b316e 100644 --- a/quartz/src/test/java/com/vitorpamplona/quartz/utils/RelayListRecommendationProcessorTest.kt +++ b/quartz/src/test/java/com/vitorpamplona/quartz/nip65RelayList/RelayListRecommendationProcessorTest.kt @@ -18,7 +18,7 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.utils +package com.vitorpamplona.quartz.nip65RelayList import junit.framework.TestCase.assertEquals import junit.framework.TestCase.assertTrue