Updated on 2026-08-14

This commit is contained in:
Tangem 2026-07-07 14:59:18 +01:00
parent b995f180f1
commit 2b49c5f2c8
4 changed files with 15 additions and 19 deletions

View file

@ -126,9 +126,8 @@ internal class DefaultAddressBookRepository(
override suspend fun syncAddressBooks(): Either<AddressBookSyncError, Unit> = withContext(dispatchers.default) {
val wallets = userWalletsListRepository.userWalletsSync()
// Debug (Logcat only, dev builds) — the persisted prod log stays quiet on the happy path; only failures
// below are written at Error level.
logger.d("Syncing address books for ${wallets.size} wallet(s)")
// Metadata only (wallet count) — persisted to the prod log so sync activity is traceable.
logger.i("Syncing address books for ${wallets.size} wallet(s)")
// The backend rejects more than MAX_SYNC_WALLETS per request, so sync in chunks and stop on the
// first failed chunk.
wallets.chunked(MAX_SYNC_WALLETS)
@ -150,13 +149,13 @@ internal class DefaultAddressBookRepository(
call = {
val response = withContext(dispatchers.io) { addressBookApi.syncAddressBooks(request).bind() }
// Only wallets whose etag changed are returned; the rest keep their local copy.
logger.d("Sync response: ${response.items.size} updated book(s) out of ${wallets.size} requested")
logger.i("Sync response: ${response.items.size} updated book(s) out of ${wallets.size} requested")
response.items.forEach { item ->
val userWalletId = UserWalletId(stringValue = item.walletId)
// Metadata only — helps QA verify what the backend delivered (esp. for cross-platform books).
// Debug (Logcat only) to keep the persisted prod log free of happy-path sync noise.
logger.d(
"Storing synced address book for wallet ${item.walletId}: version=${item.version}, " +
// Metadata only (no keys/ciphertext/plaintext) — helps QA verify what the backend delivered
// (esp. for cross-platform books).
logger.i(
"Storing synced address book for wallet ${item.walletId}: " +
"updatedAt=${item.updatedAt}, nonceLen=${item.nonce.length}, " +
"ciphertextLen=${item.ciphertext.length}, authTagLen=${item.authTag.length}",
)

View file

@ -62,9 +62,9 @@ class AddressBookCipher {
authTag = authTag.toHexString().lowercase(),
).also { blob ->
// Metadata only — the plaintext (contact names/addresses/memos) is never logged.
logger.d(
logger.i(
"Encrypted address book for wallet ${blob.walletId}: contacts=${addressBook.contacts.size}, " +
"plaintextBytes=${plaintext.size}, version=${blob.version}, " +
"plaintextBytes=${plaintext.size}, " +
"nonceLen=${blob.nonce.length}, ciphertextLen=${blob.ciphertext.length}, " +
"authTagLen=${blob.authTag.length}",
)
@ -73,14 +73,14 @@ class AddressBookCipher {
fun decrypt(blob: AddressBookBlob, userWallet: UserWallet): Either<AddressBookCryptoError, AddressBook> = either {
// Metadata only — helps QA correlate a failing blob with what was received from the backend/other platform.
logger.d(
"Decrypting address book for wallet ${blob.walletId}: version=${blob.version}, " +
logger.i(
"Decrypting address book for wallet ${blob.walletId}: " +
"updatedAt=${blob.updatedAt}, nonceLen=${blob.nonce.length}, " +
"ciphertextLen=${blob.ciphertext.length}, authTagLen=${blob.authTag.length}",
)
ensure(blob.walletId == userWallet.walletId.stringValue) {
logger.w(
logger.e(
"Wallet mismatch decrypting address book: blob wallet=${blob.walletId}, " +
"target wallet=${userWallet.walletId.stringValue}",
)
@ -116,12 +116,12 @@ class AddressBookCipher {
// reason (missing/extra field, wrong type, JSON path) but strips any raw plaintext the exception echoes.
logger.e(
"Failed to parse decrypted address book for wallet ${blob.walletId} " +
"(plaintextBytes=${plaintext.size}, version=${blob.version}): ${error.safeDescription()}. " +
"(plaintextBytes=${plaintext.size}): ${error.safeDescription()}. " +
"Decryption OK → cross-platform payload schema/format mismatch.",
)
raise(AddressBookCryptoError.MalformedBlob)
}.also { addressBook ->
logger.d(
logger.i(
messageString = "Decrypted address book for wallet ${blob.walletId}: " +
"contacts=${addressBook.contacts.size}",
)
@ -135,7 +135,7 @@ class AddressBookCipher {
): Nothing {
logger.e(
"Address book blob has non-hex $field for wallet ${blob.walletId} " +
"(${field}Len=${value.length}, version=${blob.version}).",
"(${field}Len=${value.length}).",
)
raise(AddressBookCryptoError.DecryptionFailed)
}

View file

@ -112,7 +112,6 @@ internal class ContactsBlockModelTest {
id = AddressEntryId("e-$id"),
address = "0x$id",
networkId = Network.RawID(ETHEREUM),
networkName = "Ethereum",
memo = null,
signature = "sig",
),

View file

@ -986,7 +986,6 @@ internal class EditContactModelTest {
id = AddressEntryId("e-1"),
address = "0xAAA",
networkId = Network.RawID("ethereum"),
networkName = "Ethereum",
memo = null,
signature = "sig",
),
@ -994,7 +993,6 @@ internal class EditContactModelTest {
id = AddressEntryId("e-2"),
address = "0xBBB",
networkId = Network.RawID("bsc"),
networkName = "BSC",
memo = null,
signature = "sig",
),