diff --git a/settings.gradle b/settings.gradle index e265afae..a71d60e5 100644 --- a/settings.gradle +++ b/settings.gradle @@ -97,6 +97,8 @@ include ':sphinx:application:network:concepts:queries:concept-network-query-cryp include ':sphinx:application:network:features:queries:feature-network-query-crypter' include ':sphinx:application:network:concepts:queries:concept-network-query-discover-tribes' include ':sphinx:application:network:features:queries:feature-network-query-discover-tribes' +include ':sphinx:application:network:concepts:queries:concept-network-query-hive' +include ':sphinx:application:network:features:queries:feature-network-query-hive' include ':sphinx:application:network:concepts:queries:concept-network-query-feed-status' include ':sphinx:application:network:features:queries:feature-network-query-feed-status' diff --git a/sphinx/application/data/features/feature-repository-android/src/main/java/chat/sphinx/feature_repository_android/SphinxRepositoryAndroid.kt b/sphinx/application/data/features/feature-repository-android/src/main/java/chat/sphinx/feature_repository_android/SphinxRepositoryAndroid.kt index 09bdd217..e92cb6e8 100644 --- a/sphinx/application/data/features/feature-repository-android/src/main/java/chat/sphinx/feature_repository_android/SphinxRepositoryAndroid.kt +++ b/sphinx/application/data/features/feature-repository-android/src/main/java/chat/sphinx/feature_repository_android/SphinxRepositoryAndroid.kt @@ -14,6 +14,7 @@ import chat.sphinx.concept_network_query_invite.NetworkQueryInvite import chat.sphinx.concept_network_query_meme_server.NetworkQueryMemeServer import chat.sphinx.concept_network_query_feed_search.NetworkQueryFeedSearch import chat.sphinx.concept_network_query_feed_status.NetworkQueryFeedStatus +import chat.sphinx.concept_network_query_hive.NetworkQueryHive import chat.sphinx.concept_network_query_people.NetworkQueryPeople import chat.sphinx.concept_network_query_verify_external.NetworkQueryAuthorizeExternal import chat.sphinx.concept_paging.PageSourceWrapper @@ -61,6 +62,7 @@ class SphinxRepositoryAndroid( networkQueryPeople: NetworkQueryPeople, networkQueryFeedSearch: NetworkQueryFeedSearch, networkQueryFeedStatus: NetworkQueryFeedStatus, + networkQueryHive: NetworkQueryHive, connectManager: ConnectManager, dataSyncManager: DataSyncManager, walletDataHandler: WalletDataHandler, @@ -88,6 +90,7 @@ class SphinxRepositoryAndroid( networkQueryPeople, networkQueryFeedSearch, networkQueryFeedStatus, + networkQueryHive, connectManager, dataSyncManager, walletDataHandler, diff --git a/sphinx/application/data/features/feature-repository/build.gradle b/sphinx/application/data/features/feature-repository/build.gradle index 20d67407..49a2ab1f 100644 --- a/sphinx/application/data/features/feature-repository/build.gradle +++ b/sphinx/application/data/features/feature-repository/build.gradle @@ -36,6 +36,7 @@ dependencies { api project(path: ':sphinx:application:network:concepts:concept-meme-input-stream') api project(path: ':sphinx:application:network:concepts:queries:concept-network-query-meme-server') api project(path: ':sphinx:application:network:concepts:queries:concept-network-query-discover-tribes') + api project(path: ':sphinx:application:network:concepts:queries:concept-network-query-hive') api project(path: ':sphinx:application:network:concepts:queries:concept-network-query-chat') api project(path: ':sphinx:application:network:concepts:queries:concept-network-query-contact') api project(path: ':sphinx:application:network:concepts:queries:concept-network-query-invite') diff --git a/sphinx/application/data/features/feature-repository/src/main/java/chat/sphinx/feature_repository/SphinxRepository.kt b/sphinx/application/data/features/feature-repository/src/main/java/chat/sphinx/feature_repository/SphinxRepository.kt index 9ed7d795..7f26870a 100644 --- a/sphinx/application/data/features/feature-repository/src/main/java/chat/sphinx/feature_repository/SphinxRepository.kt +++ b/sphinx/application/data/features/feature-repository/src/main/java/chat/sphinx/feature_repository/SphinxRepository.kt @@ -16,6 +16,7 @@ import chat.sphinx.concept_network_query_feed_search.model.toFeedSearchResult import chat.sphinx.concept_network_query_feed_status.NetworkQueryFeedStatus import chat.sphinx.concept_network_query_feed_status.model.ContentFeedStatusDto import chat.sphinx.concept_network_query_feed_status.model.EpisodeStatusDto +import chat.sphinx.concept_network_query_hive.NetworkQueryHive import chat.sphinx.concept_network_query_invite.NetworkQueryInvite import chat.sphinx.concept_network_query_meme_server.NetworkQueryMemeServer import chat.sphinx.concept_network_query_people.NetworkQueryPeople @@ -208,6 +209,7 @@ abstract class SphinxRepository( private val networkQueryPeople: NetworkQueryPeople, private val networkQueryFeedSearch: NetworkQueryFeedSearch, private val networkQueryFeedStatus: NetworkQueryFeedStatus, + private val networkQueryHive: NetworkQueryHive, private val connectManager: ConnectManager, private val dataSyncManager: DataSyncManager, private val walletDataHandler: WalletDataHandler, @@ -236,6 +238,7 @@ abstract class SphinxRepository( // PersistentStorage Keys const val REPOSITORY_LIGHTNING_BALANCE = "REPOSITORY_LIGHTNING_BALANCE" const val REPOSITORY_PUSH_KEY = "REPOSITORY_PUSH_KEY" + const val HIVE_AUTHENTICATION_TOKEN = "HIVE_AUTHENTICATION_TOKEN" const val MEDIA_KEY_SIZE = 32 @@ -246,6 +249,38 @@ abstract class SphinxRepository( var lastMessageIndex: Long? = null + //////////////////// + /// Hive Auth /// + ////////////////// + + suspend fun authenticateWithHive(): Boolean { + retrieveHiveToken()?.let { return true } + + val signedToken = connectManager.getSignedTimeStamps() ?: return false + val pubkey = accountOwner.value?.nodePubKey?.value ?: return false + val timestamp = System.currentTimeMillis().toString() + + var success = false + networkQueryHive.authenticateWithHive(signedToken, pubkey, timestamp) + .collect { response -> + when (response) { + is Response.Success -> { + val jwt = response.value.token + ?.takeIf { it.isNotBlank() } + ?: return@collect + authenticationStorage.putString(HIVE_AUTHENTICATION_TOKEN, jwt) + success = true + } + else -> { /* success remains false */ } + } + } + return success + } + + suspend fun retrieveHiveToken(): String? { + return authenticationStorage.getString(HIVE_AUTHENTICATION_TOKEN, null) + } + //////////////////////// /// Connect Manager /// ////////////////////// diff --git a/sphinx/application/network/concepts/queries/concept-network-query-hive/build.gradle b/sphinx/application/network/concepts/queries/concept-network-query-hive/build.gradle new file mode 100644 index 00000000..4ac94a5f --- /dev/null +++ b/sphinx/application/network/concepts/queries/concept-network-query-hive/build.gradle @@ -0,0 +1,16 @@ +plugins { + id 'java-library' + id 'kotlin' + id 'kotlin-kapt' +} + +dependencies { + api project(path: ':sphinx:application:common:kotlin-response') + + implementation deps.kotlin.coroutinesCore + + // needed to override moshi's use of 1.4.31 + implementation deps.kotlin.reflect + implementation deps.square.moshi + kapt kaptDeps.square.moshiCodegen +} diff --git a/sphinx/application/network/concepts/queries/concept-network-query-hive/src/main/java/chat/sphinx/concept_network_query_hive/NetworkQueryHive.kt b/sphinx/application/network/concepts/queries/concept-network-query-hive/src/main/java/chat/sphinx/concept_network_query_hive/NetworkQueryHive.kt new file mode 100644 index 00000000..d3ac53a7 --- /dev/null +++ b/sphinx/application/network/concepts/queries/concept-network-query-hive/src/main/java/chat/sphinx/concept_network_query_hive/NetworkQueryHive.kt @@ -0,0 +1,15 @@ +package chat.sphinx.concept_network_query_hive + +import chat.sphinx.concept_network_query_hive.model.HiveAuthenticationTokenDto +import chat.sphinx.kotlin_response.LoadResponse +import chat.sphinx.kotlin_response.ResponseError +import kotlinx.coroutines.flow.Flow + +abstract class NetworkQueryHive { + + abstract fun authenticateWithHive( + token: String, + pubkey: String, + timestamp: String + ): Flow> +} diff --git a/sphinx/application/network/concepts/queries/concept-network-query-hive/src/main/java/chat/sphinx/concept_network_query_hive/model/HiveAuthRequestDto.kt b/sphinx/application/network/concepts/queries/concept-network-query-hive/src/main/java/chat/sphinx/concept_network_query_hive/model/HiveAuthRequestDto.kt new file mode 100644 index 00000000..f4c3ddd1 --- /dev/null +++ b/sphinx/application/network/concepts/queries/concept-network-query-hive/src/main/java/chat/sphinx/concept_network_query_hive/model/HiveAuthRequestDto.kt @@ -0,0 +1,11 @@ +package chat.sphinx.concept_network_query_hive.model + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass + +@JsonClass(generateAdapter = true) +data class HiveAuthRequestDto( + @Json(name = "token") val token: String, + @Json(name = "pubkey") val pubkey: String, + @Json(name = "timestamp") val timestamp: String +) diff --git a/sphinx/application/network/concepts/queries/concept-network-query-hive/src/main/java/chat/sphinx/concept_network_query_hive/model/HiveAuthenticationTokenDto.kt b/sphinx/application/network/concepts/queries/concept-network-query-hive/src/main/java/chat/sphinx/concept_network_query_hive/model/HiveAuthenticationTokenDto.kt new file mode 100644 index 00000000..7e0f9f98 --- /dev/null +++ b/sphinx/application/network/concepts/queries/concept-network-query-hive/src/main/java/chat/sphinx/concept_network_query_hive/model/HiveAuthenticationTokenDto.kt @@ -0,0 +1,6 @@ +package chat.sphinx.concept_network_query_hive.model + +import com.squareup.moshi.JsonClass + +@JsonClass(generateAdapter = true) +data class HiveAuthenticationTokenDto(val token: String?) diff --git a/sphinx/application/network/features/queries/feature-network-query-hive/build.gradle b/sphinx/application/network/features/queries/feature-network-query-hive/build.gradle new file mode 100644 index 00000000..121be719 --- /dev/null +++ b/sphinx/application/network/features/queries/feature-network-query-hive/build.gradle @@ -0,0 +1,20 @@ +plugins { + id 'app.cash.exhaustive' + id 'java-library' + id 'kotlin' + id 'kotlin-kapt' +} + +dependencies { + api project(path: ':sphinx:application:network:concepts:queries:concept-network-query-hive') + api project(path: ':sphinx:application:network:concepts:calls:concept-network-relay-call') + + implementation deps.kotlin.coroutinesCore + + // needed to override moshi's use of 1.4.31 + implementation deps.kotlin.reflect + implementation deps.square.moshi + kapt kaptDeps.square.moshiCodegen + + testImplementation project(path: ':sphinx:test:test-network-query') +} diff --git a/sphinx/application/network/features/queries/feature-network-query-hive/src/main/java/chat/sphinx/feature_network_query_hive/NetworkQueryHiveImpl.kt b/sphinx/application/network/features/queries/feature-network-query-hive/src/main/java/chat/sphinx/feature_network_query_hive/NetworkQueryHiveImpl.kt new file mode 100644 index 00000000..5f6b7794 --- /dev/null +++ b/sphinx/application/network/features/queries/feature-network-query-hive/src/main/java/chat/sphinx/feature_network_query_hive/NetworkQueryHiveImpl.kt @@ -0,0 +1,31 @@ +package chat.sphinx.feature_network_query_hive + +import chat.sphinx.concept_network_call.NetworkCall +import chat.sphinx.concept_network_query_hive.NetworkQueryHive +import chat.sphinx.concept_network_query_hive.model.HiveAuthRequestDto +import chat.sphinx.concept_network_query_hive.model.HiveAuthenticationTokenDto +import chat.sphinx.kotlin_response.LoadResponse +import chat.sphinx.kotlin_response.ResponseError +import kotlinx.coroutines.flow.Flow + +class NetworkQueryHiveImpl( + private val networkCall: NetworkCall +) : NetworkQueryHive() { + + companion object { + const val HIVE_BASE_URL = "https://hive.sphinx.chat/api" + const val ENDPOINT_AUTH = "/auth/sphinx/token" + } + + override fun authenticateWithHive( + token: String, + pubkey: String, + timestamp: String + ): Flow> = + networkCall.post( + url = HIVE_BASE_URL + ENDPOINT_AUTH, + responseJsonClass = HiveAuthenticationTokenDto::class.java, + requestBodyJsonClass = HiveAuthRequestDto::class.java, + requestBody = HiveAuthRequestDto(token, pubkey, timestamp) + ) +} diff --git a/sphinx/application/sphinx/build.gradle b/sphinx/application/sphinx/build.gradle index d64db83c..af8f5543 100644 --- a/sphinx/application/sphinx/build.gradle +++ b/sphinx/application/sphinx/build.gradle @@ -118,6 +118,7 @@ dependencies { implementation project(path: ':sphinx:application:network:features:queries:feature-network-query-crypter') implementation project(path: ':sphinx:application:network:features:queries:feature-network-query-discover-tribes') implementation project(path: ':sphinx:application:network:features:queries:feature-network-query-feed-status') + implementation project(path: ':sphinx:application:network:features:queries:feature-network-query-hive') implementation project(path: ':sphinx:application:network:features:feature-network-relay-call') implementation project(path: ':sphinx:screens:onboard:key-restore') diff --git a/sphinx/application/sphinx/src/main/java/chat/sphinx/di/NetworkModule.kt b/sphinx/application/sphinx/src/main/java/chat/sphinx/di/NetworkModule.kt index 07b6b106..ba97b9da 100644 --- a/sphinx/application/sphinx/src/main/java/chat/sphinx/di/NetworkModule.kt +++ b/sphinx/application/sphinx/src/main/java/chat/sphinx/di/NetworkModule.kt @@ -13,6 +13,7 @@ import chat.sphinx.concept_network_query_chat.NetworkQueryChat import chat.sphinx.concept_network_query_contact.NetworkQueryContact import chat.sphinx.concept_network_query_crypter.NetworkQueryCrypter import chat.sphinx.concept_network_query_discover_tribes.NetworkQueryDiscoverTribes +import chat.sphinx.concept_network_query_hive.NetworkQueryHive import chat.sphinx.concept_network_query_invite.NetworkQueryInvite import chat.sphinx.concept_network_query_meme_server.NetworkQueryMemeServer import chat.sphinx.concept_network_query_feed_search.NetworkQueryFeedSearch @@ -28,6 +29,7 @@ import chat.sphinx.feature_network_query_chat.NetworkQueryChatImpl import chat.sphinx.feature_network_query_contact.NetworkQueryContactImpl import chat.sphinx.feature_network_query_crypter.NetworkQueryCrypterImpl import chat.sphinx.feature_network_query_discover_tribes.NetworkQueryDiscoverTribesImpl +import chat.sphinx.feature_network_query_hive.NetworkQueryHiveImpl import chat.sphinx.feature_network_query_feed_status.NetworkQueryFeedStatusImpl import chat.sphinx.feature_network_query_invite.NetworkQueryInviteImpl import chat.sphinx.feature_network_query_meme_server.NetworkQueryMemeServerImpl @@ -322,4 +324,16 @@ object NetworkModule { networkQueryFeedStatusImpl: NetworkQueryFeedStatusImpl ): NetworkQueryFeedStatus = networkQueryFeedStatusImpl + + @Provides + fun provideNetworkQueryHiveImpl( + networkCall: NetworkCall + ): NetworkQueryHiveImpl = + NetworkQueryHiveImpl(networkCall) + + @Provides + fun provideNetworkQueryHive( + networkQueryHiveImpl: NetworkQueryHiveImpl + ): NetworkQueryHive = + networkQueryHiveImpl } diff --git a/sphinx/application/sphinx/src/main/java/chat/sphinx/di/RepositoryModule.kt b/sphinx/application/sphinx/src/main/java/chat/sphinx/di/RepositoryModule.kt index aa789ded..fa99398e 100644 --- a/sphinx/application/sphinx/src/main/java/chat/sphinx/di/RepositoryModule.kt +++ b/sphinx/application/sphinx/src/main/java/chat/sphinx/di/RepositoryModule.kt @@ -12,6 +12,7 @@ import chat.sphinx.concept_network_query_invite.NetworkQueryInvite import chat.sphinx.concept_network_query_meme_server.NetworkQueryMemeServer import chat.sphinx.concept_network_query_feed_search.NetworkQueryFeedSearch import chat.sphinx.concept_network_query_feed_status.NetworkQueryFeedStatus +import chat.sphinx.concept_network_query_hive.NetworkQueryHive import chat.sphinx.concept_network_query_people.NetworkQueryPeople import chat.sphinx.concept_network_query_verify_external.NetworkQueryAuthorizeExternal import chat.sphinx.concept_relay.RelayDataHandler @@ -146,6 +147,7 @@ object RepositoryModule { networkQueryPeople: NetworkQueryPeople, networkQueryFeedSearch: NetworkQueryFeedSearch, networkQueryFeedStatus: NetworkQueryFeedStatus, + networkQueryHive: NetworkQueryHive, connectManager: ConnectManager, dataSyncManager: DataSyncManager, walletDataHandler: WalletDataHandler, @@ -174,6 +176,7 @@ object RepositoryModule { networkQueryPeople, networkQueryFeedSearch, networkQueryFeedStatus, + networkQueryHive, connectManager, dataSyncManager, walletDataHandler,