Skip to content

Commit

Permalink
Merge pull request #326 from tangem/release-app_4.10
Browse files Browse the repository at this point in the history
Release app 4.10
  • Loading branch information
kozarezvlad authored Sep 11, 2023
2 parents 88494f8 + 42847b0 commit 4732380
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,4 @@ class ChiaAddressService(blockchain: Blockchain) : AddressService() {
return Crypto.convertBits(dataBytes, 0, dataBytes.size, 5, 8, false)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ import com.tangem.blockchain.common.TransactionData
import com.tangem.blockchain.extensions.Result
import com.tangem.blstlib.generated.P2
import com.tangem.blstlib.generated.P2_Affine
import com.tangem.common.extensions.*
import com.tangem.common.extensions.calculateSha256
import com.tangem.common.extensions.hexToBytes
import com.tangem.common.extensions.toHexString
import java.math.BigDecimal

class ChiaTransactionBuilder(private val walletPublicKey: ByteArray, val blockchain: Blockchain) {
Expand All @@ -35,9 +37,20 @@ class ChiaTransactionBuilder(private val walletPublicKey: ByteArray, val blockch
BlockchainSdkError.CustomError("Unspent coins are missing")
)

val change = calculateChange(transactionData, unspentCoins)
val unspentsToSpend = getUnspentsToSpend()

coinSpends = transactionData.toChiaCoinSpends(unspentCoins, change)
val change = calculateChange(transactionData, unspentsToSpend)
if (change < 0) { // unspentsToSpend not enough to cover transaction amount
val maxAmount = transactionData.amount.value!! + change.toBigDecimal().movePointLeft(blockchain.decimals())
return Result.Failure(
BlockchainSdkError.Chia.UtxoAmountError(
maxOutputs = MAX_INPUT_COUNT,
maxAmount = maxAmount
)
)
}

coinSpends = transactionData.toChiaCoinSpends(unspentsToSpend, change)

val hashesForSign = coinSpends.map { it ->
// our solutions are always Cons
Expand All @@ -61,6 +74,12 @@ class ChiaTransactionBuilder(private val walletPublicKey: ByteArray, val blockch
return (coinSpends.size * COIN_SPEND_COST) + (numberOfCoinsCreated * CREATE_COIN_COST)
}

private fun getUnspentsToSpend() = unspentCoins
.sortedByDescending { it.amount }
.take(getUnspentsToSpendCount())

private fun getUnspentsToSpendCount(): Int = unspentCoins.size.coerceAtMost(MAX_INPUT_COUNT)

private fun calculateChange(
transactionData: TransactionData,
unspentCoins: List<ChiaCoin>,
Expand Down Expand Up @@ -143,6 +162,8 @@ class ChiaTransactionBuilder(private val walletPublicKey: ByteArray, val blockch
private const val COIN_SPEND_COST = 4500000L
private const val CREATE_COIN_COST = 2400000L

private const val MAX_INPUT_COUNT = 50 // Aligned inside Tangem. In iOS max input count is 15.

private const val AUG_SCHEME_DST = "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_AUG_"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,31 @@ sealed class BlockchainSdkError(
cause = throwable,
)

sealed class Chia(
subCode: Int,
customMessage: String? = null,
throwable: Throwable? = null,
) : BlockchainSdkError(
code = ERROR_CODE_CHIA + subCode,
customMessage = customMessage ?: (ERROR_CODE_CHIA + subCode).toString(),
messageResId = null,
cause = throwable,
) {
class UtxoAmountError(val maxOutputs: Int, val maxAmount: BigDecimal) : Chia(
1,
"Due to Chia limitations only $maxOutputs UTXOs can fit in a single transaction. This means you can only" +
" send ${maxAmount.toPlainString()}."
)
}

companion object {
const val ERROR_CODE_SOLANA = 1000
const val ERROR_CODE_POLKADOT = 2000
const val ERROR_CODE_KASPA = 3000
const val ERROR_CODE_TON = 4000
const val ERROR_CODE_COSMOS = 5000
const val ERROR_CODE_WALLET_CORE = 6000
const val ERROR_CODE_CHIA = 7000
}
}

Expand Down

0 comments on commit 4732380

Please sign in to comment.