decred.org/dcrdex@v1.0.5/dex/networks/btc/config.go (about) 1 // This code is available on the terms of the project LICENSE.md file, 2 // also available online at https://blueoakcouncil.org/license/1.0.0. 3 4 package btc 5 6 import ( 7 "fmt" 8 "net" 9 "path/filepath" 10 "strconv" 11 "strings" 12 13 "decred.org/dcrdex/dex" 14 "github.com/btcsuite/btcd/btcutil" 15 ) 16 17 // NetPorts are a set of port to use with the different networks. 18 type NetPorts struct { 19 Mainnet string 20 Testnet string 21 Simnet string 22 } 23 24 // RPCPorts are the default BTC ports. 25 var RPCPorts = NetPorts{ 26 Mainnet: "8332", 27 Testnet: "18332", 28 Simnet: "18443", 29 } 30 31 // RPCConfig holds the parameters needed to initialize an RPC connection to a btc 32 // wallet or backend. Default values are used for RPCBind and/or RPCPort if not 33 // set. 34 type RPCConfig struct { 35 RPCUser string `ini:"rpcuser"` 36 RPCPass string `ini:"rpcpassword"` 37 RPCBind string `ini:"rpcbind"` 38 RPCPort int `ini:"rpcport"` 39 RPCConnect string `ini:"rpcconnect"` // (bitcoin-cli) if set, reflected in RPCBind 40 // IsPublicProvider: Set rpcbind with a URL with protocol https, and we'll 41 // assume it's a public RPC provider. This means that we assume TLS and 42 // permit omission of the RPCUser and RPCPass, since they might be encoded 43 // in the URL. 44 IsPublicProvider bool 45 } 46 47 func CheckRPCConfig(cfg *RPCConfig, name string, network dex.Network, ports NetPorts) error { 48 49 var port string 50 switch network { 51 case dex.Mainnet: 52 port = ports.Mainnet 53 case dex.Testnet: 54 port = ports.Testnet 55 case dex.Regtest: 56 port = ports.Simnet 57 default: 58 return fmt.Errorf("unknown network ID %v", network) 59 } 60 61 StandardizeRPCConf(cfg, port) 62 63 // When using a public provider, the credentials can be in the url's path. 64 if !cfg.IsPublicProvider { 65 if cfg.RPCUser == "" { 66 return fmt.Errorf("no rpcuser set in %q config file", name) 67 } 68 if cfg.RPCPass == "" { 69 return fmt.Errorf("no rpcpassword set in %q config file", name) 70 } 71 } 72 73 return nil 74 } 75 76 // StandardizeRPCConf standardizes the RPCBind and RPCPort fields, and returns 77 // the updated RPCBind field. defaultPort must be either an empty string or a 78 // valid representation of a positive 16-bit integer. 79 func StandardizeRPCConf(cfg *RPCConfig, defaultPort string) { 80 host := "127.0.0.1" // default if not in RPCBind or RPCConnect 81 port := strconv.Itoa(cfg.RPCPort) 82 if cfg.RPCPort <= 0 { 83 port = defaultPort 84 } 85 86 if cfg.RPCBind != "" { 87 // Allow RPC providers 88 if strings.HasPrefix(cfg.RPCBind, "https://") { 89 cfg.IsPublicProvider = true 90 cfg.RPCBind = cfg.RPCBind[len("https://"):] 91 port = "" 92 } 93 94 h, p, err := net.SplitHostPort(cfg.RPCBind) 95 if err != nil { 96 // Will error for i.e. "localhost", but not for "localhost:" or ":1234" 97 host = cfg.RPCBind // use port from RPCPort 98 } else { 99 if h != "" { 100 host = h 101 } 102 // If RPCBind includes a port, it takes precedence over RPCPort. 103 if p != "" { 104 port = p 105 } 106 } 107 } 108 109 // If RPCConnect is set, that's how the user has bitcoin-cli configured, so 110 // use that instead of rpcbind's host or default (localhost). 111 if cfg.RPCConnect != "" { 112 host = cfg.RPCConnect 113 // RPCConnect does not include port, so use what we got above. 114 } 115 116 if port != "" { 117 cfg.RPCBind = net.JoinHostPort(host, port) 118 cfg.RPCPort, _ = strconv.Atoi(port) 119 } else { 120 cfg.RPCBind = host 121 } 122 } 123 124 // SystemConfigPath will return the default config file path for bitcoin-like 125 // assets. 126 func SystemConfigPath(asset string) string { 127 homeDir := btcutil.AppDataDir(asset, false) 128 return filepath.Join(homeDir, fmt.Sprintf("%s.conf", asset)) 129 }