Updated on 2026-08-14
This commit is contained in:
commit
0d54da74a5
14 changed files with 305 additions and 11 deletions
|
|
@ -1,15 +1,18 @@
|
|||
package com.tangem.blockchain.blockchains.bitcoin
|
||||
|
||||
|
||||
import com.tangem.blockchain.blockchains.ducatus.DucatusMainNetParams
|
||||
import com.tangem.blockchain.blockchains.litecoin.LitecoinMainNetParams
|
||||
import com.tangem.blockchain.common.AddressService
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.common.extensions.calculateRipemd160
|
||||
import com.tangem.common.extensions.calculateSha256
|
||||
import org.bitcoinj.core.*
|
||||
import org.bitcoinj.core.Base58
|
||||
import org.bitcoinj.core.LegacyAddress
|
||||
import org.bitcoinj.core.NetworkParameters
|
||||
import org.bitcoinj.core.SegwitAddress
|
||||
import org.bitcoinj.params.MainNetParams
|
||||
import org.bitcoinj.params.TestNet3Params
|
||||
import java.security.MessageDigest
|
||||
|
||||
class BitcoinAddressService(private val blockchain: Blockchain) : AddressService {
|
||||
|
||||
|
|
@ -17,6 +20,7 @@ class BitcoinAddressService(private val blockchain: Blockchain) : AddressService
|
|||
Blockchain.Bitcoin -> MainNetParams()
|
||||
Blockchain.BitcoinTestnet -> TestNet3Params()
|
||||
Blockchain.Litecoin -> LitecoinMainNetParams()
|
||||
Blockchain.Ducatus -> DucatusMainNetParams()
|
||||
else -> throw Exception("${blockchain.fullName} blockchain is not supported by ${this::class.simpleName}")
|
||||
}
|
||||
|
||||
|
|
@ -52,6 +56,7 @@ class BitcoinAddressService(private val blockchain: Blockchain) : AddressService
|
|||
Blockchain.Bitcoin -> LegacyAddress.fromBase58(MainNetParams(), address)
|
||||
Blockchain.BitcoinTestnet -> LegacyAddress.fromBase58(TestNet3Params(), address)
|
||||
Blockchain.Litecoin -> LegacyAddress.fromBase58(LitecoinMainNetParams(), address)
|
||||
Blockchain.Ducatus -> LegacyAddress.fromBase58(DucatusMainNetParams(), address)
|
||||
else -> return false
|
||||
}
|
||||
true
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.blockchain.blockchains.bitcoin
|
||||
|
||||
import com.tangem.blockchain.blockchains.ducatus.DucatusMainNetParams
|
||||
import com.tangem.blockchain.blockchains.litecoin.LitecoinMainNetParams
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.TransactionData
|
||||
|
|
@ -23,6 +24,7 @@ open class BitcoinTransactionBuilder(
|
|||
Blockchain.Bitcoin, Blockchain.BitcoinCash -> MainNetParams()
|
||||
Blockchain.BitcoinTestnet -> TestNet3Params()
|
||||
Blockchain.Litecoin -> LitecoinMainNetParams()
|
||||
Blockchain.Ducatus -> DucatusMainNetParams()
|
||||
else -> throw Exception("${blockchain.fullName} blockchain is not supported by ${this::class.simpleName}")
|
||||
}
|
||||
var unspentOutputs: List<BitcoinUnspentOutput>? = null
|
||||
|
|
@ -64,7 +66,7 @@ open class BitcoinTransactionBuilder(
|
|||
}
|
||||
|
||||
fun calculateChange(transactionData: TransactionData, unspentOutputs: List<BitcoinUnspentOutput>): BigDecimal {
|
||||
val fullAmount = unspentOutputs!!.map { it.amount }.reduce { acc, number -> acc + number }
|
||||
val fullAmount = unspentOutputs.map { it.amount }.reduce { acc, number -> acc + number }
|
||||
return fullAmount - (transactionData.amount.value!! + (transactionData.fee?.value
|
||||
?: 0.toBigDecimal()))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import java.math.BigDecimal
|
|||
open class BitcoinWalletManager(
|
||||
cardId: String,
|
||||
wallet: Wallet,
|
||||
private val transactionBuilder: BitcoinTransactionBuilder,
|
||||
protected val transactionBuilder: BitcoinTransactionBuilder,
|
||||
private val networkManager: BitcoinProvider
|
||||
) : WalletManager(cardId, wallet), TransactionSender {
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,69 @@
|
|||
package com.tangem.blockchain.blockchains.ducatus;
|
||||
|
||||
import org.bitcoinj.core.Utils;
|
||||
import org.bitcoinj.params.AbstractBitcoinNetParams;
|
||||
import org.bitcoinj.params.MainNetParams;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
|
||||
public class DucatusMainNetParams extends AbstractBitcoinNetParams {
|
||||
public static final int MAINNET_MAJORITY_WINDOW = MainNetParams.MAINNET_MAJORITY_WINDOW;
|
||||
public static final int MAINNET_MAJORITY_REJECT_BLOCK_OUTDATED = MainNetParams.MAINNET_MAJORITY_REJECT_BLOCK_OUTDATED;
|
||||
public static final int MAINNET_MAJORITY_ENFORCE_BLOCK_UPGRADE = MainNetParams.MAINNET_MAJORITY_ENFORCE_BLOCK_UPGRADE;
|
||||
|
||||
public DucatusMainNetParams() {
|
||||
super();
|
||||
id = "org.bitcoinj.ducatus_mainnet";
|
||||
// Genesis hash is 12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2
|
||||
packetMagic = 0xfbc0b6db;
|
||||
|
||||
maxTarget = Utils.decodeCompactBits(0x1e0fffffL);
|
||||
port = 9333;
|
||||
addressHeader = 49;
|
||||
p2shHeader = 51; //TODO: is this right? Haven't seen Ducatus p2sh address ever
|
||||
segwitAddressHrp = "duc"; //TODO: does Ducatus even have bech32 addresses? At least other blockchain's addresses won't pass
|
||||
dumpedPrivateKeyHeader = 176;
|
||||
|
||||
spendableCoinbaseDepth = 100;
|
||||
subsidyDecreaseBlockCount = 840000;
|
||||
|
||||
genesisBlock.setTime(1317972665L);
|
||||
genesisBlock.setDifficultyTarget(0x1e0ffff0L);
|
||||
genesisBlock.setNonce(2084524493);
|
||||
|
||||
String genesisHash = genesisBlock.getHashAsString();
|
||||
checkState(genesisHash.equals("5155a7ed2219a75c0735c58b5d459c6d07d97917570e27b9d1d4546fb8431381"));
|
||||
alertSigningKey = Hex.decode("040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9");
|
||||
|
||||
majorityEnforceBlockUpgrade = MAINNET_MAJORITY_ENFORCE_BLOCK_UPGRADE;
|
||||
majorityRejectBlockOutdated = MAINNET_MAJORITY_REJECT_BLOCK_OUTDATED;
|
||||
majorityWindow = MAINNET_MAJORITY_WINDOW;
|
||||
|
||||
dnsSeeds = new String[]{
|
||||
"dnsseed.litecointools.com",
|
||||
"dnsseed.litecoinpool.org",
|
||||
"dnsseed.ltc.xurious.com",
|
||||
"dnsseed.koin-project.com",
|
||||
"dnsseed.weminemnc.com"
|
||||
};
|
||||
bip32HeaderP2PKHpub = 0x0488B21E;
|
||||
bip32HeaderP2PKHpriv = 0x0488ADE4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPaymentProtocolId() {
|
||||
return PAYMENT_PROTOCOL_ID_MAINNET;
|
||||
}
|
||||
|
||||
|
||||
private static DucatusMainNetParams instance;
|
||||
|
||||
public static synchronized DucatusMainNetParams get() {
|
||||
if (instance == null) {
|
||||
instance = new DucatusMainNetParams();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
package com.tangem.blockchain.blockchains.ducatus
|
||||
|
||||
import com.tangem.blockchain.blockchains.bitcoin.BitcoinTransactionBuilder
|
||||
import com.tangem.blockchain.blockchains.bitcoin.BitcoinWalletManager
|
||||
import com.tangem.blockchain.blockchains.ducatus.network.DucatusNetworkManager
|
||||
import com.tangem.blockchain.common.Amount
|
||||
import com.tangem.blockchain.common.TransactionData
|
||||
import com.tangem.blockchain.common.TransactionSender
|
||||
import com.tangem.blockchain.common.Wallet
|
||||
import com.tangem.blockchain.extensions.Result
|
||||
import java.math.BigDecimal
|
||||
|
||||
class DucatusWalletManager(
|
||||
cardId: String,
|
||||
wallet: Wallet,
|
||||
transactionBuilder: BitcoinTransactionBuilder,
|
||||
networkManager: DucatusNetworkManager
|
||||
) : BitcoinWalletManager(cardId, wallet, transactionBuilder, networkManager), TransactionSender {
|
||||
override suspend fun getFee(amount: Amount, destination: String): Result<List<Amount>> {
|
||||
val feeValue = BigDecimal.ONE.movePointLeft(blockchain.decimals())
|
||||
val sizeResult = transactionBuilder.getEstimateSize(
|
||||
TransactionData(amount, Amount(amount, feeValue), wallet.address, destination)
|
||||
)
|
||||
return when (sizeResult) {
|
||||
is Result.Failure -> sizeResult
|
||||
is Result.Success -> {
|
||||
val transactionSize = sizeResult.data.toBigDecimal()
|
||||
val minFee = BigDecimal.valueOf(0.00000089).multiply(transactionSize)
|
||||
val normalFee = BigDecimal.valueOf(0.00000144).multiply(transactionSize)
|
||||
val priorityFee = BigDecimal.valueOf(0.00000350).multiply(transactionSize)
|
||||
val fees = listOf(
|
||||
Amount(minFee, blockchain),
|
||||
Amount(normalFee, blockchain),
|
||||
Amount(priorityFee, blockchain)
|
||||
)
|
||||
Result.Success(fees)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package com.tangem.blockchain.blockchains.ducatus.network
|
||||
|
||||
import com.tangem.blockchain.blockchains.ducatus.network.bitcore.BitcoreApi
|
||||
import com.tangem.blockchain.blockchains.ducatus.network.bitcore.BitcoreProvider
|
||||
import com.tangem.blockchain.network.API_DUCATUS
|
||||
import com.tangem.blockchain.network.createRetrofitInstance
|
||||
|
||||
class DucatusNetworkManager() : BitcoreProvider(createRetrofitInstance(API_DUCATUS).create(BitcoreApi::class.java))
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package com.tangem.blockchain.blockchains.ducatus.network.bitcore
|
||||
|
||||
import com.squareup.moshi.JsonClass
|
||||
import retrofit2.http.Body
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.POST
|
||||
import retrofit2.http.Path
|
||||
|
||||
interface BitcoreApi {
|
||||
@GET("api/DUC/mainnet/address/{address}/balance")
|
||||
suspend fun getBalance(@Path("address") address: String): BitcoreBalance
|
||||
|
||||
@GET("api/DUC/mainnet/address/{address}/?unspent=true")
|
||||
suspend fun getUnspents(@Path("address") address: String): List<BitcoreUtxo>
|
||||
|
||||
@POST("api/DUC/mainnet/tx/send")
|
||||
suspend fun sendTransaction(@Body body: BitcoreSendBody): BitcoreSendResponse
|
||||
}
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class BitcoreSendBody(val rawTx: List<String>)
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
package com.tangem.blockchain.blockchains.ducatus.network.bitcore
|
||||
|
||||
import com.tangem.blockchain.blockchains.bitcoin.BitcoinUnspentOutput
|
||||
import com.tangem.blockchain.blockchains.bitcoin.network.BitcoinAddressResponse
|
||||
import com.tangem.blockchain.blockchains.bitcoin.network.BitcoinFee
|
||||
import com.tangem.blockchain.blockchains.bitcoin.network.BitcoinProvider
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.extensions.Result
|
||||
import com.tangem.blockchain.extensions.SimpleResult
|
||||
import com.tangem.blockchain.extensions.retryIO
|
||||
import com.tangem.common.extensions.hexToBytes
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
|
||||
open class BitcoreProvider(private val api: BitcoreApi) : BitcoinProvider{
|
||||
private val decimals = Blockchain.Ducatus.decimals()
|
||||
|
||||
override suspend fun getInfo(address: String): Result<BitcoinAddressResponse> {
|
||||
return try {
|
||||
coroutineScope {
|
||||
val balanceDeferred = retryIO { async { api.getBalance(address) } }
|
||||
val unspentsDeferred = retryIO { async { api.getUnspents(address) } }
|
||||
|
||||
val balanceData = balanceDeferred.await()
|
||||
val unspents = unspentsDeferred.await()
|
||||
|
||||
val unspentTransactions = unspents.map {
|
||||
BitcoinUnspentOutput(
|
||||
amount = it.amount!!.toBigDecimal().movePointLeft(decimals),
|
||||
outputIndex = it.index!!.toLong(),
|
||||
transactionHash = it.transactionHash!!.hexToBytes(),
|
||||
outputScript = it.script!!.hexToBytes()
|
||||
)
|
||||
}
|
||||
|
||||
Result.Success(BitcoinAddressResponse(
|
||||
balance = balanceData.confirmed!!.toBigDecimal().movePointLeft(decimals),//only confirmed balance is returned right
|
||||
hasUnconfirmed = balanceData.unconfirmed != null,
|
||||
unspentOutputs = unspentTransactions
|
||||
))
|
||||
}
|
||||
} catch (error: Exception) {
|
||||
Result.Failure(error)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getFee(): Result<BitcoinFee> {
|
||||
TODO("Not yet implemented")// bitcore is used only in ducatus and fee is hardcoded there
|
||||
}
|
||||
|
||||
|
||||
override suspend fun sendTransaction(transaction: String): SimpleResult {
|
||||
return try {
|
||||
val response = retryIO { api.sendTransaction(BitcoreSendBody(listOf(transaction))) }
|
||||
if (response.txid != null) {
|
||||
SimpleResult.Success
|
||||
} else {
|
||||
SimpleResult.Failure(Exception("Unknown send transaction error"))
|
||||
}
|
||||
} catch (error: Exception) {
|
||||
SimpleResult.Failure(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package com.tangem.blockchain.blockchains.ducatus.network.bitcore
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class BitcoreBalance(
|
||||
@Json(name = "confirmed")
|
||||
var confirmed: Long? = null,
|
||||
|
||||
@Json(name = "unconfirmed")
|
||||
var unconfirmed: Long? = null
|
||||
)
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class BitcoreUtxo(
|
||||
@Json(name = "mintTxid")
|
||||
var transactionHash: String? = null,
|
||||
|
||||
@Json(name = "mintIndex")
|
||||
var index: Int? = null,
|
||||
|
||||
@Json(name = "value")
|
||||
var amount: Long? = null,
|
||||
|
||||
@Json(name = "script")
|
||||
var script: String? = null
|
||||
)
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class BitcoreSendResponse(
|
||||
@Json(name = "txid")
|
||||
var txid: String? = null
|
||||
)
|
||||
|
|
@ -19,6 +19,7 @@ enum class Blockchain(
|
|||
BitcoinTestnet("BTC/test", "BTCt", "Bitcoin Testnet"),
|
||||
BitcoinCash("BCH", "BCH", "Bitcoin Cash"),
|
||||
Litecoin("LTC", "LTC", "Litecoin"),
|
||||
Ducatus("DUC", "DUC", "Ducatus"),
|
||||
Ethereum("ETH", "ETH", "Ethereum"),
|
||||
RSK("RSK", "RBTC", "RSK"),
|
||||
Cardano("CARDANO", "ADA", "Cardano"),
|
||||
|
|
@ -29,7 +30,7 @@ enum class Blockchain(
|
|||
Tezos("TEZOS", "XTZ", "Tezos");
|
||||
|
||||
fun decimals(): Int = when (this) {
|
||||
Bitcoin, BitcoinTestnet, BitcoinCash, Binance, BinanceTestnet, Litecoin -> 8
|
||||
Bitcoin, BitcoinTestnet, BitcoinCash, Binance, BinanceTestnet, Litecoin, Ducatus -> 8
|
||||
Cardano, XRP, Tezos -> 6
|
||||
Ethereum, RSK -> 18
|
||||
Stellar -> 7
|
||||
|
|
@ -45,8 +46,7 @@ enum class Blockchain(
|
|||
fun validateAddress(address: String): Boolean = getAddressService().validate(address)
|
||||
|
||||
private fun getAddressService(): AddressService = when (this) {
|
||||
Unknown -> throw Exception("unsupported blockchain")
|
||||
Bitcoin, BitcoinTestnet, Litecoin -> BitcoinAddressService(this)
|
||||
Bitcoin, BitcoinTestnet, Litecoin, Ducatus -> BitcoinAddressService(this)
|
||||
BitcoinCash -> BitcoinCashAddressService()
|
||||
Ethereum, RSK -> EthereumAddressService()
|
||||
Cardano -> CardanoAddressService()
|
||||
|
|
@ -55,6 +55,7 @@ enum class Blockchain(
|
|||
BinanceTestnet -> BinanceAddressService(true)
|
||||
Stellar -> StellarAddressService()
|
||||
Tezos -> TezosAddressService()
|
||||
Unknown -> throw Exception("unsupported blockchain")
|
||||
}
|
||||
|
||||
fun getShareUri(address: String): String = when (this) {
|
||||
|
|
@ -71,9 +72,10 @@ enum class Blockchain(
|
|||
BitcoinTestnet -> "https://live.blockcypher.com/btc-testnet/address/$address"
|
||||
BitcoinCash -> "https://blockchair.com/bitcoin-cash/address/$address"
|
||||
Litecoin -> "https://live.blockcypher.com/ltc/address/$address"
|
||||
Ducatus -> "https://insight.ducatus.io/#/DUC/mainnet/address/$address"
|
||||
Cardano -> "https://cardanoexplorer.com/address/$address"
|
||||
Ethereum -> if (token == null) {
|
||||
"https://etherscan.io/address/"
|
||||
"https://etherscan.io/address/$address"
|
||||
} else {
|
||||
"https://etherscan.io/token/${token.contractAddress}?a=$address"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ import com.tangem.blockchain.blockchains.bitcoincash.BitcoinCashWalletManager
|
|||
import com.tangem.blockchain.blockchains.cardano.CardanoTransactionBuilder
|
||||
import com.tangem.blockchain.blockchains.cardano.CardanoWalletManager
|
||||
import com.tangem.blockchain.blockchains.cardano.network.CardanoNetworkManager
|
||||
import com.tangem.blockchain.blockchains.ducatus.DucatusWalletManager
|
||||
import com.tangem.blockchain.blockchains.ducatus.network.DucatusNetworkManager
|
||||
import com.tangem.blockchain.blockchains.ethereum.EthereumTransactionBuilder
|
||||
import com.tangem.blockchain.blockchains.ethereum.EthereumWalletManager
|
||||
import com.tangem.blockchain.blockchains.ethereum.network.EthereumNetworkManager
|
||||
|
|
@ -19,7 +21,6 @@ import com.tangem.blockchain.blockchains.litecoin.LitecoinNetworkManager
|
|||
import com.tangem.blockchain.blockchains.litecoin.LitecoinWalletManager
|
||||
import com.tangem.blockchain.blockchains.stellar.StellarNetworkManager
|
||||
import com.tangem.blockchain.blockchains.stellar.StellarTransactionBuilder
|
||||
|
||||
import com.tangem.blockchain.blockchains.stellar.StellarWalletManager
|
||||
import com.tangem.blockchain.blockchains.tezos.TezosTransactionBuilder
|
||||
import com.tangem.blockchain.blockchains.tezos.TezosWalletManager
|
||||
|
|
@ -72,6 +73,13 @@ object WalletManagerFactory {
|
|||
LitecoinNetworkManager()
|
||||
)
|
||||
}
|
||||
Blockchain.Ducatus -> {
|
||||
return DucatusWalletManager(
|
||||
cardId, wallet,
|
||||
BitcoinTransactionBuilder(walletPublicKey, blockchain),
|
||||
DucatusNetworkManager()
|
||||
)
|
||||
}
|
||||
Blockchain.Ethereum, Blockchain.RSK -> {
|
||||
return EthereumWalletManager(
|
||||
cardId, wallet,
|
||||
|
|
|
|||
|
|
@ -55,4 +55,5 @@ const val API_RIPPLED = "https://s1.ripple.com:51234/"
|
|||
const val API_RIPPLED_RESERVE = "https://s2.ripple.com:51234/"
|
||||
const val API_BLOCKCHAIR = "https://api.blockchair.com/"
|
||||
const val API_TEZOS = "https://teznode.letzbake.com"
|
||||
const val API_TEZOS_RESERVE = "https://mainnet.tezrpc.me"
|
||||
const val API_TEZOS_RESERVE = "https://mainnet.tezrpc.me"
|
||||
const val API_DUCATUS = "https://ducapi.rocknblock.io/"
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package com.tangem.blockchain.blockchains.ducatus
|
||||
|
||||
import com.google.common.truth.Truth
|
||||
import com.tangem.blockchain.blockchains.bitcoin.BitcoinAddressService
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.common.extensions.hexToBytes
|
||||
import org.junit.Test
|
||||
|
||||
class DucatusAddressTest {
|
||||
|
||||
private val addressService = BitcoinAddressService(Blockchain.Ducatus)
|
||||
|
||||
@Test
|
||||
fun makeAddressFromCorrectPublicKey() {
|
||||
val walletPublicKey = "0485D520C8B907F0BC5E03FCBBAC212CCD270764BBFF4990A28653A2FB0D656C342DF143C4D52C43582289E20A81D5D014C1384A1FFFEA1D121903AD7ED35A01EA".hexToBytes()
|
||||
val expected = "Ly3SZetcgr5gkZMwiNwVrts2z2r3jYieAG"
|
||||
|
||||
Truth.assertThat(addressService.makeAddress(walletPublicKey))
|
||||
.isEqualTo(expected)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun validateCorrectAddress() {
|
||||
val address = "Ly3SZetcgr5gkZMwiNwVrts2z2r3jYieAG"
|
||||
Truth.assertThat(addressService.validate(address))
|
||||
.isTrue()
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ import com.tangem.blockchain.blockchains.binance.BinanceWalletManager
|
|||
import com.tangem.blockchain.blockchains.bitcoin.BitcoinWalletManager
|
||||
import com.tangem.blockchain.blockchains.bitcoincash.BitcoinCashWalletManager
|
||||
import com.tangem.blockchain.blockchains.cardano.CardanoWalletManager
|
||||
import com.tangem.blockchain.blockchains.ducatus.DucatusWalletManager
|
||||
import com.tangem.blockchain.blockchains.ethereum.EthereumWalletManager
|
||||
import com.tangem.blockchain.blockchains.litecoin.LitecoinWalletManager
|
||||
import com.tangem.blockchain.blockchains.stellar.StellarWalletManager
|
||||
|
|
@ -107,7 +108,7 @@ internal class WalletManagerFactoryTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun createLTezosWalletManager() {
|
||||
fun createTezosWalletManager() {
|
||||
val data = "0108BB00000000000080200754414E47454D00020102800A322E3432642053444B0003410436CFC5D0A11353AE6AFEEDC84A2D02B2635C044DEEE47F99913072B8D166D14E557230AC5FB5272F1A0E523332CCE1A744B51DB53102FF7D3FDE023DC3477C460A04041E76310C638102FFFF8A0101820407E40514830B54414E47454D2053444B00840554455A4F538640C752685B29333CFB0DB0A7347579A0AE763F2B5C4BB09FD68E0B81A06CD01EC51347001732815A3ECFFCD78DDE4E53877581B9E4914B069570629D0C40A771B93041045F16BD1D2EAFE463E62A335A09E6B2BBCBD04452526885CB679FC4D27AF1BD22F553C7DEEFB54FD3D4F361D14E6DC3F11B7D4EA183250A60720EBDF9E110CD26050865643235353139000804000186A0070100602098E0E504F3A5FDE704400302ABB0A2EFB0DF0F95C166C91D7F207DEDCE10CBA362040001869F6304000000010F01009000"
|
||||
val responseApdu = ResponseApdu(data.hexToBytes())
|
||||
val card = ReadCommand().deserialize(SessionEnvironment(), responseApdu)
|
||||
|
|
@ -116,4 +117,15 @@ internal class WalletManagerFactoryTest {
|
|||
Truth.assertThat(walletManager)
|
||||
.isInstanceOf(TezosWalletManager::class.java)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun createDucatusWalletManager() {
|
||||
val data = "0108BB00000000000098200754414E47454D00020102800A322E3432642053444B000341041B5FD7C590938E836B388B996AE451FDED54F625FF2CF05E26E5AADF6F690AEF125E3D0F23CB6B8D1F78040DF6F71B40D098F2D8BE504DDEE2E1F99BEADD90500A04041E76310C618102FFFF8A0101820407E40515830B54414E47454D2053444B00840344554386401B453C10A092A3448FA83CAFD4FC3D7EB5EA1BBBDD6A020CAAC8CED36BB2661F41EF0B0C7418214F670DFE1200DCE18597158119BEF6CC52A4FF3B7E021A53B93041045F16BD1D2EAFE463E62A335A09E6B2BBCBD04452526885CB679FC4D27AF1BD22F553C7DEEFB54FD3D4F361D14E6DC3F11B7D4EA183250A60720EBDF9E110CD26050A736563703235366B31000804000186A007010060410485D520C8B907F0BC5E03FCBBAC212CCD270764BBFF4990A28653A2FB0D656C342DF143C4D52C43582289E20A81D5D014C1384A1FFFEA1D121903AD7ED35A01EA62040001869D6304000000030F01009000"
|
||||
val responseApdu = ResponseApdu(data.hexToBytes())
|
||||
val card = ReadCommand().deserialize(SessionEnvironment(), responseApdu)
|
||||
val walletManager = WalletManagerFactory.makeWalletManager(card)
|
||||
|
||||
Truth.assertThat(walletManager)
|
||||
.isInstanceOf(DucatusWalletManager::class.java)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue