diff --git a/config.go b/config.go index 20d6f83..ffdd07a 100644 --- a/config.go +++ b/config.go @@ -11,6 +11,7 @@ import ( "strings" "github.com/decred/dcrd/dcrutil/v3" + "github.com/decred/dcrd/hdkeychain/v3" flags "github.com/jessevdk/go-flags" ) @@ -30,6 +31,7 @@ type config struct { Listen string `long:"listen" ini-name:"listen" description:"The ip:port to listen for API requests."` LogLevel string `long:"loglevel" ini-name:"loglevel" description:"Logging level." choice:"trace" choice:"debug" choice:"info" choice:"warn" choice:"error" choice:"critical"` Network string `long:"network" ini-name:"network" description:"Decred network to use." choice:"testnet" choice:"mainnet" choice:"simnet"` + FeeXPub string `long:"feexpub" ini-name:"feexpub" description:"cold wallet xpub used for collecting fees"` VSPFee float64 `long:"vspfee" ini-name:"vspfee" description:"The fee percentage charged for VSP use. eg. 0.01 (1%), 0.05 (5%)."` HomeDir string `long:"homedir" ini-name:"homedir" no-ini:"true" description:"Path to application home directory. Used for storing VSP database and logs."` ConfigFile string `long:"configfile" ini-name:"configfile" no-ini:"true" description:"Path to configuration file."` @@ -279,5 +281,11 @@ func loadConfig() (*config, error) { // Set the database path cfg.dbPath = filepath.Join(dataDir, "vsp.db") + // Validate the cold wallet xpub. + _, err = hdkeychain.NewKeyFromString(cfg.FeeXPub, cfg.netParams.Params) + if err != nil { + return nil, err + } + return &cfg, nil } diff --git a/go.mod b/go.mod index b485d80..922e18f 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/decred/dcrd/chaincfg/v3 v3.0.0-20200511175520-d08cb3f72b3b github.com/decred/dcrd/dcrec v1.0.0 github.com/decred/dcrd/dcrutil/v3 v3.0.0-20200517213104-6ade94486839 + github.com/decred/dcrd/hdkeychain/v3 v3.0.0-20200421213827-b60c60ffe98b github.com/decred/dcrd/rpc/jsonrpc/types/v2 v2.0.0 github.com/decred/dcrd/txscript/v3 v3.0.0-20200511175520-d08cb3f72b3b github.com/decred/dcrd/wire v1.3.0 diff --git a/go.sum b/go.sum index 4c2bbf1..ab8aa4f 100644 --- a/go.sum +++ b/go.sum @@ -70,6 +70,7 @@ github.com/decred/dcrd/dcrutil/v3 v3.0.0-20200517213104-6ade94486839 h1:1re/l3jv github.com/decred/dcrd/dcrutil/v3 v3.0.0-20200517213104-6ade94486839/go.mod h1:85NtF/fmqL2UDf0/gLhTHG/m/0HQHwG+erQKkwWW27A= github.com/decred/dcrd/gcs/v2 v2.0.0/go.mod h1:3XjKcrtvB+r2ezhIsyNCLk6dRnXRJVyYmsd1P3SkU3o= github.com/decred/dcrd/gcs/v2 v2.0.2-0.20200312171759-0a8cc56a776e/go.mod h1:JJGd1m0DrFgV4J2J8HKNB9YVkM06ewQHT6iINis39Z4= +github.com/decred/dcrd/hdkeychain/v3 v3.0.0-20200421213827-b60c60ffe98b h1:pfhggbZaR/h4mjHwMMgCl4+UnstAssVA7FEezvMKCQo= github.com/decred/dcrd/hdkeychain/v3 v3.0.0-20200421213827-b60c60ffe98b/go.mod h1:qKN0WzeSEEZ4fUBsTwKzOPkLP7GqSM6jBUm5Auq9mrM= github.com/decred/dcrd/rpc/jsonrpc/types/v2 v2.0.0 h1:uyvwjO+90KHxZIIztobB9cG+qVSHhCT+aGSiZF1vGAg= github.com/decred/dcrd/rpc/jsonrpc/types/v2 v2.0.0/go.mod h1:c5S+PtQWNIA2aUakgrLhrlopkMadcOv51dWhCEdo49c= diff --git a/main.go b/main.go index 4f6f9bc..ca546aa 100644 --- a/main.go +++ b/main.go @@ -53,7 +53,7 @@ func run(ctx context.Context) error { // Create dcrwallet RPC client. walletRPC := rpc.Setup(ctx, &shutdownWg, cfg.WalletUser, cfg.WalletPass, cfg.WalletHost, cfg.dcrwCert) - _, err = walletRPC() + walletClient, err := walletRPC() if err != nil { log.Errorf("dcrwallet RPC error: %v", err) requestShutdown() @@ -68,6 +68,36 @@ func run(ctx context.Context) error { shutdownWg.Wait() return err } + + // Get the masterpubkey from the fees account, if it exists, and make + // sure it matches the configuration. + var existingXPub string + err = walletClient.Call(ctx, "getmasterpubkey", &existingXPub, "fees") + if err != nil { + // TODO - ignore account not found + log.Errorf("dcrwallet RPC error: %v", err) + requestShutdown() + shutdownWg.Wait() + return err + } + + + // account exists - make sure it matches the configuration. + if existingXPub != cfg.FeeXPub { + log.Errorf("fees account xpub differs: %s != %s", existingXPub, cfg.FeeXPub) + requestShutdown() + shutdownWg.Wait() + return err + } else { + // account does not exist - import xpub from configuration. + if err = walletClient.Call(ctx, "importxpub", nil, "fees"); err != nil { + log.Errorf("failed to import xpub: %v", err) + requestShutdown() + shutdownWg.Wait() + return err + } + } + // Create and start webapi server. apiCfg := webapi.Config{ SignKey: signKey,