Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Version 1.7.2206 #97

Merged
merged 53 commits into from
Mar 8, 2022
Merged
Show file tree
Hide file tree
Changes from 52 commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
a34cbc6
DB schema change for xpubkey support #32
MrStahlfelge Feb 15, 2022
24f0dc2
Make add read only screen support using xpubkey #32
MrStahlfelge Feb 15, 2022
fc43d22
DB schema change for xpubkey missing field assignment #32
MrStahlfelge Feb 15, 2022
67388b6
Support deriving addresses from xpubkey #32
MrStahlfelge Feb 15, 2022
23b5e8c
Android display xpubkey #32 introduces ShareWithQrDialogFragment and …
MrStahlfelge Feb 16, 2022
816d4fa
Android use viewLifeCycle where it should be used
MrStahlfelge Feb 16, 2022
c3c0d8e
iOS display xpubkey #32 introduces ShareWithQrCodeViewController
MrStahlfelge Feb 16, 2022
03926c6
Merge pull request #92 from ergoplatform/xpubkey
MrStahlfelge Feb 16, 2022
fce2f95
Fix crash caused by Italian translation
MrStahlfelge Feb 18, 2022
e8412b9
Upgrade Appkit/ergo-wallet, use available Eip4Token outbox informatio…
MrStahlfelge Feb 10, 2022
5f9ae6a
Introduce TokenModels and TokenDbProvider
MrStahlfelge Feb 22, 2022
117fa6f
NodeConnector: fetch ERG fiat value and wallet states at the same time
MrStahlfelge Feb 22, 2022
54afebc
NodeConnector renamed to WalletStateSyncManager
MrStahlfelge Feb 22, 2022
0e38c21
Introduce TokenInfoManager and implement TokenInformationDialogFragme…
MrStahlfelge Feb 22, 2022
832fb07
Improve formatted token amounts and TokenInformationDialogFragment UI #9
MrStahlfelge Feb 22, 2022
1ca5a90
Android add database layer for token information #9
MrStahlfelge Feb 23, 2022
c5ab391
WalletStateSyncManager fetch token prices #9
MrStahlfelge Feb 23, 2022
711cfc4
Improved Italian translation
MrStahlfelge Feb 23, 2022
5e8a599
Fix ErgoDexPriceApi, show balance value on token detail page #9
MrStahlfelge Feb 23, 2022
337756b
TokenInfoManager verify tokens according to EIP-21 and set correct ty…
MrStahlfelge Feb 23, 2022
d270881
TokenInfoManager emitting Flow #9
MrStahlfelge Feb 24, 2022
b87d8e6
TokenInformationDialogFragment add EIP-21 badge #9
MrStahlfelge Feb 24, 2022
381c0c2
WalletDetailsUiLogic refactoring, move onDataChanged callback away fr…
MrStahlfelge Feb 25, 2022
24d0aeb
Prepare WalletDetails to show additional TokenInformation #9
MrStahlfelge Feb 25, 2022
fe0a0c6
WalletDetails showing token price and genuineness #9
MrStahlfelge Feb 25, 2022
f6ac264
ChooseTokenListDialogFragment showing genuineness #9
MrStahlfelge Feb 25, 2022
82077a2
SendFundsFragment improve token view #9
MrStahlfelge Feb 25, 2022
d402dde
Token Enhancements small fixes #9
MrStahlfelge Feb 25, 2022
4760fd4
SendFundsFragment improve token view: Small improvements for NFT toke…
MrStahlfelge Feb 26, 2022
cc6b1c7
TokenEntryViews show thumbnail for NFTs #9
MrStahlfelge Feb 27, 2022
e766218
WalletDetailsUiLogic prepopulate TokenInformation hashmap to avoid UI…
MrStahlfelge Feb 28, 2022
c55ae0e
TokenInformationDialogFragment show NFT information #9
MrStahlfelge Feb 28, 2022
69bc99c
TokenInformationUiLogic.kt introduced, show picture NFT preview and v…
MrStahlfelge Mar 1, 2022
b1021b3
Settings add ipfs gateway and picture NFT content toggle #9
MrStahlfelge Mar 1, 2022
71bfd25
Android make headline a bit smaller
MrStahlfelge Mar 1, 2022
a6e29db
TokenInformationDialogFragment refactor more logic into common-jvm, a…
MrStahlfelge Mar 1, 2022
5e74c06
SqlDelight add TokenInformation and TokenPrice #9
MrStahlfelge Mar 2, 2022
607b421
iOS WalletDetailsViewController add gatherTokenInformation and balanc…
MrStahlfelge Mar 2, 2022
a378f5a
iOS Fix errors in tokeninformation persistence layer #9
MrStahlfelge Mar 2, 2022
e7e8b81
iOS Wallet details token view images for verified tokens and NFT adde…
MrStahlfelge Mar 2, 2022
e682213
iOS ChooseTokenListViewController.kt images for verified tokens and N…
MrStahlfelge Mar 2, 2022
e148426
iOS SendTokenEntryView revamped, added balance and amount value #9
MrStahlfelge Mar 3, 2022
bb7afe2
iOS introduced TokenInformationViewController #9
MrStahlfelge Mar 4, 2022
333fac8
iOS TokenInformationLayoutView shows all non-NFT information #9
MrStahlfelge Mar 4, 2022
42f9e0d
iOS TokenInformationLayoutView show NFT content link and thumbnail #9
MrStahlfelge Mar 4, 2022
706d8ea
iOS TokenInformationLayoutView show NFT content hash and activate dow…
MrStahlfelge Mar 4, 2022
c89c2f5
iOS TokenInformationLayoutView show NFT image contents #9
MrStahlfelge Mar 5, 2022
e6c7a2f
iOS SettingsViewController add NFT settings #9
MrStahlfelge Mar 5, 2022
b79981d
Turkish translation (#95)
ahmetsagirli Mar 5, 2022
dbdc7ab
Improved Turkish translation
MrStahlfelge Mar 5, 2022
5ce2b2e
Merge pull request #96 from ergoplatform/token-enhancements
MrStahlfelge Mar 5, 2022
8edd1d3
Build 1.7.2206
MrStahlfelge Mar 5, 2022
9fa31e9
documentations added
MrStahlfelge Mar 7, 2022
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
4 changes: 2 additions & 2 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ android {
applicationId "org.ergoplatform.android"
minSdkVersion 24
targetSdkVersion 30
versionCode 2205
versionName "1.6.2205"
versionCode 2206
versionName "1.7.2206"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
Expand Down
4 changes: 2 additions & 2 deletions android/src/main/java/org/ergoplatform/android/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package org.ergoplatform.android

import android.app.Application
import androidx.appcompat.app.AppCompatDelegate
import org.ergoplatform.NodeConnector
import org.ergoplatform.WalletStateSyncManager
import org.ergoplatform.appkit.NetworkType
import org.ergoplatform.isErgoMainNet
import org.ergoplatform.utils.LogUtils
Expand All @@ -19,7 +19,7 @@ class App : Application() {
isErgoMainNet = (StageConstants.NETWORK_TYPE == NetworkType.MAINNET)
val preferences = Preferences(applicationContext)
AppCompatDelegate.setDefaultNightMode(preferences.dayNightMode)
NodeConnector.getInstance().loadPreferenceValues(preferences)
WalletStateSyncManager.getInstance().loadPreferenceValues(preferences, AppDatabase.getInstance(applicationContext))

LogUtils.stackTraceLogger = { lastStackTrace = it }
}
Expand Down
67 changes: 60 additions & 7 deletions android/src/main/java/org/ergoplatform/android/AppDatabase.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ import androidx.room.withTransaction
import androidx.sqlite.db.SupportSQLiteDatabase
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import org.ergoplatform.android.tokens.TokenDbDao
import org.ergoplatform.android.tokens.TokenInformationDbEntity
import org.ergoplatform.android.tokens.TokenPriceDbEntity
import org.ergoplatform.android.tokens.toDbEntity
import org.ergoplatform.android.wallet.*
import org.ergoplatform.persistance.*

Expand All @@ -17,11 +21,14 @@ import org.ergoplatform.persistance.*
WalletConfigDbEntity::class,
WalletStateDbEntity::class,
WalletAddressDbEntity::class,
WalletTokenDbEntity::class
), version = 4
WalletTokenDbEntity::class,
TokenPriceDbEntity::class,
TokenInformationDbEntity::class
), version = 6
)
abstract class AppDatabase : RoomDatabase() {
abstract class AppDatabase : RoomDatabase(), IAppDatabase {
abstract fun walletDao(): WalletDbDao
abstract fun tokenDao(): TokenDbDao

companion object {

Expand All @@ -40,18 +47,20 @@ abstract class AppDatabase : RoomDatabase() {
.addMigrations(MIGRATION_1_2)
.addMigrations(MIGRATION_2_3)
.addMigrations(MIGRATION_3_4)
.addMigrations(MIGRATION_4_5)
.addMigrations(MIGRATION_5_6)
.build()
}

val MIGRATION_1_2 = object : Migration(1, 2) {
private val MIGRATION_1_2 = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("DROP TABLE `wallet_states`")
// taken from AppDatabase_Impl :-)
database.execSQL("CREATE TABLE IF NOT EXISTS `wallet_states` (`public_address` TEXT NOT NULL, `transactions` INTEGER, `balance` INTEGER, `unconfirmed_balance` INTEGER, PRIMARY KEY(`public_address`))")
}
}

val MIGRATION_2_3 = object : Migration(2, 3) {
private val MIGRATION_2_3 = object : Migration(2, 3) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("DROP TABLE `wallet_states`")
// taken from AppDatabase_Impl :-)
Expand All @@ -62,15 +71,31 @@ abstract class AppDatabase : RoomDatabase() {
}
}

val MIGRATION_3_4 = object : Migration(3, 4) {
private val MIGRATION_3_4 = object : Migration(3, 4) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE wallet_addresses ADD COLUMN `label` TEXT")
}
}

private val MIGRATION_4_5 = object : Migration(4, 5) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE wallet_configs ADD COLUMN `xpubkey` TEXT")
}
}

private val MIGRATION_5_6 = object : Migration(5, 6) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("CREATE TABLE IF NOT EXISTS `token_price` (`tokenId` TEXT NOT NULL, `display_name` TEXT, `source` TEXT NOT NULL, `erg_value` TEXT NOT NULL, PRIMARY KEY(`tokenId`))")
database.execSQL("CREATE TABLE IF NOT EXISTS `token_info` (`tokenId` TEXT NOT NULL, `issuing_box` TEXT NOT NULL, `minting_tx` TEXT NOT NULL, `display_name` TEXT NOT NULL, `description` TEXT NOT NULL, `decimals` INTEGER NOT NULL, `full_supply` INTEGER NOT NULL, `reg7` TEXT, `reg8` TEXT, `reg9` TEXT, `genuine_flag` INTEGER NOT NULL, `issuer_link` TEXT, `thumbnail_bytes` BLOB, `thunbnail_type` INTEGER NOT NULL, `updated_ms` INTEGER NOT NULL, PRIMARY KEY(`tokenId`))")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to make this SQL statements multi-line strings?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it is, but the statements are a 1:1 copy of the generated code from Room and I'd rather leave it this way. I'll make the explaining comment more eye-catching

}
}
}

override val tokenDbProvider get() = RoomTokenDbProvider(this)
override val walletDbProvider get() = RoomWalletDbProvider(this)
}

class RoomWalletDbProvider(val database: AppDatabase) : WalletDbProvider {
class RoomWalletDbProvider(private val database: AppDatabase) : WalletDbProvider {
override suspend fun <R> withTransaction(block: suspend () -> R): R {
return database.withTransaction(block)
}
Expand Down Expand Up @@ -153,4 +178,32 @@ class RoomWalletDbProvider(val database: AppDatabase) : WalletDbProvider {
database.walletDao()
.insertWalletTokens(*(walletTokens.map { it.toDbEntity() }.toTypedArray()))
}
}

class RoomTokenDbProvider(private val database: AppDatabase) : TokenDbProvider {
override suspend fun loadTokenPrices(): List<TokenPrice> {
return database.tokenDao().getAllTokenPrices().map { it.toModel() }
}

override suspend fun updateTokenPrices(priceList: List<TokenPrice>) {
database.withTransaction {
database.tokenDao().deleteAllTokenPrices()
database.tokenDao()
.insertTokenPrices(*(priceList.map { it.toDbEntity() }.toTypedArray()))
}
}

override suspend fun loadTokenInformation(tokenId: String): TokenInformation? {
return database.tokenDao().getTokenInformation(tokenId)?.toModel()
}

override suspend fun insertOrReplaceTokenInformation(tokenInfo: TokenInformation) {
database.tokenDao().insertOrUpdateTokenInformation(tokenInfo.toDbEntity())
}

override suspend fun pruneUnusedTokenInformation() {
database.tokenDao()
.deleteOutdatedTokenInformation(System.currentTimeMillis() - TOKEN_INFO_MS_OUTDATED)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,16 @@ class ConnectionSettingsDialogFragment : BottomSheetDialogFragment() {
val preferences = Preferences(requireContext())
binding.editNodeUrl.editText?.setText(preferences.prefNodeUrl)
binding.editExplorerApiUrl.editText?.setText(preferences.prefExplorerApiUrl)
binding.inputIpfsGateway.setText(preferences.prefIpfsGatewayUrl)
binding.buttonApply.setOnClickListener { buttonApply() }
binding.editNodeUrl.editText?.setOnEditorActionListener { _, _, _ ->
binding.inputIpfsGateway.setOnEditorActionListener { _, _, _ ->
buttonApply()
true
}
binding.buttonDefaults.setOnClickListener {
binding.editNodeUrl.editText?.setText(preferences.getDefaultNodeApiUrl())
binding.editExplorerApiUrl.editText?.setText(getDefaultExplorerApiUrl())
binding.inputIpfsGateway.setText(preferences.defaultIpfsGatewayUrl)
}
}

Expand All @@ -56,6 +58,7 @@ class ConnectionSettingsDialogFragment : BottomSheetDialogFragment() {
val preferences = Preferences(requireContext())
preferences.prefExplorerApiUrl = explorerApiUrl
preferences.prefNodeUrl = nodeUrl
preferences.prefIpfsGatewayUrl = binding.inputIpfsGateway.text?.toString() ?: ""

// reset api service of NodeConnector to load new settings
ErgoApiService.resetApiService()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import org.ergoplatform.NodeConnector
import org.ergoplatform.WalletStateSyncManager
import org.ergoplatform.android.Preferences
import org.ergoplatform.android.R
import org.ergoplatform.android.databinding.FragmentDisplayCurrencyDialogBinding
Expand Down Expand Up @@ -43,7 +43,7 @@ class DisplayCurrencyListDialogFragment : BottomSheetDialogFragment() {
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
val nodeConnector = NodeConnector.getInstance()
val nodeConnector = WalletStateSyncManager.getInstance()
nodeConnector.fetchCurrencies()

binding.list.layoutManager =
Expand Down Expand Up @@ -75,7 +75,7 @@ class DisplayCurrencyListDialogFragment : BottomSheetDialogFragment() {

private fun onChooseCurrency(currency: String) {
Preferences(requireContext()).prefDisplayCurrency = currency
NodeConnector.getInstance().invalidateCache(resetFiatValue = true)
WalletStateSyncManager.getInstance().invalidateCache(resetFiatValue = true)
(parentFragment as? SettingsFragment)?.showDisplayCurrency()
dismiss()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,20 @@ class SettingsFragment : Fragment() {
showDialogWithCopyOption(requireContext(), it)
}
}

setButtonDownloadContentText()
binding.buttonDownloadContent.setOnClickListener {
val preferences = Preferences(requireContext())
preferences.downloadNftContent = !preferences.downloadNftContent
setButtonDownloadContentText()
}
}

private fun setButtonDownloadContentText() {
binding.buttonDownloadContent.setText(
if (Preferences(requireContext()).downloadNftContent) R.string.button_download_content_off
else R.string.button_download_content_on
)
}

private fun changeDayNightMode(mode: Int) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package org.ergoplatform.android.tokens

import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query

@Dao
interface TokenDbDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertTokenPrices(vararg tokenPrices: TokenPriceDbEntity)

@Query("DELETE FROM token_price")
suspend fun deleteAllTokenPrices()

@Query("SELECT * FROM token_price")
suspend fun getAllTokenPrices(): List<TokenPriceDbEntity>

@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertOrUpdateTokenInformation(vararg tokenInfo: TokenInformationDbEntity)

@Query("DELETE FROM token_info WHERE updated_ms < :thresholdMs")
suspend fun deleteOutdatedTokenInformation(thresholdMs: Long)

@Query("SELECT * FROM token_info WHERE tokenId = :tokenId")
suspend fun getTokenInformation(tokenId: String): TokenInformationDbEntity?

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package org.ergoplatform.android.tokens

import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import org.ergoplatform.persistance.GENUINE_UNKNOWN
import org.ergoplatform.persistance.TokenInformation
import org.ergoplatform.persistance.TokenPrice
import java.math.BigDecimal

@Entity(tableName = "token_price")
data class TokenPriceDbEntity(
@PrimaryKey val tokenId: String,
@ColumnInfo(name = "display_name") val displayName: String?,
@ColumnInfo(name = "source") val priceSource: String,
@ColumnInfo(name = "erg_value") val ergValue: String
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just out of curiosity, why not Long type?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The token erg value can be fractional even compared to nanoergs, and actually is for most tokens. I have experimented with long value/decimals but had problems in deciding how many decimals should actually be used. Since JS developers settled to handle all of these types of values as strings and these are usually our sources, I decided to follow this practice for this application.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just out of curiosity, why not a numeric type?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doublicate of former comment?

) {
fun toModel(): TokenPrice {
return TokenPrice(
tokenId,
displayName,
priceSource,
BigDecimal(ergValue)
)
}
}

fun TokenPrice.toDbEntity(): TokenPriceDbEntity {
return TokenPriceDbEntity(
tokenId,
displayName,
priceSource,
ergValue.toString()
)
}

@Entity(tableName = "token_info")
data class TokenInformationDbEntity(
@PrimaryKey val tokenId: String,
@ColumnInfo(name = "issuing_box") val issuingBoxId: String,
@ColumnInfo(name = "minting_tx") val mintingTxId: String,
@ColumnInfo(name = "display_name") val displayName: String,
@ColumnInfo(name = "description") val description: String,
@ColumnInfo(name = "decimals") val decimals: Int,
@ColumnInfo(name = "full_supply") val fullSupply: Long,
@ColumnInfo(name = "reg7") val reg7hex: String?,
@ColumnInfo(name = "reg8") val reg8hex: String?,
@ColumnInfo(name = "reg9") val reg9hex: String?,
@ColumnInfo(name = "genuine_flag") val genuineFlag: Int = GENUINE_UNKNOWN,
@ColumnInfo(name = "issuer_link") val issuerLink: String? = null,
@ColumnInfo(name = "thumbnail_bytes") val thumbnailBytes: ByteArray? = null,
@ColumnInfo(name = "thunbnail_type") val thumbnailType: Int,
@ColumnInfo(name = "updated_ms") val updatedMs: Long
) {
fun toModel(): TokenInformation {
return TokenInformation(
tokenId,
issuingBoxId,
mintingTxId,
displayName,
description,
decimals,
fullSupply,
reg7hex,
reg8hex,
reg9hex,
genuineFlag,
issuerLink,
thumbnailBytes,
thumbnailType,
updatedMs
)
}
}

fun TokenInformation.toDbEntity(): TokenInformationDbEntity {
return TokenInformationDbEntity(
tokenId,
issuingBoxId,
mintingTxId,
displayName,
description,
decimals,
fullSupply,
reg7hex,
reg8hex,
reg9hex,
genuineFlag,
issuerLink,
thumbnailBytes,
thumbnailType,
updatedMs
)
}
Loading