Skip to content

Commit

Permalink
Merge pull request #6 from ProtonProtocol/develop
Browse files Browse the repository at this point in the history
Fixed API routes and PIN validation
  • Loading branch information
Joey Harward authored Sep 8, 2020
2 parents 21fdd8e + 56a3649 commit 7cdcd50
Show file tree
Hide file tree
Showing 12 changed files with 99 additions and 42 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Then add the following dependency to your module's build.gradle
```gradle
dependencies {
...
implementation "com.metallicus:protonsdk:0.5.3"
implementation "com.metallicus:protonsdk:0.5.4"
}
```

Expand Down
4 changes: 2 additions & 2 deletions buildSrc/src/main/kotlin/Dependencies.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ const val kotlinVersion = "1.3.72"
const val orchidVersion = "0.21.1"

object ProtonSdk {
const val versionCode = 15
const val versionName = "0.5.3"
const val versionCode = 16
const val versionName = "0.5.4"
}

object BuildPlugins {
Expand Down
28 changes: 23 additions & 5 deletions protonsdk/src/main/java/com/metallicus/protonsdk/AccountModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
package com.metallicus.protonsdk

import android.content.Context
import android.util.Base64
import com.metallicus.protonsdk.common.SecureKeys
import com.metallicus.protonsdk.common.Prefs
import com.metallicus.protonsdk.common.Resource
Expand Down Expand Up @@ -58,8 +59,8 @@ class AccountModule {
DaggerInjector.component.inject(this)
}

fun hasActiveAccount(): Boolean {
return prefs.getActiveAccountName().isNotEmpty()
fun getActiveAccountName(): String {
return prefs.getActiveAccountName()
}

suspend fun accountAvailable(chainUrl: String, accountName: String): Boolean {
Expand Down Expand Up @@ -105,6 +106,18 @@ class AccountModule {
}
}

fun hasPrivateKeys(): Boolean {
return secureKeys.hasKeys()
}

fun resetPrivateKeys(oldPin: String, newPin: String): Boolean {
return secureKeys.resetKeys(oldPin, newPin)
}

fun isPinValid(pin: String): Boolean {
return secureKeys.checkPin(pin)
}

private suspend fun fetchAccountContact(chainUrl: String, accountName: String): AccountContact {
val accountContact = AccountContact(accountName)
accountContact.accountName = accountName
Expand Down Expand Up @@ -216,6 +229,11 @@ class AccountModule {
}
}

fun getActiveAccountPrivateKey(pin: String): String {
val publicKey = prefs.getActivePublicKey()
return secureKeys.getPrivateKey(publicKey, pin).orEmpty()
}

private fun getActiveAccountSignature(pin: String): String {
val accountName = prefs.getActiveAccountName()
val publicKey = prefs.getActivePublicKey()
Expand All @@ -233,7 +251,7 @@ class AccountModule {
val accountName = chainAccount.account.accountName

val updateAccountNameUrl =
chainAccount.chainProvider.chainUrl + chainAccount.chainProvider.updateAccountNamePath
chainAccount.chainProvider.chainApiUrl + chainAccount.chainProvider.updateAccountNamePath

val response = accountRepository.updateAccountName(
updateAccountNameUrl,
Expand Down Expand Up @@ -264,7 +282,7 @@ class AccountModule {
val accountName = chainAccount.account.accountName

val updateAccountAvatarUrl =
chainAccount.chainProvider.chainUrl + chainAccount.chainProvider.updateAccountAvatarPath
chainAccount.chainProvider.chainApiUrl + chainAccount.chainProvider.updateAccountAvatarPath

val response = accountRepository.updateAccountAvatar(
updateAccountAvatarUrl,
Expand All @@ -274,7 +292,7 @@ class AccountModule {

return if (response.isSuccessful) {
val account = chainAccount.account
account.accountContact.avatar = imageByteArray.toString(Charset.defaultCharset())
account.accountContact.avatar = Base64.encodeToString(imageByteArray, Base64.DEFAULT)
accountRepository.updateAccount(account)

Resource.success(chainAccount)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,19 +249,19 @@ class ActionsModule {
if (pushTransactionResponse.isSuccessful) {
Resource.success(pushTransactionResponse.body())
} else {
val msg = jsonToBinResponse.errorBody()?.string()
val msg = pushTransactionResponse.errorBody()?.string()
val errorMsg = if (msg.isNullOrEmpty()) {
jsonToBinResponse.message()
pushTransactionResponse.message()
} else {
msg
}

Resource.error(errorMsg)
}
} else {
val msg = jsonToBinResponse.errorBody()?.string()
val msg = chainInfoResponse.errorBody()?.string()
val errorMsg = if (msg.isNullOrEmpty()) {
jsonToBinResponse.message()
chainInfoResponse.message()
} else {
msg
}
Expand Down
30 changes: 26 additions & 4 deletions protonsdk/src/main/java/com/metallicus/protonsdk/Proton.kt
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,18 @@ class Proton private constructor(context: Context) {
} catch (e: Exception) { "" }
}

fun hasPrivateKeys(): Boolean {
return accountModule.hasPrivateKeys()
}

fun resetPrivateKeys(oldPin: String, newPin: String): Boolean {
return accountModule.resetPrivateKeys(oldPin, newPin)
}

fun isPinValid(pin: String): Boolean {
return accountModule.isPinValid(pin)
}

fun accountAvailable(accountName: String): LiveData<Resource<Boolean>> = liveData {
emit(Resource.loading())

Expand Down Expand Up @@ -197,8 +209,12 @@ class Proton private constructor(context: Context) {
}
}

fun getActiveAccountName(): String {
return accountModule.getActiveAccountName()
}

fun hasActiveAccount(): Boolean {
return accountModule.hasActiveAccount()
return getActiveAccountName().isNotEmpty()
}

fun setActiveAccount(activeAccount: ActiveAccount): LiveData<Resource<ChainAccount>> = liveData {
Expand All @@ -214,6 +230,10 @@ class Proton private constructor(context: Context) {
}
}

fun getActiveAccountPrivateKey(pin: String): String {
return accountModule.getActiveAccountPrivateKey(pin)
}

private suspend fun getActiveAccountAsync() = suspendCoroutine<ChainAccount> { continuation ->
workersModule.onInitActiveAccount { success, data ->
if (success) {
Expand Down Expand Up @@ -268,7 +288,7 @@ class Proton private constructor(context: Context) {
}

val exchangeRateUrl =
activeAccount.chainProvider.chainUrl + activeAccount.chainProvider.exchangeRatePath
activeAccount.chainProvider.chainApiUrl + activeAccount.chainProvider.exchangeRatePath

tokenContractsModule.updateExchangeRates(exchangeRateUrl, tokenContractsMap)

Expand Down Expand Up @@ -358,16 +378,18 @@ class Proton private constructor(context: Context) {
}
}

fun transferTokens(pin: String, contract: String, toAccount: String, amount: String, memo: String): LiveData<Resource<JsonObject>> = liveData {
fun transferTokens(pin: String, tokenContractId: String, toAccount: String, amount: String, memo: String): LiveData<Resource<JsonObject>> = liveData {
emit(Resource.loading())

try {
val activeAccount = getActiveAccountAsync()

val tokenContract = tokenContractsModule.getTokenContract(tokenContractId)

emit(actionsModule.transferTokens(
activeAccount.chainProvider.chainUrl,
pin,
contract,
tokenContract.contract,
activeAccount.account.accountName,
toAccount,
amount,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
package com.metallicus.protonsdk.common

import android.content.Context
import com.metallicus.protonsdk.eosio.commander.ec.EosPrivateKey
import com.metallicus.protonsdk.securestorage.SecurePreferences
import com.metallicus.protonsdk.securestorage.SecureStorageException
import timber.log.Timber
Expand All @@ -39,6 +40,41 @@ class SecureKeys(private val context: Context) {
return securePrefs.all.isNotEmpty()
}

fun checkPin(pin: String): Boolean {
var isValid = false
SecurePreferences.setSharedPreferencesName(SHARED_PREFS_FILENAME)
val securePrefs = SecurePreferences.getSharedPreferences(context)
if (securePrefs.all.isNotEmpty()) {
isValid = try {
val firstAccount = securePrefs.all.entries.iterator().next()
val publicKey = firstAccount.key
val privateKey = SecurePreferences.getStringValue(context, publicKey, pin, "")
EosPrivateKey(privateKey).publicKey.toString() == publicKey
} catch (e: Exception) {
false
}
}
return isValid
}

fun resetKeys(oldPin: String, newPin: String): Boolean {
return try {
SecurePreferences.setSharedPreferencesName(SHARED_PREFS_FILENAME)
val securePrefs = SecurePreferences.getSharedPreferences(context)
securePrefs.all.forEach { secureKey ->
val publicKey = secureKey.key
val privateKey = SecurePreferences.getStringValue(context, publicKey, oldPin, "")
privateKey?.let {
SecurePreferences.setValue(context, publicKey, it, newPin)
}
}
true
} catch (e: SecureStorageException) {
Timber.d(e)
false
}
}

fun keyExists(publicKey: String): Boolean {
SecurePreferences.setSharedPreferencesName(SHARED_PREFS_FILENAME)
return SecurePreferences.contains(context, publicKey)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import com.metallicus.protonsdk.model.*
AccountContact::class,
CurrencyBalance::class,
Action::class],
version = 16,
version = 17,
exportSchema = false
)
abstract class ProtonDb : RoomDatabase() {
Expand Down
22 changes: 0 additions & 22 deletions protonsdk/src/main/java/com/metallicus/protonsdk/model/Action.kt
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@ data class Action(

lateinit var accountContact: AccountContact

enum class IconType { AVATAR, SEND, RECEIVE, STAKE, UNSTAKE, BUY_RAM }

fun isTransfer(): Boolean {
return (actionTrace.act.name == "transfer")
}
Expand All @@ -63,26 +61,6 @@ data class Action(
return (accountName == actionTrace.act.data?.from && actionTrace.act.data.from != actionTrace.act.data.to)
}

fun getIconType(): IconType {
return IconType.AVATAR

// return if (accountContact.isLynxChain) {
// IconType.AVATAR
// } else {
// if (actionTrace.act.data?.to == "eosio.ramfee" || actionTrace.act.data?.to == "eosio.ram") {
// IconType.BUY_RAM
// } else if (actionTrace.act.data?.to == "eosio.stake") {
// IconType.STAKE
// } else if (actionTrace.act.data?.from == "eosio.stake") {
// IconType.UNSTAKE
// } else if (!isSender()) {
// IconType.RECEIVE
// } else {
// IconType.SEND
// }
// }
}

fun getDisplayName(): String {
return when {
actionTrace.act.data?.to == "eosio.ramfee" -> "Buy RAM Fee"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,6 @@ data class ChainProvider(
@SerializedName("updateAccountAvatarPath") val updateAccountAvatarPath: String,
@SerializedName("updateAccountNamePath") val updateAccountNamePath: String,
@SerializedName("exchangeRatePath") val exchangeRatePath: String
)
) {
lateinit var chainApiUrl: String
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class ActionRepository @Inject constructor(
}

suspend fun getChainInfo(chainUrl: String): Response<ChainInfo> {
return protonChainService.getChainInfo(chainUrl)
return protonChainService.getChainInfo("$chainUrl/v1/chain/get_info")
}

suspend fun getRequiredKeys(chainUrl: String, requiredKeysBody: RequiredKeysBody): Response<RequiredKeysResponse> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class InitChainProviderWorker
chainProviderRepository.removeAll()

val chainProvider = Gson().fromJson(response.body(), ChainProvider::class.java)
chainProvider.chainApiUrl = protonChainUrl

chainProviderRepository.addChainProvider(chainProvider)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class UpdateTokenContractRatesWorker
tokenContractsMap["${it.contract}:${it.getSymbol()}"] = it.id
}

val exchangeRateUrl = chainProvider.chainUrl + chainProvider.exchangeRatePath
val exchangeRateUrl = chainProvider.chainApiUrl + chainProvider.exchangeRatePath

val exchangeRatesResponse = tokenContractRepository.fetchExchangeRates(exchangeRateUrl)
if (exchangeRatesResponse.isSuccessful) {
Expand Down

0 comments on commit 7cdcd50

Please sign in to comment.