Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AND-4852 Added ExternalLinkProvider's #345

Merged
merged 1 commit into from
Oct 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 7 additions & 129 deletions blockchain/src/main/java/com/tangem/blockchain/common/Blockchain.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import com.tangem.blockchain.common.address.AddressService
import com.tangem.blockchain.common.address.MultisigAddressProvider
import com.tangem.blockchain.common.address.TrustWalletAddressService
import com.tangem.blockchain.common.derivation.DerivationStyle
import com.tangem.blockchain.externallinkprovider.ExternalLinkProvider
import com.tangem.blockchain.externallinkprovider.ExternalLinkProviderFactory
import com.tangem.common.card.EllipticCurve
import com.tangem.crypto.hdWallet.DerivationPath

Expand Down Expand Up @@ -96,6 +98,8 @@ enum class Blockchain(
ChiaTestnet("chia/test", "TXCH", "Chia Network Testnet"),
;

private val externalLinkProvider: ExternalLinkProvider by lazy { ExternalLinkProviderFactory.makeProvider(this) }

fun decimals(): Int = when (this) {
Unknown -> 0
Near, NearTestnet,
Expand Down Expand Up @@ -224,142 +228,16 @@ enum class Blockchain(
return scheme == getShareScheme()
}

private fun getBaseExploreUrl(): String = when (this) {
Arbitrum -> "https://arbiscan.io/"
ArbitrumTestnet -> "https://goerli-rollup-explorer.arbitrum.io/"
Avalanche -> "https://snowtrace.io/"
AvalancheTestnet -> "https://testnet.snowtrace.io/"
Binance -> "https://explorer.binance.org/"
BinanceTestnet -> "https://testnet-explorer.binance.org/"
Bitcoin -> "https://www.blockchair.com/bitcoin/"
BitcoinTestnet -> "https://www.blockchair.com/bitcoin/testnet/"
BitcoinCash -> "https://www.blockchair.com/bitcoin-cash/"
BitcoinCashTestnet -> "https://www.blockchain.com/bch-testnet/"
BSC -> "https://bscscan.com/"
BSCTestnet -> "https://testnet.bscscan.com/"
Cardano -> "https://www.blockchair.com/cardano/"
Dogecoin -> "https://blockchair.com/dogecoin/"
Ducatus -> "https://insight.ducatus.io/#/DUC/mainnet/"
Ethereum -> "https://etherscan.io/"
EthereumTestnet -> "https://goerli.etherscan.io/"
EthereumClassic -> "https://blockscout.com/etc/mainnet/"
EthereumClassicTestnet -> "https://blockscout.com/etc/kotti/"
Fantom -> "https://ftmscan.com/"
FantomTestnet -> "https://testnet.ftmscan.com/"
Litecoin -> "https://blockchair.com/litecoin/"
Near -> "https://explorer.near.org/"
NearTestnet -> "https://explorer.testnet.near.org/"
Polkadot -> "https://polkadot.subscan.io/"
PolkadotTestnet -> "https://westend.subscan.io/"
Kusama -> "https://kusama.subscan.io/"
Polygon -> "https://polygonscan.com/"
PolygonTestnet -> "https://explorer-mumbai.maticvigil.com/"
RSK -> "https://explorer.rsk.co/"
Stellar -> "https://stellar.expert/explorer/public/"
StellarTestnet -> "https://stellar.expert/explorer/testnet/"
Solana -> "https://explorer.solana.com/"
SolanaTestnet -> "https://explorer.solana.com/"
Tezos -> "https://tzkt.io/"
Telos -> "https://teloscan.io/"
TelosTestnet -> "https://testnet.teloscan.io/"
TON -> "https://tonscan.org/"
TONTestnet -> "https://testnet.tonscan.org/"
Tron -> "https://tronscan.org/#/"
TronTestnet -> "https://nile.tronscan.org/#/"
XRP -> "https://xrpscan.com/"
Gnosis -> "https://blockscout.com/xdai/mainnet/"
Dash -> "https://blockexplorer.one/dash/mainnet/"
Optimism -> "https://optimistic.etherscan.io/"
OptimismTestnet -> "https://blockscout.com/optimism/goerli/"
EthereumFair -> "https://explorer.etherfair.org/"
EthereumPow -> "https://mainnet.ethwscan.com/"
EthereumPowTestnet -> "https://iceberg.ethwscan.com/"
Kaspa -> "https://explorer.kaspa.org/"
Kava -> "https://explorer.kava.io/"
KavaTestnet -> "https://explorer.testnet.kava.io/"
Ravencoin -> "https://api.ravencoin.org/"
RavencoinTestnet -> "https://testnet.ravencoin.network/"
CosmosTestnet -> "https://explorer.theta-testnet.polypore.xyz/accounts/"
Cosmos -> "https://www.mintscan.io/cosmos/account/"
TerraV1 -> "https://atomscan.com/terra/accounts/"
TerraV2 -> "https://terrasco.pe/mainnet/"
Cronos -> "https://cronoscan.com/"
AlephZero -> "https://alephzero.subscan.io/"
AlephZeroTestnet -> throw Exception("unsupported blockchain")
OctaSpace -> "https://explorer.octa.space/"
OctaSpaceTestnet -> throw Exception("unsupported blockchain")
Chia -> "https://xchscan.com/"
ChiaTestnet -> "https://testnet10.spacescan.io/"
Unknown -> throw Exception("unsupported blockchain")
}

fun getExploreUrl(address: String, tokenContractAddress: String? = null): String {
val path = "address/$address"
val baseUrl = getBaseExploreUrl()
val fullUrl = baseUrl + path
return when (this) {
Ethereum, EthereumTestnet -> if (tokenContractAddress == null) {
fullUrl
} else {
"$baseUrl$tokenContractAddress?a=$address"
}

EthereumClassic, EthereumClassicTestnet,
Kava, KavaTestnet,
-> "$fullUrl/transactions"

RSK -> if (tokenContractAddress != null) {
"$fullUrl?__tab=tokens"
} else {
fullUrl
}

SolanaTestnet -> "$fullUrl/?cluster=devnet"
XRP, Stellar, StellarTestnet -> "${baseUrl}account/$address"
Tezos -> "$baseUrl$address"
Kaspa -> "${baseUrl}addresses/$address"
Cosmos -> "${baseUrl}$address"
TerraV1 -> "${baseUrl}$address"
CosmosTestnet -> "${baseUrl}$address"
Near, NearTestnet -> "${baseUrl}accounts/$address"
else -> fullUrl
}
return externalLinkProvider.explorerUrl(walletAddress = address, contractAddress = tokenContractAddress)
}

fun getExploreTxUrl(transactionHash: String): String {
val url = getBaseExploreUrl() + "tx/$transactionHash"
return when (this) {
Bitcoin, BitcoinTestnet -> "${getBaseExploreUrl()}transaction/$transactionHash"
SolanaTestnet -> "$url/?cluster=devnet"
else -> url
}
return externalLinkProvider.explorerTransactionUrl(transactionHash)
}

fun getTestnetTopUpUrl(): String? {
return when (this) {
AvalancheTestnet -> "https://faucet.avax-test.network/"
BitcoinTestnet -> "https://coinfaucet.eu/en/btc-testnet/"
EthereumTestnet -> "https://goerlifaucet.com/"
EthereumClassicTestnet -> "https://kottifaucet.me"
BitcoinCashTestnet -> "https://coinfaucet.eu/en/bch-testnet/"
BinanceTestnet -> "https://docs.binance.org/smart-chain/wallet/binance.html"
BSCTestnet -> "https://testnet.binance.org/faucet-smart"
FantomTestnet -> "https://faucet.fantom.network"
PolygonTestnet -> "https://faucet.matic.network"
PolkadotTestnet -> "https://app.element.io/#/room/#westend_faucet:matrix.org"
StellarTestnet -> "https://laboratory.stellar.org/#account-creator?network=test"
SolanaTestnet -> "https://solfaucet.com/"
TronTestnet -> "https://nileex.io/join/getJoinPage"
OptimismTestnet -> "https://optimismfaucet.xyz" //another one https://faucet.paradigm.xyz
EthereumPowTestnet -> "https://faucet.ethwscan.com"
KavaTestnet -> "https://faucet.kava.io"
TelosTestnet -> "https://app.telos.net/testnet/developers"
CosmosTestnet -> "https://discord.com/channels/669268347736686612/953697793476821092"
AlephZeroTestnet -> "https://faucet.test.azero.dev/"
ChiaTestnet -> "https://xchdev.com/#!faucet.md"
NearTestnet -> "https://near-faucet.io/"
else -> null
}
return externalLinkProvider.testNetTopUpUrl
}

fun isTestnet(): Boolean = this == getTestnetVersion()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.tangem.blockchain.externallinkprovider

interface ExternalLinkProvider {

val explorerBaseUrl: String
val testNetTopUpUrl: String? get() = null

fun explorerUrl(walletAddress: String, contractAddress: String?): String

fun explorerTransactionUrl(transactionHash: String): String
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.tangem.blockchain.externallinkprovider

import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.externallinkprovider.providers.*

internal object ExternalLinkProviderFactory {

fun makeProvider(blockchain: Blockchain): ExternalLinkProvider {
val isTestnet = blockchain.isTestnet()
return when (blockchain) {
Blockchain.Unknown -> error("There is no ExternalLinkProvider for Blockchain.Unknown")
Blockchain.Arbitrum, Blockchain.ArbitrumTestnet -> ArbitrumExternalLinkProvider(isTestnet)
Blockchain.Avalanche, Blockchain.AvalancheTestnet -> AvalancheExternalLinkProvider(isTestnet)
Blockchain.Binance, Blockchain.BinanceTestnet -> BinanceExternalLinkProvider(isTestnet)
Blockchain.BSC, Blockchain.BSCTestnet -> BSCExternalLinkProvider(isTestnet)
Blockchain.Bitcoin, Blockchain.BitcoinTestnet -> BitcoinExternalLinkProvider(isTestnet)
Blockchain.BitcoinCash, Blockchain.BitcoinCashTestnet -> BitcoinCashExternalLinkProvider(isTestnet)
Blockchain.Cardano -> CardanoExternalLinkProvider()
Blockchain.Cosmos, Blockchain.CosmosTestnet -> CosmosExternalLinkProvider(isTestnet)
Blockchain.Dogecoin -> DogecoinExternalLinkProvider()
Blockchain.Ducatus -> DucatusExternalLinkProvider()
Blockchain.Ethereum, Blockchain.EthereumTestnet -> EthereumExternalLinkProvider(isTestnet)
Blockchain.EthereumClassic, Blockchain.EthereumClassicTestnet -> EthereumClassicExternalLinkProvider(isTestnet)
Blockchain.Fantom, Blockchain.FantomTestnet -> FantomExternalLinkProvider(isTestnet)
Blockchain.Litecoin -> LitecoinExternalLinkProvider()
Blockchain.Near, Blockchain.NearTestnet -> NearExternalLinkProvider(isTestnet)
Blockchain.Polkadot, Blockchain.PolkadotTestnet -> PolkadotExternalLinkProvider(isTestnet)
Blockchain.Kava, Blockchain.KavaTestnet -> KavaExternalLinkProvider(isTestnet)
Blockchain.Kusama -> KusamaExternalLinkProvider()
Blockchain.Polygon, Blockchain.PolygonTestnet -> PolygonExternalLinkProvider(isTestnet)
Blockchain.RSK -> RSKExternalLinkProvider()
Blockchain.Stellar, Blockchain.StellarTestnet -> StellarExternalLinkProvider(isTestnet)
Blockchain.Solana, Blockchain.SolanaTestnet -> SolanaExternalLinkProvider(isTestnet)
Blockchain.Tezos -> TezosExternalLinkProvider()
Blockchain.Tron, Blockchain.TronTestnet -> TronExternalLinkProvider(isTestnet)
Blockchain.XRP -> XRPExternalLinkProvider()
Blockchain.Gnosis -> GnosisExternalLinkProvider()
Blockchain.Dash -> DashExternalLinkProvider()
Blockchain.Optimism, Blockchain.OptimismTestnet -> OptimismExternalLinkProvider(isTestnet)
Blockchain.EthereumFair -> EthereumFairExternalLinkProvider()
Blockchain.EthereumPow, Blockchain.EthereumPowTestnet -> EthereumPowExternalLinkProvider(isTestnet)
Blockchain.Kaspa -> KaspaExternalLinkProvider()
Blockchain.Telos, Blockchain.TelosTestnet -> TelosExternalLinkProvider(isTestnet)
Blockchain.TON, Blockchain.TONTestnet -> TONExternalLinkProvider(isTestnet)
Blockchain.Ravencoin, Blockchain.RavencoinTestnet -> RavencoinExternalLinkProvider(isTestnet)
Blockchain.TerraV1 -> TerraV1ExternalLinkProvider()
Blockchain.TerraV2 -> TerraV2ExternalLinkProvider()
Blockchain.Cronos -> CronosExternalLinkProvider()
Blockchain.AlephZero -> AlephZeroExternalLinkProvider()
Blockchain.AlephZeroTestnet -> throw Exception("unsupported blockchain")
Blockchain.OctaSpace -> OctaSpaceExternalLinkProvider()
Blockchain.OctaSpaceTestnet -> throw Exception("unsupported blockchain")
Blockchain.Chia, Blockchain.ChiaTestnet -> ChiaExternalLinkProvider(isTestnet)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.tangem.blockchain.externallinkprovider.providers

import com.tangem.blockchain.externallinkprovider.ExternalLinkProvider

internal class AlephZeroExternalLinkProvider : ExternalLinkProvider {

override val explorerBaseUrl: String = "https://alephzero.subscan.io/"

override fun explorerUrl(walletAddress: String, contractAddress: String?): String {
return explorerBaseUrl + "account/$walletAddress"
}

override fun explorerTransactionUrl(transactionHash: String): String {
return explorerBaseUrl + "extrinsic/$transactionHash"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.tangem.blockchain.externallinkprovider.providers

import com.tangem.blockchain.externallinkprovider.ExternalLinkProvider

internal class ArbitrumExternalLinkProvider(isTestnet: Boolean) : ExternalLinkProvider {

override val explorerBaseUrl: String = if (isTestnet) "https://testnet.arbiscan.io/" else "https://arbiscan.io/"

override val testNetTopUpUrl: String? = if (isTestnet) "https://nileex.io/join/getJoinPage" else null

override fun explorerUrl(walletAddress: String, contractAddress: String?): String {
return if (contractAddress != null) {
explorerBaseUrl + "token/$contractAddress?a=$walletAddress"
} else {
explorerBaseUrl + "address/$walletAddress"
}
}

override fun explorerTransactionUrl(transactionHash: String): String {
return explorerBaseUrl + "tx/$transactionHash"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.tangem.blockchain.externallinkprovider.providers

import com.tangem.blockchain.externallinkprovider.ExternalLinkProvider

internal class AvalancheExternalLinkProvider(isTestnet: Boolean) : ExternalLinkProvider {

override val explorerBaseUrl: String = if (isTestnet) "https://testnet.snowtrace.io/" else "https://snowtrace.io/"

override val testNetTopUpUrl: String? = if (isTestnet) "https://faucet.avax-test.network/" else null

override fun explorerUrl(walletAddress: String, contractAddress: String?): String {
return if (contractAddress != null) {
explorerBaseUrl + "token/$contractAddress?a=$walletAddress"
} else {
explorerBaseUrl + "address/$walletAddress"
}
}

override fun explorerTransactionUrl(transactionHash: String): String {
return explorerBaseUrl + "tx/$transactionHash"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.tangem.blockchain.externallinkprovider.providers

import com.tangem.blockchain.externallinkprovider.ExternalLinkProvider

internal class BSCExternalLinkProvider(isTestnet: Boolean) : ExternalLinkProvider {

override val explorerBaseUrl: String = if (isTestnet) "https://testnet.bscscan.com/" else "https://bscscan.com/"

override val testNetTopUpUrl: String? = if (isTestnet) "https://testnet.binance.org/faucet-smart" else null

override fun explorerUrl(walletAddress: String, contractAddress: String?): String {
return if (contractAddress != null) {
explorerBaseUrl + "token/$contractAddress?a=$walletAddress"
} else {
explorerBaseUrl + "address/$walletAddress"
}
}

override fun explorerTransactionUrl(transactionHash: String): String {
return explorerBaseUrl + "tx/$transactionHash"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.tangem.blockchain.externallinkprovider.providers

import com.tangem.blockchain.externallinkprovider.ExternalLinkProvider

internal class BinanceExternalLinkProvider(isTestnet: Boolean) : ExternalLinkProvider {

override val explorerBaseUrl: String =
if (isTestnet) "https://testnet-explorer.binance.org/" else "https://explorer.binance.org/"

override val testNetTopUpUrl: String? =
if (isTestnet) "https://docs.binance.org/smart-chain/wallet/binance.html" else null

override fun explorerUrl(walletAddress: String, contractAddress: String?): String {
return explorerBaseUrl + "address/$walletAddress"
}

override fun explorerTransactionUrl(transactionHash: String): String {
return explorerBaseUrl + "tx/$transactionHash"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.tangem.blockchain.externallinkprovider.providers

import com.tangem.blockchain.externallinkprovider.ExternalLinkProvider

internal class BitcoinCashExternalLinkProvider(private val isTestnet: Boolean) : ExternalLinkProvider {

override val explorerBaseUrl: String =
if (isTestnet) "https://blockexplorer.one/bitcoin-cash/testnet/" else "https://www.blockchair.com/bitcoin-cash/"

override val testNetTopUpUrl: String? = if (isTestnet) "https://coinfaucet.eu/en/bch-testnet/" else null

override fun explorerUrl(walletAddress: String, contractAddress: String?): String {
return explorerBaseUrl + "address/$walletAddress"
}

override fun explorerTransactionUrl(transactionHash: String): String {
return if (isTestnet) {
explorerBaseUrl + "tx/$transactionHash"
} else {
explorerBaseUrl + "transaction/$transactionHash"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.tangem.blockchain.externallinkprovider.providers

import com.tangem.blockchain.externallinkprovider.ExternalLinkProvider

internal class BitcoinExternalLinkProvider(isTestnet: Boolean) : ExternalLinkProvider {

override val explorerBaseUrl: String =
if (isTestnet) "https://www.blockchair.com/bitcoin/" else "https://www.blockchair.com/bitcoin/testnet/"

override val testNetTopUpUrl: String? = if (isTestnet) "https://coinfaucet.eu/en/btc-testnet/" else null

override fun explorerUrl(walletAddress: String, contractAddress: String?): String {
return explorerBaseUrl + "address/$walletAddress"
}

override fun explorerTransactionUrl(transactionHash: String): String {
return explorerBaseUrl + "transaction/$transactionHash"
}
}
Loading