Skip to content

Commit

Permalink
Merge pull request #8 from ProtonProtocol/develop
Browse files Browse the repository at this point in the history
Push multiple transactions
  • Loading branch information
Joey Harward authored Sep 18, 2020
2 parents 62a78f4 + a7ed549 commit edf9a65
Show file tree
Hide file tree
Showing 8 changed files with 152 additions and 43 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.5"
implementation "com.metallicus:protonsdk:0.5.6"
}
```

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.4.10"
const val orchidVersion = "0.21.1"

object ProtonSdk {
const val versionCode = 17
const val versionName = "0.5.5"
const val versionCode = 18
const val versionName = "0.5.6"
}

object BuildPlugins {
Expand Down
112 changes: 81 additions & 31 deletions protonsdk/src/main/java/com/metallicus/protonsdk/ActionsModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ package com.metallicus.protonsdk
import android.content.Context
import com.google.gson.Gson
import com.google.gson.JsonObject
import com.google.gson.JsonParser
import com.metallicus.protonsdk.common.Prefs
import com.metallicus.protonsdk.common.Resource
import com.metallicus.protonsdk.common.SecureKeys
Expand Down Expand Up @@ -201,11 +202,15 @@ class ActionsModule {
ActionTrace(actionTrxId, actionTraceAct))
}

suspend fun transferTokens(chainUrl: String, pin: String, contract: String, from: String, to: String, quantity: String, memo: String): Resource<JsonObject> {
suspend fun transferTokens(chainUrl: String, pin: String, contract: String, from: String,
to: String, quantity: String, memo: String): Resource<JsonObject> {
return try {
val eosTransfer = EosTransfer(from, to, quantity, memo)
val jsonToBinArgs = eosTransfer.jsonToBinArgs()

val action = Action(contract, eosTransfer.action)
action.setAuthorization(eosTransfer.activePermission)

val jsonToBinResponse =
actionRepository.jsonToBin(
chainUrl,
Expand All @@ -217,61 +222,106 @@ class ActionsModule {

requireNotNull(jsonToBin)

val action = Action(contract, eosTransfer.action)
action.setData(jsonToBin.binArgs)
action.setAuthorization(eosTransfer.activePermission)

val signedTransaction = SignedTransaction()
signedTransaction.addAction(action)

val chainInfoResponse = actionRepository.getChainInfo(chainUrl)
if (chainInfoResponse.isSuccessful) {
val chainInfo = chainInfoResponse.body()
signAndPushTransaction(chainUrl, pin, signedTransaction)
} else {
val msg = jsonToBinResponse.errorBody()?.string()
val errorMsg = if (msg.isNullOrEmpty()) {
jsonToBinResponse.message()
} else {
msg
}

requireNotNull(chainInfo)
Resource.error(errorMsg)
}
} catch (e: Exception) {
Resource.error(e.localizedMessage.orEmpty())
}
}

signedTransaction.setReferenceBlock(chainInfo.headBlockId)
signedTransaction.expiration = chainInfo.getTimeAfterHeadBlockTime(30000)
suspend fun pushTransactions(chainUrl: String, pin: String, actions: List<Action>): Resource<JsonObject> {
try {
if (actions.isNotEmpty()) {
actions.forEach { action ->
val jsonToBinResponse = actionRepository.jsonToBin(
chainUrl,
action.account,
action.name,
JsonParser.parseString(action.data.asString)
)
if (jsonToBinResponse.isSuccessful) {
val jsonToBin = jsonToBinResponse.body()

requireNotNull(jsonToBin)

action.setData(jsonToBin.binArgs)
} else {
val msg = jsonToBinResponse.errorBody()?.string()
val errorMsg = if (msg.isNullOrEmpty()) {
jsonToBinResponse.message()
} else {
msg
}

val publicKey = prefs.getActivePublicKey()
return Resource.error(errorMsg)
}
}
} else {
return Resource.error("No Actions")
}
} catch (e: Exception) {
return Resource.error(e.localizedMessage.orEmpty())
}

val privateKeyStr = secureKeys.getPrivateKey(publicKey, pin)
val signedTransaction = SignedTransaction()
signedTransaction.actions = actions
return signAndPushTransaction(chainUrl, pin, signedTransaction)
}

require(privateKeyStr != null && privateKeyStr != "") { "No private key found" }
private suspend fun signAndPushTransaction(chainUrl: String, pin: String, signedTransaction: SignedTransaction): Resource<JsonObject> {
return try {
val chainInfoResponse = actionRepository.getChainInfo(chainUrl)
if (chainInfoResponse.isSuccessful) {
val chainInfo = chainInfoResponse.body()

val privateKey = EosPrivateKey(privateKeyStr)
requireNotNull(chainInfo)

signedTransaction.sign(privateKey, TypeChainId(chainInfo.chainId))
signedTransaction.setReferenceBlock(chainInfo.headBlockId)
signedTransaction.expiration = chainInfo.getTimeAfterHeadBlockTime(30000)

val packedTransaction = PackedTransaction(signedTransaction)
val publicKey = prefs.getActivePublicKey()

val pushTransactionResponse = actionRepository.pushTransaction(chainUrl, packedTransaction)
if (pushTransactionResponse.isSuccessful) {
Resource.success(pushTransactionResponse.body())
} else {
val msg = pushTransactionResponse.errorBody()?.string()
val errorMsg = if (msg.isNullOrEmpty()) {
pushTransactionResponse.message()
} else {
msg
}
val privateKeyStr = secureKeys.getPrivateKey(publicKey, pin)

Resource.error(errorMsg)
}
require(privateKeyStr != null && privateKeyStr != "") { "No private key found" }

val privateKey = EosPrivateKey(privateKeyStr)

signedTransaction.sign(privateKey, TypeChainId(chainInfo.chainId))

val packedTransaction = PackedTransaction(signedTransaction)

val pushTransactionResponse = actionRepository.pushTransaction(chainUrl, packedTransaction)
if (pushTransactionResponse.isSuccessful) {
Resource.success(pushTransactionResponse.body())
} else {
val msg = chainInfoResponse.errorBody()?.string()
val msg = pushTransactionResponse.errorBody()?.string()
val errorMsg = if (msg.isNullOrEmpty()) {
chainInfoResponse.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
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ class CurrencyBalancesModule {
currencyBalanceRepository.addCurrencyBalance(currencyBalance)
}

val tokenCurrencyBalances = currencyBalanceRepository.getTokenCurrencyBalance(tokenContractId)
val tokenCurrencyBalances = currencyBalanceRepository.getTokenCurrencyBalance(accountName, tokenContractId)

Resource.success(tokenCurrencyBalances)
} else {
Expand Down
64 changes: 63 additions & 1 deletion protonsdk/src/main/java/com/metallicus/protonsdk/Proton.kt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import com.metallicus.protonsdk.di.DaggerInjector
import com.metallicus.protonsdk.di.ProtonModule
import com.metallicus.protonsdk.eosio.commander.digest.Sha256
import com.metallicus.protonsdk.eosio.commander.ec.EosPrivateKey
import com.metallicus.protonsdk.eosio.commander.model.chain.Action as ChainAction
import com.metallicus.protonsdk.model.*
import kotlinx.coroutines.*
import timber.log.Timber
Expand Down Expand Up @@ -402,7 +403,7 @@ class Proton private constructor(context: Context) {
}
}

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

try {
Expand All @@ -426,4 +427,65 @@ class Proton private constructor(context: Context) {
emit(error)
}
}

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

try {
val activeAccount = getActiveAccountAsync()

emit(actionsModule.transferTokens(
activeAccount.chainProvider.chainUrl,
pin,
contract,
activeAccount.account.accountName,
toAccount,
amount,
memo))
} catch (e: ProtonException) {
val error: Resource<JsonObject> = Resource.error(e)
emit(error)
} catch (e: Exception) {
val error: Resource<JsonObject> = Resource.error(e.localizedMessage.orEmpty())
emit(error)
}
}

/*fun pushTransaction(pin: String, action: ChainAction): LiveData<Resource<JsonObject>> = liveData {
emit(Resource.loading())
try {
val activeAccount = getActiveAccountAsync()
emit(actionsModule.pushTransaction(
activeAccount.chainProvider.chainUrl,
pin,
action))
} catch (e: ProtonException) {
val error: Resource<JsonObject> = Resource.error(e)
emit(error)
} catch (e: Exception) {
val error: Resource<JsonObject> = Resource.error(e.localizedMessage.orEmpty())
emit(error)
}
}*/

fun pushTransactions(pin: String, actions: List<ChainAction>): LiveData<Resource<JsonObject>> = liveData {
emit(Resource.loading())

try {
val activeAccount = getActiveAccountAsync()

emit(actionsModule.pushTransactions(
activeAccount.chainProvider.chainUrl,
pin,
actions))
} catch (e: ProtonException) {
val error: Resource<JsonObject> = Resource.error(e)
emit(error)
} catch (e: Exception) {
val error: Resource<JsonObject> = Resource.error(e.localizedMessage.orEmpty())
emit(error)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ interface AccountDao {
@Update
suspend fun update(account: Account)

@Transaction
@Query("SELECT * FROM account WHERE accountName = :accountName")
suspend fun findByAccountName(accountName: String): ChainAccount

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,9 @@ 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 tokenContractId = :tokenContractId")
suspend fun findByTokenContract(tokenContractId: String): TokenCurrencyBalance
@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<TokenCurrencyBalance>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ class CurrencyBalanceRepository @Inject constructor(
return protonChainService.getCurrencyBalances("$chainUrl/v2/state/get_tokens", accountName)
}

suspend fun getTokenCurrencyBalance(tokenContractId: String): TokenCurrencyBalance {
return currencyBalanceDao.findByTokenContract(tokenContractId)
suspend fun getTokenCurrencyBalance(accountName: String, tokenContractId: String): TokenCurrencyBalance {
return currencyBalanceDao.findByTokenContract(accountName, tokenContractId)
}

suspend fun getTokenCurrencyBalances(accountName: String): List<TokenCurrencyBalance> {
Expand Down

0 comments on commit edf9a65

Please sign in to comment.