Saves a copy of the NIP65 and NIP17 relay lists locally
This commit is contained in:
@@ -42,6 +42,8 @@ import com.vitorpamplona.quartz.encoders.Nip47WalletConnect
|
|||||||
import com.vitorpamplona.quartz.encoders.hexToByteArray
|
import com.vitorpamplona.quartz.encoders.hexToByteArray
|
||||||
import com.vitorpamplona.quartz.encoders.toHexKey
|
import com.vitorpamplona.quartz.encoders.toHexKey
|
||||||
import com.vitorpamplona.quartz.encoders.toNpub
|
import com.vitorpamplona.quartz.encoders.toNpub
|
||||||
|
import com.vitorpamplona.quartz.events.AdvertisedRelayListEvent
|
||||||
|
import com.vitorpamplona.quartz.events.ChatMessageRelayListEvent
|
||||||
import com.vitorpamplona.quartz.events.ContactListEvent
|
import com.vitorpamplona.quartz.events.ContactListEvent
|
||||||
import com.vitorpamplona.quartz.events.Event
|
import com.vitorpamplona.quartz.events.Event
|
||||||
import com.vitorpamplona.quartz.events.LnZapEvent
|
import com.vitorpamplona.quartz.events.LnZapEvent
|
||||||
@@ -90,6 +92,8 @@ private object PrefKeys {
|
|||||||
const val DEFAULT_DISCOVERY_FOLLOW_LIST = "defaultDiscoveryFollowList"
|
const val DEFAULT_DISCOVERY_FOLLOW_LIST = "defaultDiscoveryFollowList"
|
||||||
const val ZAP_PAYMENT_REQUEST_SERVER = "zapPaymentServer"
|
const val ZAP_PAYMENT_REQUEST_SERVER = "zapPaymentServer"
|
||||||
const val LATEST_CONTACT_LIST = "latestContactList"
|
const val LATEST_CONTACT_LIST = "latestContactList"
|
||||||
|
const val LATEST_DM_RELAY_LIST = "latestDMRelayList"
|
||||||
|
const val LATEST_NIP65_RELAY_LIST = "latestNIP65RelayList"
|
||||||
const val HIDE_DELETE_REQUEST_DIALOG = "hide_delete_request_dialog"
|
const val HIDE_DELETE_REQUEST_DIALOG = "hide_delete_request_dialog"
|
||||||
const val HIDE_BLOCK_ALERT_DIALOG = "hide_block_alert_dialog"
|
const val HIDE_BLOCK_ALERT_DIALOG = "hide_block_alert_dialog"
|
||||||
const val HIDE_NIP_17_WARNING_DIALOG = "hide_nip24_warning_dialog" // delete later
|
const val HIDE_NIP_17_WARNING_DIALOG = "hide_nip24_warning_dialog" // delete later
|
||||||
@@ -311,10 +315,33 @@ object LocalPreferences {
|
|||||||
PrefKeys.ZAP_PAYMENT_REQUEST_SERVER,
|
PrefKeys.ZAP_PAYMENT_REQUEST_SERVER,
|
||||||
Event.mapper.writeValueAsString(account.zapPaymentRequest),
|
Event.mapper.writeValueAsString(account.zapPaymentRequest),
|
||||||
)
|
)
|
||||||
|
if (account.backupContactList != null) {
|
||||||
putString(
|
putString(
|
||||||
PrefKeys.LATEST_CONTACT_LIST,
|
PrefKeys.LATEST_CONTACT_LIST,
|
||||||
Event.mapper.writeValueAsString(account.backupContactList),
|
Event.mapper.writeValueAsString(account.backupContactList),
|
||||||
)
|
)
|
||||||
|
} else {
|
||||||
|
remove(PrefKeys.LATEST_CONTACT_LIST)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (account.backupDMRelayList != null) {
|
||||||
|
putString(
|
||||||
|
PrefKeys.LATEST_DM_RELAY_LIST,
|
||||||
|
Event.mapper.writeValueAsString(account.backupDMRelayList),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
remove(PrefKeys.LATEST_DM_RELAY_LIST)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (account.backupNIP65RelayList != null) {
|
||||||
|
putString(
|
||||||
|
PrefKeys.LATEST_NIP65_RELAY_LIST,
|
||||||
|
Event.mapper.writeValueAsString(account.backupNIP65RelayList),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
remove(PrefKeys.LATEST_NIP65_RELAY_LIST)
|
||||||
|
}
|
||||||
|
|
||||||
putBoolean(PrefKeys.HIDE_DELETE_REQUEST_DIALOG, account.hideDeleteRequestDialog)
|
putBoolean(PrefKeys.HIDE_DELETE_REQUEST_DIALOG, account.hideDeleteRequestDialog)
|
||||||
putBoolean(PrefKeys.HIDE_NIP_17_WARNING_DIALOG, account.hideNIP17WarningDialog)
|
putBoolean(PrefKeys.HIDE_NIP_17_WARNING_DIALOG, account.hideNIP17WarningDialog)
|
||||||
putBoolean(PrefKeys.HIDE_BLOCK_ALERT_DIALOG, account.hideBlockAlertDialog)
|
putBoolean(PrefKeys.HIDE_BLOCK_ALERT_DIALOG, account.hideBlockAlertDialog)
|
||||||
@@ -471,8 +498,8 @@ object LocalPreferences {
|
|||||||
val latestContactList =
|
val latestContactList =
|
||||||
try {
|
try {
|
||||||
getString(PrefKeys.LATEST_CONTACT_LIST, null)?.let {
|
getString(PrefKeys.LATEST_CONTACT_LIST, null)?.let {
|
||||||
println("Decoding Contact List: " + it)
|
if (it != "null") {
|
||||||
if (it != null) {
|
println("Decoding Contact List: $it")
|
||||||
Event.fromJson(it) as ContactListEvent?
|
Event.fromJson(it) as ContactListEvent?
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
@@ -488,6 +515,46 @@ object LocalPreferences {
|
|||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val latestDmRelayList =
|
||||||
|
try {
|
||||||
|
getString(PrefKeys.LATEST_DM_RELAY_LIST, null)?.let {
|
||||||
|
if (it != "null") {
|
||||||
|
println("Decoding DM Relay List: $it")
|
||||||
|
Event.fromJson(it) as ChatMessageRelayListEvent?
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
if (e is CancellationException) throw e
|
||||||
|
Log.w(
|
||||||
|
"LocalPreferences",
|
||||||
|
"Error Decoding DM Relay List ${getString(PrefKeys.LATEST_DM_RELAY_LIST, null)}",
|
||||||
|
e,
|
||||||
|
)
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
|
val latestNip65RelayList =
|
||||||
|
try {
|
||||||
|
getString(PrefKeys.LATEST_NIP65_RELAY_LIST, null)?.let {
|
||||||
|
if (it != "null") {
|
||||||
|
println("Decoding NIP65 Relay List: $it")
|
||||||
|
Event.fromJson(it) as AdvertisedRelayListEvent?
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
if (e is CancellationException) throw e
|
||||||
|
Log.w(
|
||||||
|
"LocalPreferences",
|
||||||
|
"Error Decoding NIP65 Relay List ${getString(PrefKeys.LATEST_NIP65_RELAY_LIST, null)}",
|
||||||
|
e,
|
||||||
|
)
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
val pendingAttestations =
|
val pendingAttestations =
|
||||||
try {
|
try {
|
||||||
getString(PrefKeys.PENDING_ATTESTATIONS, null)?.let {
|
getString(PrefKeys.PENDING_ATTESTATIONS, null)?.let {
|
||||||
@@ -502,7 +569,7 @@ object LocalPreferences {
|
|||||||
if (e is CancellationException) throw e
|
if (e is CancellationException) throw e
|
||||||
Log.w(
|
Log.w(
|
||||||
"LocalPreferences",
|
"LocalPreferences",
|
||||||
"Error Decoding Contact List ${getString(PrefKeys.LATEST_CONTACT_LIST, null)}",
|
"Error Decoding Contact List ${getString(PrefKeys.PENDING_ATTESTATIONS, null)}",
|
||||||
e,
|
e,
|
||||||
)
|
)
|
||||||
null
|
null
|
||||||
@@ -595,6 +662,8 @@ object LocalPreferences {
|
|||||||
hideBlockAlertDialog = hideBlockAlertDialog,
|
hideBlockAlertDialog = hideBlockAlertDialog,
|
||||||
hideNIP17WarningDialog = hideNIP17WarningDialog,
|
hideNIP17WarningDialog = hideNIP17WarningDialog,
|
||||||
backupContactList = latestContactList,
|
backupContactList = latestContactList,
|
||||||
|
backupNIP65RelayList = latestNip65RelayList,
|
||||||
|
backupDMRelayList = latestDmRelayList,
|
||||||
proxy = proxy,
|
proxy = proxy,
|
||||||
proxyPort = proxyPort,
|
proxyPort = proxyPort,
|
||||||
showSensitiveContent = MutableStateFlow(showSensitiveContent),
|
showSensitiveContent = MutableStateFlow(showSensitiveContent),
|
||||||
|
|||||||
@@ -116,6 +116,7 @@ import kotlinx.coroutines.flow.Flow
|
|||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.SharingStarted
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import kotlinx.coroutines.flow.collect
|
||||||
import kotlinx.coroutines.flow.combineTransform
|
import kotlinx.coroutines.flow.combineTransform
|
||||||
import kotlinx.coroutines.flow.flatMapLatest
|
import kotlinx.coroutines.flow.flatMapLatest
|
||||||
import kotlinx.coroutines.flow.flattenMerge
|
import kotlinx.coroutines.flow.flattenMerge
|
||||||
@@ -192,6 +193,8 @@ class Account(
|
|||||||
var hideBlockAlertDialog: Boolean = false,
|
var hideBlockAlertDialog: Boolean = false,
|
||||||
var hideNIP17WarningDialog: Boolean = false,
|
var hideNIP17WarningDialog: Boolean = false,
|
||||||
var backupContactList: ContactListEvent? = null,
|
var backupContactList: ContactListEvent? = null,
|
||||||
|
var backupDMRelayList: ChatMessageRelayListEvent? = null,
|
||||||
|
var backupNIP65RelayList: AdvertisedRelayListEvent? = null,
|
||||||
var proxy: Proxy? = null,
|
var proxy: Proxy? = null,
|
||||||
var proxyPort: Int = 9050,
|
var proxyPort: Int = 9050,
|
||||||
var showSensitiveContent: MutableStateFlow<Boolean?> = MutableStateFlow(null),
|
var showSensitiveContent: MutableStateFlow<Boolean?> = MutableStateFlow(null),
|
||||||
@@ -269,7 +272,9 @@ class Account(
|
|||||||
if (mappedRelaySet.none { it.url == newUrl }) {
|
if (mappedRelaySet.none { it.url == newUrl }) {
|
||||||
mappedRelaySet = mappedRelaySet +
|
mappedRelaySet = mappedRelaySet +
|
||||||
RelaySetupInfo(
|
RelaySetupInfo(
|
||||||
newUrl, true, true,
|
newUrl,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
setOf(
|
setOf(
|
||||||
FeedType.PRIVATE_DMS,
|
FeedType.PRIVATE_DMS,
|
||||||
),
|
),
|
||||||
@@ -294,7 +299,9 @@ class Account(
|
|||||||
if (mappedRelaySet.none { it.url == newUrl }) {
|
if (mappedRelaySet.none { it.url == newUrl }) {
|
||||||
mappedRelaySet = mappedRelaySet +
|
mappedRelaySet = mappedRelaySet +
|
||||||
RelaySetupInfo(
|
RelaySetupInfo(
|
||||||
newUrl, true, false,
|
newUrl,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
setOf(
|
setOf(
|
||||||
FeedType.SEARCH,
|
FeedType.SEARCH,
|
||||||
),
|
),
|
||||||
@@ -319,9 +326,14 @@ class Account(
|
|||||||
if (mappedRelaySet.none { it.url == newUrl }) {
|
if (mappedRelaySet.none { it.url == newUrl }) {
|
||||||
mappedRelaySet = mappedRelaySet +
|
mappedRelaySet = mappedRelaySet +
|
||||||
RelaySetupInfo(
|
RelaySetupInfo(
|
||||||
newUrl, true, true,
|
newUrl,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
setOf(
|
setOf(
|
||||||
FeedType.FOLLOWS, FeedType.PUBLIC_CHATS, FeedType.GLOBAL, FeedType.PRIVATE_DMS,
|
FeedType.FOLLOWS,
|
||||||
|
FeedType.PUBLIC_CHATS,
|
||||||
|
FeedType.GLOBAL,
|
||||||
|
FeedType.PRIVATE_DMS,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -344,9 +356,14 @@ class Account(
|
|||||||
if (mappedRelaySet.none { it.url == newUrl }) {
|
if (mappedRelaySet.none { it.url == newUrl }) {
|
||||||
mappedRelaySet = mappedRelaySet +
|
mappedRelaySet = mappedRelaySet +
|
||||||
RelaySetupInfo(
|
RelaySetupInfo(
|
||||||
newUrl, true, true,
|
newUrl,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
setOf(
|
setOf(
|
||||||
FeedType.FOLLOWS, FeedType.PUBLIC_CHATS, FeedType.GLOBAL, FeedType.PRIVATE_DMS,
|
FeedType.FOLLOWS,
|
||||||
|
FeedType.PUBLIC_CHATS,
|
||||||
|
FeedType.GLOBAL,
|
||||||
|
FeedType.PRIVATE_DMS,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -363,10 +380,14 @@ class Account(
|
|||||||
val write = nip65setup.type == AdvertisedRelayListEvent.AdvertisedRelayType.BOTH || nip65setup.type == AdvertisedRelayListEvent.AdvertisedRelayType.READ
|
val write = nip65setup.type == AdvertisedRelayListEvent.AdvertisedRelayType.BOTH || nip65setup.type == AdvertisedRelayListEvent.AdvertisedRelayType.READ
|
||||||
|
|
||||||
RelaySetupInfo(
|
RelaySetupInfo(
|
||||||
relay.url, true, relay.write || write,
|
relay.url,
|
||||||
|
true,
|
||||||
|
relay.write || write,
|
||||||
relay.feedTypes +
|
relay.feedTypes +
|
||||||
setOf(
|
setOf(
|
||||||
FeedType.FOLLOWS, FeedType.GLOBAL, FeedType.PUBLIC_CHATS,
|
FeedType.FOLLOWS,
|
||||||
|
FeedType.GLOBAL,
|
||||||
|
FeedType.PUBLIC_CHATS,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
@@ -380,9 +401,12 @@ class Account(
|
|||||||
|
|
||||||
mappedRelaySet = mappedRelaySet +
|
mappedRelaySet = mappedRelaySet +
|
||||||
RelaySetupInfo(
|
RelaySetupInfo(
|
||||||
newNip65Setup.relayUrl, true, write,
|
newNip65Setup.relayUrl,
|
||||||
|
true,
|
||||||
|
write,
|
||||||
setOf(
|
setOf(
|
||||||
FeedType.FOLLOWS, FeedType.PUBLIC_CHATS,
|
FeedType.FOLLOWS,
|
||||||
|
FeedType.PUBLIC_CHATS,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -2635,6 +2659,26 @@ class Account(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun updateDMRelayList(newDMRelayList: ChatMessageRelayListEvent?) {
|
||||||
|
if (newDMRelayList == null || newDMRelayList.tags.isEmpty()) return
|
||||||
|
|
||||||
|
// Events might be different objects, we have to compare their ids.
|
||||||
|
if (backupDMRelayList?.id != newDMRelayList.id) {
|
||||||
|
backupDMRelayList = newDMRelayList
|
||||||
|
saveable.invalidateData()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateNIP65RelayList(newNIP65RelayList: AdvertisedRelayListEvent?) {
|
||||||
|
if (newNIP65RelayList == null || newNIP65RelayList.tags.isEmpty()) return
|
||||||
|
|
||||||
|
// Events might be different objects, we have to compare their ids.
|
||||||
|
if (backupNIP65RelayList?.id != newNIP65RelayList.id) {
|
||||||
|
backupNIP65RelayList = newNIP65RelayList
|
||||||
|
saveable.invalidateData()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Takes a User's relay list and adds the types of feeds they are active for.
|
// Takes a User's relay list and adds the types of feeds they are active for.
|
||||||
fun activeRelays(): Array<RelaySetupInfo>? {
|
fun activeRelays(): Array<RelaySetupInfo>? {
|
||||||
val usersRelayList =
|
val usersRelayList =
|
||||||
@@ -2968,8 +3012,32 @@ class Account(
|
|||||||
suspend fun registerObservers() =
|
suspend fun registerObservers() =
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
// saves contact list for the next time.
|
// saves contact list for the next time.
|
||||||
userProfile().live().follows.observeForever {
|
scope.launch {
|
||||||
GlobalScope.launch(Dispatchers.IO) { updateContactListTo(userProfile().latestContactList) }
|
Log.d("AccountRegisterObservers", "Kind 3 Collector Start")
|
||||||
|
userProfile().flow().follows.stateFlow.collect {
|
||||||
|
Log.d("AccountRegisterObservers", "Updating Kind 3 ${userProfile().toBestDisplayName()}")
|
||||||
|
updateContactListTo(userProfile().latestContactList)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scope.launch {
|
||||||
|
Log.d("AccountRegisterObservers", "NIP-17 Relay List Collector Start")
|
||||||
|
getDMRelayListFlow().collect {
|
||||||
|
Log.d("AccountRegisterObservers", "Updating DM Relay List for ${userProfile().toBestDisplayName()}")
|
||||||
|
(it.note.event as? ChatMessageRelayListEvent)?.let {
|
||||||
|
updateDMRelayList(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scope.launch {
|
||||||
|
Log.d("AccountRegisterObservers", "NIP-65 Relay List Collector Start")
|
||||||
|
getNIP65RelayListFlow().collect {
|
||||||
|
Log.d("AccountRegisterObservers", "Updating NIP-65 List for ${userProfile().toBestDisplayName()}")
|
||||||
|
(it.note.event as? AdvertisedRelayListEvent)?.let {
|
||||||
|
updateNIP65RelayList(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// imports transient blocks due to spam.
|
// imports transient blocks due to spam.
|
||||||
@@ -2990,7 +3058,7 @@ class Account(
|
|||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
Log.d("Init", "Account")
|
Log.d("Account", "Init")
|
||||||
backupContactList?.let {
|
backupContactList?.let {
|
||||||
println("Loading saved contacts ${it.toJson()}")
|
println("Loading saved contacts ${it.toJson()}")
|
||||||
|
|
||||||
@@ -2998,6 +3066,16 @@ class Account(
|
|||||||
GlobalScope.launch(Dispatchers.IO) { LocalCache.consume(it) }
|
GlobalScope.launch(Dispatchers.IO) { LocalCache.consume(it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
backupDMRelayList?.let {
|
||||||
|
println("Loading DM Relay List ${it.toJson()}")
|
||||||
|
GlobalScope.launch(Dispatchers.IO) { LocalCache.verifyAndConsume(it, null) }
|
||||||
|
}
|
||||||
|
|
||||||
|
backupNIP65RelayList?.let {
|
||||||
|
println("Loading saved contacts ${it.toJson()}")
|
||||||
|
GlobalScope.launch(Dispatchers.IO) { LocalCache.verifyAndConsume(it, null) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+80
-26
@@ -25,19 +25,35 @@ import com.vitorpamplona.amethyst.AccountInfo
|
|||||||
import com.vitorpamplona.amethyst.BuildConfig
|
import com.vitorpamplona.amethyst.BuildConfig
|
||||||
import com.vitorpamplona.amethyst.LocalPreferences
|
import com.vitorpamplona.amethyst.LocalPreferences
|
||||||
import com.vitorpamplona.amethyst.model.Account
|
import com.vitorpamplona.amethyst.model.Account
|
||||||
|
import com.vitorpamplona.amethyst.model.LocalCache
|
||||||
import com.vitorpamplona.ammolite.service.HttpClientManager
|
import com.vitorpamplona.ammolite.service.HttpClientManager
|
||||||
|
import com.vitorpamplona.quartz.events.AdvertisedRelayListEvent
|
||||||
|
import com.vitorpamplona.quartz.events.ChatMessageRelayListEvent
|
||||||
import com.vitorpamplona.quartz.events.RelayAuthEvent
|
import com.vitorpamplona.quartz.events.RelayAuthEvent
|
||||||
import kotlinx.coroutines.CancellationException
|
import kotlinx.coroutines.CancellationException
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.async
|
||||||
|
import kotlinx.coroutines.coroutineScope
|
||||||
|
import kotlinx.coroutines.joinAll
|
||||||
|
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
import kotlinx.coroutines.withTimeoutOrNull
|
||||||
import okhttp3.MediaType.Companion.toMediaType
|
import okhttp3.MediaType.Companion.toMediaType
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.RequestBody.Companion.toRequestBody
|
import okhttp3.RequestBody.Companion.toRequestBody
|
||||||
|
import kotlin.coroutines.resume
|
||||||
|
|
||||||
class RegisterAccounts(
|
class RegisterAccounts(
|
||||||
private val accounts: List<AccountInfo>,
|
private val accounts: List<AccountInfo>,
|
||||||
) {
|
) {
|
||||||
private fun recursiveAuthCreation(
|
val tag =
|
||||||
|
if (BuildConfig.FLAVOR == "play") {
|
||||||
|
"RegisterAccounts FirebaseMsgService"
|
||||||
|
} else {
|
||||||
|
"RegisterAccounts UnifiedPushService"
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun signAllAuths(
|
||||||
notificationToken: String,
|
notificationToken: String,
|
||||||
remainingTos: List<Pair<Account, String>>,
|
remainingTos: List<Pair<Account, String>>,
|
||||||
output: MutableList<RelayAuthEvent>,
|
output: MutableList<RelayAuthEvent>,
|
||||||
@@ -48,13 +64,33 @@ class RegisterAccounts(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val next = remainingTos.first()
|
coroutineScope {
|
||||||
|
val jobs =
|
||||||
next.first.createAuthEvent(next.second, notificationToken) {
|
remainingTos.map { accountRelayPair ->
|
||||||
output.add(it)
|
async {
|
||||||
recursiveAuthCreation(notificationToken, remainingTos.filter { next != it }, output, onReady)
|
val result =
|
||||||
|
withTimeoutOrNull(10000) {
|
||||||
|
suspendCancellableCoroutine { continuation ->
|
||||||
|
accountRelayPair.first.createAuthEvent(accountRelayPair.second, notificationToken) { result ->
|
||||||
|
continuation.resume(result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result != null) {
|
||||||
|
output.add(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// runs in parallel to avoid overcrowding Amber.
|
||||||
|
withTimeoutOrNull(15000) {
|
||||||
|
jobs.joinAll()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onReady(output)
|
||||||
|
}
|
||||||
|
|
||||||
// creates proof that it controls all accounts
|
// creates proof that it controls all accounts
|
||||||
private suspend fun signEventsToProveControlOfAccounts(
|
private suspend fun signEventsToProveControlOfAccounts(
|
||||||
@@ -63,25 +99,48 @@ class RegisterAccounts(
|
|||||||
onReady: (List<RelayAuthEvent>) -> Unit,
|
onReady: (List<RelayAuthEvent>) -> Unit,
|
||||||
) {
|
) {
|
||||||
val readyToSend =
|
val readyToSend =
|
||||||
accounts.mapNotNull {
|
accounts
|
||||||
val acc = LocalPreferences.loadCurrentAccountFromEncryptedStorage(it.npub)
|
.map {
|
||||||
if (acc != null && acc.isWriteable()) {
|
Log.d(tag, "Register Account ${it.npub}")
|
||||||
val readRelays =
|
|
||||||
acc.userProfile().latestContactList?.relays() ?: acc.backupContactList?.relays()
|
|
||||||
|
|
||||||
val relayToUse = readRelays?.firstNotNullOfOrNull { if (it.value.read) it.key else null }
|
val acc = LocalPreferences.loadCurrentAccountFromEncryptedStorage(it.npub)
|
||||||
if (relayToUse != null) {
|
|
||||||
Pair(acc, relayToUse)
|
if (acc != null && acc.isWriteable()) {
|
||||||
} else {
|
val nip65Read =
|
||||||
null
|
(
|
||||||
|
LocalCache
|
||||||
|
.getAddressableNoteIfExists(
|
||||||
|
AdvertisedRelayListEvent.createAddressTag(acc.userProfile().pubkeyHex),
|
||||||
|
)?.event as? AdvertisedRelayListEvent
|
||||||
|
)?.readRelays() ?: acc.backupNIP65RelayList?.readRelays() ?: emptyList<String>()
|
||||||
|
|
||||||
|
Log.d(tag, "Register Account ${acc.userProfile().toBestDisplayName()} NIP65 Reads ${nip65Read.joinToString(", ")}")
|
||||||
|
|
||||||
|
val nip17Read =
|
||||||
|
(
|
||||||
|
LocalCache
|
||||||
|
.getAddressableNoteIfExists(
|
||||||
|
ChatMessageRelayListEvent.createAddressTag(acc.userProfile().pubkeyHex),
|
||||||
|
)?.event as? ChatMessageRelayListEvent
|
||||||
|
)?.relays() ?: acc.backupDMRelayList?.relays() ?: emptyList<String>()
|
||||||
|
|
||||||
|
Log.d(tag, "Register Account ${acc.userProfile().toBestDisplayName()} NIP17 Reads ${nip17Read.joinToString(", ")}")
|
||||||
|
|
||||||
|
val kind3Relays = (acc.userProfile().latestContactList?.relays() ?: acc.backupContactList?.relays())
|
||||||
|
val readKind3Relays = kind3Relays?.mapNotNull { if (it.value.read) it.key else null } ?: emptyList<String>()
|
||||||
|
|
||||||
|
Log.d(tag, "Register Account ${acc.userProfile().toBestDisplayName()} Kind3 Reads ${readKind3Relays.joinToString(", ")}")
|
||||||
|
|
||||||
|
(nip65Read + nip17Read + readKind3Relays).map {
|
||||||
|
Pair(acc, it)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
null
|
emptyList<Pair<Account, String>>()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}.flatten()
|
||||||
|
|
||||||
val listOfAuthEvents = mutableListOf<RelayAuthEvent>()
|
val listOfAuthEvents = mutableListOf<RelayAuthEvent>()
|
||||||
recursiveAuthCreation(
|
signAllAuths(
|
||||||
notificationToken,
|
notificationToken,
|
||||||
readyToSend,
|
readyToSend,
|
||||||
listOfAuthEvents,
|
listOfAuthEvents,
|
||||||
@@ -101,7 +160,8 @@ class RegisterAccounts(
|
|||||||
val body = jsonObject.toRequestBody(mediaType)
|
val body = jsonObject.toRequestBody(mediaType)
|
||||||
|
|
||||||
val request =
|
val request =
|
||||||
Request.Builder()
|
Request
|
||||||
|
.Builder()
|
||||||
.header("User-Agent", "Amethyst/${BuildConfig.VERSION_NAME}")
|
.header("User-Agent", "Amethyst/${BuildConfig.VERSION_NAME}")
|
||||||
.url("https://push.amethyst.social/register")
|
.url("https://push.amethyst.social/register")
|
||||||
.post(body)
|
.post(body)
|
||||||
@@ -112,12 +172,6 @@ class RegisterAccounts(
|
|||||||
val isSucess = client.newCall(request).execute().use { it.isSuccessful }
|
val isSucess = client.newCall(request).execute().use { it.isSuccessful }
|
||||||
} catch (e: java.lang.Exception) {
|
} catch (e: java.lang.Exception) {
|
||||||
if (e is CancellationException) throw e
|
if (e is CancellationException) throw e
|
||||||
val tag =
|
|
||||||
if (BuildConfig.FLAVOR == "play") {
|
|
||||||
"FirebaseMsgService"
|
|
||||||
} else {
|
|
||||||
"UnifiedPushService"
|
|
||||||
}
|
|
||||||
Log.e(tag, "Unable to register with push server", e)
|
Log.e(tag, "Unable to register with push server", e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user