diff --git a/.gitignore b/.gitignore index 496ee2c..f14c809 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,4 @@ -.DS_Store \ No newline at end of file +.DS_Store + +vendor/ +build/ \ No newline at end of file diff --git a/Gopkg.lock b/Gopkg.lock new file mode 100644 index 0000000..3c7d028 --- /dev/null +++ b/Gopkg.lock @@ -0,0 +1,190 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[[projects]] + digest = "1:abeb38ade3f32a92943e5be54f55ed6d6e3b6602761d74b4aab4c9dd45c18abd" + name = "github.com/fsnotify/fsnotify" + packages = ["."] + pruneopts = "UT" + revision = "c2828203cd70a50dcccfb2761f8b1f8ceef9a8e9" + version = "v1.4.7" + +[[projects]] + digest = "1:c0d19ab64b32ce9fe5cf4ddceba78d5bc9807f0016db6b1183599da3dcc24d10" + name = "github.com/hashicorp/hcl" + packages = [ + ".", + "hcl/ast", + "hcl/parser", + "hcl/printer", + "hcl/scanner", + "hcl/strconv", + "hcl/token", + "json/parser", + "json/scanner", + "json/token", + ] + pruneopts = "UT" + revision = "8cb6e5b959231cc1119e43259c4a608f9c51a241" + version = "v1.0.0" + +[[projects]] + digest = "1:870d441fe217b8e689d7949fef6e43efbc787e50f200cb1e70dbca9204a1d6be" + name = "github.com/inconshreveable/mousetrap" + packages = ["."] + pruneopts = "UT" + revision = "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75" + version = "v1.0" + +[[projects]] + digest = "1:31e761d97c76151dde79e9d28964a812c46efc5baee4085b86f68f0c654450de" + name = "github.com/konsorten/go-windows-terminal-sequences" + packages = ["."] + pruneopts = "UT" + revision = "f55edac94c9bbba5d6182a4be46d86a2c9b5b50e" + version = "v1.0.2" + +[[projects]] + digest = "1:c568d7727aa262c32bdf8a3f7db83614f7af0ed661474b24588de635c20024c7" + name = "github.com/magiconair/properties" + packages = ["."] + pruneopts = "UT" + revision = "c2353362d570a7bfa228149c62842019201cfb71" + version = "v1.8.0" + +[[projects]] + digest = "1:5d231480e1c64a726869bc4142d270184c419749d34f167646baa21008eb0a79" + name = "github.com/mitchellh/go-homedir" + packages = ["."] + pruneopts = "UT" + revision = "af06845cf3004701891bf4fdb884bfe4920b3727" + version = "v1.1.0" + +[[projects]] + digest = "1:53bc4cd4914cd7cd52139990d5170d6dc99067ae31c56530621b18b35fc30318" + name = "github.com/mitchellh/mapstructure" + packages = ["."] + pruneopts = "UT" + revision = "3536a929edddb9a5b34bd6861dc4a9647cb459fe" + version = "v1.1.2" + +[[projects]] + digest = "1:95741de3af260a92cc5c7f3f3061e85273f5a81b5db20d4bd68da74bd521675e" + name = "github.com/pelletier/go-toml" + packages = ["."] + pruneopts = "UT" + revision = "c01d1270ff3e442a8a57cddc1c92dc1138598194" + version = "v1.2.0" + +[[projects]] + digest = "1:e4c72127d910a96daf869a44f3dd563b86dbe6931a172863a0e99c5ff04b59e4" + name = "github.com/sirupsen/logrus" + packages = ["."] + pruneopts = "UT" + revision = "dae0fa8d5b0c810a8ab733fbd5510c7cae84eca4" + version = "v1.4.0" + +[[projects]] + digest = "1:bb495ec276ab82d3dd08504bbc0594a65de8c3b22c6f2aaa92d05b73fbf3a82e" + name = "github.com/spf13/afero" + packages = [ + ".", + "mem", + ] + pruneopts = "UT" + revision = "588a75ec4f32903aa5e39a2619ba6a4631e28424" + version = "v1.2.2" + +[[projects]] + digest = "1:08d65904057412fc0270fc4812a1c90c594186819243160dc779a402d4b6d0bc" + name = "github.com/spf13/cast" + packages = ["."] + pruneopts = "UT" + revision = "8c9545af88b134710ab1cd196795e7f2388358d7" + version = "v1.3.0" + +[[projects]] + digest = "1:645cabccbb4fa8aab25a956cbcbdf6a6845ca736b2c64e197ca7cbb9d210b939" + name = "github.com/spf13/cobra" + packages = ["."] + pruneopts = "UT" + revision = "ef82de70bb3f60c65fb8eebacbb2d122ef517385" + version = "v0.0.3" + +[[projects]] + digest = "1:1b753ec16506f5864d26a28b43703c58831255059644351bbcb019b843950900" + name = "github.com/spf13/jwalterweatherman" + packages = ["."] + pruneopts = "UT" + revision = "94f6ae3ed3bceceafa716478c5fbf8d29ca601a1" + version = "v1.1.0" + +[[projects]] + digest = "1:c1b1102241e7f645bc8e0c22ae352e8f0dc6484b6cb4d132fa9f24174e0119e2" + name = "github.com/spf13/pflag" + packages = ["."] + pruneopts = "UT" + revision = "298182f68c66c05229eb03ac171abe6e309ee79a" + version = "v1.0.3" + +[[projects]] + digest = "1:1b773526998f3dbde3a51a4a5881680c4d237d3600f570d900f97ac93c7ba0a8" + name = "github.com/spf13/viper" + packages = ["."] + pruneopts = "UT" + revision = "9e56dacc08fbbf8c9ee2dbc717553c758ce42bc9" + version = "v1.3.2" + +[[projects]] + branch = "master" + digest = "1:bbe51412d9915d64ffaa96b51d409e070665efc5194fcf145c4a27d4133107a4" + name = "golang.org/x/crypto" + packages = ["ssh/terminal"] + pruneopts = "UT" + revision = "a5d413f7728c81fb97d96a2b722368945f651e78" + +[[projects]] + branch = "master" + digest = "1:6b3e6ddcebac95be1d690dbd53b5aa2e520715becb7e521bb526ccf3b4c53c15" + name = "golang.org/x/sys" + packages = [ + "unix", + "windows", + ] + pruneopts = "UT" + revision = "f49334f85ddcf0f08d7fb6dd7363e9e6d6b777eb" + +[[projects]] + digest = "1:8029e9743749d4be5bc9f7d42ea1659471767860f0cdc34d37c3111bd308a295" + name = "golang.org/x/text" + packages = [ + "internal/gen", + "internal/triegen", + "internal/ucd", + "transform", + "unicode/cldr", + "unicode/norm", + ] + pruneopts = "UT" + revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0" + version = "v0.3.0" + +[[projects]] + digest = "1:4d2e5a73dc1500038e504a8d78b986630e3626dc027bc030ba5c75da257cdb96" + name = "gopkg.in/yaml.v2" + packages = ["."] + pruneopts = "UT" + revision = "51d6538a90f86fe93ac480b35f37b2be17fef232" + version = "v2.2.2" + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + input-imports = [ + "github.com/mitchellh/go-homedir", + "github.com/sirupsen/logrus", + "github.com/spf13/cobra", + "github.com/spf13/viper", + ] + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml new file mode 100644 index 0000000..d7072c2 --- /dev/null +++ b/Gopkg.toml @@ -0,0 +1,30 @@ +# Gopkg.toml example +# +# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html +# for detailed Gopkg.toml documentation. +# +# required = ["github.com/user/thing/cmd/thing"] +# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] +# +# [[constraint]] +# name = "github.com/user/project" +# version = "1.0.0" +# +# [[constraint]] +# name = "github.com/user/project2" +# branch = "dev" +# source = "github.com/myfork/project2" +# +# [[override]] +# name = "github.com/x/y" +# version = "2.4.0" +# +# [prune] +# non-go = false +# go-tests = true +# unused-packages = true + + +[prune] + go-tests = true + unused-packages = true diff --git a/README.md b/README.md index 04ee3f3..60c1c8e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # 🍣 Nigiri Bitcoin -A dockerized environment hosting a bitcoin and liquid daemons in regtest network with an electrum server that indexes and keeps track of all UTXOs. +Nigiri provides a fully dockerized ready-to-use bitcoin environment thats supports different networks and chains. ## Utensils @@ -15,53 +15,63 @@ A dockerized environment hosting a bitcoin and liquid daemons in regtest network ## Directions -| Preparation Time: 20 min | Cooking Difficulty: Easy | +| Preparation Time: 5 min | Cooking Difficulty: Easy | | --- | --- | Clone the repo: ```bash -$ git clone https://github.com/vulpemventures/nigiri.git && cd nigiri +$ git clone https://github.com/vulpemventures/nigiri.git ``` -Create and start nigiri (only the first time or after cleaning): +Enter project directory and install dependencies: ```bash -$ bash scripts/create +nigiri $ bash scripts/install +``` + +Build binary (Mac version): +``` +nigiri $ bash scripts/build darwin amd64 ``` At the moment bitcoind, liquidd and electrs are started on *regtest* network. -Start nigiri: +Create nigiri environment: ```bash -$ bash scripts/start +nigiri/build $ nigiri-linux-amd64 create ``` -This will start 4 containers that run the following services respectevely: +Nigiri uses the default directory `~/.nigiri` to store the configuration file and docker stuff. +To set a custom directory use the `--datadir` flag, but do not forget to always pass this flag to other commands, just as you do with your `bitcoind`. -* bitcoin daemon (regtest) -* liquid daemon +The environment will start with 3 containers for `regtest` bitcoin network that run the following services respectevely: + +* bitcoin daemon * electrs REST server * API passthrough with optional faucet and mining capabilities (nigiri-chopsticks) -Stop nigiri: +Use the `--liquid` flag to let you do experiments with the Liquid sidechain. A liquid daemon and a block explorer +are also started when passing this flag. + +Start/Stop nigiri: ```bash -$ bash scripts/stop +nigiri/build $ nigiri-linux-amd64 start|stop ``` -Stop and uninstall nigiri: +Stop and delete nigiri environment: ```bash -$ bash scripts/clean +nigiri/build $ nigiri-linux-amd64 delete ``` -When setup is completed, you can call any endpoint at `http://localhost:3000/`. +This command stops and deletes any active contained and deletes the configuration file and all the Docker-generated files and directories. ## Nutrition Facts -The [list](https://github.com/blockstream/esplora/blob/master/API.md) of all available endpoints has been extended with one more `POST /send` which expects a body `{ "address": }` +The [list](https://github.com/blockstream/esplora/blob/master/API.md) of all available endpoints can be extended with one more `POST /faucet` which expects a body `{ "address": }` by enabling faucet. ## Footnotes diff --git a/bitcoin/Dockerfile b/bitcoin/Dockerfile deleted file mode 100644 index 2f47f55..0000000 --- a/bitcoin/Dockerfile +++ /dev/null @@ -1,23 +0,0 @@ -# bitcoin-box docker image -FROM ubuntu:18.04 - -# add bitcoind from the official PPA -# install bitcoind (from PPA) and make -RUN apt-get update && \ - apt-get install --yes clang cmake jq software-properties-common && \ - add-apt-repository --yes ppa:bitcoin/bitcoin && \ - apt-get update && \ - apt-get install --yes bitcoind - -RUN mkdir -p /config /script - -# copy the box files into the image -ADD bitcoin/config /config -ADD bitcoin/run /script - -WORKDIR /script -# expose two rpc ports for the nodes to allow outside container access -EXPOSE 19001 -STOPSIGNAL SIGINT - -CMD ["./run"] diff --git a/bitcoin/config/bitcoin.conf b/bitcoin/config/bitcoin.conf deleted file mode 100644 index e0bf901..0000000 --- a/bitcoin/config/bitcoin.conf +++ /dev/null @@ -1,23 +0,0 @@ -# testnet-box functionality -regtest=1 -testnet=0 -dnsseed=0 -upnp=0 - -[regtest] -# listen on different ports than default testnet -port=19000 -rpcport=19001 - -# always run a server, even with bitcoin-qt -server=1 -txindex=0 - -# enable to allow non-localhost RPC connections -# recommended to change to a subnet, such as your LAN -rpcallowip=0.0.0.0/0 - -rpcuser=admin1 -rpcpassword=123 - - diff --git a/bitcoin/run b/bitcoin/run deleted file mode 100755 index 7bb4129..0000000 --- a/bitcoin/run +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash -set -ex - -b1="bitcoin-cli -datadir=/config" - -function clean { - $b1 stop -} - -trap clean SIGINT - -bitcoind -datadir=/config & - -sleep 10 - -$b1 generate 200 -wait $! \ No newline at end of file diff --git a/chopsticks/Dockerfile b/chopsticks/Dockerfile deleted file mode 100644 index 1c7d6dd..0000000 --- a/chopsticks/Dockerfile +++ /dev/null @@ -1,10 +0,0 @@ -FROM ubuntu:18.04 - -WORKDIR /build -COPY chopsticks/nigiri-chopsticks-linux-amd64.tar.gz /build -RUN ls -RUN tar -xzf nigiri-chopsticks-linux-amd64.tar.gz && rm -rf *.tar.gz - -EXPOSE 3000 - -CMD ["./nigiri-chopsticks-linux-amd64", "--addr", "0.0.0.0:3000", "--electrs-addr", "10.10.0.12:3002", "--rpc-addr", "10.10.0.10:19001"] \ No newline at end of file diff --git a/chopsticks/nigiri-chopsticks-linux-amd64.tar.gz b/chopsticks/nigiri-chopsticks-linux-amd64.tar.gz deleted file mode 100644 index ccc126a..0000000 Binary files a/chopsticks/nigiri-chopsticks-linux-amd64.tar.gz and /dev/null differ diff --git a/cli/cmd/create.go b/cli/cmd/create.go new file mode 100644 index 0000000..2161303 --- /dev/null +++ b/cli/cmd/create.go @@ -0,0 +1,98 @@ +package cmd + +import ( + "fmt" + "os" + "os/exec" + "path/filepath" + + log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" + "github.com/vulpemventures/nigiri/cli/builder" + "github.com/vulpemventures/nigiri/cli/config" + "github.com/vulpemventures/nigiri/cli/helpers" +) + +var composeBuilder = map[string]func(path string) builder.ComposeBuilder{ + "regtest": helpers.NewRegtestBuilder, +} + +var CreateCmd = &cobra.Command{ + Use: "create", + Short: "Build and run the entire Docker environment", + Run: create, + PreRun: createChecks, +} + +func createChecks(cmd *cobra.Command, args []string) { + network, _ := cmd.Flags().GetString("network") + datadir, _ := cmd.Flags().GetString("datadir") + + // check flags + if !isNetworkOk(network) { + log.WithField("network_flag", network).Fatal("Invalid network") + } + + if !isDatadirOk(datadir) { + log.WithField("datadir_flag", datadir).Fatal("Invalid datadir, it must be an absolute path") + } + + // scratch datadir if not exists + if err := os.MkdirAll(datadir, 0755); err != nil { + log.WithError(err).Fatal("An error occured while scratching config dir") + } + + // check if config file already exists in datadir + filedir := filepath.Join(datadir, "nigiri.config.json") + if _, err := os.Stat(filedir); !os.IsNotExist(err) { + log.WithField("datadir", datadir).Fatal("Configuration file already exists, please delete it first") + } + + // write and read config file to have viper updated + if err := config.WriteConfig(filedir); err != nil { + log.WithError(err).Fatal("An error occured while writing config file") + } + + if err := config.ReadFromFile(datadir); err != nil { + log.WithError(err).Fatal("An error occured while reading config file") + } +} + +func create(cmd *cobra.Command, args []string) { + composePath := getComposePath() + + bashCmd := exec.Command("docker-compose", "-f", composePath, "up", "-d") + bashCmd.Stdout = os.Stdout + bashCmd.Stderr = os.Stderr + + if err := bashCmd.Run(); err != nil { + log.WithError(err).Fatal("An error occured while composing Docker environment") + } +} + +func isNetworkOk(network string) bool { + var ok bool + for _, n := range []string{"regtest"} { + if network == n { + ok = true + } + } + + return ok +} + +func isDatadirOk(datadir string) bool { + return filepath.IsAbs(datadir) +} + +func getComposePath() string { + viper := config.Viper() + datadir := viper.GetString("datadir") + network := viper.GetString("network") + attachLiquid := viper.GetBool("attachLiquid") + if attachLiquid { + network += "-liquid" + } + + return filepath.Join(datadir, "resources", fmt.Sprintf("docker-compose-%s.yml", network)) +} diff --git a/cli/cmd/delete.go b/cli/cmd/delete.go new file mode 100644 index 0000000..5ecc9e8 --- /dev/null +++ b/cli/cmd/delete.go @@ -0,0 +1,90 @@ +package cmd + +import ( + "fmt" + "io/ioutil" + "os" + "os/exec" + "path/filepath" + + log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" + "github.com/vulpemventures/nigiri/cli/config" +) + +var DeleteCmd = &cobra.Command{ + Use: "delete", + Short: "Delete all Docker environment components", + Run: delete, + PreRun: deleteChecks, +} + +func delete(cmd *cobra.Command, args []string) { + composePath := getComposePath() + + bashCmd := exec.Command("docker-compose", "-f", composePath, "down") + bashCmd.Stdout = os.Stdout + bashCmd.Stderr = os.Stderr + + if err := bashCmd.Run(); err != nil { + log.WithError(err).Fatal("An error occured while deleting Docker environment") + } + + if err := cleanVolumes(); err != nil { + log.WithError(err).Fatal("An error occured while cleanin Docker volumes") + } + + if err := deleteConfig(); err != nil { + log.WithError(err).Fatal("An error occured while deleting config file, please delete it manually") + } +} + +func deleteChecks(cmd *cobra.Command, args []string) { + datadir, _ := cmd.Flags().GetString("datadir") + if err := config.ReadFromFile(datadir); err != nil { + log.Fatal(err) + } +} + +/* + When deleting nigiri we need to clean the Docker volumes that are + used as datadir of the bitcoin/liquid daemon. These folders contain + both the *.conf files provided by us and files and directories created + by the daemons. + cleanVolumes navigates into /resources/volumes/ + and deletes all files and directories but the *.conf config files. +*/ +func cleanVolumes() error { + datadir := config.GetString(config.Datadir) + network := config.GetString(config.Network) + attachLiquid := config.GetBool(config.AttachLiquid) + if attachLiquid { + network = fmt.Sprintf("liquid%s", network) + } + volumedir := filepath.Join(datadir, "resources", "volumes", network) + + subdirs, err := ioutil.ReadDir(volumedir) + if err != nil { + return err + } + + for _, d := range subdirs { + volumedir := filepath.Join(volumedir, d.Name()) + subsubdirs, _ := ioutil.ReadDir(volumedir) + for _, sd := range subsubdirs { + if sd.IsDir() { + if err := os.RemoveAll(filepath.Join(volumedir, sd.Name())); err != nil { + return err + } + } + } + } + + return nil +} + +func deleteConfig() error { + datadir := config.GetString(config.Datadir) + configFile := filepath.Join(datadir, config.Filename) + return os.Remove(configFile) +} diff --git a/cli/cmd/flags.go b/cli/cmd/flags.go new file mode 100644 index 0000000..e8ad0dd --- /dev/null +++ b/cli/cmd/flags.go @@ -0,0 +1,52 @@ +package cmd + +import ( + "os" + "path/filepath" + + "github.com/mitchellh/go-homedir" + log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" + "github.com/vulpemventures/nigiri/cli/config" +) + +var ( + flagDatadir string + flagNetwork string + flagAttachLiquid bool +) + +var RootCmd = &cobra.Command{ + Use: "nigiri", + Short: "Nigiri lets you manage a full dockerized bitcoin environment", + Long: "Nigiri lets you create your dockerized environment with a bitcoin and optionally a liquid node + block explorer powered by an electrum server", +} + +func init() { + defaultDir := getDefaultDir() + + RootCmd.PersistentFlags().StringVar(&flagDatadir, "datadir", defaultDir, "Set directory for config file and docker stuff") + CreateCmd.PersistentFlags().StringVar(&flagNetwork, "network", "regtest", "Set network for containers' services - regtest only for now") + CreateCmd.PersistentFlags().BoolVar(&flagAttachLiquid, "liquid", false, "Add liquid sidechain to bitcoin environment") + + RootCmd.AddCommand(CreateCmd) + RootCmd.AddCommand(StartCmd) + RootCmd.AddCommand(StopCmd) + RootCmd.AddCommand(DeleteCmd) + RootCmd.AddCommand(VersionCmd) + + viper := config.Viper() + viper.BindPFlag(config.Datadir, RootCmd.PersistentFlags().Lookup("datadir")) + viper.BindPFlag(config.Network, CreateCmd.PersistentFlags().Lookup("network")) + viper.BindPFlag(config.AttachLiquid, CreateCmd.PersistentFlags().Lookup("liquid")) + + cobra.OnInitialize(func() { + log.SetOutput(os.Stdout) + log.SetLevel(log.InfoLevel) + }) +} + +func getDefaultDir() string { + home, _ := homedir.Expand("~") + return filepath.Join(home, ".nigiri") +} diff --git a/cli/cmd/start.go b/cli/cmd/start.go new file mode 100644 index 0000000..283537e --- /dev/null +++ b/cli/cmd/start.go @@ -0,0 +1,36 @@ +package cmd + +import ( + "os" + "os/exec" + + log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" + "github.com/vulpemventures/nigiri/cli/config" +) + +var StartCmd = &cobra.Command{ + Use: "start", + Short: "Start containers", + Run: start, + PreRun: startStopChecks, +} + +func start(cmd *cobra.Command, args []string) { + composePath := getComposePath() + + bashCmd := exec.Command("docker-compose", "-f", composePath, "start") + bashCmd.Stdout = os.Stdout + bashCmd.Stderr = os.Stderr + + if err := bashCmd.Run(); err != nil { + log.WithError(err).Fatal("An error occured while starting Docker containers") + } +} + +func startStopChecks(cmd *cobra.Command, args []string) { + datadir, _ := cmd.Flags().GetString("datadir") + if err := config.ReadFromFile(datadir); err != nil { + log.Fatal(err) + } +} diff --git a/cli/cmd/stop.go b/cli/cmd/stop.go new file mode 100644 index 0000000..045a35d --- /dev/null +++ b/cli/cmd/stop.go @@ -0,0 +1,28 @@ +package cmd + +import ( + "os" + "os/exec" + + log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" +) + +var StopCmd = &cobra.Command{ + Use: "stop", + Short: "Stop containers", + Run: stop, + PreRun: startStopChecks, +} + +func stop(cmd *cobra.Command, args []string) { + composePath := getComposePath() + + bashCmd := exec.Command("docker-compose", "-f", composePath, "stop") + bashCmd.Stdout = os.Stdout + bashCmd.Stderr = os.Stderr + + if err := bashCmd.Run(); err != nil { + log.WithError(err).Fatal("Error while stopping Docker containers:") + } +} diff --git a/cli/cmd/version.go b/cli/cmd/version.go new file mode 100644 index 0000000..207d4cc --- /dev/null +++ b/cli/cmd/version.go @@ -0,0 +1,26 @@ +package cmd + +import ( + "fmt" + "os" + + log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" + "github.com/vulpemventures/nigiri/cli/config" +) + +var VersionCmd = &cobra.Command{ + Use: "version", + Short: "Get current tool version", + Run: func(cmd *cobra.Command, args []string) { + viper := config.Viper() + fmt.Println(viper.GetString("version")) + os.Exit(0) + }, + PreRun: func(cmd *cobra.Command, args []string) { + datadir, _ := cmd.Flags().GetString("datadir") + if err := config.ReadFromFile(datadir); err != nil { + log.Fatal(err) + } + }, +} diff --git a/cli/config/main.go b/cli/config/main.go new file mode 100644 index 0000000..138e8fd --- /dev/null +++ b/cli/config/main.go @@ -0,0 +1,70 @@ +package config + +import ( + "path/filepath" + + homedir "github.com/mitchellh/go-homedir" + "github.com/spf13/viper" +) + +const ( + Datadir = "datadir" + Network = "network" + Filename = "nigiri.config.json" + AttachLiquid = "attachLiquid" + Version = "version" +) + +var vip *viper.Viper + +func init() { + vip = viper.New() + vip.SetEnvPrefix("NIGIRI") + vip.AutomaticEnv() + vip.BindEnv("config") + + defaults := viper.New() + newDefaultConfig(defaults) + setConfigFromDefaults(vip, defaults) + // vip.SetConfigFile(GetFullPath()) +} + +func Viper() *viper.Viper { + return vip +} + +func ReadFromFile(path string) error { + vip.SetConfigFile(filepath.Join(path, Filename)) + return vip.ReadInConfig() +} + +func WriteConfig(path string) error { + vip.SetConfigFile(path) + return vip.WriteConfig() +} + +func GetString(str string) string { + return vip.GetString(str) +} + +func GetBool(str string) bool { + return vip.GetBool(str) +} + +func GetPath() string { + home, _ := homedir.Expand("~") + return filepath.Join(home, ".nigiri") +} + +func newDefaultConfig(v *viper.Viper) { + v.SetDefault(Datadir, GetPath()) + v.SetDefault(Network, "regtest") + v.SetDefault(AttachLiquid, false) + v.SetDefault(Version, "0.1.0") +} + +func setConfigFromDefaults(v *viper.Viper, d *viper.Viper) { + for key, value := range d.AllSettings() { + v.SetDefault(key, value) + } +} diff --git a/cli/main.go b/cli/main.go new file mode 100644 index 0000000..3f83d44 --- /dev/null +++ b/cli/main.go @@ -0,0 +1,7 @@ +package main + +import "github.com/vulpemventures/nigiri/cli/cmd" + +func main() { + cmd.RootCmd.Execute() +} diff --git a/cli/resources/docker-compose-regtest-liquid.yml b/cli/resources/docker-compose-regtest-liquid.yml new file mode 100644 index 0000000..25f1247 --- /dev/null +++ b/cli/resources/docker-compose-regtest-liquid.yml @@ -0,0 +1,78 @@ +version: '3' +services: + bitcoin: + image: vulpemventures/bitcoin:latest + networks: + local: + ipv4_address: 10.10.0.10 + volumes: + - ./volumes/liquidregtest/config/:/config + liquid: + image: vulpemventures/liquid:latest + networks: + local: + ipv4_address: 10.10.0.11 + volumes: + - ./volumes/liquidregtest/liquid-config/:/config + electrs: + image: vulpemventures/electrs:latest + entrypoint: + - /build/electrs + command: + - -vvvv + - --network + - regtest + - --daemon-dir + - /config + - --daemon-rpc-addr + - 10.10.0.10:19001 + - --cookie + - admin1:123 + - --http-addr + - 0.0.0.0:3002 + networks: + local: + ipv4_address: 10.10.0.12 + ports: + - 3002:3002 + volumes: + - ./volumes/liquidregtest/config/:/config + electrs-liquid: + image: vulpemventures/electrs-liquid:latest + networks: + local: + ipv4_address: 10.10.0.13 + entrypoint: + - /build/electrs + command: + - -vvvv + - --network + - liquidregtest + - --daemon-dir + - /config + - --daemon-rpc-addr + - 10.10.0.11:18884 + - --cookie + - admin1:123 + - --http-addr + - 0.0.0.0:3002 + volumes: + - ./volumes/liquidregtest/liquid-config/:/config + ports: + - 3022:3002 + # chopsticks: + # build: + # context: chopsticks/ + # dockerfile: Dockerfile + # ports: + # - 3000:3000 + # networks: + # local: + # ipv4_address: 10.10.0.13 + +networks: + local: + driver: bridge + ipam: + config: + - subnet: 10.10.0.0/24 \ No newline at end of file diff --git a/cli/resources/docker-compose-regtest.yml b/cli/resources/docker-compose-regtest.yml new file mode 100644 index 0000000..4a87627 --- /dev/null +++ b/cli/resources/docker-compose-regtest.yml @@ -0,0 +1,50 @@ +version: '3' +services: + bitcoin: + image: vulpemventures/bitcoin:latest + networks: + local: + ipv4_address: 10.10.0.10 + ports: + - 19001:19001 + volumes: + - ./volumes/regtest/config/:/config + electrs: + image: vulpemventures/electrs:latest + entrypoint: + - /build/electrs + command: + - -vvvv + - --network + - regtest + - --daemon-dir + - /config + - --daemon-rpc-addr + - 10.10.0.10:19001 + - --cookie + - admin1:123 + - --http-addr + - 0.0.0.0:3002 + networks: + local: + ipv4_address: 10.10.0.12 + ports: + - 3002:3002 + volumes: + - ./volumes/regtest/config/:/config + # chopsticks: + # build: + # context: chopsticks/ + # dockerfile: Dockerfile + # ports: + # - 3000:3000 + # networks: + # local: + # ipv4_address: 10.10.0.13 + +networks: + local: + driver: bridge + ipam: + config: + - subnet: 10.10.0.0/24 \ No newline at end of file diff --git a/cli/resources/volumes/liquidregtest/config/bitcoin.conf b/cli/resources/volumes/liquidregtest/config/bitcoin.conf new file mode 100644 index 0000000..ee4669c --- /dev/null +++ b/cli/resources/volumes/liquidregtest/config/bitcoin.conf @@ -0,0 +1,15 @@ +regtest=1 +testnet=0 +dnsseed=0 +upnp=0 + +[regtest] +port=19000 +rpcport=19001 + +server=1 +txindex=0 + +rpcuser=admin1 +rpcpassword=123 +rpcallowip=0.0.0.0/0 \ No newline at end of file diff --git a/liquid/config/liquid.conf b/cli/resources/volumes/liquidregtest/liquid-config/liquid.conf similarity index 57% rename from liquid/config/liquid.conf rename to cli/resources/volumes/liquidregtest/liquid-config/liquid.conf index 2528ca0..da9ed91 100644 --- a/liquid/config/liquid.conf +++ b/cli/resources/volumes/liquidregtest/liquid-config/liquid.conf @@ -1,23 +1,18 @@ -# Standard bitcoind stuff -rpcuser=user1 -rpcpassword=password1 -rpcport=18884 -port=18886 - -# Over p2p we will only connect to local other liquidd -# connect=localhost:18887 - regtest=1 -# Make sure you set listen after -connect, otherwise neither -# will accept incoming connections! listen=1 -# Just for looking at random txs +port=18886 txindex=0 -# enable to allow non-localhost RPC connections -# recommended to change to a subnet, such as your LAN +rpcport=18884 +rpcuser=admin1 +rpcpassword=123 rpcallowip=0.0.0.0/0 +mainchainrpcport=19001 +mainchainrpchost=10.10.0.10 +mainchainrpcuser=admin1 +mainchainrpcpassword=123 + # This is the script that controls pegged in funds in Bitcoin network # Users will be pegging into a P2SH of this, and the "watchmen" # can then recover these funds and send them to users who desire to peg out. @@ -32,15 +27,6 @@ rpcallowip=0.0.0.0/0 # We want to validate pegins by checking with bitcoind if header exists # in best known chain, and how deep. We combine this with pegin # proof included in the pegin to get full security. + validatepegin=0 - -# If in the same datadir and using standard ports, these are unneeded -# thanks to cookie auth. If not, like in our situation, liquidd needs -# more info to connect to bitcoind: -mainchainrpcport=19001 -mainchainrpchost=10.10.0.10 -mainchainrpcuser=admin1 -mainchainrpcpassword=123 - -# Free money to make testing easier -initialfreecoins=10000000000 +initialfreecoins=10000000000 \ No newline at end of file diff --git a/cli/resources/volumes/regtest/config/bitcoin.conf b/cli/resources/volumes/regtest/config/bitcoin.conf new file mode 100644 index 0000000..ee4669c --- /dev/null +++ b/cli/resources/volumes/regtest/config/bitcoin.conf @@ -0,0 +1,15 @@ +regtest=1 +testnet=0 +dnsseed=0 +upnp=0 + +[regtest] +port=19000 +rpcport=19001 + +server=1 +txindex=0 + +rpcuser=admin1 +rpcpassword=123 +rpcallowip=0.0.0.0/0 \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index 2d52d42..0000000 --- a/docker-compose.yml +++ /dev/null @@ -1,50 +0,0 @@ -version: '3' -services: - bitcoin: - build: - context: . - dockerfile: bitcoin/Dockerfile - networks: - local: - ipv4_address: 10.10.0.10 - volumes: - - bitcoin-config:/config - liquid: - build: - context: . - dockerfile: liquid/Dockerfile - networks: - local: - ipv4_address: 10.10.0.11 - volumes: - - liquid-config:/config - electrs: - build: - context: . - dockerfile: electrs/Dockerfile - networks: - local: - ipv4_address: 10.10.0.12 - volumes: - - bitcoin-config:/config - - liquid-config:/liquidconfig - chopsticks: - build: - context: . - dockerfile: chopsticks/Dockerfile - ports: - - 3000:3000 - networks: - local: - ipv4_address: 10.10.0.13 - -networks: - local: - driver: bridge - ipam: - config: - - subnet: 10.10.0.0/24 - -volumes: - bitcoin-config: - liquid-config: diff --git a/electrs/Dockerfile b/electrs/Dockerfile deleted file mode 100644 index 439b855..0000000 --- a/electrs/Dockerfile +++ /dev/null @@ -1,16 +0,0 @@ -FROM ubuntu:18.04 - -RUN apt-get update && apt-get install --yes wget - -WORKDIR /build -RUN wget -qO- https://github.com/vulpemventures/electrs/releases/download/v0.4.1-bin/electrs.tar.gz | tar -xvz && rm -rf electrs.tar.gz - -# RUN cargo build --release -WORKDIR /scripts -ADD electrs/run /scripts - -# Electrum REST -EXPOSE 3002 -STOPSIGNAL SIGINT - -CMD ["./run"] \ No newline at end of file diff --git a/electrs/run b/electrs/run deleted file mode 100755 index ff78c5e..0000000 --- a/electrs/run +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash -set -e - -function clean { - kill -9 $(pidof electrs) -} -trap clean SIGINT - -/build/electrs -vvvv --network regtest --daemon-dir /config --daemon-rpc-addr="10.10.0.10:19001" --cookie="admin1:123" --http-addr="0.0.0.0:3002" & -wait $! \ No newline at end of file diff --git a/liquid/Dockerfile b/liquid/Dockerfile deleted file mode 100644 index 3b91f34..0000000 --- a/liquid/Dockerfile +++ /dev/null @@ -1,17 +0,0 @@ -FROM ubuntu:18.04 - -RUN apt-get update && apt-get install --yes curl wget - -RUN mkdir -p /tmp /config /script - -ADD liquid/config /config -ADD liquid/script /script - -WORKDIR /script - -RUN /script/install - -EXPOSE 18884 -STOPSIGNAL SIGINT - -CMD ["./run"] diff --git a/liquid/script/install b/liquid/script/install deleted file mode 100755 index f0ddb39..0000000 --- a/liquid/script/install +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash -set -e - -LATEST_VERSION=$(curl --silent "https://api.github.com/repos/blockstream/liquid/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') -VERSION_NAME=$(echo $LATEST_VERSION | sed '1,/\./s/\./\-/') - -wget -qO- https://github.com/Blockstream/liquid/releases/download/$LATEST_VERSION/$VERSION_NAME-x86_64-linux-gnu.tar.gz | tar xvz -C /tmp - -mv /tmp/$VERSION_NAME/bin/liquidd /usr/bin/liquidd -mv /tmp/$VERSION_NAME/bin/liquid-cli /usr/bin/liquid-cli -mv /tmp/$VERSION_NAME/bin/liquid-tx /usr/bin/liquid-tx - -rm -rf /tmp \ No newline at end of file diff --git a/liquid/script/run b/liquid/script/run deleted file mode 100755 index 864f3b3..0000000 --- a/liquid/script/run +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash -set -e - -function clean { - kill -9 $(pidof liquidd) -} -trap clean SIGINT - -liquidd -datadir=/config & -wait $! \ No newline at end of file diff --git a/scripts/stop b/scripts/build similarity index 55% rename from scripts/stop rename to scripts/build index ba94128..fdcf096 100644 --- a/scripts/stop +++ b/scripts/build @@ -1,11 +1,9 @@ #!/bin/bash - set -ex PARENT_PATH=$(dirname $(cd $(dirname $0); pwd -P)) pushd $PARENT_PATH - -docker-compose stop - -popd +mkdir -p build +GOOS=$1 GOARCH=$2 go build -o build/nigiri-$1-$2 ./cli +popd \ No newline at end of file diff --git a/scripts/clean b/scripts/clean deleted file mode 100644 index 1f84356..0000000 --- a/scripts/clean +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -set -ex - -PARENT_PATH=$(dirname $(cd $(dirname $0); pwd -P)) - -pushd $PARENT_PATH - -docker-compose down && \ -docker volume rm nigiri_bitcoin-config nigiri_liquid-config && \ -docker rmi nigiri_electrs nigiri_bitcoin nigiri_liquid - -popd diff --git a/scripts/create b/scripts/install similarity index 72% rename from scripts/create rename to scripts/install index 5f97282..73efed8 100644 --- a/scripts/create +++ b/scripts/install @@ -1,11 +1,10 @@ #!/bin/bash - set -ex PARENT_PATH=$(dirname $(cd $(dirname $0); pwd -P)) pushd $PARENT_PATH +dep ensure -v -docker-compose up -d - -popd +go generate ./... +popd \ No newline at end of file diff --git a/scripts/start b/scripts/start deleted file mode 100644 index 01200cf..0000000 --- a/scripts/start +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash - -set -ex - -PARENT_PATH=$(dirname $(cd $(dirname $0); pwd -P)) - -pushd $PARENT_PATH - -docker-compose start - -popd