diff --git a/README.md b/README.md index 3e821c7f..22e856ea 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ Then add the following dependency to your module's build.gradle ```gradle dependencies { ... - implementation "com.metallicus:protonsdk:0.5.6" + implementation "com.metallicus:protonsdk:0.6.0" } ``` diff --git a/buildSrc/src/main/kotlin/Dependencies.kt b/buildSrc/src/main/kotlin/Dependencies.kt index e40b7f61..ba371dcc 100644 --- a/buildSrc/src/main/kotlin/Dependencies.kt +++ b/buildSrc/src/main/kotlin/Dependencies.kt @@ -23,8 +23,8 @@ const val kotlinVersion = "1.4.10" const val orchidVersion = "0.21.1" object ProtonSdk { - const val versionCode = 18 - const val versionName = "0.5.6" + const val versionCode = 21 + const val versionName = "0.6.0" } object BuildPlugins { diff --git a/protonsdk/src/main/java/com/metallicus/protonsdk/AccountModule.kt b/protonsdk/src/main/java/com/metallicus/protonsdk/AccountModule.kt index 7e825a79..46264ebe 100644 --- a/protonsdk/src/main/java/com/metallicus/protonsdk/AccountModule.kt +++ b/protonsdk/src/main/java/com/metallicus/protonsdk/AccountModule.kt @@ -23,6 +23,8 @@ package com.metallicus.protonsdk import android.content.Context import android.util.Base64 +import com.google.gson.Gson +import com.google.gson.JsonSyntaxException import com.metallicus.protonsdk.common.SecureKeys import com.metallicus.protonsdk.common.Prefs import com.metallicus.protonsdk.common.Resource @@ -33,7 +35,6 @@ import com.metallicus.protonsdk.model.* import com.metallicus.protonsdk.repository.AccountContactRepository import com.metallicus.protonsdk.repository.AccountRepository import timber.log.Timber -import java.nio.charset.Charset import javax.inject.Inject /** @@ -122,16 +123,16 @@ class AccountModule { val accountContact = AccountContact(accountName) accountContact.accountName = accountName - val usersInfoTableScope = context.getString(R.string.protonChainUsersInfoTableScope) - val usersInfoTableCode = context.getString(R.string.protonChainUsersInfoTableCode) - val usersInfoTableName = context.getString(R.string.protonChainUsersInfoTableName) + val usersInfoTableScope = context.getString(R.string.usersInfoTableScope) + val usersInfoTableCode = context.getString(R.string.usersInfoTableCode) + val usersInfoTableName = context.getString(R.string.usersInfoTableName) val response = accountContactRepository.fetchAccountContact( chainUrl, accountName, usersInfoTableScope, usersInfoTableCode, usersInfoTableName) if (response.isSuccessful) { - val userInfoJsonObject = response.body() + val userInfoRows = response.body() - val rows = userInfoJsonObject?.getAsJsonArray("rows") + val rows = userInfoRows?.getAsJsonArray("rows") val size = rows?.size() ?: 0 if (size > 0) { val userInfo = rows?.get(0)?.asJsonObject @@ -152,6 +153,80 @@ class AccountModule { return accountContact } + private suspend fun fetchAccountVotersXPRInfo(chainUrl: String, accountName: String): AccountVotersXPRInfo { + var accountVotersXPRInfo = AccountVotersXPRInfo() + + val votersXPRInfoTableScope = context.getString(R.string.votersXPRInfoTableScope) + val votersXPRInfoTableCode = context.getString(R.string.votersXPRInfoTableCode) + val votersXPRInfoTableName = context.getString(R.string.votersXPRInfoTableName) + + val response = accountContactRepository.fetchAccountVotersXPRInfo( + chainUrl, accountName, votersXPRInfoTableScope, votersXPRInfoTableCode, votersXPRInfoTableName) + if (response.isSuccessful) { + val votersXPRInfoRows = response.body() + + val rows = votersXPRInfoRows?.getAsJsonArray("rows") + val size = rows?.size() ?: 0 + if (size > 0) { + val votersXPRInfo = rows?.get(0)?.asJsonObject + + try { + accountVotersXPRInfo = Gson().fromJson(votersXPRInfo, AccountVotersXPRInfo::class.java) + } catch(e: JsonSyntaxException) { + Timber.e(e) + } + } + } else { + val msg = response.errorBody()?.string() + val errorMsg = if (msg.isNullOrEmpty()) { + response.message() + } else { + msg + } + + Timber.e(errorMsg) + } + + return accountVotersXPRInfo + } + + private suspend fun fetchAccountRefundsXPRInfo(chainUrl: String, accountName: String): AccountRefundsXPRInfo { + var accountRefundsXPRInfo = AccountRefundsXPRInfo() + + val refundsXPRInfoTableScope = accountName + val refundsXPRInfoTableCode = context.getString(R.string.refundsXPRInfoTableCode) + val refundsXPRInfoTableName = context.getString(R.string.refundsXPRInfoTableName) + + val response = accountContactRepository.fetchAccountRefundsXPRInfo( + chainUrl, accountName, refundsXPRInfoTableScope, refundsXPRInfoTableCode, refundsXPRInfoTableName) + if (response.isSuccessful) { + val refundsXPRInfoRows = response.body() + + val rows = refundsXPRInfoRows?.getAsJsonArray("rows") + val size = rows?.size() ?: 0 + if (size > 0) { + val refundsXPRInfo = rows?.get(0)?.asJsonObject + + try { + accountRefundsXPRInfo = Gson().fromJson(refundsXPRInfo, AccountRefundsXPRInfo::class.java) + } catch(e: JsonSyntaxException) { + Timber.e(e) + } + } + } else { + val msg = response.errorBody()?.string() + val errorMsg = if (msg.isNullOrEmpty()) { + response.message() + } else { + msg + } + + Timber.d(errorMsg) + } + + return accountRefundsXPRInfo + } + private suspend fun fetchAccount(chainId: String, chainUrl: String, accountName: String): Account? { var account: Account? = null @@ -159,8 +234,16 @@ class AccountModule { if (response.isSuccessful) { response.body()?.let { it -> it.accountChainId = chainId + + // fetch contact info it.accountContact = fetchAccountContact(chainUrl, accountName) + // fetch voter info + it.votersXPRInfo = fetchAccountVotersXPRInfo(chainUrl, accountName) + + // fetch refund info + it.refundsXPRInfo = fetchAccountRefundsXPRInfo(chainUrl, accountName) + account = it } } else { diff --git a/protonsdk/src/main/java/com/metallicus/protonsdk/ActionsModule.kt b/protonsdk/src/main/java/com/metallicus/protonsdk/ActionsModule.kt index cf286870..dd7f0d09 100644 --- a/protonsdk/src/main/java/com/metallicus/protonsdk/ActionsModule.kt +++ b/protonsdk/src/main/java/com/metallicus/protonsdk/ActionsModule.kt @@ -95,9 +95,9 @@ class ActionsModule { accountContactRepository.addAccountContact(accountContact) } - val usersInfoTableScope = context.getString(R.string.protonChainUsersInfoTableScope) - val usersInfoTableCode = context.getString(R.string.protonChainUsersInfoTableCode) - val usersInfoTableName = context.getString(R.string.protonChainUsersInfoTableName) + val usersInfoTableScope = context.getString(R.string.usersInfoTableScope) + val usersInfoTableCode = context.getString(R.string.usersInfoTableCode) + val usersInfoTableName = context.getString(R.string.usersInfoTableName) val accountContactResponse = accountContactRepository.fetchAccountContact(chainUrl, accountContactId, usersInfoTableScope, usersInfoTableCode, usersInfoTableName) if (accountContactResponse.isSuccessful) { diff --git a/protonsdk/src/main/java/com/metallicus/protonsdk/CurrencyBalancesModule.kt b/protonsdk/src/main/java/com/metallicus/protonsdk/CurrencyBalancesModule.kt index bc289bce..c5df81c3 100644 --- a/protonsdk/src/main/java/com/metallicus/protonsdk/CurrencyBalancesModule.kt +++ b/protonsdk/src/main/java/com/metallicus/protonsdk/CurrencyBalancesModule.kt @@ -105,13 +105,15 @@ class CurrencyBalancesModule { val symbol = token.get("symbol").asString val amount = token.get("amount").asString - val tokenContractId = tokenContractsMap.getValue("$code:$symbol") + if (tokenContractsMap.containsKey("$code:$symbol")) { + val tokenContractId = tokenContractsMap.getValue("$code:$symbol") - val currencyBalance = CurrencyBalance(code, symbol, amount) - currencyBalance.tokenContractId = tokenContractId - currencyBalance.accountName = accountName + val currencyBalance = CurrencyBalance(code, symbol, amount) + currencyBalance.tokenContractId = tokenContractId + currencyBalance.accountName = accountName - currencyBalanceRepository.addCurrencyBalance(currencyBalance) + currencyBalanceRepository.addCurrencyBalance(currencyBalance) + } } val tokenCurrencyBalances = currencyBalanceRepository.getTokenCurrencyBalances(accountName) diff --git a/protonsdk/src/main/java/com/metallicus/protonsdk/db/AccountDao.kt b/protonsdk/src/main/java/com/metallicus/protonsdk/db/AccountDao.kt index d01d6952..31df6f0f 100755 --- a/protonsdk/src/main/java/com/metallicus/protonsdk/db/AccountDao.kt +++ b/protonsdk/src/main/java/com/metallicus/protonsdk/db/AccountDao.kt @@ -36,6 +36,7 @@ interface AccountDao { @Update suspend fun update(account: Account) + @Transaction @Query("SELECT * FROM account WHERE accountName = :accountName") suspend fun findByAccountName(accountName: String): ChainAccount diff --git a/protonsdk/src/main/java/com/metallicus/protonsdk/db/CurrencyBalanceDao.kt b/protonsdk/src/main/java/com/metallicus/protonsdk/db/CurrencyBalanceDao.kt index 945c6772..489c3ed6 100755 --- a/protonsdk/src/main/java/com/metallicus/protonsdk/db/CurrencyBalanceDao.kt +++ b/protonsdk/src/main/java/com/metallicus/protonsdk/db/CurrencyBalanceDao.kt @@ -36,9 +36,11 @@ interface CurrencyBalanceDao { @Query("UPDATE currencyBalance SET amount = :amount WHERE accountName = :accountName AND contract = :contract AND symbol = :symbol") suspend fun updateAmount(accountName: String, contract: String, symbol: String, amount: String) + @Transaction @Query("SELECT * FROM currencyBalance WHERE accountName = :accountName AND tokenContractId = :tokenContractId") suspend fun findByTokenContract(accountName: String, tokenContractId: String): TokenCurrencyBalance + @Transaction @Query("SELECT * FROM currencyBalance WHERE accountName = :accountName") suspend fun findByAccountName(accountName: String): List diff --git a/protonsdk/src/main/java/com/metallicus/protonsdk/db/ProtonDb.kt b/protonsdk/src/main/java/com/metallicus/protonsdk/db/ProtonDb.kt index 999b4878..4cc68b32 100755 --- a/protonsdk/src/main/java/com/metallicus/protonsdk/db/ProtonDb.kt +++ b/protonsdk/src/main/java/com/metallicus/protonsdk/db/ProtonDb.kt @@ -33,7 +33,7 @@ import com.metallicus.protonsdk.model.* AccountContact::class, CurrencyBalance::class, Action::class], - version = 17, + version = 19, exportSchema = false ) abstract class ProtonDb : RoomDatabase() { diff --git a/protonsdk/src/main/java/com/metallicus/protonsdk/db/ProtonTypeConverters.kt b/protonsdk/src/main/java/com/metallicus/protonsdk/db/ProtonTypeConverters.kt index d6cf668b..1ded5be9 100755 --- a/protonsdk/src/main/java/com/metallicus/protonsdk/db/ProtonTypeConverters.kt +++ b/protonsdk/src/main/java/com/metallicus/protonsdk/db/ProtonTypeConverters.kt @@ -25,6 +25,8 @@ import androidx.room.TypeConverter import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.metallicus.protonsdk.model.AccountContact +import com.metallicus.protonsdk.model.AccountRefundsXPRInfo +import com.metallicus.protonsdk.model.AccountVotersXPRInfo object ProtonTypeConverters { @TypeConverter @@ -40,4 +42,32 @@ object ProtonTypeConverters { val type = object : TypeToken() {}.type return Gson().toJson(accountContact, type) } + + @TypeConverter + @JvmStatic + fun stringToAccountVotersXPRInfo(value: String?): AccountVotersXPRInfo? { + val type = object : TypeToken() {}.type + return Gson().fromJson(value, type) + } + + @TypeConverter + @JvmStatic + fun accountVotersXPRInfoToString(accountVotersXPRInfo: AccountVotersXPRInfo): String { + val type = object : TypeToken() {}.type + return Gson().toJson(accountVotersXPRInfo, type) + } + + @TypeConverter + @JvmStatic + fun stringToAccountRefundsXPRInfo(value: String?): AccountRefundsXPRInfo? { + val type = object : TypeToken() {}.type + return Gson().fromJson(value, type) + } + + @TypeConverter + @JvmStatic + fun accountRefundsXPRInfoToString(accountRefundsXPRInfo: AccountRefundsXPRInfo): String { + val type = object : TypeToken() {}.type + return Gson().toJson(accountRefundsXPRInfo, type) + } } \ No newline at end of file diff --git a/protonsdk/src/main/java/com/metallicus/protonsdk/model/Account.kt b/protonsdk/src/main/java/com/metallicus/protonsdk/model/Account.kt index d35063e5..c451e606 100644 --- a/protonsdk/src/main/java/com/metallicus/protonsdk/model/Account.kt +++ b/protonsdk/src/main/java/com/metallicus/protonsdk/model/Account.kt @@ -65,6 +65,10 @@ data class Account( lateinit var accountContact: AccountContact + lateinit var votersXPRInfo: AccountVotersXPRInfo + + lateinit var refundsXPRInfo: AccountRefundsXPRInfo + fun getBalance(): String { return coreLiquidBalance ?: "0" } @@ -95,4 +99,12 @@ data class Account( } return selfDelegatedResources } + + fun getStakedXPR(): Double { + return votersXPRInfo.getStakedAmount() + } + + fun getRefundsXPR(): Double { + return refundsXPRInfo.quantityToDouble() + } } \ No newline at end of file diff --git a/protonsdk/src/main/java/com/metallicus/protonsdk/model/AccountRefundsXPRInfo.kt b/protonsdk/src/main/java/com/metallicus/protonsdk/model/AccountRefundsXPRInfo.kt new file mode 100644 index 00000000..4498c06a --- /dev/null +++ b/protonsdk/src/main/java/com/metallicus/protonsdk/model/AccountRefundsXPRInfo.kt @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2020 Proton Chain LLC, Delaware + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.metallicus.protonsdk.model + +import com.google.gson.annotations.SerializedName + +data class AccountRefundsXPRInfo( + @SerializedName("owner") val owner: String? = "", + @SerializedName("quantity") val quantity: String? = "", + @SerializedName("request_time") val requestTime: String? = "" +) { + fun quantityToDouble(): Double { + var quantityDouble = 0.0 + if (quantity != "") { + quantityDouble = quantity?.substringBefore(" ")?.toDouble() ?: 0.0 + } + return quantityDouble + } +} \ No newline at end of file diff --git a/protonsdk/src/main/java/com/metallicus/protonsdk/model/AccountVotersXPRInfo.kt b/protonsdk/src/main/java/com/metallicus/protonsdk/model/AccountVotersXPRInfo.kt new file mode 100644 index 00000000..9ad91f63 --- /dev/null +++ b/protonsdk/src/main/java/com/metallicus/protonsdk/model/AccountVotersXPRInfo.kt @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2020 Proton Chain LLC, Delaware + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.metallicus.protonsdk.model + +import com.google.gson.annotations.SerializedName +import com.metallicus.protonsdk.eosio.commander.model.types.TypeAsset +import com.metallicus.protonsdk.eosio.commander.model.types.TypeSymbol + +data class AccountVotersXPRInfo( + @SerializedName("owner") val owner: String? = "", + @SerializedName("staked") val staked: Long? = 0, + @SerializedName("isqualified") val isQualified: Long? = 0, + @SerializedName("claimamount") val claimAmount: Long? = 0, + @SerializedName("lastclaim") val lastClaim: String? = "" +) { + fun getStakedAmount(): Double { + var stakedAmount = 0.0 + if (staked != null) { + val stakedAsset = TypeAsset(staked, TypeSymbol.fromString("4,XPR")) + stakedAmount = stakedAsset.toString().substringBefore(" ").toDouble() + } + return stakedAmount + } +} \ No newline at end of file diff --git a/protonsdk/src/main/java/com/metallicus/protonsdk/model/CurrencyBalance.kt b/protonsdk/src/main/java/com/metallicus/protonsdk/model/CurrencyBalance.kt index d33bdb93..11e4f76a 100755 --- a/protonsdk/src/main/java/com/metallicus/protonsdk/model/CurrencyBalance.kt +++ b/protonsdk/src/main/java/com/metallicus/protonsdk/model/CurrencyBalance.kt @@ -36,4 +36,8 @@ data class CurrencyBalance( ) { lateinit var tokenContractId: String lateinit var accountName: String + + fun getAmountDouble(): Double { + return amount.toDouble() + } } \ No newline at end of file diff --git a/protonsdk/src/main/java/com/metallicus/protonsdk/model/TokenContract.kt b/protonsdk/src/main/java/com/metallicus/protonsdk/model/TokenContract.kt index b00584e9..8c664628 100644 --- a/protonsdk/src/main/java/com/metallicus/protonsdk/model/TokenContract.kt +++ b/protonsdk/src/main/java/com/metallicus/protonsdk/model/TokenContract.kt @@ -39,7 +39,8 @@ data class TokenContract( @SerializedName("desc") val description: String, @SerializedName("iconurl") val iconUrl: String, @SerializedName("symbol") val precisionSymbol: String, - @SerializedName("blisted") val blacklisted: Int + @SerializedName("blisted") val blacklisted: Int, + var isSystemToken: Boolean = false ) { lateinit var rates: Map diff --git a/protonsdk/src/main/java/com/metallicus/protonsdk/model/TokenCurrencyBalance.kt b/protonsdk/src/main/java/com/metallicus/protonsdk/model/TokenCurrencyBalance.kt index 8bee9477..bbd30203 100644 --- a/protonsdk/src/main/java/com/metallicus/protonsdk/model/TokenCurrencyBalance.kt +++ b/protonsdk/src/main/java/com/metallicus/protonsdk/model/TokenCurrencyBalance.kt @@ -36,28 +36,24 @@ data class TokenCurrencyBalance( ) val tokenContract: TokenContract ) { - private fun getBalanceDouble(selfDelegatedResources: Double): Double { - return if (selfDelegatedResources > 0.0) { - currencyBalance.amount.toDouble() + selfDelegatedResources - } else { - currencyBalance.amount.toDouble() - } + fun isSystemToken(): Boolean { + return (tokenContract.isSystemToken) } - fun formatBalance(selfDelegatedResources: Double): String { - val balance = getBalanceDouble(selfDelegatedResources) + private fun getBalanceDouble(adjustments: Double = 0.0): Double { + return currencyBalance.getAmountDouble() + adjustments + } + + fun formatBalance(adjustments: Double = 0.0): String { + val balance = getBalanceDouble(adjustments) val nf = NumberFormat.getNumberInstance(Locale.US) nf.minimumFractionDigits = tokenContract.getPrecision() nf.maximumFractionDigits = tokenContract.getPrecision() return nf.format(balance) } - fun formatBalance(): String { - return formatBalance(-1.0) - } - - fun getBalanceForCurrencyDouble(currency: String, selfDelegatedResources: Double): Double { - val amount = getBalanceDouble(selfDelegatedResources) + fun getBalanceForCurrencyDouble(currency: String, adjustments: Double = 0.0): Double { + val amount = getBalanceDouble(adjustments) val rate = if (tokenContract.rates.containsKey(currency)) { tokenContract.rates.getValue(currency) } else { @@ -66,18 +62,10 @@ data class TokenCurrencyBalance( return amount.times(rate) } - fun getBalanceForCurrencyDouble(currency: String): Double { - return getBalanceForCurrencyDouble(currency, -1.0) - } - - fun formatBalanceForCurrency(currency: String, selfDelegatedResources: Double): String { - val amountCurrency = getBalanceForCurrencyDouble(currency, selfDelegatedResources) + fun formatBalanceForCurrency(currency: String, adjustments: Double = 0.0): String { + val amountCurrency = getBalanceForCurrencyDouble(currency, adjustments) val nf = NumberFormat.getCurrencyInstance(Locale.US) return nf.format(amountCurrency) } - - fun formatBalanceForCurrency(currency: String): String { - return formatBalanceForCurrency(currency, -1.0) - } } \ No newline at end of file diff --git a/protonsdk/src/main/java/com/metallicus/protonsdk/repository/AccountContactRepository.kt b/protonsdk/src/main/java/com/metallicus/protonsdk/repository/AccountContactRepository.kt index debe2069..fa97d72e 100755 --- a/protonsdk/src/main/java/com/metallicus/protonsdk/repository/AccountContactRepository.kt +++ b/protonsdk/src/main/java/com/metallicus/protonsdk/repository/AccountContactRepository.kt @@ -50,4 +50,12 @@ class AccountContactRepository @Inject constructor( suspend fun fetchAccountContact(chainUrl: String, accountName: String, usersInfoTableScope: String, usersInfoTableCode: String, usersInfoTableName: String): Response { return protonChainService.getTableRows("$chainUrl/v1/chain/get_table_rows", TableRowsBody(usersInfoTableScope, usersInfoTableCode, usersInfoTableName, accountName, accountName)) } + + suspend fun fetchAccountVotersXPRInfo(chainUrl: String, accountName: String, votersXPRInfoTableScope: String, votersXPRInfoTableCode: String, votersXPRInfoTableName: String): Response { + return protonChainService.getTableRows("$chainUrl/v1/chain/get_table_rows", TableRowsBody(votersXPRInfoTableScope, votersXPRInfoTableCode, votersXPRInfoTableName, accountName, accountName)) + } + + suspend fun fetchAccountRefundsXPRInfo(chainUrl: String, accountName: String, refundsXPRInfoTableScope: String, refundsXPRInfoTableCode: String, refundsXPRInfoTableName: String): Response { + return protonChainService.getTableRows("$chainUrl/v1/chain/get_table_rows", TableRowsBody(refundsXPRInfoTableScope, refundsXPRInfoTableCode, refundsXPRInfoTableName, accountName, accountName)) + } } diff --git a/protonsdk/src/main/java/com/metallicus/protonsdk/repository/TokenContractRepository.kt b/protonsdk/src/main/java/com/metallicus/protonsdk/repository/TokenContractRepository.kt index 8f0bb7be..e3a80776 100755 --- a/protonsdk/src/main/java/com/metallicus/protonsdk/repository/TokenContractRepository.kt +++ b/protonsdk/src/main/java/com/metallicus/protonsdk/repository/TokenContractRepository.kt @@ -45,7 +45,7 @@ class TokenContractRepository @Inject constructor( } suspend fun fetchTokenContracts(chainUrl: String, tokensTableScope: String, tokensTableCode: String, tokensTableName: String): Response { - return protonChainService.getTableRows("$chainUrl/v1/chain/get_table_rows", TableRowsBody(tokensTableScope, tokensTableCode, tokensTableName)) + return protonChainService.getTableRows("$chainUrl/v1/chain/get_table_rows", TableRowsBody(tokensTableScope, tokensTableCode, tokensTableName, "", "", 100)) } suspend fun getTokenContract(tokenContractId: String): TokenContract { diff --git a/protonsdk/src/main/java/com/metallicus/protonsdk/workers/InitActiveAccountWorker.kt b/protonsdk/src/main/java/com/metallicus/protonsdk/workers/InitActiveAccountWorker.kt index 797c9c5e..be69c39c 100644 --- a/protonsdk/src/main/java/com/metallicus/protonsdk/workers/InitActiveAccountWorker.kt +++ b/protonsdk/src/main/java/com/metallicus/protonsdk/workers/InitActiveAccountWorker.kt @@ -25,10 +25,14 @@ import android.content.Context import androidx.work.CoroutineWorker import androidx.work.Data import androidx.work.WorkerParameters +import com.google.gson.Gson +import com.google.gson.JsonSyntaxException import com.metallicus.protonsdk.R import com.metallicus.protonsdk.common.Prefs import com.metallicus.protonsdk.common.ProtonError import com.metallicus.protonsdk.model.AccountContact +import com.metallicus.protonsdk.model.AccountRefundsXPRInfo +import com.metallicus.protonsdk.model.AccountVotersXPRInfo import com.metallicus.protonsdk.repository.AccountContactRepository import com.metallicus.protonsdk.repository.AccountRepository import com.metallicus.protonsdk.repository.ChainProviderRepository @@ -47,9 +51,16 @@ class InitActiveAccountWorker private val accountContactRepository: AccountContactRepository ) : CoroutineWorker(context, params) { - private val usersInfoTableScope = context.getString(R.string.protonChainUsersInfoTableScope) - private val usersInfoTableCode = context.getString(R.string.protonChainUsersInfoTableCode) - private val usersInfoTableName = context.getString(R.string.protonChainUsersInfoTableName) + private val usersInfoTableScope = context.getString(R.string.usersInfoTableScope) + private val usersInfoTableCode = context.getString(R.string.usersInfoTableCode) + private val usersInfoTableName = context.getString(R.string.usersInfoTableName) + + private val votersXPRInfoTableScope = context.getString(R.string.votersXPRInfoTableScope) + private val votersXPRInfoTableCode = context.getString(R.string.votersXPRInfoTableCode) + private val votersXPRInfoTableName = context.getString(R.string.votersXPRInfoTableName) + + private val refundsXPRInfoTableCode = context.getString(R.string.refundsXPRInfoTableCode) + private val refundsXPRInfoTableName = context.getString(R.string.refundsXPRInfoTableName) @Suppress("BlockingMethodInNonBlockingContext") override suspend fun doWork(): Result { @@ -64,37 +75,15 @@ class InitActiveAccountWorker response.body()?.let { account -> account.accountChainId = chainId - val accountContact = AccountContact(accountName) - accountContact.accountName = accountName - - val accountInfoResponse = accountContactRepository.fetchAccountContact( - chainProvider.chainUrl, accountName, usersInfoTableScope, usersInfoTableCode, usersInfoTableName) - if (accountInfoResponse.isSuccessful) { - val userInfoJsonObject = accountInfoResponse.body() - - val rows = userInfoJsonObject?.getAsJsonArray("rows") - val size = rows?.size() ?: 0 - if (size > 0) { - val userInfo = rows?.get(0)?.asJsonObject - accountContact.name = userInfo?.get("name")?.asString.orEmpty() - accountContact.avatar = userInfo?.get("avatar")?.asString.orEmpty() - } - } else { - val msg = response.errorBody()?.string() - val errorMsg = if (msg.isNullOrEmpty()) { - response.message() - } else { - msg - } - - Timber.d(errorMsg) - - // Don't fail if can't find usersinfo - //Result.failure() - } - + val accountContact = fetchAccountContact(chainProvider.chainUrl, accountName) account.accountContact = accountContact + val accountVotersXPRInfo = fetchAccountVotersXPRInfo(chainProvider.chainUrl, accountName) + account.votersXPRInfo = accountVotersXPRInfo + + val accountRefundsXPRInfo = fetchAccountRefundsXPRInfo(chainProvider.chainUrl, accountName) + account.refundsXPRInfo = accountRefundsXPRInfo + accountRepository.addAccount(account) Result.success() @@ -123,6 +112,104 @@ class InitActiveAccountWorker } } + private suspend fun fetchAccountContact(chainUrl: String, accountName: String): AccountContact { + val accountContact = AccountContact(accountName) + accountContact.accountName = accountName + + val response = accountContactRepository.fetchAccountContact( + chainUrl, accountName, usersInfoTableScope, usersInfoTableCode, usersInfoTableName) + if (response.isSuccessful) { + val userInfoRows = response.body() + + val rows = userInfoRows?.getAsJsonArray("rows") + val size = rows?.size() ?: 0 + if (size > 0) { + val userInfo = rows?.get(0)?.asJsonObject + accountContact.name = userInfo?.get("name")?.asString.orEmpty() + accountContact.avatar = userInfo?.get("avatar")?.asString.orEmpty() + } + } else { + val msg = response.errorBody()?.string() + val errorMsg = if (msg.isNullOrEmpty()) { + response.message() + } else { + msg + } + + Timber.d(errorMsg) + } + + return accountContact + } + + private suspend fun fetchAccountVotersXPRInfo(chainUrl: String, accountName: String): AccountVotersXPRInfo { + var accountVotersXPRInfo = AccountVotersXPRInfo() + + val response = accountContactRepository.fetchAccountVotersXPRInfo( + chainUrl, accountName, votersXPRInfoTableScope, votersXPRInfoTableCode, votersXPRInfoTableName) + if (response.isSuccessful) { + val votersXPRInfoRows = response.body() + + val rows = votersXPRInfoRows?.getAsJsonArray("rows") + val size = rows?.size() ?: 0 + if (size > 0) { + val votersXPRInfo = rows?.get(0)?.asJsonObject + + try { + accountVotersXPRInfo = Gson().fromJson(votersXPRInfo, AccountVotersXPRInfo::class.java) + } catch(e: JsonSyntaxException) { + Timber.e(e) + } + } + } else { + val msg = response.errorBody()?.string() + val errorMsg = if (msg.isNullOrEmpty()) { + response.message() + } else { + msg + } + + Timber.e(errorMsg) + } + + return accountVotersXPRInfo + } + + private suspend fun fetchAccountRefundsXPRInfo(chainUrl: String, accountName: String): AccountRefundsXPRInfo { + var accountRefundsXPRInfo = AccountRefundsXPRInfo() + + val refundsXPRInfoTableScope = accountName + + val response = accountContactRepository.fetchAccountRefundsXPRInfo( + chainUrl, accountName, refundsXPRInfoTableScope, refundsXPRInfoTableCode, refundsXPRInfoTableName) + if (response.isSuccessful) { + val refundsXPRInfoRows = response.body() + + val rows = refundsXPRInfoRows?.getAsJsonArray("rows") + val size = rows?.size() ?: 0 + if (size > 0) { + val refundsXPRInfo = rows?.get(0)?.asJsonObject + + try { + accountRefundsXPRInfo = Gson().fromJson(refundsXPRInfo, AccountRefundsXPRInfo::class.java) + } catch(e: JsonSyntaxException) { + Timber.e(e) + } + } + } else { + val msg = response.errorBody()?.string() + val errorMsg = if (msg.isNullOrEmpty()) { + response.message() + } else { + msg + } + + Timber.d(errorMsg) + } + + return accountRefundsXPRInfo + } + @AssistedInject.Factory interface Factory : ChildWorkerFactory } \ No newline at end of file diff --git a/protonsdk/src/main/java/com/metallicus/protonsdk/workers/InitTokenContractsWorker.kt b/protonsdk/src/main/java/com/metallicus/protonsdk/workers/InitTokenContractsWorker.kt index e2274c80..cc1848df 100644 --- a/protonsdk/src/main/java/com/metallicus/protonsdk/workers/InitTokenContractsWorker.kt +++ b/protonsdk/src/main/java/com/metallicus/protonsdk/workers/InitTokenContractsWorker.kt @@ -46,9 +46,9 @@ class InitTokenContractsWorker private val tokenContractRepository: TokenContractRepository ) : CoroutineWorker(context, params) { - private val protonChainTokensTableScope = context.getString(R.string.protonChainTokensTableScope) - private val protonChainTokensTableCode = context.getString(R.string.protonChainTokensTableCode) - private val protonChainTokensTableName = context.getString(R.string.protonChainTokensTableName) + private val protonChainTokensTableScope = context.getString(R.string.tokensTableScope) + private val protonChainTokensTableCode = context.getString(R.string.tokensTableCode) + private val protonChainTokensTableName = context.getString(R.string.tokensTableName) @Suppress("BlockingMethodInNonBlockingContext") override suspend fun doWork(): Result { @@ -73,6 +73,10 @@ class InitTokenContractsWorker val tokenContract = gson.fromJson(tokenContractJsonObject, TokenContract::class.java) tokenContract.rates = mapOf(Pair("USD", 0.0)) + if (chainProvider.systemTokenSymbol == tokenContract.getSymbol()) { + tokenContract.isSystemToken = true + } + // TODO: add supply, maxSupply, and issuer from get_currency_stats tokenContractRepository.addTokenContract(tokenContract) diff --git a/protonsdk/src/main/res/values/strings.xml b/protonsdk/src/main/res/values/strings.xml index c967afb9..449f4215 100755 --- a/protonsdk/src/main/res/values/strings.xml +++ b/protonsdk/src/main/res/values/strings.xml @@ -2,13 +2,21 @@ 384da888112027f0321850a169f737c33e53b388aad48b5adace4bab97f437e0 https://proton.cryptolions.io/ - eosio.proton - eosio.proton - usersinfo + eosio + eosio + votersxpr - token.proton - token.proton - tokens + + eosio + refundsxpr + + eosio.proton + eosio.proton + usersinfo + + token.proton + token.proton + tokens KeyPair already exists! KeyPair does not exist in Keystore