diff --git a/app/src/main/java/com/tangem/data/network/Server.java b/app/src/main/java/com/tangem/data/network/Server.java index 8638e2e1dd..a74bace4ac 100644 --- a/app/src/main/java/com/tangem/data/network/Server.java +++ b/app/src/main/java/com/tangem/data/network/Server.java @@ -11,7 +11,7 @@ public class Server { public static class Method { public static final String VERIFY = URL_TANGEM + "verify"; - public static final String VERIFY_AND_GET_ARTWORK = URL_TANGEM + "card/verify-and-get-artwork"; + public static final String VERIFY_AND_GET_INFO = URL_TANGEM + "card/verify-and-get-info"; public static final String ARTWORK = URL_TANGEM + "card/artwork"; } } diff --git a/app/src/main/java/com/tangem/data/network/ServerApiHelper.java b/app/src/main/java/com/tangem/data/network/ServerApiHelper.java index e3df2ad909..2f16b30b9f 100644 --- a/app/src/main/java/com/tangem/data/network/ServerApiHelper.java +++ b/app/src/main/java/com/tangem/data/network/ServerApiHelper.java @@ -5,10 +5,7 @@ import android.support.annotation.NonNull; import android.util.Log; import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory; -import com.tangem.data.network.model.CardVerify; -import com.tangem.data.network.model.CardVerifyAndGetArtwork; -import com.tangem.data.network.model.CardVerifyBody; -import com.tangem.data.network.model.CardVerifyResponse; +import com.tangem.data.network.model.CardVerifyAndGetInfo; import com.tangem.data.network.model.InfuraBody; import com.tangem.data.network.model.InfuraResponse; import com.tangem.data.network.model.RateInfoResponse; @@ -242,17 +239,17 @@ public class ServerApiHelper { * HTTP * Card verify */ - private CardVerifyAndGetArtworkListener cardVerifyAndGetArtworkListener; + private CardVerifyAndGetInfoListener cardVerifyAndGetInfoListener; - public interface CardVerifyAndGetArtworkListener { - void onCardVerifyAndGetArtwork(CardVerifyAndGetArtwork.Response cardVerifyAndGetArtworkResponse); + public interface CardVerifyAndGetInfoListener { + void onCardVerifyAndGetInfo(CardVerifyAndGetInfo.Response cardVerifyAndGetArtworkResponse); } - public void setCardVerifyAndGetArtworkListener(CardVerifyAndGetArtworkListener listener) { - cardVerifyAndGetArtworkListener = listener; + public void setCardVerifyAndGetInfoListener(CardVerifyAndGetInfoListener listener) { + cardVerifyAndGetInfoListener = listener; } - public void cardVerifyAndGetArtwork(TangemCard card) { + public void cardVerifyAndGetInfo(TangemCard card) { HttpLoggingInterceptor logging = new HttpLoggingInterceptor(); logging.setLevel(HttpLoggingInterceptor.Level.BODY); @@ -269,26 +266,26 @@ public class ServerApiHelper { TangemApi tangemApi = retrofit.create(TangemApi.class); - List requests = new ArrayList<>(); - requests.add(new CardVerifyAndGetArtwork.Request.Item(Util.bytesToHex(card.getCID()), Util.bytesToHex(card.getCardPublicKey()))); + List requests = new ArrayList<>(); + requests.add(new CardVerifyAndGetInfo.Request.Item(Util.bytesToHex(card.getCID()), Util.bytesToHex(card.getCardPublicKey()))); - CardVerifyAndGetArtwork.Request requestBody = new CardVerifyAndGetArtwork.Request(requests); + CardVerifyAndGetInfo.Request requestBody = new CardVerifyAndGetInfo.Request(requests); - Call call = tangemApi.getCardVerifyAndGetArtwork(requestBody); - call.enqueue(new Callback() { + Call call = tangemApi.getCardVerifyAndGetInfo(requestBody); + call.enqueue(new Callback() { @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { + public void onResponse(@NonNull Call call, @NonNull Response response) { if (response.code() == 200) { - CardVerifyAndGetArtwork.Response cardVerifyAndGetArtworkResponse = response.body(); - cardVerifyAndGetArtworkListener.onCardVerifyAndGetArtwork(cardVerifyAndGetArtworkResponse); - Log.i(TAG, "cardVerifyAndGetArtwork onResponse " + response.code()); + CardVerifyAndGetInfo.Response cardVerifyAndGetArtworkResponse = response.body(); + cardVerifyAndGetInfoListener.onCardVerifyAndGetInfo(cardVerifyAndGetArtworkResponse); + Log.i(TAG, "cardVerifyAndGeInfo onResponse " + response.code()); } else - Log.e(TAG, "cardVerifyAndGetArtwork onResponse " + response.code()); + Log.e(TAG, "cardVerifyAndGetInfo onResponse " + response.code()); } @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - Log.e(TAG, "cardVerifyAndGetArtwork onFailure " + t.getMessage()); + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + Log.e(TAG, "cardVerifyAndGetInfo onFailure " + t.getMessage()); } }); } diff --git a/app/src/main/java/com/tangem/data/network/TangemApi.java b/app/src/main/java/com/tangem/data/network/TangemApi.java index 38e658e49b..7fd96c51a9 100644 --- a/app/src/main/java/com/tangem/data/network/TangemApi.java +++ b/app/src/main/java/com/tangem/data/network/TangemApi.java @@ -1,6 +1,6 @@ package com.tangem.data.network; -import com.tangem.data.network.model.CardVerifyAndGetArtwork; +import com.tangem.data.network.model.CardVerifyAndGetInfo; import com.tangem.data.network.model.CardVerifyBody; import com.tangem.data.network.model.CardVerifyResponse; @@ -18,8 +18,8 @@ public interface TangemApi { Call getCardVerify(@Body CardVerifyBody body); @Headers("Content-Type: application/json") - @POST(Server.ApiTangem.Method.VERIFY_AND_GET_ARTWORK) - Call getCardVerifyAndGetArtwork(@Body CardVerifyAndGetArtwork.Request requestBody); + @POST(Server.ApiTangem.Method.VERIFY_AND_GET_INFO) + Call getCardVerifyAndGetInfo(@Body CardVerifyAndGetInfo.Request requestBody); @GET(Server.ApiTangem.Method.ARTWORK) Call getArtwork(@Query("artworkId") String artworkId, @Query("CID") String CID, @Query("publicKey") String publicKey); diff --git a/app/src/main/java/com/tangem/data/network/model/CardVerifyAndGetArtwork.kt b/app/src/main/java/com/tangem/data/network/model/CardVerifyAndGetArtwork.kt deleted file mode 100644 index 5d58b694d0..0000000000 --- a/app/src/main/java/com/tangem/data/network/model/CardVerifyAndGetArtwork.kt +++ /dev/null @@ -1,56 +0,0 @@ -package com.tangem.data.network.model - -import android.os.Build -import java.text.SimpleDateFormat -import java.time.Instant -import java.time.LocalDateTime -import java.time.ZoneOffset -import java.time.format.DateTimeFormatter -import java.util.* - -class CardVerifyAndGetArtwork { - data class Request( - var requests: List? = null - ) { - - data class Item( - var CID: String = "", - var publicKey: String = "" - ) - - } - - data class Response( - var results: List? = null - ) { - - data class Item( - var error: String? = null, - var CID: String = "", - var passed: Boolean = false, - var batch: String = "", - var artworkId: String = "", - var artworkHash: String = "", - var updateDate: String = "" - ) { - fun getUpdateDate(): Instant? { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - return try { - LocalDateTime.parse(updateDate, DateTimeFormatter.ISO_LOCAL_DATE_TIME).toInstant(ZoneOffset.UTC) - } catch (e: Exception) { - e.printStackTrace() - null - } - } else { - return try { - SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.US).parse(updateDate).toInstant() - } catch (e: Exception) { - e.printStackTrace() - null - } - } - } - } - } - -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/data/network/model/CardVerifyAndGetInfo.kt b/app/src/main/java/com/tangem/data/network/model/CardVerifyAndGetInfo.kt new file mode 100644 index 0000000000..92060eaccf --- /dev/null +++ b/app/src/main/java/com/tangem/data/network/model/CardVerifyAndGetInfo.kt @@ -0,0 +1,64 @@ +package com.tangem.data.network.model + +import android.os.Build +import java.text.SimpleDateFormat +import java.time.Instant +import java.time.LocalDateTime +import java.time.ZoneOffset +import java.time.format.DateTimeFormatter +import java.util.* + +class CardVerifyAndGetInfo { + data class Request( + var requests: List? = null + ) { + + data class Item( + var CID: String = "", + var publicKey: String = "" + ) + + } + + data class Response( + var results: List? = null + ) { + + data class Item( + var error: String? = null, + var CID: String = "", + var passed: Boolean = false, + var batch: String = "", + var artwork: ArtworkInfo? = null, + var substitution: SubstitutionInfo? = null + ) { + + data class ArtworkInfo( + var id: String = "", + var hash: String = "", + var date: String = "" + ) { + fun getUpdateDate(): Instant? { + try { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + return LocalDateTime.parse(date, DateTimeFormatter.ISO_LOCAL_DATE_TIME).toInstant(ZoneOffset.UTC) + } else { + return SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.US).parse(date).toInstant() + } + } catch (e: Exception) { + e.printStackTrace() + return null + } + } + + } + + data class SubstitutionInfo( + var data: String? = null, + var signature: String? = null + ) + + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/domain/wallet/ArtworksStorage.kt b/app/src/main/java/com/tangem/domain/wallet/LocalStorage.kt similarity index 52% rename from app/src/main/java/com/tangem/domain/wallet/ArtworksStorage.kt rename to app/src/main/java/com/tangem/domain/wallet/LocalStorage.kt index 29eac018f9..d9e391a87c 100644 --- a/app/src/main/java/com/tangem/domain/wallet/ArtworksStorage.kt +++ b/app/src/main/java/com/tangem/domain/wallet/LocalStorage.kt @@ -8,23 +8,31 @@ import kotlin.collections.HashMap import android.graphics.BitmapFactory import com.google.gson.Gson import com.google.gson.reflect.TypeToken +import com.tangem.data.network.model.CardVerifyAndGetInfo +import com.tangem.domain.cardReader.CardCrypto import com.tangem.util.Util import com.tangem.wallet.R import java.io.InputStream import java.lang.Exception +import java.nio.charset.StandardCharsets import java.time.Instant -data class ArtworksStorage( +data class LocalStorage( val context: Context ) { - private val cache: FileCache = FileCache(context) private lateinit var artworks: HashMap private lateinit var batches: HashMap - private var artworksFile: File = File(context.filesDir, "artworks.json") - private var batchesFile: File = File(context.filesDir, "batches.json") + private val artworksFile: File = File(context.filesDir, "artworks.json") + private val batchesFile: File = File(context.filesDir, "batches.json") + + private var cacheDir: File? = null init { + cacheDir = File(context.filesDir, "artworks") + if (!cacheDir!!.exists()) + cacheDir!!.mkdirs() + if (artworksFile.exists()) { artworksFile.bufferedReader().use { artworks = Gson().fromJson(it, object : TypeToken>() {}.type) } } else { @@ -62,24 +70,44 @@ data class ArtworksStorage( } } - fun checkNeedUpdateArtwork(artworkId: String, artworkHash: String, updateDate: Instant?): Boolean { - val artwork = artworks[artworkId] ?: return true - - if (artwork.hash == artworkHash) return false - - if (updateDate == null) return false - - return artwork.updateDate == null || artwork.updateDate < updateDate + private fun getArtworkFile(artworkId: String): File { + return File(cacheDir, "$artworkId.png") } - fun checkBatchArtworkChanged(batch: String, artworkId: String): Boolean { - val batchInfo = batches[batch] - if (batchInfo == null) { - putBatchToCatalog(batch, artworkId) - return true + private fun loadArtworkBitmapFromFile(artworkId: String): Bitmap? { + return try { + BitmapFactory.decodeFile(getArtworkFile(artworkId).absolutePath) + } catch (E: Exception) { + E.printStackTrace() + null } - if (batchInfo.artworkId != artworkId) { - putBatchToCatalog(batch, artworkId) + } + + private fun saveArtworkBitmapToFile(artworkId: String, data: ByteArray) { + val file = getArtworkFile(artworkId) + file.writeBytes(data) + } + + fun checkNeedUpdateArtwork(artwork: CardVerifyAndGetInfo.Response.Item.ArtworkInfo?): Boolean { + if (artwork == null) return false + val localArtwork = artworks[artwork.id] ?: return true + + if (localArtwork.hash == artwork.hash) return false + + + return localArtwork.updateDate == null || localArtwork.updateDate < artwork.getUpdateDate() + } + + fun checkBatchInfoChanged(result: CardVerifyAndGetInfo.Response.Item): Boolean { + var sData: String? = result.substitution?.data + var sSignature: String? = result.substitution?.signature + if (!BatchInfo.CardDataSubstitution.verifySignature(result.batch, sData, sSignature)) { + sData = null + sSignature = null + } + val batchInfo = batches[result.batch] + if (batchInfo == null || batchInfo.artworkId != result.artwork?.id || batchInfo.dataSubstitution != sData) { + putBatchToCatalog(result.batch, result.artwork?.id, sData, sSignature) return true } return false @@ -87,12 +115,12 @@ data class ArtworksStorage( fun updateArtwork(artworkId: String, inputStream: InputStream, updateDate: Instant) { val data = inputStream.readBytes() - cache.saveBitmap(artworkId, data) + saveArtworkBitmapToFile(artworkId, data) putArtworkToCatalog(artworkId, false, data, updateDate, true) } - private fun putBatchToCatalog(batch: String, artworkId: String, forceSave: Boolean = true) { - batches[batch] = BatchInfo(artworkId) + private fun putBatchToCatalog(batch: String, artworkId: String?, substitution: String?, substitutionSignature: String?, forceSave: Boolean = true) { + batches[batch] = BatchInfo(artworkId, substitution, substitutionSignature) if (forceSave) { val sBatches = Gson().toJson(batches) batchesFile.bufferedWriter().use { it.write(sBatches) } @@ -122,15 +150,16 @@ data class ArtworksStorage( if (resID == 0) return null BitmapFactory.decodeResource(context.resources, resID) } else { - cache.getBitmap(artworkId) + loadArtworkBitmapFromFile(artworkId) } } private fun getDefaultArtworkBitmap(): Bitmap { + val defaultArtworkId = context.resources.getResourceEntryName(R.drawable.card_default) val info = artworks[defaultArtworkId] var bitmap: Bitmap? = null if (info != null && !info.isResource) { - bitmap = cache.getBitmap(defaultArtworkId) + bitmap = loadArtworkBitmapFromFile(defaultArtworkId) } if (bitmap == null) return BitmapFactory.decodeResource(context.resources, R.drawable.card_default) return bitmap @@ -138,57 +167,63 @@ data class ArtworksStorage( fun getCardArtworkBitmap(card: TangemCard): Bitmap { // special cases (first series of cards, hardcode CID->artwork), on new series batch<->artwork - var artworkId = + val artworkId = when (card.cidDescription) { in "AA01 0000 0000 0000".."AA01 0000 0000 4999" -> { - context.resources.getResourceName(R.drawable.card_btc_001) + context.resources.getResourceEntryName(R.drawable.card_btc_001) } in "AA01 0000 0000 5000".."AA01 0000 0000 9999" -> { - context.resources.getResourceName(R.drawable.card_btc_005) + context.resources.getResourceEntryName(R.drawable.card_btc_005) } in "AE01 0000 0000 0000".."AE01 0000 0000 4999" -> { - context.resources.getResourceName(R.drawable.card_btc_001) + context.resources.getResourceEntryName(R.drawable.card_btc_001) } in "AE01 0000 0000 5000".."AE01 0000 0000 9999" -> { - context.resources.getResourceName(R.drawable.card_btc_005) + context.resources.getResourceEntryName(R.drawable.card_btc_005) } in "CB01 0000 0000 0000".."CB01 0000 0000 9999" -> { - context.resources.getResourceName(R.drawable.card_btc_001) + context.resources.getResourceEntryName(R.drawable.card_btc_001) } in "CB01 0000 0001 0000".."CB01 0000 0001 9999" -> { - context.resources.getResourceName(R.drawable.card_btc_005) + context.resources.getResourceEntryName(R.drawable.card_btc_005) } in "CB01 0000 0002 0000".."CB01 0000 0003 9999" -> { - context.resources.getResourceName(R.drawable.card_btc_001) + context.resources.getResourceEntryName(R.drawable.card_btc_001) } in "CB01 0000 0004 0000".."CB01 0000 0005 9999" -> { - context.resources.getResourceName(R.drawable.card_btc_005) + context.resources.getResourceEntryName(R.drawable.card_btc_005) } in "CB02 0000 0000 0000".."CB02 0000 0002 4999" -> { - context.resources.getResourceName(R.drawable.card_btc_001) + context.resources.getResourceEntryName(R.drawable.card_btc_001) } in "CB02 0000 0002 5000".."CB02 0000 0004 9999" -> { - context.resources.getResourceName(R.drawable.card_btc_005) + context.resources.getResourceEntryName(R.drawable.card_btc_005) } in "CB05 0000 1000 0000".."CB05 0000 1000 9999" -> { - context.resources.getResourceName(R.drawable.card_btc_001) + context.resources.getResourceEntryName(R.drawable.card_btc_001) } else -> { val batchInfo = batches[card.batch] ?: return getDefaultArtworkBitmap() batchInfo.artworkId } - } - if( artworkId.contains('/')) - artworkId=artworkId.split('/').last() + } ?: return getDefaultArtworkBitmap() +// if (artworkId.contains('/')) +// artworkId = artworkId.split('/').last() return getArtworkBitmap(artworkId) ?: return getDefaultArtworkBitmap() } + fun applySubstitution(card: TangemCard) { + val batchInfo = batches[card.batch] ?: return + val substitution = batchInfo.getDataSubstitution(card.batch) ?: return + substitution.applyToCard(card) + } + data class ArtworkInfo( val isResource: Boolean, val hash: String, @@ -196,51 +231,40 @@ data class ArtworksStorage( ) data class BatchInfo( - val artworkId: String - ) + val artworkId: String?, + val dataSubstitution: String?, + val dataSubstitutionSignature: String? + ) { - inner class FileCache(context: Context) { - - private var cacheDir: File? = null - - init { - cacheDir = File(context.filesDir, "artworks") - //Find the dir to save cached images -// if (android.os.Environment.getExternalStorageState() == android.os.Environment.MEDIA_MOUNTED) -// cacheDir = File(android.os.Environment.getExternalStorageDirectory(), "artworks_cache") -// else -// cacheDir = context.getCacheDir() - if (!cacheDir!!.exists()) - cacheDir!!.mkdirs() - } - - private fun getFile(artworkId: String): File { - return File(cacheDir, "$artworkId.png") - } - - fun getBitmap(artworkId: String): Bitmap? { - return try { - BitmapFactory.decodeFile(getFile(artworkId).absolutePath) - } catch (E: Exception) { - E.printStackTrace() + fun getDataSubstitution(batch: String): CardDataSubstitution? { + return if (CardDataSubstitution.verifySignature(batch, dataSubstitution, dataSubstitutionSignature)) { + Gson().fromJson(dataSubstitution, CardDataSubstitution::class.java) + } else { null } } - fun saveBitmap(artworkId: String, data: ByteArray) { - val file = getFile(artworkId) - file.writeBytes(data) + class CardDataSubstitution( + val tokenSymbol: String?, + val tokenDecimal: Int?, + val contractAddress: String? + ) { + fun applyToCard(card: TangemCard) { + if (card.tokenSymbol.isNullOrBlank()) card.tokenSymbol = tokenSymbol + if (tokenDecimal != null) card.tokensDecimal = tokenDecimal + if (card.contractAddress.isNullOrBlank()) card.contractAddress = contractAddress + } + + companion object { + private val substitutionPublicKey: ByteArray = byteArrayOf(0x00, 0x00) + fun verifySignature(batch: String, substitutionData: String?, substitutionSignature: String?): Boolean { + if (substitutionData == null && substitutionSignature == null) return true + if (substitutionData == null || substitutionSignature == null) return false + val dataToSign = batch.toByteArray(StandardCharsets.UTF_8) + substitutionData.toByteArray(StandardCharsets.UTF_8) + return CardCrypto.VerifySignature(substitutionPublicKey, dataToSign, Util.hexToBytes(substitutionSignature)) + } + } + } - - fun clear() { - val files = cacheDir!!.listFiles() ?: return - for (f in files) - f.delete() - } - - } - - companion object { - const val defaultArtworkId = "" } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/presentation/fragment/LoadedWallet.kt b/app/src/main/java/com/tangem/presentation/fragment/LoadedWallet.kt index e331492274..8396d858f7 100644 --- a/app/src/main/java/com/tangem/presentation/fragment/LoadedWallet.kt +++ b/app/src/main/java/com/tangem/presentation/fragment/LoadedWallet.kt @@ -76,7 +76,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific private var timerRepeatRefresh: Timer? = null - private lateinit var artworksStorage: ArtworksStorage + private lateinit var localStorage: LocalStorage override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -92,7 +92,9 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific lastTag = activity!!.intent.getParcelableExtra(MainActivity.EXTRA_LAST_DISCOVERED_TAG) - artworksStorage = ArtworksStorage(context!!) + localStorage = LocalStorage(context!!) + localStorage.applySubstitution(card!!) + } override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { @@ -108,7 +110,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific tvBalance.setSingleLine(false) //ivTangemCard.setImageResource(card!!.cardImageResource) - ivTangemCard.setImageBitmap(artworksStorage.getCardArtworkBitmap(card!!)) + ivTangemCard.setImageBitmap(localStorage.getCardArtworkBitmap(card!!)) val engine = CoinEngineFactory.create(card!!.blockchain) val visibleFlag = engine?.inOutPutVisible() ?: true @@ -224,34 +226,34 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific // //// Log.i(TAG, "setCardVerify " + it.results!![0].passed) // } - serverApiHelper!!.setCardVerifyAndGetArtworkListener { + serverApiHelper!!.setCardVerifyAndGetInfoListener { srlLoadedWallet!!.isRefreshing = false val result = it.results!![0] if (result.error != null) { Log.e(TAG, "Can't verify card: ${result.error}") card!!.isOnlineVerified = false - return@setCardVerifyAndGetArtworkListener + return@setCardVerifyAndGetInfoListener } card!!.isOnlineVerified = result.passed - if (!result.passed) return@setCardVerifyAndGetArtworkListener + if (!result.passed) return@setCardVerifyAndGetInfoListener - if (artworksStorage.checkBatchArtworkChanged(result.batch, result.artworkId)) { - Log.w(TAG, "Batch ${result.batch} artwork changed to '${result.artworkId}'") - ivTangemCard.setImageBitmap(artworksStorage.getCardArtworkBitmap(card!!)) + if (localStorage.checkBatchInfoChanged(result)) { + Log.w(TAG, "Batch ${result.batch} info changed to '$result'") + ivTangemCard.setImageBitmap(localStorage.getCardArtworkBitmap(card!!)) + updateViews() } - if (artworksStorage.checkNeedUpdateArtwork(result.artworkId, result.artworkHash, result.getUpdateDate())) { - Log.w(TAG, "Artwork '${result.artworkId}' updated, need download") - serverApiHelper!!.requestArtwork(result.artworkId, result.getUpdateDate(), card!!) + if (result.artwork!=null && localStorage.checkNeedUpdateArtwork(result.artwork)) { + Log.w(TAG, "Artwork '${result.artwork!!.id}' updated, need download") + serverApiHelper!!.requestArtwork(result.artwork!!.id, result.artwork!!.getUpdateDate(), card!!) } - // Log.i(TAG, "setCardVerify " + it.results!![0].passed) } serverApiHelper!!.setArtworkListener { artworkId, inputStream, updateDate -> Log.w(TAG, "Artwork '$artworkId' downloaded") - artworksStorage.updateArtwork(artworkId, inputStream, updateDate) - ivTangemCard.setImageBitmap(artworksStorage.getCardArtworkBitmap(card!!)) + localStorage.updateArtwork(artworkId, inputStream, updateDate) + ivTangemCard.setImageBitmap(localStorage.getCardArtworkBitmap(card!!)) } // request rate info listener @@ -380,7 +382,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific private fun requestCardVerify() { if ((card!!.isOnlineVerified == null || !card!!.isOnlineVerified)) - serverApiHelper!!.cardVerifyAndGetArtwork(card) //serverApiHelper!!.cardVerify(card) + serverApiHelper!!.cardVerifyAndGetInfo(card) //serverApiHelper!!.cardVerify(card) } private fun requestRateInfo(cryptoId: String) {