Updated on 2026-08-14
This commit is contained in:
parent
063ae63a94
commit
894e601444
15 changed files with 50 additions and 44 deletions
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
@ -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()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 }
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package com.tangem.blockchain.common
|
||||
|
||||
data class Token(
|
||||
val symbol: String,
|
||||
val contractAddress: String,
|
||||
val decimals: Int
|
||||
)
|
||||
|
|
@ -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>
|
||||
}
|
||||
|
|
@ -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
|
||||
)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue