@@ -21,6 +21,7 @@ import (
2121 "net/url"
2222 "os"
2323 "path/filepath"
24+ "reflect"
2425 "strings"
2526 "time"
2627
@@ -69,13 +70,6 @@ var fixedURLWhitelist = []string{
6970 "https://shiftcrypto.support/" ,
7071 // Exchange rates.
7172 "https://www.coingecko.com/" ,
72- // Block explorers.
73- "https://blockstream.info/tx/" ,
74- "https://blockstream.info/testnet/tx/" ,
75- "https://sochain.com/tx/LTCTEST/" ,
76- "https://blockchair.com/litecoin/transaction/" ,
77- "https://etherscan.io/tx/" ,
78- "https://goerli.etherscan.io/tx/" ,
7973 // Moonpay onramp
8074 "https://www.moonpay.com/" ,
8175 "https://support.moonpay.com/" ,
@@ -482,43 +476,51 @@ func (backend *Backend) Coin(code coinpkg.Code) (coinpkg.Coin, error) {
482476 servers := backend .defaultElectrumXServers (code )
483477 coin = btc .NewCoin (coinpkg .CodeRBTC , "Bitcoin Regtest" , "RBTC" , coinpkg .BtcUnitDefault , & chaincfg .RegressionNetParams , dbFolder , servers , "" , backend .socksProxy )
484478 case code == coinpkg .CodeTBTC :
479+ blockExplorerPrefix := backend .config .AppConfig ().Backend .BlockExplorers .TBTC
485480 servers := backend .defaultElectrumXServers (code )
486481 coin = btc .NewCoin (coinpkg .CodeTBTC , "Bitcoin Testnet" , "TBTC" , btcFormatUnit , & chaincfg .TestNet3Params , dbFolder , servers ,
487- "https://blockstream.info/testnet/tx/" , backend .socksProxy )
482+ blockExplorerPrefix , backend .socksProxy )
488483 case code == coinpkg .CodeBTC :
484+ blockExplorerPrefix := backend .config .AppConfig ().Backend .BlockExplorers .BTC
489485 servers := backend .defaultElectrumXServers (code )
490486 coin = btc .NewCoin (coinpkg .CodeBTC , "Bitcoin" , "BTC" , btcFormatUnit , & chaincfg .MainNetParams , dbFolder , servers ,
491- "https://blockstream.info/tx/" , backend .socksProxy )
487+ blockExplorerPrefix , backend .socksProxy )
492488 case code == coinpkg .CodeTLTC :
489+ blockExplorerPrefix := backend .config .AppConfig ().Backend .BlockExplorers .TLTC
493490 servers := backend .defaultElectrumXServers (code )
494491 coin = btc .NewCoin (coinpkg .CodeTLTC , "Litecoin Testnet" , "TLTC" , coinpkg .BtcUnitDefault , & ltc .TestNet4Params , dbFolder , servers ,
495- "https://sochain.com/tx/LTCTEST/" , backend .socksProxy )
492+ blockExplorerPrefix , backend .socksProxy )
496493 case code == coinpkg .CodeLTC :
494+ blockExplorerPrefix := backend .config .AppConfig ().Backend .BlockExplorers .LTC
497495 servers := backend .defaultElectrumXServers (code )
498496 coin = btc .NewCoin (coinpkg .CodeLTC , "Litecoin" , "LTC" , coinpkg .BtcUnitDefault , & ltc .MainNetParams , dbFolder , servers ,
499- "https://blockchair.com/litecoin/transaction/" , backend .socksProxy )
497+ blockExplorerPrefix , backend .socksProxy )
500498 case code == coinpkg .CodeETH :
499+ blockExplorerPrefix := backend .config .AppConfig ().Backend .BlockExplorers .ETH
501500 etherScan := etherscan .NewEtherScan ("https://api.etherscan.io/api" , backend .etherScanHTTPClient )
502501 coin = eth .NewCoin (etherScan , code , "Ethereum" , "ETH" , "ETH" , params .MainnetChainConfig ,
503- "https://etherscan.io/tx/" ,
502+ blockExplorerPrefix ,
504503 etherScan ,
505504 nil )
506505 case code == coinpkg .CodeGOETH :
506+ blockExplorerPrefix := backend .config .AppConfig ().Backend .BlockExplorers .GOETH
507507 etherScan := etherscan .NewEtherScan ("https://api-goerli.etherscan.io/api" , backend .etherScanHTTPClient )
508508 coin = eth .NewCoin (etherScan , code , "Ethereum Goerli" , "GOETH" , "GOETH" , params .GoerliChainConfig ,
509- "https://goerli.etherscan.io/tx/" ,
509+ blockExplorerPrefix ,
510510 etherScan ,
511511 nil )
512512 case code == coinpkg .CodeSEPETH :
513+ blockExplorerPrefix := backend .config .AppConfig ().Backend .BlockExplorers .SEPETH
513514 etherScan := etherscan .NewEtherScan ("https://api-sepolia.etherscan.io/api" , backend .etherScanHTTPClient )
514515 coin = eth .NewCoin (etherScan , code , "Ethereum Sepolia" , "SEPETH" , "SEPETH" , params .SepoliaChainConfig ,
515- "https://sepolia.etherscan.io/tx/" ,
516+ blockExplorerPrefix ,
516517 etherScan ,
517518 nil )
518519 case erc20Token != nil :
520+ blockExplorerPrefix := backend .config .AppConfig ().Backend .BlockExplorers .ETH
519521 etherScan := etherscan .NewEtherScan ("https://api.etherscan.io/api" , backend .etherScanHTTPClient )
520522 coin = eth .NewCoin (etherScan , erc20Token .code , erc20Token .name , erc20Token .unit , "ETH" , params .MainnetChainConfig ,
521- "https://etherscan.io/tx/" ,
523+ blockExplorerPrefix ,
522524 etherScan ,
523525 erc20Token .token ,
524526 )
@@ -819,6 +821,16 @@ func (backend *Backend) SystemOpen(url string) error {
819821 }
820822 }
821823
824+ // Block explorers are not defined in the fixedURLWhiteList but in AvailableBlockexplorers.
825+ var allAvailableExplorers = reflect .ValueOf (config .AvailableExplorers )
826+ for i := 0 ; i < allAvailableExplorers .NumField (); i ++ {
827+ coinAvailableExplorers := allAvailableExplorers .Field (i ).Interface ().([]config.BlockExplorer )
828+ for _ , explorer := range coinAvailableExplorers {
829+ if strings .HasPrefix (url , explorer .Url ) {
830+ return backend .environment .SystemOpen (url )
831+ }
832+ }
833+ }
822834 return errp .Newf ("Blocked /open with url: %s" , url )
823835}
824836
@@ -942,3 +954,8 @@ func (backend *Backend) SetWatchonly(rootFingerprint []byte, watchonly bool) err
942954 & t ,
943955 )
944956}
957+
958+ // AvailableExplorers returns a struct containing all available block explorers for each coin.
959+ func (backend * Backend ) AvailableExplorers () config.AvailableBlockExplorers {
960+ return config .AvailableExplorers
961+ }
0 commit comments