Updated on 2026-08-14
This commit is contained in:
parent
cfaea982bc
commit
17174cbde8
6 changed files with 30 additions and 23 deletions
|
|
@ -2,6 +2,7 @@ package com.tangem.blockchain.bitcoin
|
|||
|
||||
import com.tangem.blockchain.common.TransactionData
|
||||
import com.tangem.blockchain.common.extensions.Result
|
||||
import com.tangem.blockchain.common.extensions.isZero
|
||||
import org.bitcoinj.core.*
|
||||
import org.bitcoinj.crypto.TransactionSignature
|
||||
import org.bitcoinj.script.Script
|
||||
|
|
@ -81,7 +82,7 @@ internal fun TransactionData.toBitcoinJTransaction(networkParameters: NetworkPar
|
|||
transaction.addOutput(
|
||||
Coin.parseCoin(this.amount.value!!.toPlainString()),
|
||||
Address.fromString(networkParameters, this.destinationAddress))
|
||||
if (change != 0.toBigDecimal()) {
|
||||
if (!change.isZero()) {
|
||||
transaction.addOutput(
|
||||
Coin.parseCoin(change.toPlainString()),
|
||||
Address.fromString(networkParameters,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ package com.tangem.blockchain.bitcoin
|
|||
import android.util.Log
|
||||
import com.tangem.blockchain.bitcoin.network.BitcoinAddressResponse
|
||||
import com.tangem.blockchain.bitcoin.network.BitcoinNetworkManager
|
||||
import com.tangem.blockchain.bitcoin.network.BitcoinNetworkManager.Companion.SATOSHI_IN_BTC
|
||||
import com.tangem.blockchain.common.*
|
||||
import com.tangem.blockchain.common.extensions.Result
|
||||
import com.tangem.blockchain.common.extensions.SimpleResult
|
||||
|
|
@ -27,7 +26,7 @@ class BitcoinWalletManager(
|
|||
private val networkManager = BitcoinNetworkManager(isTestNet)
|
||||
|
||||
init {
|
||||
wallet.balances[AmountType.Coin] = Amount(null, blockchain)
|
||||
wallet.balances[AmountType.Coin] = Amount(null, blockchain, address)
|
||||
}
|
||||
|
||||
override suspend fun update() {
|
||||
|
|
@ -80,9 +79,11 @@ class BitcoinWalletManager(
|
|||
when (val result = networkManager.getFee()) {
|
||||
is Result.Failure -> return result
|
||||
is Result.Success -> {
|
||||
val feeValue = BigDecimal.ONE.movePointLeft(blockchain.decimals.toInt())
|
||||
amount.value = amount.value!! - feeValue
|
||||
val sizeResult = transactionBuilder.getEstimateSize(
|
||||
TransactionData(amount,
|
||||
Amount(1.toBigDecimal().divide(SATOSHI_IN_BTC), blockchain),
|
||||
Amount(feeValue, blockchain),
|
||||
address, destination),
|
||||
walletPublicKey
|
||||
)
|
||||
|
|
|
|||
|
|
@ -85,10 +85,6 @@ class BitcoinNetworkManager(private val isTestNet: Boolean) : BitcoinProvider {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
val SATOSHI_IN_BTC = 100000000.toBigDecimal()
|
||||
}
|
||||
}
|
||||
|
||||
data class BitcoinAddressResponse(
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
package com.tangem.blockchain.bitcoin.network
|
||||
|
||||
import com.tangem.blockchain.bitcoin.UnspentTransaction
|
||||
import com.tangem.blockchain.bitcoin.network.BitcoinNetworkManager.Companion.SATOSHI_IN_BTC
|
||||
import com.tangem.blockchain.bitcoin.network.api.BlockchainInfoApi
|
||||
import com.tangem.blockchain.bitcoin.network.api.EstimatefeeApi
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.extensions.Result
|
||||
import com.tangem.blockchain.common.extensions.SimpleResult
|
||||
import com.tangem.blockchain.common.extensions.retryIO
|
||||
|
|
@ -16,6 +16,7 @@ class BlockchainInfoProvider(
|
|||
private val blockchainApi: BlockchainInfoApi,
|
||||
private val estimatefeeApi: EstimatefeeApi
|
||||
) : BitcoinProvider {
|
||||
val decimals = Blockchain.Bitcoin.decimals.toInt()
|
||||
|
||||
override suspend fun getInfo(address: String): Result<BitcoinAddressResponse> {
|
||||
return try {
|
||||
|
|
@ -29,7 +30,7 @@ class BlockchainInfoProvider(
|
|||
|
||||
val bitcoinUnspents = unspents.unspentOutputs.map {
|
||||
UnspentTransaction(
|
||||
it.amount!!.toBigDecimal().divide(SATOSHI_IN_BTC),
|
||||
it.amount!!.toBigDecimal().movePointLeft(decimals),
|
||||
it.outputIndex!!.toLong(),
|
||||
it.hash!!.hexToBytes(),
|
||||
it.outputScript!!.hexToBytes())
|
||||
|
|
@ -37,7 +38,7 @@ class BlockchainInfoProvider(
|
|||
|
||||
Result.Success(
|
||||
BitcoinAddressResponse(
|
||||
addressData.finalBalance?.toBigDecimal()?.divide(SATOSHI_IN_BTC)
|
||||
addressData.finalBalance?.toBigDecimal()?.movePointLeft(decimals)
|
||||
?: 0.toBigDecimal(), unconfirmedTransactions, bitcoinUnspents))
|
||||
}
|
||||
} catch (exception: Exception) {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
package com.tangem.blockchain.bitcoin.network
|
||||
|
||||
import com.tangem.blockchain.bitcoin.UnspentTransaction
|
||||
import com.tangem.blockchain.bitcoin.network.BitcoinNetworkManager.Companion.SATOSHI_IN_BTC
|
||||
import com.tangem.blockchain.bitcoin.network.api.BlockcypherApi
|
||||
import com.tangem.blockchain.bitcoin.network.api.BlockcypherBody
|
||||
import com.tangem.blockchain.bitcoin.network.response.BlockcypherFee
|
||||
import com.tangem.blockchain.bitcoin.network.response.BlockcypherResponse
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.extensions.Result
|
||||
import com.tangem.blockchain.common.extensions.SimpleResult
|
||||
import com.tangem.blockchain.common.extensions.retryIO
|
||||
|
|
@ -14,6 +14,7 @@ import com.tangem.common.extensions.hexToBytes
|
|||
class BlockcypherProvider(private val api: BlockcypherApi, isTestNet: Boolean) : BitcoinProvider {
|
||||
|
||||
private val blockchain = "btc"
|
||||
private val decimals = Blockchain.Bitcoin.decimals.toInt()
|
||||
|
||||
private val network = if (isTestNet) {
|
||||
BlockcypherNetwork.Test.network
|
||||
|
|
@ -26,14 +27,14 @@ class BlockcypherProvider(private val api: BlockcypherApi, isTestNet: Boolean) :
|
|||
val addressData: BlockcypherResponse = retryIO { api.getAddressData(blockchain, network, address) }
|
||||
val unspents = addressData.txrefs?.map {
|
||||
UnspentTransaction(
|
||||
it.amount!!.toBigDecimal().divide(SATOSHI_IN_BTC),
|
||||
it.amount!!.toBigDecimal().movePointLeft(decimals),
|
||||
it.outputIndex!!.toLong(),
|
||||
it.hash!!.hexToBytes(),
|
||||
it.outputScript!!.hexToBytes()
|
||||
)
|
||||
}
|
||||
return Result.Success(BitcoinAddressResponse(
|
||||
addressData.balance!!.toBigDecimal().divide(SATOSHI_IN_BTC),
|
||||
addressData.balance!!.toBigDecimal().movePointLeft(decimals),
|
||||
addressData.unconfirmedBalance != 0L,
|
||||
unspents))
|
||||
|
||||
|
|
@ -43,27 +44,27 @@ class BlockcypherProvider(private val api: BlockcypherApi, isTestNet: Boolean) :
|
|||
}
|
||||
|
||||
override suspend fun getFee(): Result<BitcoinFee> {
|
||||
try {
|
||||
return try {
|
||||
val receivedFee: BlockcypherFee = retryIO { api.getFee(blockchain, network) }
|
||||
return Result.Success(
|
||||
BitcoinFee(receivedFee.minFeePerKb!!.toBigDecimal().divide(SATOSHI_IN_BTC),
|
||||
receivedFee.normalFeePerKb!!.toBigDecimal().divide(SATOSHI_IN_BTC),
|
||||
receivedFee.priorityFeePerKb!!.toBigDecimal().divide(SATOSHI_IN_BTC))
|
||||
Result.Success(
|
||||
BitcoinFee(receivedFee.minFeePerKb!!.toBigDecimal().movePointLeft(decimals),
|
||||
receivedFee.normalFeePerKb!!.toBigDecimal().movePointLeft(decimals),
|
||||
receivedFee.priorityFeePerKb!!.toBigDecimal().movePointLeft(decimals))
|
||||
)
|
||||
} catch (error: Exception) {
|
||||
return Result.Failure(error)
|
||||
Result.Failure(error)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun sendTransaction(transaction: String): SimpleResult {
|
||||
try {
|
||||
return try {
|
||||
retryIO {
|
||||
api.sendTransaction(
|
||||
blockchain, network, BlockcypherBody(transaction), BlockcypherToken.getToken())
|
||||
}
|
||||
return SimpleResult.Success
|
||||
SimpleResult.Success
|
||||
} catch (error: Exception) {
|
||||
return SimpleResult.Failure(error)
|
||||
SimpleResult.Failure(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
package com.tangem.blockchain.common.extensions
|
||||
|
||||
import java.math.BigDecimal
|
||||
|
||||
fun BigDecimal.isZero() : Boolean {
|
||||
return this.compareTo(BigDecimal.ZERO) == 0
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue