From 2f79026f4f56a6f4e5f2b96bba5b100d40fd6738 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 26 Feb 2020 13:17:14 +0300 Subject: [PATCH] Updated on 2026-08-14 --- .../main/java/com/tangem/data/Blockchain.java | 1 + .../data/network/ServerApiBlockcypher.java | 1 + .../com/tangem/ui/fragment/id/IdFragment.kt | 2 +- .../fragment/wallet/LoadedWalletFragment.kt | 2 +- .../com/tangem/wallet/CoinEngineFactory.kt | 4 +++ .../java/com/tangem/wallet/btc/BtcEngine.java | 6 ++-- .../wallet/btcmultisig/BtcMultisigEngine.kt | 33 +++++++++++-------- 7 files changed, 30 insertions(+), 19 deletions(-) diff --git a/app/src/main/java/com/tangem/data/Blockchain.java b/app/src/main/java/com/tangem/data/Blockchain.java index 3f3a033388..3a76e07b04 100644 --- a/app/src/main/java/com/tangem/data/Blockchain.java +++ b/app/src/main/java/com/tangem/data/Blockchain.java @@ -9,6 +9,7 @@ public enum Blockchain { Unknown("", "", 1.0, R.drawable.ic_logo_unknown, ""), Bitcoin("BTC", "BTC", 100000000.0, R.drawable.ic_logo_bitcoin, "Bitcoin"), BitcoinTestNet("BTC/test", "BTC", 100000000.0, R.drawable.ic_logo_bitcoin_testnet, "Bitcoin Testnet"), + BitcoinDual("BTC/dual", "BTC", 100000000.0, R.drawable.ic_logo_bitcoin, "Bitcoin"), Ethereum("ETH", "ETH", 1.0, R.drawable.ic_logo_ethereum, "Ethereum"), EthereumId("ETH/ID", "ETH", 1.0, R.drawable.ic_logo_ethereum, "Ethereum ID"), EthereumTestNet("ETH/test", "ETH", 1.0, R.drawable.ic_logo_ethereum_testnet, "Ethereum Testnet"), diff --git a/app/src/main/java/com/tangem/data/network/ServerApiBlockcypher.java b/app/src/main/java/com/tangem/data/network/ServerApiBlockcypher.java index 8f0f0011fe..bccbfd5a1e 100644 --- a/app/src/main/java/com/tangem/data/network/ServerApiBlockcypher.java +++ b/app/src/main/java/com/tangem/data/network/ServerApiBlockcypher.java @@ -70,6 +70,7 @@ public class ServerApiBlockcypher { network = "test3"; } if (blockchainID.equals(Blockchain.Token.getID())) blockchain = "eth"; + if (blockchainID.equals(Blockchain.BitcoinDual.getID())) blockchain = "btc"; switch (method) { case BLOCKCYPHER_ADDRESS: diff --git a/app/src/main/java/com/tangem/ui/fragment/id/IdFragment.kt b/app/src/main/java/com/tangem/ui/fragment/id/IdFragment.kt index 76f14bc2bc..7c8ec384e4 100644 --- a/app/src/main/java/com/tangem/ui/fragment/id/IdFragment.kt +++ b/app/src/main/java/com/tangem/ui/fragment/id/IdFragment.kt @@ -364,7 +364,7 @@ class IdFragment : BaseFragment(), NfcAdapter.ReaderCallback, updateViews() // Bitcoin, Litecoin, BitcoinCash, Stellar - if (ctx.blockchain == Blockchain.Bitcoin || ctx.blockchain == Blockchain.BitcoinTestNet || + if (ctx.blockchain == Blockchain.Bitcoin || ctx.blockchain == Blockchain.BitcoinTestNet || ctx.blockchain == Blockchain.BitcoinDual || ctx.blockchain == Blockchain.Litecoin || ctx.blockchain == Blockchain.BitcoinCash || ctx.blockchain == Blockchain.Stellar || ctx.blockchain == Blockchain.StellarTestNet || ctx.blockchain == Blockchain.StellarAsset) { ctx.coinData.setIsBalanceEqual(true) diff --git a/app/src/main/java/com/tangem/ui/fragment/wallet/LoadedWalletFragment.kt b/app/src/main/java/com/tangem/ui/fragment/wallet/LoadedWalletFragment.kt index 50597ac664..ca0505d7aa 100644 --- a/app/src/main/java/com/tangem/ui/fragment/wallet/LoadedWalletFragment.kt +++ b/app/src/main/java/com/tangem/ui/fragment/wallet/LoadedWalletFragment.kt @@ -707,7 +707,7 @@ class LoadedWalletFragment : BaseFragment(), NavigationResultListener, NfcAdapte updateViews() // Bitcoin, Litecoin, BitcoinCash, Stellar - if (ctx.blockchain == Blockchain.Bitcoin || ctx.blockchain == Blockchain.BitcoinTestNet || + if (ctx.blockchain == Blockchain.Bitcoin || ctx.blockchain == Blockchain.BitcoinTestNet || ctx.blockchain == Blockchain.BitcoinDual || ctx.blockchain == Blockchain.Litecoin || ctx.blockchain == Blockchain.BitcoinCash || ctx.blockchain == Blockchain.Stellar || ctx.blockchain == Blockchain.StellarTestNet || ctx.blockchain == Blockchain.StellarAsset) { ctx.coinData.setIsBalanceEqual(true) diff --git a/app/src/main/java/com/tangem/wallet/CoinEngineFactory.kt b/app/src/main/java/com/tangem/wallet/CoinEngineFactory.kt index 3d93e06d50..1570ea6621 100644 --- a/app/src/main/java/com/tangem/wallet/CoinEngineFactory.kt +++ b/app/src/main/java/com/tangem/wallet/CoinEngineFactory.kt @@ -5,6 +5,7 @@ import com.tangem.data.Blockchain import com.tangem.wallet.bch.BtcCashEngine import com.tangem.wallet.binance.BinanceEngine import com.tangem.wallet.btc.BtcEngine +import com.tangem.wallet.btcmultisig.BtcMultisigEngine import com.tangem.wallet.cardano.CardanoData import com.tangem.wallet.cardano.CardanoEngine import com.tangem.wallet.ducatus.DucatusEngine @@ -56,6 +57,7 @@ object CoinEngineFactory { Blockchain.Eos -> EosEngine() Blockchain.Ducatus -> DucatusEngine() Blockchain.Tezos -> TezosEngine() + Blockchain.BitcoinDual -> BtcMultisigEngine() else -> null } } @@ -101,6 +103,8 @@ object CoinEngineFactory { DucatusEngine(context) else if (Blockchain.Tezos == context.blockchain) TezosEngine(context) + else if (Blockchain.BitcoinDual == context.blockchain) + BtcMultisigEngine(context) else return null } catch (e: Exception) { diff --git a/app/src/main/java/com/tangem/wallet/btc/BtcEngine.java b/app/src/main/java/com/tangem/wallet/btc/BtcEngine.java index 4159d44d5b..4bfa331eda 100644 --- a/app/src/main/java/com/tangem/wallet/btc/BtcEngine.java +++ b/app/src/main/java/com/tangem/wallet/btc/BtcEngine.java @@ -181,7 +181,7 @@ public class BtcEngine extends CoinEngine { return false; } - if (ctx.getBlockchain() != Blockchain.BitcoinTestNet && ctx.getBlockchain() != Blockchain.Bitcoin) { + if (ctx.getBlockchain() != Blockchain.BitcoinTestNet && ctx.getBlockchain() != Blockchain.Bitcoin && ctx.getBlockchain() != Blockchain.BitcoinDual) { return false; } @@ -190,7 +190,7 @@ public class BtcEngine extends CoinEngine { } } else { try { - if (ctx.getBlockchain() == Blockchain.Bitcoin) { + if (ctx.getBlockchain() == Blockchain.Bitcoin || ctx.getBlockchain() == Blockchain.BitcoinDual) { SegwitAddress.fromBech32(new MainNetParams(), address); } else if (ctx.getBlockchain() == Blockchain.BitcoinTestNet) { SegwitAddress.fromBech32(new TestNet3Params(), address); @@ -213,7 +213,7 @@ public class BtcEngine extends CoinEngine { @Override public Uri getWalletExplorerUri() { - return Uri.parse((ctx.getBlockchain() == Blockchain.Bitcoin ? "https://www.blockchain.com/btc/address/" : "https://live.blockcypher.com/btc-testnet/address/") + ctx.getCoinData().getWallet()); + return Uri.parse((ctx.getBlockchain() == Blockchain.Bitcoin || ctx.getBlockchain() == Blockchain.BitcoinDual ? "https://www.blockchain.com/btc/address/" : "https://live.blockcypher.com/btc-testnet/address/") + ctx.getCoinData().getWallet()); } @Override diff --git a/app/src/main/java/com/tangem/wallet/btcmultisig/BtcMultisigEngine.kt b/app/src/main/java/com/tangem/wallet/btcmultisig/BtcMultisigEngine.kt index 76fd5d8962..4f87b26d94 100644 --- a/app/src/main/java/com/tangem/wallet/btcmultisig/BtcMultisigEngine.kt +++ b/app/src/main/java/com/tangem/wallet/btcmultisig/BtcMultisigEngine.kt @@ -5,18 +5,22 @@ import com.tangem.tangem_card.data.TangemCard import com.tangem.tangem_card.reader.CardProtocol.TangemException import com.tangem.tangem_card.tasks.SignTask import com.tangem.tangem_card.util.Util +import com.tangem.wallet.TangemContext import com.tangem.wallet.btc.BtcEngine import org.bitcoinj.core.* import org.bitcoinj.crypto.TransactionSignature import org.bitcoinj.params.MainNetParams import org.bitcoinj.script.Script import org.bitcoinj.script.ScriptBuilder -import org.bitcoinj.script.ScriptPattern import java.math.BigInteger -class BtcMultisigEngine : BtcEngine() { +class BtcMultisigEngine : BtcEngine { val networkParameters = MainNetParams.get() + constructor(): super() + + constructor(context: TangemContext): super(context) + override fun defineWallet() { try { val wallet = calculateAddress(ctx.card.walletPublicKeyRar) @@ -28,13 +32,14 @@ class BtcMultisigEngine : BtcEngine() { } override fun calculateAddress(compressedPublicKey: ByteArray): String? { - val script = createMultisigOutputScript( - mutableListOf(compressedPublicKey, ctx.card.getUserData) - ) - val scriptHash = ScriptPattern.extractHashFromP2SH(script) - - val address = LegacyAddress.fromScriptHash(networkParameters, scriptHash) - return address.toBase58() + if (ctx.card.issuerData != null && ctx.card.issuerData.size == 33) { + val script = createMultisigOutputScript() + val scriptHash = Utils.sha256hash160(script.program) + val address = LegacyAddress.fromScriptHash(networkParameters, scriptHash) + return address.toBase58() + } else { + return Util.byteArrayToHexString(compressedPublicKey) + } } override fun constructTransaction(amountValue: Amount, feeValue: Amount, IncFee: Boolean, targetAddress: String): SignTask.TransactionToSign { @@ -78,7 +83,8 @@ class BtcMultisigEngine : BtcEngine() { val hashesForSign: MutableList = MutableList(transaction.inputs.size) { byteArrayOf() } for (input in transaction.inputs) { val index = input.index - hashesForSign[index] = transaction.hashForSignature(index, input.scriptBytes, Transaction.SigHash.ALL, false).bytes + val outputScript = createMultisigOutputScript() + hashesForSign[index] = transaction.hashForSignature(index, outputScript, Transaction.SigHash.ALL, false).bytes } return hashesForSign.toTypedArray() } @@ -116,13 +122,12 @@ class BtcMultisigEngine : BtcEngine() { val canonicalS = ECKey.ECDSASignature(r, s).toCanonicalised().s val signature = TransactionSignature(r, canonicalS) - val outputScript = createMultisigOutputScript( - mutableListOf(ctx.card.walletPublicKeyRar, ctx.card.getUserData) - ) + val outputScript = createMultisigOutputScript() return ScriptBuilder.createP2SHMultiSigInputScript(mutableListOf(signature), outputScript) } - private fun createMultisigOutputScript(publicKeys: MutableList): Script { + private fun createMultisigOutputScript(): Script { + val publicKeys = mutableListOf(ctx.card.walletPublicKeyRar, ctx.card.issuerData) publicKeys.sortWith(UnsignedBytes.lexicographicalComparator()) val publicEcKeys = MutableList(publicKeys.size) { i -> ECKey.fromPublicOnly(publicKeys[i]) }