Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed
- Improve Pubky profile restore, contact editing, and contact routing flows #905

### Fixed
- Polish Terms of Use screen padding to match iOS #903

Expand Down
17 changes: 17 additions & 0 deletions app/src/main/java/to/bitkit/models/BackupPayloads.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import com.synonym.bitkitcore.IBtInfo
import com.synonym.bitkitcore.IBtOrder
import com.synonym.bitkitcore.IcJitEntry
import com.synonym.bitkitcore.PreActivityMetadata
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import to.bitkit.data.AppCacheData
import to.bitkit.data.SettingsData
Expand All @@ -26,8 +27,24 @@ data class MetadataBackupV1(
val createdAt: Long,
val tagMetadata: List<PreActivityMetadata>,
val cache: AppCacheData,
val pubkySession: PubkySessionBackupV1? = null,
)

@Serializable
data class PubkySessionBackupV1(
val kind: PubkySessionBackupKind,
val sessionSecret: String? = null,
)

@Serializable
enum class PubkySessionBackupKind {
@SerialName("localSeed")
LocalSeed,

@SerialName("externalSession")
ExternalSession,
}

@Serializable
data class BlocktankBackupV1(
val version: Int = 1,
Expand Down
43 changes: 31 additions & 12 deletions app/src/main/java/to/bitkit/repositories/BackupRepo.kt
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ class BackupRepo @Inject constructor(
private val widgetsStore: WidgetsStore,
private val blocktankRepo: BlocktankRepo,
private val activityRepo: ActivityRepo,
private val pubkyRepo: PubkyRepo,
private val preActivityMetadataRepo: PreActivityMetadataRepo,
private val lightningService: LightningService,
private val clock: Clock,
Expand Down Expand Up @@ -268,6 +269,16 @@ class BackupRepo @Inject constructor(
}
dataListenerJobs.add(preActivityMetadataJob)

val pubkyStateJob = scope.launch {
pubkyRepo.backupStateVersion
.drop(1)
.collect {
if (shouldSkipBackup()) return@collect
markBackupRequired(BackupCategory.METADATA)
}
}
dataListenerJobs.add(pubkyStateJob)

// BLOCKTANK - Observe blocktank state changes (orders, cjitEntries, info)
val blocktankJob = scope.launch {
blocktankRepo.blocktankState
Expand Down Expand Up @@ -461,18 +472,7 @@ class BackupRepo @Inject constructor(
json.encodeToString(payload).toByteArray()
}

BackupCategory.METADATA -> {
val preActivityMetadata = preActivityMetadataRepo.getAllPreActivityMetadata().getOrDefault(emptyList())
val cacheData = cacheStore.data.first()

val payload = MetadataBackupV1(
createdAt = currentTimeMillis(),
tagMetadata = preActivityMetadata,
cache = cacheData,
)

json.encodeToString(payload).toByteArray()
}
BackupCategory.METADATA -> getMetadataBackupDataBytes()

BackupCategory.BLOCKTANK -> {
val blocktankState = blocktankRepo.blocktankState.first()
Expand Down Expand Up @@ -505,6 +505,21 @@ class BackupRepo @Inject constructor(
BackupCategory.LIGHTNING_CONNECTIONS -> throw NotImplementedError("LIGHTNING backup is managed by ldk-node")
}

private suspend fun getMetadataBackupDataBytes(): ByteArray = withContext(ioDispatcher) {
val preActivityMetadata = preActivityMetadataRepo.getAllPreActivityMetadata().getOrDefault(emptyList())
val cacheData = cacheStore.data.first()
val pubkySession = pubkyRepo.snapshotSessionBackupState().getOrDefault(null)

val payload = MetadataBackupV1(
createdAt = currentTimeMillis(),
tagMetadata = preActivityMetadata,
cache = cacheData,
pubkySession = pubkySession,
)

json.encodeToString(payload).toByteArray()
}

suspend fun performFullRestoreFromLatestBackup(
onCacheRestored: suspend () -> Unit = {},
): Result<Unit> = withContext(ioDispatcher) {
Expand All @@ -520,6 +535,10 @@ class BackupRepo @Inject constructor(
Logger.debug("Restored caches: ${jsonLogOf(parsed.cache.copy(cachedRates = emptyList()))}", TAG)
onCacheRestored()
preActivityMetadataRepo.upsertPreActivityMetadata(parsed.tagMetadata).getOrNull()
pubkyRepo.restoreSessionBackupState(parsed.pubkySession)
.onFailure {
Logger.warn("Failed to restore pubky session backup state", it, context = TAG)
}
Logger.debug("Restored ${parsed.tagMetadata.size} pre-activity metadata", TAG)
parsed.createdAt
}
Expand Down
Loading
Loading