Updated on 2026-08-14

This commit is contained in:
Tangem 2020-04-23 11:47:09 +03:00
parent 063ae63a94
commit 894e601444
15 changed files with 50 additions and 44 deletions

View file

@ -1,6 +1,5 @@
package com.tangem.blockchain.blockchains.binance
import com.tangem.blockchain.blockchains.binance.client.BinanceDexApiRestClient
import com.tangem.blockchain.blockchains.binance.client.domain.broadcast.TransactionOption
import com.tangem.blockchain.blockchains.binance.client.domain.broadcast.Transfer
import com.tangem.blockchain.blockchains.binance.client.encoding.message.MessageType
@ -8,6 +7,8 @@ import com.tangem.blockchain.blockchains.binance.client.encoding.message.Transac
import com.tangem.blockchain.blockchains.binance.client.encoding.message.TransferMessage
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.TransactionData
import com.tangem.blockchain.extensions.Result
import com.tangem.blockchain.extensions.isAboveZero
import com.tangem.common.extensions.calculateSha256
import com.tangem.common.extensions.toCompressedPublicKey
import org.bitcoinj.core.ECKey
@ -15,7 +16,7 @@ import org.bitcoinj.core.Utils
import java.math.BigInteger
class BinanceTransactionBuilder(
publicKey: ByteArray, private val client: BinanceDexApiRestClient, isTestNet: Boolean = false
publicKey: ByteArray, isTestNet: Boolean = false
) {
var accountNumber: Long? = null
var sequence: Long? = null
@ -26,7 +27,12 @@ class BinanceTransactionBuilder(
private var transactionAssembler: TransactionRequestAssemblerExtSign? = null
private var transferMessage: TransferMessage? = null
fun buildToSign(transactionData: TransactionData): ByteArray {
fun buildToSign(transactionData: TransactionData): Result<ByteArray> {
if (!transactionData.amount.isAboveZero()) return Result.Failure(Exception("Transaction amount is not defined"))
val accountNumber = accountNumber ?: return Result.Failure(Exception("No account number"))
val sequence = sequence ?: return Result.Failure(Exception("No sequence"))
val transfer = Transfer()
transfer.coin = transactionData.amount.currencySymbol
transfer.fromAddress = transactionData.sourceAddress
@ -36,12 +42,12 @@ class BinanceTransactionBuilder(
val options = TransactionOption.DEFAULT_INSTANCE
val accountData = BinanceAccountData(chainId, accountNumber!!, sequence!!)
val accountData = BinanceAccountData(chainId, accountNumber, sequence)
transactionAssembler = client.prepareTransfer(transfer, accountData, prefixedPubKey, options, true)
transactionAssembler = TransactionRequestAssemblerExtSign(accountData, prefixedPubKey, options)
transferMessage = transactionAssembler!!.createTransferMessage(transfer)
return transactionAssembler!!.prepareForSign(transferMessage).calculateSha256()
return Result.Success(transactionAssembler!!.prepareForSign(transferMessage).calculateSha256())
}
fun buildToSend(signature: ByteArray): ByteArray {

View file

@ -39,14 +39,18 @@ class BinanceWalletManager(
}
override suspend fun send(transactionData: TransactionData, signer: TransactionSigner): SimpleResult {
val transactionHash = transactionBuilder.buildToSign(transactionData)
when (val signerResponse = signer.sign(arrayOf(transactionHash), cardId)) {
is CompletionResult.Success -> {
val transactionToSend = transactionBuilder.buildToSend(signerResponse.data.signature)
return networkManager.sendTransaction(transactionToSend)
val buildTransactionResult = transactionBuilder.buildToSign(transactionData)
when (buildTransactionResult) {
is Result.Failure -> return SimpleResult.Failure(buildTransactionResult.error)
is Result.Success -> {
when (val signerResponse = signer.sign(arrayOf(buildTransactionResult.data), cardId)) {
is CompletionResult.Success -> {
val transactionToSend = transactionBuilder.buildToSend(signerResponse.data.signature)
return networkManager.sendTransaction(transactionToSend)
}
is CompletionResult.Failure -> return SimpleResult.Failure(signerResponse.error)
}
}
is CompletionResult.Failure -> return SimpleResult.Failure(signerResponse.error)
}
}

View file

@ -1,6 +1,7 @@
package com.tangem.blockchain.blockchains.binance.network
import com.tangem.blockchain.blockchains.binance.client.BinanceDexApiClientFactory
import com.tangem.blockchain.blockchains.binance.client.BinanceDexApiRestClient
import com.tangem.blockchain.blockchains.binance.client.BinanceDexEnvironment
import com.tangem.blockchain.blockchains.binance.client.encoding.message.TransactionRequestAssemblerExtSign
import com.tangem.blockchain.common.Blockchain
@ -14,11 +15,15 @@ import okhttp3.RequestBody
import java.math.BigDecimal
class BinanceNetworkManager(isTestNet: Boolean = false) {
val api = createRetrofitInstance(if (!isTestNet) API_BINANCE else API_BINANCE_TESTNET)
.create(BinanceApi::class.java)
val client = BinanceDexApiClientFactory.newInstance().newRestClient(
if (!isTestNet) BinanceDexEnvironment.PROD.baseUrl else BinanceDexEnvironment.TEST_NET.baseUrl
)
val api: BinanceApi by lazy {
createRetrofitInstance(if (!isTestNet) API_BINANCE else API_BINANCE_TESTNET)
.create(BinanceApi::class.java)
}
val client: BinanceDexApiRestClient by lazy {
BinanceDexApiClientFactory.newInstance().newRestClient(
if (!isTestNet) BinanceDexEnvironment.PROD.baseUrl else BinanceDexEnvironment.TEST_NET.baseUrl
)
}
suspend fun getInfo(address: String): Result<BinanceInfoResponse> {
return try {

View file

@ -89,6 +89,6 @@ class BitcoinWalletManager(
private fun BigDecimal.calculateFee(transactionSize: BigDecimal): BigDecimal {
val bytesInKb = BigDecimal(1024)
return this.divide(bytesInKb).multiply(transactionSize)
.setScale(8, blockchain.roundingMode())
.setScale(8, BigDecimal.ROUND_DOWN)
}
}

View file

@ -1,6 +1,5 @@
package com.tangem.blockchain.blockchains.ethereum.network
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.extensions.Result
import com.tangem.blockchain.extensions.SimpleResult
import com.tangem.blockchain.extensions.retryIO
@ -87,7 +86,7 @@ class EthereumNetworkManager {
private fun BigDecimal.convertFeeToEth(): BigDecimal {
return this.divide(ETH_IN_WEI.toBigDecimal())
.setScale(12, Blockchain.Ethereum.roundingMode()).stripTrailingZeros()
.setScale(12, BigDecimal.ROUND_DOWN).stripTrailingZeros()
}
}

View file

@ -21,4 +21,6 @@ data class Amount(
constructor(amount: Amount, value: BigDecimal) :
this(amount.currencySymbol, value, amount.address, amount.decimals, amount.type)
}
}
enum class AmountType { Coin, Token, Reserve }

View file

@ -0,0 +1,7 @@
package com.tangem.blockchain.common
data class Token(
val symbol: String,
val contractAddress: String,
val decimals: Int
)

View file

@ -58,13 +58,4 @@ class Wallet(
return amounts[amountType]?.value ?: BigDecimal.ZERO
}
// fun validateTransaction(amount: Amount, fee: Amount?): EnumSet<ValidationError> {
// TODO("not implemented")
// }
}
enum class AmountType { Coin, Token, Reserve }
interface TransactionValidator {
fun validateTransaction(amount: Amount, fee: Amount?): EnumSet<TransactionError>
}

View file

@ -82,19 +82,17 @@ object WalletManagerFactory {
)
}
Blockchain.Binance -> {
val networkManager = BinanceNetworkManager()
return BinanceWalletManager(
cardId, wallet,
BinanceTransactionBuilder(walletPublicKey, networkManager.client),
networkManager
BinanceTransactionBuilder(walletPublicKey),
BinanceNetworkManager()
)
}
Blockchain.BinanceTestnet -> {
val networkManager = BinanceNetworkManager(true)
return BinanceWalletManager(
cardId, wallet,
BinanceTransactionBuilder(walletPublicKey, networkManager.client, true),
networkManager
BinanceTransactionBuilder(walletPublicKey, true),
BinanceNetworkManager(true)
)
}
else -> return null
@ -107,10 +105,4 @@ object WalletManagerFactory {
val decimals = card.cardData?.tokenDecimal ?: return null
return Token(symbol, contractAddress, decimals)
}
}
data class Token(
val symbol: String,
val contractAddress: String,
val decimals: Int
)
}