- Refactoring services to be part of the App Lifecycle,

- Migrated services to Flows that are active while their flows remain subscribed
- Improved OTS Decoupling
- Moved OTS verification procedures from the local cache to the data source
- Migrated the forceProxy options to lambdas that return an OkHttpClient
- Isolated Connectivity services, from Compose to Flow
- Isolated Tor services, from Compose to Tor (only starts if the Tor option is marked as internal)
- Isolated Memory trimming services, from Compose to Flow
- Isolated Image Caching services, from Compose to Flow
- Isolated Video Caching services
- Isolated Logging services
- Isolated NIP-95 Caching services
- Isolated Pokey receiver services
- Improved support for Tor in push notifications
- Isolated OkHttpClient services as flows
- Reduced the coupling of Context objects with singleton objects.
- Migrated UserFeedStates, StringFeedStates and ZapFeedStates to MutableStateFlow, avoiding feed updates on Main
- Forces a reconnect into relays that lost connection if any tor, connectivity or account changes
- Speeds up Base64 parser
This commit is contained in:
Vitor Pamplona
2025-04-09 18:51:17 -04:00
parent 652373bd01
commit 3833f5f822
111 changed files with 1970 additions and 1063 deletions
@@ -21,5 +21,8 @@
package com.vitorpamplona.quartz.nip01Core.relay.sockets
interface WebsocketBuilderFactory {
fun build(forceProxy: Boolean): WebsocketBuilder
fun build(
url: String,
forceProxy: Boolean,
): WebsocketBuilder
}
@@ -51,27 +51,30 @@ class OtsEvent(
fun otsByteArray(): ByteArray = decodeOtsState(content)
fun cacheVerify(): VerificationState = VerificationStateCache.cacheVerify(this)
fun verifyState(resolver: OtsResolver): VerificationState = digestEventId()?.let { verify(otsByteArray(), it, resolver) } ?: VerificationState.Error("Digest Not found")
fun verifyState(): VerificationState = digestEventId()?.let { verify(otsByteArray(), it) } ?: VerificationState.Error("Digest Not found")
fun verify(): Long? = (verifyState() as? VerificationState.Verified)?.verifiedTime
fun verify(resolver: OtsResolver): Long? = (verifyState(resolver) as? VerificationState.Verified)?.verifiedTime
companion object {
const val KIND = 1040
const val ALT = "Opentimestamps Attestation"
fun stamp(eventId: HexKey) = OtsResolver.stamp(eventId.hexToByteArray())
fun stamp(
eventId: HexKey,
resolver: OtsResolver,
) = resolver.stamp(eventId.hexToByteArray())
fun upgrade(
otsState: ByteArray,
eventId: HexKey,
) = OtsResolver.upgrade(otsState, eventId.hexToByteArray())
resolver: OtsResolver,
) = resolver.upgrade(otsState, eventId.hexToByteArray())
fun verify(
otsState: ByteArray,
eventId: HexKey,
) = OtsResolver.verify(otsState, eventId.hexToByteArray())
resolver: OtsResolver,
) = resolver.verify(otsState, eventId.hexToByteArray())
fun encodeOtsState(otsState: ByteArray) = Base64.getEncoder().encodeToString(otsState)
@@ -21,7 +21,9 @@
package com.vitorpamplona.quartz.nip03Timestamp
import android.util.Log
import com.vitorpamplona.quartz.nip03Timestamp.ots.BitcoinExplorer
import com.vitorpamplona.quartz.nip03Timestamp.ots.BlockstreamExplorer
import com.vitorpamplona.quartz.nip03Timestamp.ots.CalendarBuilder
import com.vitorpamplona.quartz.nip03Timestamp.ots.CalendarPureJavaBuilder
import com.vitorpamplona.quartz.nip03Timestamp.ots.DetachedTimestampFile
import com.vitorpamplona.quartz.nip03Timestamp.ots.Hash
@@ -31,13 +33,11 @@ import com.vitorpamplona.quartz.nip03Timestamp.ots.exceptions.UrlException
import com.vitorpamplona.quartz.nip03Timestamp.ots.op.OpSHA256
import kotlinx.coroutines.CancellationException
object OtsResolver {
// default config
var ots =
OpenTimestamps(
BlockstreamExplorer(),
CalendarPureJavaBuilder(),
)
class OtsResolver(
explorer: BitcoinExplorer = BlockstreamExplorer(),
calendarBuilder: CalendarBuilder = CalendarPureJavaBuilder(),
) {
val ots: OpenTimestamps = OpenTimestamps(explorer, calendarBuilder)
fun info(otsState: ByteArray): String = ots.info(DetachedTimestampFile.deserialize(otsState))
@@ -24,21 +24,24 @@ import android.util.LruCache
import com.vitorpamplona.quartz.nip01Core.core.HexKey
import com.vitorpamplona.quartz.utils.TimeUtils
object VerificationStateCache {
class VerificationStateCache {
private val cache = LruCache<HexKey, VerificationState>(200)
fun cacheVerify(event: OtsEvent): VerificationState =
fun cacheVerify(
event: OtsEvent,
resolverBuilder: () -> OtsResolver,
): VerificationState =
when (val verif = cache[event.id]) {
is VerificationState.Verified -> verif
is VerificationState.NetworkError -> {
// try again in 5 mins
if (verif.time < TimeUtils.fiveMinutesAgo()) {
event.verifyState().also { cache.put(event.id, it) }
event.verifyState(resolverBuilder()).also { cache.put(event.id, it) }
} else {
verif
}
}
is VerificationState.Error -> verif
else -> event.verifyState().also { cache.put(event.id, it) }
else -> event.verifyState(resolverBuilder()).also { cache.put(event.id, it) }
}
}