From a418bac7e0d2ae9717bad4cf30f0b65c7e2ceede Mon Sep 17 00:00:00 2001
From: Marco Argentieri <3596602+tiero@users.noreply.github.com>
Date: Tue, 3 Aug 2021 10:57:59 +0200
Subject: [PATCH 01/28] clean
---
.dockerignore | 1 -
.drone.yml | 32 ---
.gitignore | 6 -
.goreleaser.yml | 25 ---
cli/cmd/faucet.go | 120 -----------
cli/cmd/faucet_test.go | 81 --------
cli/cmd/flags.go | 63 ------
cli/cmd/logs.go | 107 ----------
cli/cmd/logs_test.go | 84 --------
cli/cmd/mint.go | 121 ------------
cli/cmd/mint_test.go | 66 -------
cli/cmd/push.go | 99 ----------
cli/cmd/push_test.go | 167 ----------------
cli/cmd/rpc.go | 77 --------
cli/cmd/rpc_test.go | 102 ----------
cli/cmd/start.go | 136 -------------
cli/cmd/start_stop_test.go | 185 -----------------
cli/cmd/stop.go | 103 ----------
cli/cmd/version.go | 25 ---
cli/config/main.go | 64 ------
cli/constants/constants.go | 71 -------
cli/controller/controller.go | 187 ------------------
cli/controller/docker.go | 98 ---------
cli/controller/env.go | 125 ------------
cli/controller/parser.go | 58 ------
cli/controller/parser_test.go | 162 ---------------
cli/main.go | 7 -
go.mod | 24 +--
go.sum | 80 --------
resources/docker-compose-regtest-liquid.yml | 179 -----------------
resources/docker-compose-regtest.yml | 94 ---------
.../volumes/liquidregtest/config/bitcoin.conf | 17 --
.../liquidregtest/liquid-config/elements.conf | 35 ----
resources/volumes/regtest/config/bitcoin.conf | 17 --
scripts/build | 16 --
scripts/clean | 24 ---
scripts/install | 12 --
37 files changed, 1 insertion(+), 2869 deletions(-)
delete mode 100644 .dockerignore
delete mode 100644 .drone.yml
delete mode 100644 .gitignore
delete mode 100644 .goreleaser.yml
delete mode 100644 cli/cmd/faucet.go
delete mode 100644 cli/cmd/faucet_test.go
delete mode 100644 cli/cmd/flags.go
delete mode 100644 cli/cmd/logs.go
delete mode 100644 cli/cmd/logs_test.go
delete mode 100644 cli/cmd/mint.go
delete mode 100644 cli/cmd/mint_test.go
delete mode 100644 cli/cmd/push.go
delete mode 100644 cli/cmd/push_test.go
delete mode 100644 cli/cmd/rpc.go
delete mode 100644 cli/cmd/rpc_test.go
delete mode 100644 cli/cmd/start.go
delete mode 100644 cli/cmd/start_stop_test.go
delete mode 100644 cli/cmd/stop.go
delete mode 100644 cli/cmd/version.go
delete mode 100644 cli/config/main.go
delete mode 100644 cli/constants/constants.go
delete mode 100644 cli/controller/controller.go
delete mode 100644 cli/controller/docker.go
delete mode 100644 cli/controller/env.go
delete mode 100644 cli/controller/parser.go
delete mode 100644 cli/controller/parser_test.go
delete mode 100644 cli/main.go
delete mode 100644 go.sum
delete mode 100644 resources/docker-compose-regtest-liquid.yml
delete mode 100644 resources/docker-compose-regtest.yml
delete mode 100644 resources/volumes/liquidregtest/config/bitcoin.conf
delete mode 100644 resources/volumes/liquidregtest/liquid-config/elements.conf
delete mode 100644 resources/volumes/regtest/config/bitcoin.conf
delete mode 100755 scripts/build
delete mode 100755 scripts/clean
delete mode 100755 scripts/install
diff --git a/.dockerignore b/.dockerignore
deleted file mode 100644
index 168f6c6..0000000
--- a/.dockerignore
+++ /dev/null
@@ -1 +0,0 @@
-/.git/
\ No newline at end of file
diff --git a/.drone.yml b/.drone.yml
deleted file mode 100644
index ffbf94a..0000000
--- a/.drone.yml
+++ /dev/null
@@ -1,32 +0,0 @@
-workspace:
- base: /root
- path: go/src/github.com/vulpemventures/nigiri
-
-pipeline:
- test:
- image: docker/compose:1.24.0
- environment:
- - DOCKER_HOST=tcp://docker:2375
- commands:
- - apk update && apk add --no-cache git curl wget bash make build-base
- - mkdir -p /root/go/bin /root/go/pkg
- # Install Go
- - wget -q https://dl.google.com/go/go1.13.4.linux-amd64.tar.gz
- - tar -xf go1.13.4.linux-amd64.tar.gz -C /usr/local && rm -rf go*
- - export GOROOT=/usr/local/go
- - export GOPATH=$HOME/go
- - export PATH=$GOPATH/bin:$GOROOT/bin:$PATH
- # Test
- - export GO111MODULE=on
- - go mod init
- - bash scripts/install
- - go test -v ./...
-
-services:
- docker:
- image: docker:dind
- privileged: true
-
- compose:
- image: docker/compose:1.24.0
- privileged: true
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 19a5844..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,6 +0,0 @@
-.DS_Store
-.env
-
-vendor/
-build/
-dist/
\ No newline at end of file
diff --git a/.goreleaser.yml b/.goreleaser.yml
deleted file mode 100644
index 4438e1c..0000000
--- a/.goreleaser.yml
+++ /dev/null
@@ -1,25 +0,0 @@
-builds:
- - main: ./cli/main.go
- ldflags:
- - -s -w -X github.com/vulpemventures/nigiri/cli/cmd.version={{.Version}} -X github.com/vulpemventures/nigiri/cli/cmd.commit={{.Commit}} -X github.com/vulpemventures/nigiri/cli/cmd.date={{.Date}}
- env:
- - CGO_ENABLED=0
- goos:
- - linux
- - darwin
- goarch:
- - amd64
-checksum:
- name_template: 'checksums.txt'
-snapshot:
- name_template: "{{ .Tag }}-next"
-changelog:
- sort: asc
- filters:
- exclude:
- - '^docs:'
- - '^test:'
-archives:
- -
- format: binary
- name_template: "{{ .ProjectName }}-{{ .Os }}-{{ .Arch }}"
\ No newline at end of file
diff --git a/cli/cmd/faucet.go b/cli/cmd/faucet.go
deleted file mode 100644
index 6a96a6d..0000000
--- a/cli/cmd/faucet.go
+++ /dev/null
@@ -1,120 +0,0 @@
-package cmd
-
-import (
- "bytes"
- "encoding/json"
- "errors"
- "fmt"
- "io/ioutil"
- "net/http"
- "strconv"
-
- "github.com/spf13/cobra"
- "github.com/vulpemventures/nigiri/cli/constants"
- "github.com/vulpemventures/nigiri/cli/controller"
-)
-
-var FaucetCmd = &cobra.Command{
- Args: func(cmd *cobra.Command, args []string) error {
-
- if len(args) < 1 {
- return errors.New("missing address")
- }
- return nil
- },
- Use: "faucet
[amount] [asset]",
- Short: "Generate and send bitcoin to given address",
- RunE: faucet,
- PreRunE: faucetChecks,
-}
-
-func faucetChecks(cmd *cobra.Command, args []string) error {
- datadir, _ := cmd.Flags().GetString("datadir")
- isLiquidService, _ := cmd.Flags().GetBool("liquid")
-
- ctl, err := controller.NewController()
- if err != nil {
- return err
- }
-
- if err := ctl.ParseDatadir(datadir); err != nil {
- return err
- }
- if len(args) < 1 {
- return constants.ErrInvalidArgs
- }
-
- if isRunning, err := ctl.IsNigiriRunning(); err != nil {
- return err
- } else if !isRunning {
- return constants.ErrNigiriNotRunning
- }
-
- if err := ctl.ReadConfigFile(datadir); err != nil {
- return err
- }
-
- if isLiquidService && isLiquidService != ctl.GetConfigBoolField(constants.AttachLiquid) {
- return constants.ErrNigiriLiquidNotEnabled
- }
-
- return nil
-}
-
-func faucet(cmd *cobra.Command, args []string) error {
- isLiquidService, err := cmd.Flags().GetBool("liquid")
- datadir, _ := cmd.Flags().GetString("datadir")
- if err != nil {
- return err
- }
- request := map[string]interface{}{
- "address": args[0],
- }
- if len(args) >= 2 {
- amountFloat, err := strconv.ParseFloat(args[1], 64)
- if err != nil {
- return fmt.Errorf("invalid amount: %v", err)
- }
- request["amount"] = amountFloat
- }
- if len(args) == 3 {
- request["asset"] = args[2]
- }
-
- ctl, err := controller.NewController()
- if err != nil {
- return err
- }
- envPath := ctl.GetResourcePath(datadir, "env")
- env, _ := ctl.ReadComposeEnvironment(envPath)
- envPorts := env["ports"].(map[string]map[string]int)
- requestPort := envPorts["bitcoin"]["chopsticks"]
- if isLiquidService {
- requestPort = envPorts["liquid"]["chopsticks"]
- }
- payload, err := json.Marshal(request)
- if err != nil {
- return err
- }
- res, err := http.Post("http://127.0.0.1:"+strconv.Itoa(requestPort)+"/faucet", "application/json", bytes.NewBuffer(payload))
- if err != nil {
- return err
- }
- data, err := ioutil.ReadAll(res.Body)
- if err != nil {
- return err
- }
- if res.StatusCode != http.StatusOK {
- return errors.New(string(data))
- }
-
- var dat map[string]string
- if err := json.Unmarshal([]byte(data), &dat); err != nil {
- return errors.New("internal error, please try again")
- }
- if dat["txId"] == "" {
- return errors.New("Not Successful")
- }
- fmt.Println("txId: " + dat["txId"])
- return nil
-}
diff --git a/cli/cmd/faucet_test.go b/cli/cmd/faucet_test.go
deleted file mode 100644
index eadaec5..0000000
--- a/cli/cmd/faucet_test.go
+++ /dev/null
@@ -1,81 +0,0 @@
-package cmd
-
-import (
- "testing"
-
- "github.com/vulpemventures/nigiri/cli/constants"
-)
-
-const (
- btcAddress = "mpSGWQvbAiRt2UNLST1CdWUufoPVsVwLyK"
- liquidAddress = "CTEsqL1x9ooWWG9HBaHUpvS2DGJJ4haYdkTQPKj9U8CCdwT5vcudhbYUT8oQwwoS11aYtdznobfgT8rj"
-)
-
-func TestFaucetBitcoinServices(t *testing.T) {
- if testing.Short() {
- t.Skip("skipping testing in short mode")
- }
- testStart(t, bitcoin)
-
- if err := testCommand("faucet", btcAddress, bitcoin); err != nil {
- t.Fatal(err)
- }
-
- testDelete(t)
-}
-
-func TestFaucetLiquidServices(t *testing.T) {
- if testing.Short() {
- t.Skip("skipping testing in short mode")
- }
- testStart(t, liquid)
-
- if err := testCommand("faucet", liquidAddress, liquid); err != nil {
- t.Fatal(err)
- }
-
- testDelete(t)
-}
-
-func TestFaucetShouldFail(t *testing.T) {
- if testing.Short() {
- t.Skip("skipping testing in short mode")
- }
- expectedError := constants.ErrNigiriNotRunning.Error()
-
- err := testCommand("faucet", btcAddress, bitcoin)
- if err == nil {
- t.Fatal("Should return error when Nigiri is stopped")
- }
- if err.Error() != expectedError {
- t.Fatalf("Expected error: %s, got: %s", expectedError, err)
- }
-
- err = testCommand("faucet", liquidAddress, liquid)
- if err == nil {
- t.Fatal("Should return error when Nigiri is stopped")
- }
- if err.Error() != expectedError {
- t.Fatalf("Expected error: %s, got: %s", expectedError, err)
- }
-}
-
-func TestStartBitcoinAndFaucetNigiriServicesShouldFail(t *testing.T) {
- if testing.Short() {
- t.Skip("skipping testing in short mode")
- }
- testStart(t, bitcoin)
-
- expectedError := constants.ErrNigiriLiquidNotEnabled.Error()
-
- err := testCommand("faucet", liquidAddress, liquid)
- if err == nil {
- t.Fatal("Should return error when trying logging liquid services if not running")
- }
-
- if err.Error() != expectedError {
- t.Fatalf("Expected error: %s, got: %s", expectedError, err)
- }
-
- testDelete(t)
-}
diff --git a/cli/cmd/flags.go b/cli/cmd/flags.go
deleted file mode 100644
index d48fb1d..0000000
--- a/cli/cmd/flags.go
+++ /dev/null
@@ -1,63 +0,0 @@
-package cmd
-
-import (
- "encoding/json"
- "os"
-
- log "github.com/sirupsen/logrus"
- "github.com/spf13/cobra"
- "github.com/vulpemventures/nigiri/cli/config"
- "github.com/vulpemventures/nigiri/cli/constants"
-)
-
-var (
- flagDatadir string
- flagNetwork string
- flagDelete bool
- flagAttachLiquid bool
- flagLiquidService bool
- flagEnv string
- flagRpcWallet string
-)
-
-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 for every network",
-}
-
-func init() {
- c := &config.Config{}
- viper := c.Viper()
- defaultDir := c.GetPath()
- defaultJSON, _ := json.Marshal(constants.DefaultEnv)
-
- RootCmd.PersistentFlags().StringVar(&flagDatadir, "datadir", defaultDir, "Set nigiri default directory")
- StartCmd.PersistentFlags().StringVar(&flagNetwork, "network", "regtest", "Set bitcoin network - regtest only for now")
- StartCmd.PersistentFlags().BoolVar(&flagAttachLiquid, "liquid", false, "Enable liquid sidechain")
- StartCmd.PersistentFlags().StringVar(&flagEnv, "env", string(defaultJSON), "Set compose env in JSON format")
- StopCmd.PersistentFlags().BoolVar(&flagDelete, "delete", false, "Stop and delete nigiri")
- LogsCmd.PersistentFlags().BoolVar(&flagLiquidService, "liquid", false, "Set to see logs of a liquid service")
- FaucetCmd.PersistentFlags().BoolVar(&flagLiquidService, "liquid", false, "Set to donate liquid btc")
- PushCmd.PersistentFlags().BoolVar(&flagLiquidService, "liquid", false, "Set to use liquid")
- RpcCmd.PersistentFlags().BoolVar(&flagLiquidService, "liquid", false, "Set to use liquid node")
- RpcCmd.PersistentFlags().StringVar(&flagRpcWallet, "rpcwallet", "", "rpcwallet to be used for node JSONRPC commands")
-
- RootCmd.AddCommand(StartCmd)
- RootCmd.AddCommand(StopCmd)
- RootCmd.AddCommand(LogsCmd)
- RootCmd.AddCommand(FaucetCmd)
- RootCmd.AddCommand(RpcCmd)
- RootCmd.AddCommand(MintCmd)
- RootCmd.AddCommand(PushCmd)
- RootCmd.AddCommand(VersionCmd)
-
- viper.BindPFlag(constants.Datadir, RootCmd.PersistentFlags().Lookup("datadir"))
- viper.BindPFlag(constants.Network, StartCmd.PersistentFlags().Lookup("network"))
- viper.BindPFlag(constants.AttachLiquid, StartCmd.PersistentFlags().Lookup("liquid"))
-
- cobra.OnInitialize(func() {
- log.SetOutput(os.Stdout)
- log.SetLevel(log.InfoLevel)
- })
-}
diff --git a/cli/cmd/logs.go b/cli/cmd/logs.go
deleted file mode 100644
index cd659af..0000000
--- a/cli/cmd/logs.go
+++ /dev/null
@@ -1,107 +0,0 @@
-package cmd
-
-import (
- "errors"
- "os"
- "os/exec"
-
- "github.com/vulpemventures/nigiri/cli/constants"
- "github.com/vulpemventures/nigiri/cli/controller"
-
- "github.com/spf13/cobra"
-)
-
-var logsDescription = "Check Service logs. Requires one Service: " + servicesList()
-
-var LogsCmd = &cobra.Command{
- Args: func(cmd *cobra.Command, args []string) error {
-
- if len(args) != 1 {
- return errors.New(logsDescription)
- }
- _, found := controller.Services[args[0]]
- if !found {
- return errors.New(logsDescription)
- }
- return nil
- },
- Use: "logs ",
- Short: logsDescription,
- Long: logsDescription,
- RunE: logs,
- PreRunE: logsChecks,
-}
-
-func servicesList() string {
- var servicesString string
- for key, _ := range controller.Services {
- servicesString += key
- servicesString += " | "
- }
- return servicesString[:len(servicesString)-3]
-}
-
-func logsChecks(cmd *cobra.Command, args []string) error {
- datadir, _ := cmd.Flags().GetString("datadir")
- isLiquidService, _ := cmd.Flags().GetBool("liquid")
-
- ctl, err := controller.NewController()
- if err != nil {
- return err
- }
-
- if err := ctl.ParseDatadir(datadir); err != nil {
- return err
- }
- if len(args) != 1 {
- return constants.ErrInvalidArgs
- }
-
- service := args[0]
- if err := ctl.ParseServiceName(service); err != nil {
- return err
- }
-
- if isRunning, err := ctl.IsNigiriRunning(); err != nil {
- return err
- } else if !isRunning {
- return constants.ErrNigiriNotRunning
- }
-
- if err := ctl.ReadConfigFile(datadir); err != nil {
- return err
- }
-
- if isLiquidService && isLiquidService != ctl.GetConfigBoolField(constants.AttachLiquid) {
- return constants.ErrNigiriLiquidNotEnabled
- }
-
- return nil
-}
-
-func logs(cmd *cobra.Command, args []string) error {
- service := args[0]
- datadir, _ := cmd.Flags().GetString("datadir")
- isLiquidService, _ := cmd.Flags().GetBool("liquid")
-
- ctl, err := controller.NewController()
- if err != nil {
- return err
- }
-
- serviceName := ctl.GetServiceName(service, isLiquidService)
- composePath := ctl.GetResourcePath(datadir, "compose")
- envPath := ctl.GetResourcePath(datadir, "env")
- env := ctl.LoadComposeEnvironment(envPath)
-
- bashCmd := exec.Command("docker-compose", "-f", composePath, "logs", serviceName)
- bashCmd.Stdout = os.Stdout
- bashCmd.Stderr = os.Stderr
- bashCmd.Env = env
-
- if err := bashCmd.Run(); err != nil {
- return err
- }
-
- return nil
-}
diff --git a/cli/cmd/logs_test.go b/cli/cmd/logs_test.go
deleted file mode 100644
index 36b06cf..0000000
--- a/cli/cmd/logs_test.go
+++ /dev/null
@@ -1,84 +0,0 @@
-package cmd
-
-import (
- "testing"
-
- "github.com/vulpemventures/nigiri/cli/constants"
-)
-
-var (
- serviceList = []string{"node", "electrs", "esplora", "chopsticks"}
-)
-
-func TestLogBitcoinServices(t *testing.T) {
- if err := testCommand("start", "", bitcoin); err != nil {
- t.Fatal(err)
- }
-
- for _, service := range serviceList {
- if err := testCommand("logs", service, bitcoin); err != nil {
- t.Fatal(err)
- }
- }
-
- if err := testCommand("stop", "", delete); err != nil {
- t.Fatal(err)
- }
-}
-
-func TestLogLiquidServices(t *testing.T) {
- if err := testCommand("start", "", liquid); err != nil {
- t.Fatal(err)
- }
-
- for _, service := range serviceList {
- if err := testCommand("logs", service, liquid); err != nil {
- t.Fatal(err)
- }
- }
-
- if err := testCommand("stop", "", delete); err != nil {
- t.Fatal(err)
- }
-}
-
-func TestLogShouldFail(t *testing.T) {
- expectedError := constants.ErrNigiriNotRunning.Error()
-
- err := testCommand("logs", serviceList[0], bitcoin)
- if err == nil {
- t.Fatal("Should return error when Nigiri is stopped")
- }
- if err.Error() != expectedError {
- t.Fatalf("Expected error: %s, got: %s", expectedError, err)
- }
-
- err = testCommand("logs", serviceList[0], liquid)
- if err == nil {
- t.Fatal("Should return error when Nigiri is stopped")
- }
- if err.Error() != expectedError {
- t.Fatalf("Expected error: %s, got: %s", expectedError, err)
- }
-}
-
-func TestStartBitcoinAndLogNigiriServicesShouldFail(t *testing.T) {
- if err := testCommand("start", "", bitcoin); err != nil {
- t.Fatal(err)
- }
-
- expectedError := constants.ErrNigiriLiquidNotEnabled.Error()
-
- err := testCommand("logs", serviceList[0], liquid)
- if err == nil {
- t.Fatal("Should return error when trying logging liquid services if not running")
- }
-
- if err.Error() != expectedError {
- t.Fatalf("Expected error: %s, got: %s", expectedError, err)
- }
-
- if err := testCommand("stop", "", delete); err != nil {
- t.Fatal(err)
- }
-}
diff --git a/cli/cmd/mint.go b/cli/cmd/mint.go
deleted file mode 100644
index a2fdf5a..0000000
--- a/cli/cmd/mint.go
+++ /dev/null
@@ -1,121 +0,0 @@
-package cmd
-
-import (
- "bytes"
- "encoding/json"
- "errors"
- "fmt"
- "io/ioutil"
- "net/http"
- "strconv"
-
- "github.com/spf13/cobra"
- "github.com/vulpemventures/nigiri/cli/constants"
- "github.com/vulpemventures/nigiri/cli/controller"
-)
-
-var MintCmd = &cobra.Command{
- Use: "mint [name] [ticker]",
- Short: "Liquid only: Issue and send a given quantity of an asset",
- RunE: mint,
- PreRunE: mintChecks,
-}
-
-func mintChecks(cmd *cobra.Command, args []string) error {
- datadir, _ := cmd.Flags().GetString("datadir")
-
- ctl, err := controller.NewController()
- if err != nil {
- return err
- }
-
- if err := ctl.ParseDatadir(datadir); err != nil {
- return err
- }
- if len(args) < 2 {
- return errors.New("missing required arguments")
- }
-
- if isRunning, err := ctl.IsNigiriRunning(); err != nil {
- return err
- } else if !isRunning {
- return constants.ErrNigiriNotRunning
- }
-
- if err := ctl.ReadConfigFile(datadir); err != nil {
- return err
- }
-
- if ctl.GetConfigBoolField(constants.AttachLiquid) != true {
- return constants.ErrNigiriLiquidNotEnabled
- }
-
- return nil
-}
-
-func mint(cmd *cobra.Command, args []string) error {
- datadir, _ := cmd.Flags().GetString("datadir")
-
- var request struct {
- Address string `json:"address"`
- Quantity int `json:"quantity"`
- Name string `json:"name"`
- Ticker string `json:"ticker"`
- }
- request.Address = args[0]
- request.Quantity, _ = strconv.Atoi(args[1])
- if len(args) >= 3 {
- request.Name = args[2]
- }
- if len(args) == 4 {
- request.Ticker = args[3]
- }
-
- ctl, err := controller.NewController()
- if err != nil {
- return err
- }
- envPath := ctl.GetResourcePath(datadir, "env")
- env, _ := ctl.ReadComposeEnvironment(envPath)
- envPorts := env["ports"].(map[string]map[string]int)
- requestPort := envPorts["liquid"]["chopsticks"]
-
- payload, err := json.Marshal(request)
- if err != nil {
- return err
- }
- res, err := http.Post("http://127.0.0.1:"+strconv.Itoa(requestPort)+"/mint", "application/json", bytes.NewBuffer(payload))
- if err != nil {
- return err
- }
-
- data, err := ioutil.ReadAll(res.Body)
- if err != nil {
- return err
- }
- if res.StatusCode != http.StatusOK {
- return errors.New(string(data))
- }
- var dat map[string]interface{}
- var resp string
- if err := json.Unmarshal([]byte(data), &dat); err != nil {
- return errors.New("Internal error. Try again.")
- }
- if dat["txId"] == "" {
- return errors.New("Not Successful")
- }
- for key, element := range dat {
- if key == "issuance_txin" {
- myMap := element.(map[string]interface{})
- resp += key + ":\n"
- for key2, element2 := range myMap {
- resp += " "
- resp += key2 + ": " + fmt.Sprintf("%v", element2) + "\n"
- }
- continue
- }
- resp += key + ": " + fmt.Sprintf("%v", element) + "\n"
- }
- fmt.Println(resp[:len(resp)-1])
- return nil
-}
diff --git a/cli/cmd/mint_test.go b/cli/cmd/mint_test.go
deleted file mode 100644
index 5ef2031..0000000
--- a/cli/cmd/mint_test.go
+++ /dev/null
@@ -1,66 +0,0 @@
-package cmd
-
-import (
- "testing"
-
- "github.com/vulpemventures/nigiri/cli/constants"
-)
-
-func TestMintOneArg(t *testing.T) {
- if testing.Short() {
- t.Skip("skipping testing in short mode")
- }
- testStart(t, liquid)
-
- if err := testCommand("mint", "ert1q90dz89u8eudeswzynl3p2jke564ejc2cnfcwuq 1000", liquid); err != nil {
- t.Fatal(err)
- }
-
- testDelete(t)
-}
-
-func TestMintTwoArgs(t *testing.T) {
- if testing.Short() {
- t.Skip("skipping testing in short mode")
- }
- testStart(t, liquid)
-
- if err := testCommand("mint", "ert1q90dz89u8eudeswzynl3p2jke564ejc2cnfcwuq 2000 Test", liquid); err != nil {
- t.Fatal(err)
- }
-
- testDelete(t)
-}
-
-func TestMintThreeArgs(t *testing.T) {
- if testing.Short() {
- t.Skip("skipping testing in short mode")
- }
- testStart(t, liquid)
-
- if err := testCommand("mint", "ert1q90dz89u8eudeswzynl3p2jke564ejc2cnfcwuq 3000 TEST TST", liquid); err != nil {
- t.Fatal(err)
- }
- testDelete(t)
-
-}
-
-func TestStartBitcoinAndMintShouldFail(t *testing.T) {
- if testing.Short() {
- t.Skip("skipping testing in short mode")
- }
- testStart(t, bitcoin)
-
- expectedError := constants.ErrNigiriLiquidNotEnabled.Error()
-
- err := testCommand("mint", "ert1q90dz89u8eudeswzynl3p2jke564ejc2cnfcwuq 1000", liquid)
- if err == nil {
- t.Fatal("Should return error when trying logging liquid services if not running")
- }
-
- if err.Error() != expectedError {
- t.Fatalf("Expected error: %s, got: %s", expectedError, err)
- }
-
- testDelete(t)
-}
diff --git a/cli/cmd/push.go b/cli/cmd/push.go
deleted file mode 100644
index bec8bdb..0000000
--- a/cli/cmd/push.go
+++ /dev/null
@@ -1,99 +0,0 @@
-package cmd
-
-import (
- "bytes"
- "errors"
- "fmt"
- "io/ioutil"
- "net/http"
- "strconv"
-
- "github.com/spf13/cobra"
- "github.com/vulpemventures/nigiri/cli/constants"
- "github.com/vulpemventures/nigiri/cli/controller"
-)
-
-var PushCmd = &cobra.Command{
- Args: func(cmd *cobra.Command, args []string) error {
-
- if len(args) != 1 {
- return errors.New("Missing hex encoded transaction")
- }
- return nil
- },
- Use: "push ",
- Short: "Broadcast raw transaction",
- RunE: push,
- PreRunE: pushChecks,
-}
-
-func pushChecks(cmd *cobra.Command, args []string) error {
- datadir, _ := cmd.Flags().GetString("datadir")
- isLiquidService, _ := cmd.Flags().GetBool("liquid")
-
- ctl, err := controller.NewController()
- if err != nil {
- return err
- }
-
- if err := ctl.ParseDatadir(datadir); err != nil {
- return err
- }
- if len(args) != 1 {
- return constants.ErrInvalidArgs
- }
-
- if isRunning, err := ctl.IsNigiriRunning(); err != nil {
- return err
- } else if !isRunning {
- return constants.ErrNigiriNotRunning
- }
-
- if err := ctl.ReadConfigFile(datadir); err != nil {
- return err
- }
-
- if isLiquidService && isLiquidService != ctl.GetConfigBoolField(constants.AttachLiquid) {
- return constants.ErrNigiriLiquidNotEnabled
- }
-
- return nil
-}
-
-func push(cmd *cobra.Command, args []string) error {
- isLiquidService, err := cmd.Flags().GetBool("liquid")
- datadir, _ := cmd.Flags().GetString("datadir")
- if err != nil {
- return err
- }
- request := args[0]
- ctl, err := controller.NewController()
- if err != nil {
- return err
- }
- envPath := ctl.GetResourcePath(datadir, "env")
- env, _ := ctl.ReadComposeEnvironment(envPath)
- envPorts := env["ports"].(map[string]map[string]int)
- requestPort := envPorts["bitcoin"]["chopsticks"]
- if isLiquidService {
- requestPort = envPorts["liquid"]["chopsticks"]
- }
- hex := []byte(request)
- res, err := http.Post("http://127.0.0.1:"+strconv.Itoa(requestPort)+"/tx", "application/string", bytes.NewBuffer(hex))
- if err != nil {
- return err
- }
- data, err := ioutil.ReadAll(res.Body)
- if err != nil {
- return err
- }
- if res.StatusCode != http.StatusOK {
- return errors.New(string(data))
- }
-
- if string(data) == "" {
- return errors.New("Not Successful")
- }
- fmt.Println("\ntxId: " + string(data))
- return nil
-}
diff --git a/cli/cmd/push_test.go b/cli/cmd/push_test.go
deleted file mode 100644
index 0b913b4..0000000
--- a/cli/cmd/push_test.go
+++ /dev/null
@@ -1,167 +0,0 @@
-package cmd
-
-import (
- "encoding/json"
- "errors"
- "fmt"
- "os/exec"
- "strconv"
- "strings"
- "testing"
-)
-
-/* func TestPushBitcoinTransaction(t *testing.T) {
- if testing.Short() {
- t.Skip("skipping testing in short mode")
- }
- testStart(t, bitcoin)
- hex, err := getNewSignedTransaction(bitcoin)
- if err != nil {
- t.Fatal(err)
- }
- if err := testCommand("push", hex, bitcoin); err != nil {
- t.Fatal(err)
- }
- testDelete(t)
-} */
-
-func TestPushLiquidTransaction(t *testing.T) {
- if testing.Short() {
- t.Skip("skipping testing in short mode")
- }
- testStart(t, liquid)
- hex, err := getNewSignedTransaction(liquid)
- if err != nil {
- t.Fatal(err)
- }
- if err := testCommand("push", hex, liquid); err != nil {
- t.Fatal(err)
- }
- testDelete(t)
-}
-
-func getNewSignedTransaction(isLiquid bool) (string, error) {
- txId, vout, amount, asset, err := listUnspent(isLiquid)
- if err != nil {
- return "", err
- }
- hex, err := createRawTransaction(txId, vout, amount, asset, isLiquid)
- if err != nil {
- return "", err
- }
- hexFinal, err := signRawTransaction(hex, isLiquid)
- if err != nil {
- return "", err
- }
- return hexFinal, nil
-}
-
-func listUnspent(isLiquid bool) (string, string, string, string, error) {
- bashCmd, err := execCommand([]string{"listunspent"}, isLiquid)
- if err != nil {
- return "", "", "", "", err
- }
- type unspent map[string]interface{}
- var unspentList []unspent
- if err := json.Unmarshal([]byte(bashCmd), &unspentList); err != nil {
- return "", "", "", "", errors.New("Internal error. Try again.")
- }
- txId := fmt.Sprintf("%v", unspentList[0]["txid"])
- vout := fmt.Sprintf("%v", unspentList[0]["vout"])
- amount := fmt.Sprintf("%v", unspentList[0]["amount"])
- asset := ""
- if isLiquid {
- asset = fmt.Sprintf("%v", unspentList[0]["asset"])
- }
- return txId, vout, amount, asset, nil
-}
-
-func createRawTransaction(txId string, vout string, amount string, asset string, isLiquid bool) (string, error) {
- type inputs map[string]interface{}
- var inputsList [1]inputs
- voutInt, err := strconv.Atoi(vout)
- if err != nil {
- return "", err
- }
- inputsList[0] = make(inputs, 2)
- inputsList[0]["txid"] = txId
- inputsList[0]["vout"] = voutInt
- inputsJson, err := json.Marshal(inputsList)
- if err != nil {
- return "", err
- }
- fee := 0.00001
- amountInt, err := strconv.ParseFloat(amount, 64)
- if err != nil {
- return "", err
- }
- amountSend := fmt.Sprintf("%.6f", amountInt-fee)
- sendAdress, err := execCommand([]string{"getnewaddress"}, isLiquid)
- sendAdressString := string(sendAdress)
- if err != nil {
- return "", err
- }
- outputs := make(map[string]interface{})
- if isLiquid {
- addressInfoJson, err := execCommand([]string{"getaddressinfo", string(sendAdress)}, isLiquid)
- if err != nil {
- return "", err
- }
- var adressInfo map[string]interface{}
- if err := json.Unmarshal([]byte(addressInfoJson), &adressInfo); err != nil {
- return "", errors.New("Internal error. Try again.")
- }
- sendAdressString = fmt.Sprintf("%v", adressInfo["unconfidential"])
- outputs["fee"] = fee
- }
- outputs[sendAdressString], err = strconv.ParseFloat(amountSend, 64)
- if err != nil {
- return "", err
- }
- outputsJson, err := json.Marshal(outputs)
- if err != nil {
- return "", err
- }
- commandArgs := []string{"createrawtransaction", string(inputsJson), string(outputsJson)}
- if isLiquid {
- output_assets := make(map[string]interface{})
- output_assets[sendAdressString] = asset
- output_assets["fee"] = asset
- output_assetsJson, err := json.Marshal(output_assets)
- if err != nil {
- return "", err
- }
- commandArgs = append(commandArgs, []string{"0", "false", string(output_assetsJson)}...)
- }
- bashCmd, err := execCommand(commandArgs, isLiquid)
- if err != nil {
- return "", err
- }
- return strings.Fields(string(bashCmd))[0], nil
-}
-
-func signRawTransaction(hex string, isLiquid bool) (string, error) {
- bashCmd, err := execCommand([]string{"signrawtransactionwithwallet", hex}, isLiquid)
- if err != nil {
- return "", err
- }
- var hexJson map[string]interface{}
- if err := json.Unmarshal([]byte(bashCmd), &hexJson); err != nil {
- return "", errors.New("Internal error. Try again.")
- }
- hex = fmt.Sprintf("%v", hexJson["hex"])
- return hex, nil
-}
-
-func execCommand(args []string, isLiquid bool) ([]byte, error) {
- rpcArgs := []string{"exec", "bitcoin", "bitcoin-cli", "-datadir=config"}
- if isLiquid {
- rpcArgs = []string{"exec", "liquid", "elements-cli", "-datadir=config"}
- }
- cmdArgs := append(rpcArgs, args...)
- bashCmd, err := exec.Command("docker", cmdArgs...).Output()
- if err != nil {
- return nil, err
- }
- return bashCmd, nil
-}
diff --git a/cli/cmd/rpc.go b/cli/cmd/rpc.go
deleted file mode 100644
index 0c7860a..0000000
--- a/cli/cmd/rpc.go
+++ /dev/null
@@ -1,77 +0,0 @@
-package cmd
-
-import (
- "os"
- "os/exec"
-
- "github.com/spf13/cobra"
- "github.com/vulpemventures/nigiri/cli/constants"
- "github.com/vulpemventures/nigiri/cli/controller"
-)
-
-var RpcCmd = &cobra.Command{
- Use: "rpc ",
- Short: "Invoke the bitcoin-cli or elements-cli",
- RunE: rpc,
- PreRunE: rpcChecks,
-}
-
-func rpcChecks(cmd *cobra.Command, args []string) error {
- datadir, _ := cmd.Flags().GetString("datadir")
- isLiquidService, _ := cmd.Flags().GetBool("liquid")
-
- ctl, err := controller.NewController()
- if err != nil {
- return err
- }
-
- if err := ctl.ParseDatadir(datadir); err != nil {
- return err
- }
-
- if isRunning, err := ctl.IsNigiriRunning(); err != nil {
- return err
- } else if !isRunning {
- return constants.ErrNigiriNotRunning
- }
-
- if err := ctl.ReadConfigFile(datadir); err != nil {
- return err
- }
-
- if isLiquidService && isLiquidService != ctl.GetConfigBoolField(constants.AttachLiquid) {
- return constants.ErrNigiriLiquidNotEnabled
- }
-
- return nil
-}
-
-func rpc(cmd *cobra.Command, args []string) error {
- datadir, _ := cmd.Flags().GetString("datadir")
- isLiquidService, _ := cmd.Flags().GetBool("liquid")
- rpcWallet, _ := cmd.Flags().GetString("rpcwallet")
-
- ctl, err := controller.NewController()
- if err != nil {
- return err
- }
-
- envPath := ctl.GetResourcePath(datadir, "env")
- env := ctl.LoadComposeEnvironment(envPath)
-
- rpcArgs := []string{"exec", "bitcoin", "bitcoin-cli", "-datadir=config", "-rpcwallet=" + rpcWallet}
- if isLiquidService {
- rpcArgs = []string{"exec", "liquid", "elements-cli", "-datadir=config", "-rpcwallet=" + rpcWallet}
- }
- cmdArgs := append(rpcArgs, args...)
- bashCmd := exec.Command("docker", cmdArgs...)
- bashCmd.Stdout = os.Stdout
- bashCmd.Stderr = os.Stderr
- bashCmd.Env = env
-
- if err := bashCmd.Run(); err != nil {
- return err
- }
-
- return nil
-}
diff --git a/cli/cmd/rpc_test.go b/cli/cmd/rpc_test.go
deleted file mode 100644
index 56cb942..0000000
--- a/cli/cmd/rpc_test.go
+++ /dev/null
@@ -1,102 +0,0 @@
-package cmd
-
-import (
- "testing"
-
- "github.com/vulpemventures/nigiri/cli/constants"
-)
-
-func TestRpcBitcoinCommand(t *testing.T) {
- if testing.Short() {
- t.Skip("skipping testing in short mode")
- }
- testStart(t, bitcoin)
-
- if err := testCommand("rpc", "getblockchaininfo", bitcoin); err != nil {
- t.Fatal(err)
- }
-
- testDelete(t)
-}
-
-func TestRpcBitcoinTwoCommands(t *testing.T) {
- if testing.Short() {
- t.Skip("skipping testing in short mode")
- }
- testStart(t, bitcoin)
-
- if err := testCommand("rpc", "getblockhash 0", bitcoin); err != nil {
- t.Fatal(err)
- }
-
- testDelete(t)
-}
-
-func TestRpcLiquidCommand(t *testing.T) {
- if testing.Short() {
- t.Skip("skipping testing in short mode")
- }
- testStart(t, liquid)
-
- if err := testCommand("rpc", "getblockchaininfo", liquid); err != nil {
- t.Fatal(err)
- }
-
- testDelete(t)
-}
-
-func TestRpcLiquidTwoCommands(t *testing.T) {
- if testing.Short() {
- t.Skip("skipping testing in short mode")
- }
- testStart(t, liquid)
-
- if err := testCommand("rpc", "getblockhash 0", liquid); err != nil {
- t.Fatal(err)
- }
-
- testDelete(t)
-}
-
-func TestRpcShouldFail(t *testing.T) {
- if testing.Short() {
- t.Skip("skipping testing in short mode")
- }
- expectedError := constants.ErrNigiriNotRunning.Error()
-
- err := testCommand("rpc", "getblockchaininfo", bitcoin)
- if err == nil {
- t.Fatal("Should return error when Nigiri is stopped")
- }
- if err.Error() != expectedError {
- t.Fatalf("Expected error: %s, got: %s", expectedError, err)
- }
-
- err = testCommand("rpc", "getblockchaininfo", liquid)
- if err == nil {
- t.Fatal("Should return error when Nigiri is stopped")
- }
- if err.Error() != expectedError {
- t.Fatalf("Expected error: %s, got: %s", expectedError, err)
- }
-}
-
-func TestStartBitcoinAndRpcNigiriServicesShouldFail(t *testing.T) {
- if testing.Short() {
- t.Skip("skipping testing in short mode")
- }
- testStart(t, bitcoin)
-
- expectedError := constants.ErrNigiriLiquidNotEnabled.Error()
-
- err := testCommand("rpc", "getblockchaininfo", liquid)
- if err == nil {
- t.Fatal("Should return error when trying logging liquid services if not running")
- }
-
- if err.Error() != expectedError {
- t.Fatalf("Expected error: %s, got: %s", expectedError, err)
- }
-
- testDelete(t)
-}
diff --git a/cli/cmd/start.go b/cli/cmd/start.go
deleted file mode 100644
index 4883868..0000000
--- a/cli/cmd/start.go
+++ /dev/null
@@ -1,136 +0,0 @@
-package cmd
-
-import (
- "fmt"
- "os"
- "os/exec"
- "strings"
-
- "github.com/spf13/cobra"
- "github.com/vulpemventures/nigiri/cli/constants"
- "github.com/vulpemventures/nigiri/cli/controller"
-)
-
-var StartCmd = &cobra.Command{
- Use: "start",
- Short: "Build and start Nigiri",
- RunE: start,
- PreRunE: startChecks,
-}
-
-func startChecks(cmd *cobra.Command, args []string) error {
- network, _ := cmd.Flags().GetString("network")
- datadir, _ := cmd.Flags().GetString("datadir")
- env, _ := cmd.Flags().GetString("env")
-
- ctl, err := controller.NewController()
- if err != nil {
- return err
- }
-
- if err := ctl.ParseNetwork(network); err != nil {
- return err
- }
-
- if err := ctl.ParseDatadir(datadir); err != nil {
- return err
- }
- composeEnv, err := ctl.ParseEnv(env)
- if err != nil {
- return err
- }
-
- // if nigiri is already running return error
- if isRunning, err := ctl.IsNigiriRunning(); err != nil {
- return err
- } else if isRunning {
- return constants.ErrNigiriAlreadyRunning
- }
-
- // scratch datadir if not exists
- if err := os.MkdirAll(datadir, 0755); err != nil {
- return err
- }
-
- // if datadir is set we must copy the resources directory from ~/.nigiri
- // to the new one
- if datadir != ctl.GetDefaultDatadir() {
- if err := ctl.NewDatadirFromDefault(datadir); err != nil {
- return err
- }
- }
-
- // if nigiri not exists, we need to write the configuration file and then
- // read from it to get viper updated, otherwise we just read from it.
- if isStopped, err := ctl.IsNigiriStopped(); err != nil {
- return err
- } else if isStopped {
- if err := ctl.ReadConfigFile(datadir); err != nil {
- return err
- }
- } else {
- filedir := ctl.GetResourcePath(datadir, "config")
- if err := ctl.WriteConfigFile(filedir); err != nil {
- return err
- }
- // .env must be in the directory where docker-compose is run from, not where YAML files are placed
- // https://docs.docker.com/compose/env-file/
- filedir = ctl.GetResourcePath(datadir, "env")
- if err := ctl.WriteComposeEnvironment(filedir, composeEnv); err != nil {
- return err
- }
- }
-
- return nil
-}
-
-func start(cmd *cobra.Command, args []string) error {
- ctl, err := controller.NewController()
- if err != nil {
- return err
- }
-
- datadir, _ := cmd.Flags().GetString("datadir")
- liquidEnabled := ctl.GetConfigBoolField(constants.AttachLiquid)
-
- envPath := ctl.GetResourcePath(datadir, "env")
- composePath := ctl.GetResourcePath(datadir, "compose")
-
- bashCmd := exec.Command("docker-compose", "-f", composePath, "up", "-d")
- if isStopped, err := ctl.IsNigiriStopped(); err != nil {
- return err
- } else if isStopped {
- bashCmd = exec.Command("docker-compose", "-f", composePath, "start")
- }
- bashCmd.Stdout = os.Stdout
- bashCmd.Stderr = os.Stderr
- bashCmd.Env = ctl.LoadComposeEnvironment(envPath)
-
- if err := bashCmd.Run(); err != nil {
- return err
- }
-
- path := ctl.GetResourcePath(datadir, "env")
- env, err := ctl.ReadComposeEnvironment(path)
- if err != nil {
- return err
- }
-
- prettyPrintServices := func(chain string, services map[string]int) {
- fmt.Printf("%s services:\n", strings.Title(chain))
- for name, port := range services {
- formatName := fmt.Sprintf("%s:", name)
- fmt.Printf(" %-14s localhost:%d\n", formatName, port)
- }
- }
-
- for chain, services := range env["ports"].(map[string]map[string]int) {
- if chain == "bitcoin" {
- prettyPrintServices(chain, services)
- } else if liquidEnabled {
- prettyPrintServices(chain, services)
- }
- }
-
- return nil
-}
diff --git a/cli/cmd/start_stop_test.go b/cli/cmd/start_stop_test.go
deleted file mode 100644
index 43acf54..0000000
--- a/cli/cmd/start_stop_test.go
+++ /dev/null
@@ -1,185 +0,0 @@
-package cmd
-
-import (
- "fmt"
- "strings"
- "testing"
- "time"
-
- "github.com/vulpemventures/nigiri/cli/constants"
- "github.com/vulpemventures/nigiri/cli/controller"
-)
-
-const (
- liquid = true
- bitcoin = false
- delete = true
-)
-
-var (
- stopCmd = []string{"stop"}
- // deleteCmd = append(stopCmd, "--delete")
- startCmd = []string{"start"}
- // liquidStartCmd = append(startCmd, "--liquid")
-)
-
-func TestStartStopLiquid(t *testing.T) {
- // Start/Stop
- testStart(t, liquid)
- testStop(t)
- // Start/Delete
- testStart(t, liquid)
- testDelete(t)
-}
-
-func TestStartStopBitcoin(t *testing.T) {
- // Start/Stop
- testStart(t, bitcoin)
- testStop(t)
- // Start/Delete
- testStart(t, bitcoin)
- testDelete(t)
-}
-
-func TestStopBeforeStartShouldFail(t *testing.T) {
- expectedError := constants.ErrNigiriNotRunning.Error()
-
- err := testCommand("stop", "", !delete)
- if err == nil {
- t.Fatal("Should return error when trying to stop before starting")
- }
- if err.Error() != expectedError {
- t.Fatalf("Expected error: %s, got: %s", expectedError, err)
- }
-
- expectedError = constants.ErrNigiriNotExisting.Error()
- err = testCommand("stop", "", delete)
- if err == nil {
- t.Fatal("Should return error when trying to delete before starting")
- }
- if err.Error() != expectedError {
- t.Fatalf("Expected error: %s, got: %s", expectedError, err)
- }
-}
-
-func TestStartAfterStartShouldFail(t *testing.T) {
- expectedError := constants.ErrNigiriAlreadyRunning.Error()
-
- if err := testCommand("start", "", bitcoin); err != nil {
- t.Fatal(err)
- }
-
- err := testCommand("start", "", bitcoin)
- if err == nil {
- t.Fatal("Should return error when trying to start Nigiri if already started")
- }
- if err.Error() != expectedError {
- t.Fatalf("Expected error: %s, got: %s", expectedError, err)
- }
-
- err = testCommand("start", "", liquid)
- if err == nil {
- t.Fatal("Should return error when trying to start Nigiri if already started")
- }
- if err.Error() != expectedError {
- t.Fatalf("Expected error: %s, got: %s", expectedError, err)
- }
-
- if err := testCommand("stop", "", delete); err != nil {
- t.Fatal(err)
- }
-}
-
-func testStart(t *testing.T, flag bool) {
- ctl, err := controller.NewController()
- if err != nil {
- t.Fatal(err)
- }
- if err := testCommand("start", "", flag); err != nil {
- t.Fatal(err)
- }
- //Give some time to nigiri to be ready before calling
- time.Sleep(5 * time.Second)
- if isRunning, err := ctl.IsNigiriRunning(); err != nil {
- t.Fatal(err)
- } else if !isRunning {
- t.Fatal("Nigiri should have been started but services have not been found among running containers")
- }
-}
-
-func testStop(t *testing.T) {
- ctl, err := controller.NewController()
- if err != nil {
- t.Fatal(err)
- }
- if err := testCommand("stop", "", !delete); err != nil {
- t.Fatal(err)
- }
- //Give some time to nigiri to be ready before calling
- time.Sleep(5 * time.Second)
- if isStopped, err := ctl.IsNigiriStopped(); err != nil {
- t.Fatal(err)
- } else if !isStopped {
- t.Fatal("Nigiri should have been stopped but services have not been found among stopped containers")
- }
-}
-
-func testDelete(t *testing.T) {
- ctl, err := controller.NewController()
- if err != nil {
- t.Fatal(err)
- }
-
- if err := testCommand("stop", "", delete); err != nil {
- t.Fatal(err)
- }
- if isStopped, err := ctl.IsNigiriStopped(); err != nil {
- t.Fatal(err)
- } else if isStopped {
- t.Fatal("Nigiri should have been terminated at this point but services have been found among stopped containers")
- }
-}
-
-func testCommand(command, arg string, flag bool) error {
- cmd := RootCmd
- cmd.SetArgs(nil)
-
- if command == "start" {
- args := append(startCmd, fmt.Sprintf("--liquid=%t", flag))
- cmd.SetArgs(args)
- }
- if command == "stop" {
- args := append(stopCmd, fmt.Sprintf("--delete=%t", flag))
- cmd.SetArgs(args)
- }
- if command == "logs" {
- logsCmd := []string{command, arg, fmt.Sprintf("--liquid=%t", flag)}
- cmd.SetArgs(logsCmd)
- }
- if command == "faucet" {
- faucetCmd := []string{command, arg, fmt.Sprintf("--liquid=%t", flag)}
- cmd.SetArgs(faucetCmd)
- }
- if command == "rpc" {
- logsCmd := []string{command, fmt.Sprintf("--liquid=%t", flag)}
- args := strings.Fields(arg)
- logsCmd = append(logsCmd, args...)
- cmd.SetArgs(logsCmd)
- }
- if command == "mint" {
- logsCmd := []string{command}
- args := strings.Fields(arg)
- logsCmd = append(logsCmd, args...)
- cmd.SetArgs(logsCmd)
- }
- if command == "push" {
- pushCmd := []string{command, arg, fmt.Sprintf("--liquid=%t", flag)}
- cmd.SetArgs(pushCmd)
- }
-
- if err := cmd.Execute(); err != nil {
- return err
- }
-
- return nil
-}
diff --git a/cli/cmd/stop.go b/cli/cmd/stop.go
deleted file mode 100644
index b915727..0000000
--- a/cli/cmd/stop.go
+++ /dev/null
@@ -1,103 +0,0 @@
-package cmd
-
-import (
- "fmt"
- "os"
- "os/exec"
-
- "github.com/spf13/cobra"
- "github.com/vulpemventures/nigiri/cli/constants"
- "github.com/vulpemventures/nigiri/cli/controller"
-)
-
-var StopCmd = &cobra.Command{
- Use: "stop",
- Short: "Stop and/or delete nigiri",
- RunE: stop,
- PreRunE: stopChecks,
-}
-
-func stopChecks(cmd *cobra.Command, args []string) error {
- datadir, _ := cmd.Flags().GetString("datadir")
- delete, _ := cmd.Flags().GetBool("delete")
-
- ctl, err := controller.NewController()
- if err != nil {
- return err
- }
-
- if err := ctl.ParseDatadir(datadir); err != nil {
- return err
- }
-
- if _, err := os.Stat(datadir); os.IsNotExist(err) {
- return constants.ErrDatadirNotExisting
- }
-
- if isRunning, err := ctl.IsNigiriRunning(); err != nil {
- return err
- } else if !isRunning {
- if delete {
- if isStopped, err := ctl.IsNigiriStopped(); err != nil {
- return err
- } else if !isStopped {
- return constants.ErrNigiriNotExisting
- }
- } else {
- return constants.ErrNigiriNotRunning
- }
- }
-
- if err := ctl.ReadConfigFile(datadir); err != nil {
- return err
- }
- return nil
-}
-
-func stop(cmd *cobra.Command, args []string) error {
- delete, _ := cmd.Flags().GetBool("delete")
- datadir, _ := cmd.Flags().GetString("datadir")
-
- ctl, err := controller.NewController()
- if err != nil {
- return err
- }
-
- composePath := ctl.GetResourcePath(datadir, "compose")
- configPath := ctl.GetResourcePath(datadir, "config")
- envPath := ctl.GetResourcePath(datadir, "env")
- env := ctl.LoadComposeEnvironment(envPath)
-
- bashCmd := exec.Command("docker-compose", "-f", composePath, "stop")
- if delete {
- bashCmd = exec.Command("docker-compose", "-f", composePath, "down")
- }
- bashCmd.Stdout = os.Stdout
- bashCmd.Stderr = os.Stderr
- bashCmd.Env = env
-
- if err := bashCmd.Run(); err != nil {
- return err
- }
-
- if delete {
- fmt.Println("Removing data from volumes...")
- if err := ctl.CleanResourceVolumes(datadir); err != nil {
- return err
- }
-
- fmt.Println("Removing configuration file...")
- if err := os.Remove(configPath); err != nil {
- return err
- }
-
- fmt.Println("Removing environmet file...")
- if err := os.Remove(envPath); err != nil {
- return err
- }
-
- fmt.Println("Nigiri has been cleaned up successfully.")
- }
-
- return nil
-}
diff --git a/cli/cmd/version.go b/cli/cmd/version.go
deleted file mode 100644
index 3b6a226..0000000
--- a/cli/cmd/version.go
+++ /dev/null
@@ -1,25 +0,0 @@
-package cmd
-
-import (
- "fmt"
-
- "github.com/spf13/cobra"
-)
-
-var (
- version = "dev"
- commit = "none"
- date = "unknown"
- VersionCmd = &cobra.Command{
- Use: "version",
- Short: "Show the current version",
- RunE: versionFunc,
- }
-)
-
-func versionFunc(cmd *cobra.Command, address []string) error {
- fmt.Println("Version: " + version)
- fmt.Println("Commit: " + commit)
- fmt.Println("Date: " + date)
- return nil
-}
diff --git a/cli/config/main.go b/cli/config/main.go
deleted file mode 100644
index 54b2893..0000000
--- a/cli/config/main.go
+++ /dev/null
@@ -1,64 +0,0 @@
-package config
-
-import (
- "path/filepath"
-
- homedir "github.com/mitchellh/go-homedir"
- "github.com/spf13/viper"
- "github.com/vulpemventures/nigiri/cli/constants"
-)
-
-var vip *viper.Viper
-
-func init() {
- vip = viper.New()
- defaults := viper.New()
-
- newDefaultConfig(defaults)
- setConfigFromDefaults(vip, defaults)
-}
-
-type Config struct{}
-
-func (c *Config) Viper() *viper.Viper {
- return vip
-}
-
-func (c *Config) ReadFromFile(path string) error {
- vip.SetConfigFile(filepath.Join(path, constants.Filename))
- return vip.ReadInConfig()
-}
-
-func (c *Config) WriteConfig(path string) error {
- vip.SetConfigFile(path)
- return vip.WriteConfig()
-}
-
-func (c *Config) GetString(str string) string {
- return vip.GetString(str)
-}
-
-func (c *Config) GetBool(str string) bool {
- return vip.GetBool(str)
-}
-
-func (c *Config) GetPath() string {
- return getPath()
-}
-
-func getPath() string {
- home, _ := homedir.Expand("~")
- return filepath.Join(home, ".nigiri")
-}
-
-func newDefaultConfig(v *viper.Viper) {
- v.SetDefault(constants.Datadir, getPath())
- v.SetDefault(constants.Network, "regtest")
- v.SetDefault(constants.AttachLiquid, false)
-}
-
-func setConfigFromDefaults(v *viper.Viper, d *viper.Viper) {
- for key, value := range d.AllSettings() {
- v.SetDefault(key, value)
- }
-}
diff --git a/cli/constants/constants.go b/cli/constants/constants.go
deleted file mode 100644
index 6e0cde7..0000000
--- a/cli/constants/constants.go
+++ /dev/null
@@ -1,71 +0,0 @@
-package constants
-
-import (
- "errors"
-)
-
-const (
- // Datadir key in config json
- Datadir = "datadir"
- // Network key in config json
- Network = "network"
- // Filename key in config json
- Filename = "nigiri.config.json"
- // AttachLiquid key in config json
- AttachLiquid = "attachLiquid"
- // Version key in config json
- Version = "version"
-)
-
-var (
- AvaliableNetworks = []string{"regtest"}
- NigiriBitcoinImages = []string{
- "ghcr.io/vulpemventures/bitcoin:latest",
- "ghcr.io/vulpemventures/electrs:latest",
- "ghcr.io/vulpemventures/esplora:latest",
- "ghcr.io/vulpemventures/nigiri-chopsticks:latest",
- }
- NigiriLiquidImages = []string{
- "ghcr.io/vulpemventures/elements:latest",
- "ghcr.io/vulpemventures/electrs-liquid:latest",
- }
- NigiriImages = append(NigiriBitcoinImages, NigiriLiquidImages...)
- DefaultEnv = map[string]interface{}{
- "ports": map[string]map[string]int{
- "bitcoin": {
- "peer": 18432,
- "node": 18433,
- "esplora": 5000,
- "electrs": 3002,
- "electrs_rpc": 51401,
- "chopsticks": 3000,
- },
- "liquid": {
- "peer": 7040,
- "node": 7041,
- "esplora": 5001,
- "electrs": 3012,
- "electrs_rpc": 60401,
- "chopsticks": 3001,
- },
- },
- "urls": map[string]string{
- "bitcoin_esplora": "http://localhost:3000",
- "liquid_esplora": "http://localhost:3001",
- },
- }
-
- ErrInvalidNetwork = errors.New("Network provided is not valid")
- ErrInvalidDatadir = errors.New("Datadir provided is not valid: it must be an absolute path")
- ErrInvalidServiceName = errors.New("Service provided is not valid")
- ErrInvalidArgs = errors.New("Invalid number of args")
- ErrInvalidJSON = errors.New("JSON environment provided is not valid: missing required fields")
- ErrMalformedJSON = errors.New("Failed to parse malformed JSON environment")
- ErrEmptyJSON = errors.New("JSON environment provided is not valid: it must not be empty")
- ErrDatadirNotExisting = errors.New("Datadir provided is not valid: it must be an existing path")
- ErrNigiriNotRunning = errors.New("Nigiri is not running")
- ErrNigiriNotExisting = errors.New("Nigiri does not exists, cannot delete")
- ErrNigiriAlreadyRunning = errors.New("Nigiri is already running, please stop it first")
- ErrNigiriLiquidNotEnabled = errors.New("Nigiri has been started with no Liquid sidechain.\nPlease stop and restart it using the --liquid flag")
- ErrDockerNotRunning = errors.New("Nigiri requires the Docker daemon to be running, but it not seems to be started")
-)
diff --git a/cli/controller/controller.go b/cli/controller/controller.go
deleted file mode 100644
index 3e18a82..0000000
--- a/cli/controller/controller.go
+++ /dev/null
@@ -1,187 +0,0 @@
-package controller
-
-import (
- "fmt"
- "os/exec"
- "path/filepath"
-
- "github.com/vulpemventures/nigiri/cli/config"
- "github.com/vulpemventures/nigiri/cli/constants"
-)
-
-var Services = map[string]bool{
- "node": true,
- "esplora": true,
- "electrs": true,
- "chopsticks": true,
-}
-
-// Controller implements useful functions to securely parse flags provided at run-time
-// and to interact with the resources used by Nigiri:
-// * docker
-// * .env for docker-compose
-// * nigiri.config.json config file
-type Controller struct {
- config *config.Config
- parser *Parser
- docker *Docker
- env *Env
-}
-
-// NewController returns a new Controller instance or error
-func NewController() (*Controller, error) {
- c := &Controller{}
-
- dockerClient := &Docker{}
- if err := dockerClient.New(); err != nil {
- return nil, err
- }
- c.env = &Env{}
- c.parser = newParser(Services)
- c.docker = dockerClient
- c.config = &config.Config{}
- return c, nil
-}
-
-// ParseNetwork checks if a valid network has been provided
-func (c *Controller) ParseNetwork(network string) error {
- return c.parser.parseNetwork(network)
-}
-
-// ParseDatadir checks if a valid datadir has been provided
-func (c *Controller) ParseDatadir(path string) error {
- return c.parser.parseDatadir(path)
-}
-
-// ParseEnv checks if a valid JSON format for docker compose has been provided
-func (c *Controller) ParseEnv(env string) (string, error) {
- return c.parser.parseEnvJSON(env)
-}
-
-// ParseServiceName checks if a valid service has been provided
-func (c *Controller) ParseServiceName(name string) error {
- return c.parser.parseServiceName(name)
-}
-
-// IsNigiriRunning checks if nigiri is running by looking if the bitcoin
-// services are in the list of docker running containers
-func (c *Controller) IsNigiriRunning() (bool, error) {
- if !c.docker.isDockerRunning() {
- return false, constants.ErrDockerNotRunning
- }
- return c.docker.isNigiriRunning(), nil
-}
-
-// IsNigiriStopped checks that nigiri is not actually running and that
-// the bitcoin services appear in the list of non running containers
-func (c *Controller) IsNigiriStopped() (bool, error) {
- if !c.docker.isDockerRunning() {
- return false, constants.ErrDockerNotRunning
- }
- return c.docker.isNigiriStopped(), nil
-}
-
-// WriteComposeEnvironment creates a .env in datadir used by
-// the docker-compose YAML file resource
-func (c *Controller) WriteComposeEnvironment(datadir, env string) error {
- return c.env.writeEnvForCompose(datadir, env)
-}
-
-// ReadComposeEnvironment reads from .env and returns it as a useful type
-func (c *Controller) ReadComposeEnvironment(datadir string) (map[string]interface{}, error) {
- return c.env.readEnvForCompose(datadir)
-}
-
-// LoadComposeEnvironment returns an os.Environ created from datadir/.env resource
-func (c *Controller) LoadComposeEnvironment(datadir string) []string {
- return c.env.load(datadir)
-}
-
-// WriteConfigFile writes the configuration handled by the underlying viper
-// into the file at filedir path
-func (c *Controller) WriteConfigFile(filedir string) error {
- return c.config.WriteConfig(filedir)
-}
-
-// ReadConfigFile reads the configuration of the file at filedir path
-func (c *Controller) ReadConfigFile(filedir string) error {
- return c.config.ReadFromFile(filedir)
-}
-
-// GetConfigBoolField returns a bool field of the config file
-func (c *Controller) GetConfigBoolField(field string) bool {
- return c.config.GetBool(field)
-}
-
-// GetConfigStringField returns a string field of the config file
-func (c *Controller) GetConfigStringField(field string) string {
- return c.config.GetString(field)
-}
-
-// NewDatadirFromDefault copies the default ~/.nigiri at the desidered path
-// and cleans the docker volumes to make a fresh Nigiri instance
-func (c *Controller) NewDatadirFromDefault(datadir string) error {
- defaultDatadir := c.config.GetPath()
- cmd := exec.Command("cp", "-R", filepath.Join(defaultDatadir, "resources"), datadir)
- if err := cmd.Run(); err != nil {
- return err
- }
- c.CleanResourceVolumes(datadir)
- return nil
-}
-
-// GetResourcePath returns the absolute path of the requested resource
-func (c *Controller) GetResourcePath(datadir, resource string) string {
- if resource == "compose" {
- network := c.config.GetString(constants.Network)
- if c.config.GetBool(constants.AttachLiquid) {
- network += "-liquid"
- }
- return filepath.Join(datadir, "resources", fmt.Sprintf("docker-compose-%s.yml", network))
- }
- if resource == "env" {
- return filepath.Join(datadir, ".env")
- }
- if resource == "config" {
- return filepath.Join(datadir, "nigiri.config.json")
- }
- return ""
-}
-
-// CleanResourceVolumes recursively deletes the content of the
-// docker volumes in the resource path
-func (c *Controller) CleanResourceVolumes(datadir string) error {
- network := c.config.GetString(constants.Network)
- attachLiquid := c.config.GetBool(constants.AttachLiquid)
- if attachLiquid {
- network = fmt.Sprintf("liquid%s", network)
- }
- volumedir := filepath.Join(datadir, "resources", "volumes", network)
-
- return c.docker.cleanVolumes(volumedir)
-}
-
-// GetDefaultDatadir returns the absolute path of Nigiri default directory
-func (c *Controller) GetDefaultDatadir() string {
- return c.config.GetPath()
-}
-
-// GetServiceName returns the right name of the requested service
-// If requesting a name for a Liquid service, then the suffix -liquid
-// is appended to the canonical name except for "node" that is mapped
-// to either "bitcoin" or "liquid"
-func (c *Controller) GetServiceName(name string, liquid bool) string {
- service := name
- if service == "node" {
- service = "bitcoin"
- }
- if liquid {
- if service == "bitcoin" {
- service = "liquid"
- } else {
- service = fmt.Sprintf("%s-liquid", service)
- }
- }
-
- return service
-}
diff --git a/cli/controller/docker.go b/cli/controller/docker.go
deleted file mode 100644
index f9a5ba8..0000000
--- a/cli/controller/docker.go
+++ /dev/null
@@ -1,98 +0,0 @@
-package controller
-
-import (
- "context"
- "io/ioutil"
- "os"
- "path/filepath"
-
- "github.com/docker/docker/api/types"
- "github.com/docker/docker/client"
- "github.com/vulpemventures/nigiri/cli/constants"
-)
-
-// Docker type handles interfaction with containers via docker and docker-compose
-type Docker struct {
- cli *client.Client
-}
-
-// New initialize a new Docker handler
-func (d *Docker) New() error {
- cli, err := client.NewEnvClient()
- if err != nil {
- return err
- }
- d.cli = cli
- return nil
-}
-
-func (d *Docker) isDockerRunning() bool {
- _, err := d.cli.ContainerList(context.Background(), types.ContainerListOptions{All: false})
- if err != nil {
- return false
- }
- return true
-}
-
-func (d *Docker) findNigiriContainers(listAllContainers bool) bool {
- containers, _ := d.cli.ContainerList(context.Background(), types.ContainerListOptions{All: listAllContainers})
-
- if len(containers) <= 0 {
- return false
- }
-
- images := []string{}
- for _, c := range containers {
- images = append(images, c.Image)
- }
-
- for _, nigiriImage := range constants.NigiriBitcoinImages {
- // just check if services for bitcoin chain are up and running
- if !contains(images, nigiriImage) {
- return false
- }
- }
- return true
-}
-
-func (d *Docker) isNigiriRunning() bool {
- return d.findNigiriContainers(false)
-}
-
-func (d *Docker) isNigiriStopped() bool {
- isRunning := d.isNigiriRunning()
- if !isRunning {
- return d.findNigiriContainers(true)
- }
- return false
-}
-
-func (d *Docker) cleanVolumes(path string) error {
- subdirs, err := ioutil.ReadDir(path)
- if err != nil {
- return err
- }
-
- for _, d := range subdirs {
- path := filepath.Join(path, d.Name())
- subsubdirs, _ := ioutil.ReadDir(path)
- for _, sd := range subsubdirs {
- if sd.IsDir() {
- if err := os.RemoveAll(filepath.Join(path, sd.Name())); err != nil {
- return err
- }
- }
- }
- }
-
- return nil
-}
-
-func contains(list []string, elem string) bool {
- for _, l := range list {
- if l == elem {
- return true
- }
- }
- return false
-}
diff --git a/cli/controller/env.go b/cli/controller/env.go
deleted file mode 100644
index 83045c2..0000000
--- a/cli/controller/env.go
+++ /dev/null
@@ -1,125 +0,0 @@
-package controller
-
-import (
- "bufio"
- "encoding/json"
- "fmt"
- "io/ioutil"
- "os"
- "strconv"
- "strings"
-
- "github.com/vulpemventures/nigiri/cli/constants"
-)
-
-// Env implements functions for interacting with the environment file used by
-// docker-compose to dynamically set service ports and variables
-type Env struct{}
-
-func (e *Env) writeEnvForCompose(path, strJSON string) error {
- var env map[string]interface{}
- err := json.Unmarshal([]byte(strJSON), &env)
- if err != nil {
- return constants.ErrMalformedJSON
- }
-
- fileContent := ""
- for chain, services := range env["ports"].(map[string]interface{}) {
- for k, v := range services.(map[string]interface{}) {
- fileContent += fmt.Sprintf("%s_%s_PORT=%d\n", strings.ToUpper(chain), strings.ToUpper(k), int(v.(float64)))
- }
- }
- for hostname, url := range env["urls"].(map[string]interface{}) {
- fileContent += fmt.Sprintf("%s_URL=%s\n", strings.ToUpper(hostname), url.(string))
- }
-
- return ioutil.WriteFile(path, []byte(fileContent), os.ModePerm)
-}
-
-func (e *Env) readEnvForCompose(path string) (map[string]interface{}, error) {
- file, err := os.Open(path)
- if err != nil {
- return nil, err
- }
- defer file.Close()
-
- scanner := bufio.NewScanner(file)
- scanner.Split(bufio.ScanLines)
-
- ports := map[string]map[string]int{
- "bitcoin": map[string]int{},
- "liquid": map[string]int{},
- }
- urls := map[string]string{}
- // Each line is in the format PREFIX_SERVICE_NAME_SUFFIX=value
- // PREFIX is either 'BITCOIN' or 'LIQUID', while SUFFIX is either 'PORT' or 'URL'
- for scanner.Scan() {
- line := scanner.Text()
- splitLine := strings.Split(line, "=")
- key := splitLine[0]
-
- if strings.Contains(key, "PORT") {
- value, _ := strconv.Atoi(splitLine[1])
- chain := "bitcoin"
- if strings.HasPrefix(key, strings.ToUpper("liquid")) {
- chain = "liquid"
- }
- prefix := strings.ToUpper(fmt.Sprintf("%s_", chain))
- suffix := "_PORT"
- trimmedKey := strings.ToLower(
- strings.TrimSuffix(strings.TrimPrefix(key, prefix), suffix),
- )
- ports[chain][trimmedKey] = value
- } else {
- // Here the prefix is not trimmed
- value := splitLine[1]
- suffix := "_URL"
- trimmedKey := strings.ToLower(strings.TrimSuffix(key, suffix))
- urls[trimmedKey] = value
- }
- }
-
- return map[string]interface{}{"ports": ports, "urls": urls}, nil
-}
-
-func (e *Env) load(path string) []string {
- content, _ := ioutil.ReadFile(path)
- lines := strings.Split(string(content), "\n")
- env := os.Environ()
- for _, line := range lines {
- if line != "" {
- env = append(env, line)
- }
- }
-
- return env
-}
-
-type envPortsData struct {
- Peer int `json:"peer,omitempty"`
- Node int `json:"node,omitempty"`
- Esplora int `json:"esplora,omitempty"`
- Electrs int `json:"electrs,omitempty"`
- ElectrsRPC int `json:"electrs_rpc,omitempty"`
- Chopsticks int `json:"chopsticks,omitempty"`
-}
-type envPorts struct {
- Bitcoin *envPortsData `json:"bitcoin,omitempty"`
- Liquid *envPortsData `json:"liquid,omitempty"`
-}
-type envUrls struct {
- BitcoinEsplora string `json:"bitcoin_esplora,omitempty"`
- LiquidEsplora string `json:"liquid_esplora,omitempty"`
-}
-type envJSON struct {
- Ports *envPorts `json:"ports,omitempty"`
- Urls *envUrls `json:"urls,omitempty"`
-}
-
-func (e envJSON) copy() envJSON {
- var v envJSON
- bytes, _ := json.Marshal(e)
- json.Unmarshal(bytes, &v)
-
- return v
-}
diff --git a/cli/controller/parser.go b/cli/controller/parser.go
deleted file mode 100644
index aeb512f..0000000
--- a/cli/controller/parser.go
+++ /dev/null
@@ -1,58 +0,0 @@
-package controller
-
-import (
- "encoding/json"
- "fmt"
- "path/filepath"
-
- "github.com/vulpemventures/nigiri/cli/constants"
-)
-
-// Parser implements functions for parsing flags, JSON files
-// and system directories passed to the CLI commands
-type Parser struct {
- services map[string]bool
-}
-
-func newParser(services map[string]bool) *Parser {
- p := &Parser{services}
- return p
-}
-
-func (p *Parser) parseNetwork(network string) error {
- for _, n := range constants.AvaliableNetworks {
- if network == n {
- return nil
- }
- }
- return constants.ErrInvalidNetwork
-}
-
-func (p *Parser) parseDatadir(path string) error {
- if !filepath.IsAbs(path) {
- return constants.ErrInvalidDatadir
- }
- return nil
-}
-
-func (p *Parser) parseEnvJSON(strJSON string) (string, error) {
- // merge default json and incoming json by parsing DefaultEnv to
- // envJSON type and then parsing the incoming json using the same variable
- var parsedJSON envJSON
- defaultJSON, _ := json.Marshal(constants.DefaultEnv)
- json.Unmarshal(defaultJSON, &parsedJSON)
- err := json.Unmarshal([]byte(strJSON), &parsedJSON)
- if err != nil {
- fmt.Println(err)
- return "", constants.ErrMalformedJSON
- }
- merged, _ := json.Marshal(parsedJSON)
- return string(merged), nil
-}
-
-func (p *Parser) parseServiceName(name string) error {
- if !p.services[name] {
- return constants.ErrInvalidServiceName
- }
- return nil
-}
diff --git a/cli/controller/parser_test.go b/cli/controller/parser_test.go
deleted file mode 100644
index c20a338..0000000
--- a/cli/controller/parser_test.go
+++ /dev/null
@@ -1,162 +0,0 @@
-package controller
-
-import (
- "encoding/json"
- "os"
- "testing"
-
- "github.com/vulpemventures/nigiri/cli/constants"
-)
-
-func TestParserParseNetwork(t *testing.T) {
- p := &Parser{}
-
- validNetworks := []string{"regtest"}
- for _, n := range validNetworks {
- err := p.parseNetwork(n)
- if err != nil {
- t.Fatal(err)
- }
- }
-}
-
-func TestParserParseDatadir(t *testing.T) {
- p := &Parser{}
-
- currentDir, _ := os.Getwd()
- validDatadirs := []string{currentDir}
- for _, n := range validDatadirs {
- err := p.parseDatadir(n)
- if err != nil {
- t.Fatal(err)
- }
- }
-}
-
-func TestParserParseEnvJSON(t *testing.T) {
- p := &Parser{}
-
- for _, e := range testJSONs {
- parsedJSON, _ := json.Marshal(e)
- mergedJSON, err := p.parseEnvJSON(string(parsedJSON))
- if err != nil {
- t.Fatal(err)
- }
- t.Log(mergedJSON)
- }
-}
-
-func TestParserParseNetworkShouldFail(t *testing.T) {
- p := &Parser{}
-
- invalidNetworks := []string{"simnet", "testnet"}
- for _, n := range invalidNetworks {
- err := p.parseNetwork(n)
- if err == nil {
- t.Fatalf("Should have been failed before")
- }
- if err != constants.ErrInvalidNetwork {
- t.Fatalf("Got: %s, wanted: %s", err, constants.ErrInvalidNetwork)
- }
- }
-}
-
-func TestParserParseDatadirShouldFail(t *testing.T) {
- p := &Parser{}
-
- invalidDatadirs := []string{"."}
- for _, d := range invalidDatadirs {
- err := p.parseDatadir(d)
- if err == nil {
- t.Fatalf("Should have been failed before")
- }
- if err != constants.ErrInvalidDatadir {
- t.Fatalf("Got: %s, wanted: %s", err, constants.ErrInvalidDatadir)
- }
- }
-}
-
-var testJSONs = []map[string]interface{}{
- // only btc services
- {
- "urls": map[string]string{
- "bitcoin_esplora": "https://blockstream.info/",
- },
- "ports": map[string]map[string]int{
- "bitcoin": map[string]int{
- "peer": 1111,
- "node": 2222,
- "esplora": 3333,
- "electrs": 4444,
- "chopsticks": 5555,
- },
- },
- },
- // btc and liquid services
- {
- "urls": map[string]string{
- "bitcoin_esplora": "https://blockstream.info/",
- "liquid_esplora": "http://blockstream.info/liquid",
- },
- "ports": map[string]map[string]int{
- "bitcoin": map[string]int{
- "peer": 1111,
- "node": 2222,
- "esplora": 3333,
- "electrs": 4444,
- "chopsticks": 5555,
- },
- "liquid": map[string]int{
- "peer": 6666,
- "node": 7777,
- "esplora": 8888,
- "electrs": 9999,
- "chopsticks": 1010,
- },
- },
- },
- // incomplete examples:
- // incomplete bitcoin services
- {
- "ports": map[string]map[string]int{
- "bitcoin": map[string]int{
- "esplora": 1111,
- "electrs": 2222,
- "chopsticks": 3333,
- },
- },
- "urls": map[string]string{
- "bitcoin_esplora": "http://test.com/api",
- },
- },
- // bitcoin services ports and liquid service url
- {
- "ports": map[string]map[string]int{
- "bitcoin": map[string]int{
- "node": 1111,
- "esplora": 2222,
- "electrs": 3333,
- "chopsticks": 4444,
- },
- },
- "urls": map[string]string{
- "liquid_esplora": "http://test.com/liquid/api",
- },
- },
- // liquid services ports and bitcoin service url
- {
- "ports": map[string]map[string]int{
- "liquid": map[string]int{
- "node": 1111,
- "esplora": 2222,
- "electrs": 3333,
- "chopsticks": 4444,
- },
- },
- "urls": map[string]string{
- "bitcoin_esplora": "http://test.com/api",
- },
- },
- // empty config
- {},
-}
diff --git a/cli/main.go b/cli/main.go
deleted file mode 100644
index 3f83d44..0000000
--- a/cli/main.go
+++ /dev/null
@@ -1,7 +0,0 @@
-package main
-
-import "github.com/vulpemventures/nigiri/cli/cmd"
-
-func main() {
- cmd.RootCmd.Execute()
-}
diff --git a/go.mod b/go.mod
index 0096fe1..eef2a94 100644
--- a/go.mod
+++ b/go.mod
@@ -1,25 +1,3 @@
module github.com/vulpemventures/nigiri
-go 1.12
-
-require (
- github.com/BurntSushi/toml v0.3.1 // indirect
- github.com/Microsoft/go-winio v0.4.12 // indirect
- github.com/docker/distribution v2.7.1+incompatible // indirect
- github.com/docker/docker v1.13.1
- github.com/docker/go-connections v0.4.0 // indirect
- github.com/docker/go-units v0.3.3 // indirect
- github.com/inconshreveable/mousetrap v1.0.0 // indirect
- github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
- github.com/mitchellh/go-homedir v1.1.0
- github.com/opencontainers/go-digest v1.0.0-rc1 // indirect
- github.com/pkg/errors v0.8.1 // indirect
- github.com/sirupsen/logrus v1.4.0
- github.com/spf13/afero v1.2.2 // indirect
- github.com/spf13/cobra v0.0.3
- github.com/spf13/jwalterweatherman v1.1.0 // indirect
- github.com/spf13/viper v1.3.2
- golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c // indirect
- golang.org/x/net v0.0.0-20190419010253-1f3472d942ba // indirect
- golang.org/x/sys v0.0.0-20190322080309-f49334f85ddc // indirect
-)
+go 1.16
diff --git a/go.sum b/go.sum
deleted file mode 100644
index 22ee2b4..0000000
--- a/go.sum
+++ /dev/null
@@ -1,80 +0,0 @@
-github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
-github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/Microsoft/go-winio v0.4.12 h1:xAfWHN1IrQ0NJ9TBC0KBZoqLjzDTr1ML+4MywiUOryc=
-github.com/Microsoft/go-winio v0.4.12/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
-github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
-github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
-github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
-github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
-github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
-github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
-github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
-github.com/docker/docker v1.13.1 h1:IkZjBSIc8hBjLpqeAbeE5mca5mNgeatLHBy3GO78BWo=
-github.com/docker/docker v1.13.1/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
-github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
-github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
-github.com/docker/go-units v0.3.3 h1:Xk8S3Xj5sLGlG5g67hJmYMmUgXv5N4PhkjJHHqrwnTk=
-github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
-github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
-github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
-github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
-github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
-github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
-github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
-github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
-github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
-github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
-github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
-github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
-github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
-github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
-github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
-github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
-github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ=
-github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
-github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
-github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
-github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
-github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
-github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
-github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/sirupsen/logrus v1.4.0 h1:yKenngtzGh+cUSSh6GWbxW2abRqhYUSR/t/6+2QqNvE=
-github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
-github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
-github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=
-github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
-github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
-github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
-github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8=
-github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
-github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
-github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
-github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
-github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
-github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
-github.com/spf13/viper v1.3.2 h1:VUFqw5KcqRf7i70GOzW7N+Q7+gxVBkSSqiXB12+JQ4M=
-github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
-github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
-github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
-github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
-github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
-golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
-golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
-golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c h1:Vj5n4GlwjmQteupaxJ9+0FNOmBrHfq7vN4btdGoDZgI=
-golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/net v0.0.0-20190419010253-1f3472d942ba h1:h0zCzEL5UW1mERvwTN6AXcc75PpLkY6OcReia6Dq1BM=
-golang.org/x/net v0.0.0-20190419010253-1f3472d942ba/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190322080309-f49334f85ddc h1:4gbWbmmPFp4ySWICouJl6emP0MyS31yy9SrTlAGFT+g=
-golang.org/x/sys v0.0.0-20190322080309-f49334f85ddc/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
-golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
-gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
-gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff --git a/resources/docker-compose-regtest-liquid.yml b/resources/docker-compose-regtest-liquid.yml
deleted file mode 100644
index 1d4ec8f..0000000
--- a/resources/docker-compose-regtest-liquid.yml
+++ /dev/null
@@ -1,179 +0,0 @@
-version: '3'
-services:
- # RPC daemons
- bitcoin:
- image: ghcr.io/vulpemventures/bitcoin:latest
- container_name: bitcoin
- command:
- - -datadir=config
- networks:
- local:
- ipv4_address: 10.10.0.10
- ports:
- - ${BITCOIN_PEER_PORT}:19000
- - ${BITCOIN_NODE_PORT}:19001
- volumes:
- - ./volumes/liquidregtest/config/:/config
- restart: unless-stopped
- liquid:
- image: ghcr.io/vulpemventures/elements:latest
- container_name: liquid
- command:
- - -datadir=config
- networks:
- local:
- ipv4_address: 10.10.0.11
- ports:
- - ${LIQUID_NODE_PORT}:18884
- - ${LIQUID_PEER_PORT}:18886
- volumes:
- - ./volumes/liquidregtest/liquid-config/:/config
- restart: unless-stopped
- # Block explorer REST servers
- electrs:
- image: ghcr.io/vulpemventures/electrs:latest
- container_name: electrs
- 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
- - --electrum-rpc-addr
- - 0.0.0.0:60401
- - --cors
- - "*"
- networks:
- local:
- ipv4_address: 10.10.0.12
- depends_on:
- - bitcoin
- ports:
- - ${BITCOIN_ELECTRS_RPC_PORT}:60401
- - ${BITCOIN_ELECTRS_PORT}:3002
- volumes:
- - ./volumes/liquidregtest/config/:/config
- restart: unless-stopped
- electrs-liquid:
- image: ghcr.io/vulpemventures/electrs-liquid:latest
- container_name: electrs-liquid
- entrypoint:
- - /build/electrs
- command:
- - -vvvv
- - --parent-network
- - regtest
- - --network
- - liquidregtest
- - --daemon-dir
- - /config
- - --daemon-rpc-addr
- - 10.10.0.11:18884
- - --cookie
- - admin1:123
- - --http-addr
- - 0.0.0.0:3002
- - --electrum-rpc-addr
- - 0.0.0.0:60401
- - --cors
- - "*"
- networks:
- local:
- ipv4_address: 10.10.0.13
- depends_on:
- - liquid
- ports:
- - ${LIQUID_ELECTRS_RPC_PORT}:60401
- - ${LIQUID_ELECTRS_PORT}:3002
- volumes:
- - ./volumes/liquidregtest/liquid-config/:/config
- restart: unless-stopped
- # Block explorer frontends
- esplora:
- image: ghcr.io/vulpemventures/esplora:latest
- container_name: esplora
- networks:
- local:
- ipv4_address: 10.10.0.14
- depends_on:
- - chopsticks
- environment:
- API_URL: ${BITCOIN_ESPLORA_URL}
- ports:
- - ${BITCOIN_ESPLORA_PORT}:5000
- restart: unless-stopped
- esplora-liquid:
- image: ghcr.io/vulpemventures/esplora:latest
- container_name: esplora-liquid
- networks:
- local:
- ipv4_address: 10.10.0.15
- depends_on:
- - chopsticks-liquid
- environment:
- API_URL: ${LIQUID_ESPLORA_URL}
- ports:
- - ${LIQUID_ESPLORA_PORT}:5000
- restart: unless-stopped
- # Chopsticks
- chopsticks:
- image: ghcr.io/vulpemventures/nigiri-chopsticks:latest
- container_name: chopsticks
- command:
- - --use-faucet
- - --use-mining
- - --use-logger
- - --rpc-addr
- - 10.10.0.10:19001
- - --electrs-addr
- - 10.10.0.12:3002
- - --addr
- - 0.0.0.0:3000
- depends_on:
- - bitcoin
- - electrs
- ports:
- - ${BITCOIN_CHOPSTICKS_PORT}:3000
- networks:
- local:
- ipv4_address: 10.10.0.16
- restart: unless-stopped
- chopsticks-liquid:
- image: ghcr.io/vulpemventures/nigiri-chopsticks:latest
- container_name: chopsticks-liquid
- command:
- - --use-faucet
- - --use-mining
- - --use-logger
- - --rpc-addr
- - 10.10.0.11:18884
- - --electrs-addr
- - 10.10.0.13:3002
- - --addr
- - 0.0.0.0:3000
- - --chain
- - liquid
- depends_on:
- - liquid
- - electrs-liquid
- ports:
- - ${LIQUID_CHOPSTICKS_PORT}:3000
- networks:
- local:
- ipv4_address: 10.10.0.17
- restart: unless-stopped
-
-networks:
- local:
- driver: bridge
- ipam:
- config:
- - subnet: 10.10.0.0/24
diff --git a/resources/docker-compose-regtest.yml b/resources/docker-compose-regtest.yml
deleted file mode 100644
index 08391cf..0000000
--- a/resources/docker-compose-regtest.yml
+++ /dev/null
@@ -1,94 +0,0 @@
-version: '3'
-services:
- # RPC daemon
- bitcoin:
- image: ghcr.io/vulpemventures/bitcoin:latest
- container_name: bitcoin
- command:
- - -datadir=config
- networks:
- local:
- ipv4_address: 10.10.0.10
- ports:
- - ${BITCOIN_PEER_PORT}:19000
- - ${BITCOIN_NODE_PORT}:19001
- volumes:
- - ./volumes/regtest/config/:/config
- restart: unless-stopped
- # Block explorer server
- electrs:
- image: ghcr.io/vulpemventures/electrs:latest
- container_name: electrs
- 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
- - --electrum-rpc-addr
- - 0.0.0.0:60401
- - --cors
- - "*"
- networks:
- local:
- ipv4_address: 10.10.0.11
- depends_on:
- - bitcoin
- ports:
- - ${BITCOIN_ELECTRS_RPC_PORT}:60401
- - ${BITCOIN_ELECTRS_PORT}:3002
- volumes:
- - ./volumes/regtest/config/:/config
- restart: unless-stopped
- # Block explorer frontend
- esplora:
- image: ghcr.io/vulpemventures/esplora:latest
- container_name: esplora
- networks:
- local:
- ipv4_address: 10.10.0.12
- depends_on:
- - chopsticks
- environment:
- API_URL: ${BITCOIN_ESPLORA_URL}
- ports:
- - ${BITCOIN_ESPLORA_PORT}:5000
- restart: unless-stopped
- # Chopsticks
- chopsticks:
- image: ghcr.io/vulpemventures/nigiri-chopsticks:latest
- container_name: chopsticks
- command:
- - --use-faucet
- - --use-mining
- - --use-logger
- - --rpc-addr
- - 10.10.0.10:19001
- - --electrs-addr
- - 10.10.0.11:3002
- - --addr
- - 0.0.0.0:3000
- networks:
- local:
- ipv4_address: 10.10.0.13
- depends_on:
- - bitcoin
- - electrs
- ports:
- - ${BITCOIN_CHOPSTICKS_PORT}:3000
- restart: unless-stopped
-
-networks:
- local:
- driver: bridge
- ipam:
- config:
- - subnet: 10.10.0.0/24
diff --git a/resources/volumes/liquidregtest/config/bitcoin.conf b/resources/volumes/liquidregtest/config/bitcoin.conf
deleted file mode 100644
index c462cbc..0000000
--- a/resources/volumes/liquidregtest/config/bitcoin.conf
+++ /dev/null
@@ -1,17 +0,0 @@
-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
-rpcbind=0.0.0.0
-fallbackfee=0.00001
diff --git a/resources/volumes/liquidregtest/liquid-config/elements.conf b/resources/volumes/liquidregtest/liquid-config/elements.conf
deleted file mode 100644
index a8732e8..0000000
--- a/resources/volumes/liquidregtest/liquid-config/elements.conf
+++ /dev/null
@@ -1,35 +0,0 @@
-chain=liquidregtest
-listen=1
-txindex=1
-
-[liquidregtest]
-port=18886
-rpcport=18884
-rpcuser=admin1
-rpcpassword=123
-rpcallowip=0.0.0.0/0
-rpcbind=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.
-# This template is 1-of-1 checkmultisig
-#fedpegscript=512151ae
-
-# This is the script that controls how blocks are made
-# We have to supply a signature that satisfies this to create
-# a valid block.
-#signblockscript=512151ae
-
-# 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
-initialfreecoins=2100000000000000
-fallbackfee=0.000001
diff --git a/resources/volumes/regtest/config/bitcoin.conf b/resources/volumes/regtest/config/bitcoin.conf
deleted file mode 100644
index c462cbc..0000000
--- a/resources/volumes/regtest/config/bitcoin.conf
+++ /dev/null
@@ -1,17 +0,0 @@
-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
-rpcbind=0.0.0.0
-fallbackfee=0.00001
diff --git a/scripts/build b/scripts/build
deleted file mode 100755
index a42b977..0000000
--- a/scripts/build
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/bash
-
-set -e
-
-PARENT_PATH=$(dirname $(
- cd $(dirname $0)
- pwd -P
-))
-
-OS=$(eval "go env GOOS")
-ARCH=$(eval "go env GOARCH")
-
-pushd $PARENT_PATH
-mkdir -p build
-GO111MODULE=on go build -ldflags="-s -w" -o build/nigiri-$OS-$ARCH cli/main.go
-popd
diff --git a/scripts/clean b/scripts/clean
deleted file mode 100755
index 0498ac9..0000000
--- a/scripts/clean
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/bin/bash
-
-set -ex
-
-PARENT_PATH=$(dirname $(cd $(dirname $0); pwd -P))
-
-pushd $PARENT_PATH
-
-case $(uname -s) in
- Darwin) OS="darwin";;
- Linux) OS="linux";;
- *) echo "OS $OS not supported"; exit 1;;
-esac
-
-case $(uname -m) in
- amd64) ARCH="amd64";;
- x86_64) ARCH="amd64";;
- *) echo "Architecture $ARCH not supported"; exit 1;;
-esac
-
-./build/nigiri-$OS-$ARCH stop --delete &>/dev/null
-rm -rf build vendor ~/.nigiri
-
-popd
\ No newline at end of file
diff --git a/scripts/install b/scripts/install
deleted file mode 100755
index 0757c19..0000000
--- a/scripts/install
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/bash
-set -ex
-
-PARENT_PATH=$(dirname $(cd $(dirname $0); pwd -P))
-
-pushd $PARENT_PATH
-
-go generate ./...
-
-mkdir -p $HOME/.nigiri
-cp -R resources $HOME/.nigiri
-popd
\ No newline at end of file
From bd07d46deb6300d64ce179d8e795136790e8a9a5 Mon Sep 17 00:00:00 2001
From: Marco Argentieri <3596602+tiero@users.noreply.github.com>
Date: Tue, 3 Aug 2021 14:32:57 +0200
Subject: [PATCH 02/28] load datadir with resources and start compose
---
cmd/nigiri/faucet.go | 1 +
cmd/nigiri/logs.go | 1 +
cmd/nigiri/main.go | 188 ++++++++++++++++++
cmd/nigiri/mint.go | 1 +
cmd/nigiri/push.go | 1 +
cmd/nigiri/resources/bitcoin.conf | 17 ++
.../docker-compose-regtest-liquid.yml | 149 ++++++++++++++
.../resources/docker-compose-regtest.yml | 82 ++++++++
cmd/nigiri/resources/elements.conf | 35 ++++
cmd/nigiri/rpc.go | 1 +
cmd/nigiri/start.go | 33 +++
cmd/nigiri/state.go | 68 +++++++
cmd/nigiri/stop.go | 1 +
cmd/nigiri/version.go | 1 +
go.mod | 7 +
go.sum | 62 ++++++
16 files changed, 648 insertions(+)
create mode 100644 cmd/nigiri/faucet.go
create mode 100644 cmd/nigiri/logs.go
create mode 100644 cmd/nigiri/main.go
create mode 100644 cmd/nigiri/mint.go
create mode 100644 cmd/nigiri/push.go
create mode 100644 cmd/nigiri/resources/bitcoin.conf
create mode 100644 cmd/nigiri/resources/docker-compose-regtest-liquid.yml
create mode 100644 cmd/nigiri/resources/docker-compose-regtest.yml
create mode 100644 cmd/nigiri/resources/elements.conf
create mode 100644 cmd/nigiri/rpc.go
create mode 100644 cmd/nigiri/start.go
create mode 100644 cmd/nigiri/state.go
create mode 100644 cmd/nigiri/stop.go
create mode 100644 cmd/nigiri/version.go
create mode 100644 go.sum
diff --git a/cmd/nigiri/faucet.go b/cmd/nigiri/faucet.go
new file mode 100644
index 0000000..06ab7d0
--- /dev/null
+++ b/cmd/nigiri/faucet.go
@@ -0,0 +1 @@
+package main
diff --git a/cmd/nigiri/logs.go b/cmd/nigiri/logs.go
new file mode 100644
index 0000000..06ab7d0
--- /dev/null
+++ b/cmd/nigiri/logs.go
@@ -0,0 +1 @@
+package main
diff --git a/cmd/nigiri/main.go b/cmd/nigiri/main.go
new file mode 100644
index 0000000..47b1b2e
--- /dev/null
+++ b/cmd/nigiri/main.go
@@ -0,0 +1,188 @@
+package main
+
+import (
+ "embed"
+ "errors"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "strconv"
+
+ "github.com/btcsuite/btcutil"
+ "github.com/urfave/cli/v2"
+)
+
+var (
+ version = "dev"
+ commit = "none"
+ date = "unknown"
+
+ defaultDataDir = btcutil.AppDataDir("nigiri-new", false)
+
+ statePath = filepath.Join(defaultDataDir, "nigiri.config.json")
+ initialState = map[string]string{
+ "attachliquid": strconv.FormatBool(false),
+ "datadir": defaultDataDir,
+ "network": "regtest",
+ "ready": strconv.FormatBool(false),
+ }
+
+ regtestCompose = "docker-compose-regtest.yml"
+ regtestLiquidCompose = "docker-compose-regtest-liquid.yml"
+)
+
+var liquidFlag = cli.BoolFlag{
+ Name: "liquid",
+ Usage: "enable liquid",
+ Value: false,
+}
+
+//go:embed resources/docker-compose-regtest.yml
+//go:embed resources/docker-compose-regtest-liquid.yml
+//go:embed resources/bitcoin.conf
+//go:embed resources/elements.conf
+
+var f embed.FS
+
+func init() {
+ if err := provisionResourcesToDatadir(); err != nil {
+ fatal(err)
+ }
+}
+
+func main() {
+ app := cli.NewApp()
+
+ app.Version = formatVersion()
+ app.Name = "nigiri CLI"
+ app.Usage = "Create your dockerized environment with a bitcoin and liquid node, with a block explorer and developer tools"
+ app.Commands = append(
+ app.Commands,
+ &start,
+ )
+
+ // check the datadirectory
+
+ err := app.Run(os.Args)
+ if err != nil {
+ fatal(err)
+ }
+}
+
+type invalidUsageError struct {
+ ctx *cli.Context
+ command string
+}
+
+func (e *invalidUsageError) Error() string {
+ return fmt.Sprintf("invalid usage of command %s", e.command)
+}
+
+func fatal(err error) {
+ var e *invalidUsageError
+ if errors.As(err, &e) {
+ _ = cli.ShowCommandHelp(e.ctx, e.command)
+ } else {
+ _, _ = fmt.Fprintf(os.Stderr, "[nigiri] %v\n", err)
+ }
+ os.Exit(1)
+}
+
+func getCompose(isLiquid bool) string {
+ if isLiquid {
+ return filepath.Join(defaultDataDir, regtestLiquidCompose)
+ }
+
+ return filepath.Join(defaultDataDir, regtestCompose)
+}
+
+func provisionResourcesToDatadir() error {
+ stateConfig, err := getState()
+ if err != nil {
+ return err
+ }
+
+ if _, ok := stateConfig["ready"]; !ok {
+ return errors.New("missing config file in data directory")
+ }
+
+ isReady, err := strconv.ParseBool(stateConfig["ready"])
+ if err != nil {
+ return err
+ }
+
+ if isReady {
+ return nil
+ }
+
+ // create folders in volumes/{bitcoin,elements} for node datadirs
+ if err := makeDirectoryIfNotExists(filepath.Join(defaultDataDir, "volumes", "bitcoin")); err != nil {
+ return err
+ }
+ if err := makeDirectoryIfNotExists(filepath.Join(defaultDataDir, "volumes", "elements")); err != nil {
+ return err
+ }
+
+ // copy resources into the Nigiri data directory
+ if err := copyFromResourcesToDatadir(
+ filepath.Join("resources", regtestCompose),
+ filepath.Join(defaultDataDir, regtestCompose),
+ ); err != nil {
+ return err
+ }
+
+ if err := copyFromResourcesToDatadir(
+ filepath.Join("resources", regtestLiquidCompose),
+ filepath.Join(defaultDataDir, regtestLiquidCompose),
+ ); err != nil {
+ return err
+ }
+
+ if err := copyFromResourcesToDatadir(
+ filepath.Join("resources", "bitcoin.conf"),
+ filepath.Join(defaultDataDir, "volumes", "bitcoin", "bitcoin.conf"),
+ ); err != nil {
+ return err
+ }
+
+ if err := copyFromResourcesToDatadir(
+ filepath.Join("resources", "elements.conf"),
+ filepath.Join(defaultDataDir, "volumes", "elements", "elements.conf"),
+ ); err != nil {
+ return err
+ }
+
+ if err := setState(map[string]string{"ready": strconv.FormatBool(true)}); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func formatVersion() string {
+ return fmt.Sprintf(
+ "\nVersion: %s\nCommit: %s\nDate: %s",
+ version, commit, date,
+ )
+}
+
+func copyFromResourcesToDatadir(src string, dest string) error {
+ data, err := f.ReadFile(src)
+ if err != nil {
+ return fmt.Errorf("read embed: %w", err)
+ }
+ err = ioutil.WriteFile(dest, data, 0777)
+ if err != nil {
+ return fmt.Errorf("write %s to %s: %w", src, dest, err)
+ }
+
+ return nil
+}
+
+func makeDirectoryIfNotExists(path string) error {
+ if _, err := os.Stat(path); os.IsNotExist(err) {
+ return os.MkdirAll(path, os.ModeDir|0755)
+ }
+ return nil
+}
diff --git a/cmd/nigiri/mint.go b/cmd/nigiri/mint.go
new file mode 100644
index 0000000..06ab7d0
--- /dev/null
+++ b/cmd/nigiri/mint.go
@@ -0,0 +1 @@
+package main
diff --git a/cmd/nigiri/push.go b/cmd/nigiri/push.go
new file mode 100644
index 0000000..06ab7d0
--- /dev/null
+++ b/cmd/nigiri/push.go
@@ -0,0 +1 @@
+package main
diff --git a/cmd/nigiri/resources/bitcoin.conf b/cmd/nigiri/resources/bitcoin.conf
new file mode 100644
index 0000000..f7e765e
--- /dev/null
+++ b/cmd/nigiri/resources/bitcoin.conf
@@ -0,0 +1,17 @@
+regtest=1
+testnet=0
+dnsseed=0
+upnp=0
+
+[regtest]
+port=18444
+rpcport=18443
+
+server=1
+txindex=1
+
+rpcuser=admin1
+rpcpassword=123
+rpcallowip=0.0.0.0/0
+rpcbind=0.0.0.0
+fallbackfee=0.00001
diff --git a/cmd/nigiri/resources/docker-compose-regtest-liquid.yml b/cmd/nigiri/resources/docker-compose-regtest-liquid.yml
new file mode 100644
index 0000000..49bac47
--- /dev/null
+++ b/cmd/nigiri/resources/docker-compose-regtest-liquid.yml
@@ -0,0 +1,149 @@
+version: '3.5'
+services:
+ # RPC daemons
+ bitcoin:
+ image: vulpemventures/bitcoin:latest
+ container_name: bitcoin
+ ports:
+ - ${BITCOIN_PEER_PORT}:19000
+ - ${BITCOIN_NODE_PORT}:19001
+ volumes:
+ - ./volumes/liquidregtest/config/:/config
+ restart: unless-stopped
+ liquid:
+ image: ghcr.io/vulpemventures/elements:latest
+ container_name: liquid
+ command:
+ - -datadir=config
+ ports:
+ - ${LIQUID_NODE_PORT}:18884
+ - ${LIQUID_PEER_PORT}:18886
+ volumes:
+ - ./volumes/liquidregtest/liquid-config/:/config
+ restart: unless-stopped
+ # Block explorer REST servers
+ electrs:
+ image: vulpemventures/electrs:latest
+ container_name: electrs
+ entrypoint:
+ - /build/electrs
+ command:
+ - -vvvv
+ - --network
+ - regtest
+ - --daemon-dir
+ - /config
+ - --daemon-rpc-addr
+ - bitcoin:19001
+ - --cookie
+ - admin1:123
+ - --http-addr
+ - 0.0.0.0:3002
+ - --electrum-rpc-addr
+ - 0.0.0.0:60401
+ - --cors
+ - "*"
+ depends_on:
+ - bitcoin
+ ports:
+ - ${BITCOIN_ELECTRS_RPC_PORT}:60401
+ - ${BITCOIN_ELECTRS_PORT}:3002
+ volumes:
+ - ./volumes/liquidregtest/config/:/config
+ restart: unless-stopped
+ electrs-liquid:
+ image: vulpemventures/electrs-liquid:latest
+ container_name: electrs-liquid
+ entrypoint:
+ - /build/electrs
+ command:
+ - -vvvv
+ - --parent-network
+ - regtest
+ - --network
+ - liquidregtest
+ - --daemon-dir
+ - /config
+ - --daemon-rpc-addr
+ - liquid:18884
+ - --cookie
+ - admin1:123
+ - --http-addr
+ - 0.0.0.0:3002
+ - --electrum-rpc-addr
+ - 0.0.0.0:60401
+ - --cors
+ - "*"
+ depends_on:
+ - liquid
+ ports:
+ - ${LIQUID_ELECTRS_RPC_PORT}:60401
+ - ${LIQUID_ELECTRS_PORT}:3002
+ volumes:
+ - ./volumes/liquidregtest/liquid-config/:/config
+ restart: unless-stopped
+ # Block explorer frontends
+ esplora:
+ image: vulpemventures/esplora:latest
+ container_name: esplora
+ depends_on:
+ - chopsticks
+ environment:
+ API_URL: ${BITCOIN_ESPLORA_URL}
+ ports:
+ - ${BITCOIN_ESPLORA_PORT}:5000
+ restart: unless-stopped
+ esplora-liquid:
+ image: vulpemventures/esplora:latest
+ container_name: esplora-liquid
+ depends_on:
+ - chopsticks-liquid
+ environment:
+ API_URL: ${LIQUID_ESPLORA_URL}
+ ports:
+ - ${LIQUID_ESPLORA_PORT}:5000
+ restart: unless-stopped
+ # Chopsticks
+ chopsticks:
+ image: vulpemventures/nigiri-chopsticks:latest
+ container_name: chopsticks
+ command:
+ - --use-faucet
+ - --use-mining
+ - --use-logger
+ - --rpc-addr
+ - bitcoin:19001
+ - --electrs-addr
+ - electrs:3002
+ - --addr
+ - 0.0.0.0:3000
+ depends_on:
+ - bitcoin
+ - electrs
+ ports:
+ - ${BITCOIN_CHOPSTICKS_PORT}:3000
+ restart: unless-stopped
+ chopsticks-liquid:
+ image: vulpemventures/nigiri-chopsticks:latest
+ container_name: chopsticks-liquid
+ command:
+ - --use-faucet
+ - --use-mining
+ - --use-logger
+ - --rpc-addr
+ - liquid:18884
+ - --electrs-addr
+ - electrs-liquid:3002
+ - --addr
+ - 0.0.0.0:3000
+ - --chain
+ - liquid
+ depends_on:
+ - liquid
+ - electrs-liquid
+ ports:
+ - ${LIQUID_CHOPSTICKS_PORT}:3000
+ restart: unless-stopped
+networks:
+ default:
+ name: nigiri
diff --git a/cmd/nigiri/resources/docker-compose-regtest.yml b/cmd/nigiri/resources/docker-compose-regtest.yml
new file mode 100644
index 0000000..69e9d03
--- /dev/null
+++ b/cmd/nigiri/resources/docker-compose-regtest.yml
@@ -0,0 +1,82 @@
+version: '3.5'
+services:
+ # RPC daemon
+ bitcoin:
+ image: ghcr.io/vulpemventures/bitcoin:latest
+ container_name: bitcoin
+ command:
+ - -datadir=config
+ ports:
+ - 18443:18433
+ - 18444:18444
+ volumes:
+ - ./volumes/bitcoin/:/config
+ restart: unless-stopped
+
+ # Block explorer server
+ electrs:
+ image: ghcr.io/vulpemventures/electrs:latest
+ container_name: electrs
+ entrypoint:
+ - /build/electrs
+ command:
+ - -vvvv
+ - --network
+ - regtest
+ - --daemon-dir
+ - /config
+ - --daemon-rpc-addr
+ - bitcoin:18443
+ - --cookie
+ - admin1:123
+ - --http-addr
+ - 0.0.0.0:30000
+ - --electrum-rpc-addr
+ - 0.0.0.0:50000
+ - --cors
+ - "*"
+ depends_on:
+ - bitcoin
+ ports:
+ - 50000:50000
+ - 30000:30000
+ volumes:
+ - ./volumes/bitcoin/:/config
+ restart: unless-stopped
+
+ # Block explorer frontend
+ esplora:
+ image: ghcr.io/vulpemventures/esplora:latest
+ container_name: esplora
+ depends_on:
+ - chopsticks
+ environment:
+ API_URL: http://localhost:3000
+ ports:
+ - 5000:5000
+ restart: unless-stopped
+
+ # Chopsticks
+ chopsticks:
+ image: ghcr.io/vulpemventures/nigiri-chopsticks:latest
+ container_name: chopsticks
+ command:
+ - --use-faucet
+ - --use-mining
+ - --use-logger
+ - --rpc-addr
+ - bitcoin:18443
+ - --electrs-addr
+ - electrs:30000
+ - --addr
+ - 0.0.0.0:3000
+ depends_on:
+ - bitcoin
+ - electrs
+ ports:
+ - 3000:3000
+ restart: unless-stopped
+
+networks:
+ default:
+ name: nigiri
diff --git a/cmd/nigiri/resources/elements.conf b/cmd/nigiri/resources/elements.conf
new file mode 100644
index 0000000..728379b
--- /dev/null
+++ b/cmd/nigiri/resources/elements.conf
@@ -0,0 +1,35 @@
+chain=liquidregtest
+listen=1
+txindex=1
+
+[liquidregtest]
+port=18844
+rpcport=18843
+rpcuser=admin1
+rpcpassword=123
+rpcallowip=0.0.0.0/0
+rpcbind=0.0.0.0
+
+mainchainrpcport=18443
+#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.
+# This template is 1-of-1 checkmultisig
+#fedpegscript=512151ae
+
+# This is the script that controls how blocks are made
+# We have to supply a signature that satisfies this to create
+# a valid block.
+#signblockscript=512151ae
+
+# 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
+initialfreecoins=2100000000000000
+fallbackfee=0.000001
diff --git a/cmd/nigiri/rpc.go b/cmd/nigiri/rpc.go
new file mode 100644
index 0000000..06ab7d0
--- /dev/null
+++ b/cmd/nigiri/rpc.go
@@ -0,0 +1 @@
+package main
diff --git a/cmd/nigiri/start.go b/cmd/nigiri/start.go
new file mode 100644
index 0000000..526b252
--- /dev/null
+++ b/cmd/nigiri/start.go
@@ -0,0 +1,33 @@
+package main
+
+import (
+ "os"
+ "os/exec"
+
+ "github.com/urfave/cli/v2"
+)
+
+var start = cli.Command{
+ Name: "start",
+ Usage: "start nigiri box",
+ Action: startAction,
+ Flags: []cli.Flag{
+ &liquidFlag,
+ },
+}
+
+func startAction(ctx *cli.Context) error {
+
+ isLiquid := ctx.Bool("liquid")
+ composePath := getCompose(isLiquid)
+
+ bashCmd := exec.Command("docker-compose", "-f", composePath, "up", "-d")
+ bashCmd.Stdout = os.Stdout
+ bashCmd.Stderr = os.Stderr
+
+ if err := bashCmd.Run(); err != nil {
+ return err
+ }
+
+ return nil
+}
diff --git a/cmd/nigiri/state.go b/cmd/nigiri/state.go
new file mode 100644
index 0000000..78031f8
--- /dev/null
+++ b/cmd/nigiri/state.go
@@ -0,0 +1,68 @@
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
+ "os"
+)
+
+func getState() (map[string]string, error) {
+ file, err := ioutil.ReadFile(statePath)
+ if err != nil {
+ if !os.IsNotExist(err) {
+ return nil, err
+ }
+ if err := setState(initialState); err != nil {
+ return nil, err
+ }
+ return initialState, nil
+ }
+
+ data := map[string]string{}
+ json.Unmarshal(file, &data)
+
+ return data, nil
+}
+
+func setState(data map[string]string) error {
+ if _, err := os.Stat(defaultDataDir); os.IsNotExist(err) {
+ os.Mkdir(defaultDataDir, os.ModeDir|0755)
+ }
+
+ file, err := os.OpenFile(statePath, os.O_RDONLY|os.O_CREATE, 0644)
+ if err != nil {
+ return err
+ }
+ if err := file.Close(); err != nil {
+ return err
+ }
+
+ currentData, err := getState()
+ if err != nil {
+ return err
+ }
+
+ mergedData := merge(currentData, data)
+
+ jsonString, err := json.Marshal(mergedData)
+ if err != nil {
+ return err
+ }
+ err = ioutil.WriteFile(statePath, jsonString, 0755)
+ if err != nil {
+ return fmt.Errorf("writing to file: %w", err)
+ }
+
+ return nil
+}
+
+func merge(maps ...map[string]string) map[string]string {
+ merge := make(map[string]string, 0)
+ for _, m := range maps {
+ for k, v := range m {
+ merge[k] = v
+ }
+ }
+ return merge
+}
diff --git a/cmd/nigiri/stop.go b/cmd/nigiri/stop.go
new file mode 100644
index 0000000..06ab7d0
--- /dev/null
+++ b/cmd/nigiri/stop.go
@@ -0,0 +1 @@
+package main
diff --git a/cmd/nigiri/version.go b/cmd/nigiri/version.go
new file mode 100644
index 0000000..06ab7d0
--- /dev/null
+++ b/cmd/nigiri/version.go
@@ -0,0 +1 @@
+package main
diff --git a/go.mod b/go.mod
index eef2a94..7338946 100644
--- a/go.mod
+++ b/go.mod
@@ -1,3 +1,10 @@
module github.com/vulpemventures/nigiri
go 1.16
+
+require (
+ github.com/btcsuite/btcd v0.21.0-beta // indirect
+ github.com/btcsuite/btcutil v1.0.2
+ github.com/urfave/cli/v2 v2.3.0
+ golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad // indirect
+)
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..6b32a74
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,62 @@
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
+github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
+github.com/btcsuite/btcd v0.21.0-beta h1:At9hIZdJW0s9E/fAz28nrz6AmcNlSVucCH796ZteX1M=
+github.com/btcsuite/btcd v0.21.0-beta/go.mod h1:ZSWyehm27aAuS9bvkATT+Xte3hjHZ+MRgMY/8NJ7K94=
+github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
+github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
+github.com/btcsuite/btcutil v1.0.2 h1:9iZ1Terx9fMIOtq1VrwdqfsATL9MC2l8ZrUY6YZ2uts=
+github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts=
+github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg=
+github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY=
+github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I=
+github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
+github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
+github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY=
+github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
+github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
+github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
+github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218=
+github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
+github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
+github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
+github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
+github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
+github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
+github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
+github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
+github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
+github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
+github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M=
+github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
+golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY=
+golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
+golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
+gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
From 4160ee0c0c50eafeab4073791164aee80b8da8bf Mon Sep 17 00:00:00 2001
From: Marco Argentieri <3596602+tiero@users.noreply.github.com>
Date: Tue, 3 Aug 2021 14:59:04 +0200
Subject: [PATCH 03/28] start --liquid
---
.../docker-compose-regtest-liquid.yml | 83 ++++++++++---------
cmd/nigiri/resources/elements.conf | 4 +-
cmd/nigiri/state.go | 2 +-
3 files changed, 49 insertions(+), 40 deletions(-)
diff --git a/cmd/nigiri/resources/docker-compose-regtest-liquid.yml b/cmd/nigiri/resources/docker-compose-regtest-liquid.yml
index 49bac47..e7be3da 100644
--- a/cmd/nigiri/resources/docker-compose-regtest-liquid.yml
+++ b/cmd/nigiri/resources/docker-compose-regtest-liquid.yml
@@ -1,29 +1,33 @@
version: '3.5'
services:
- # RPC daemons
+ # RPC daemon
bitcoin:
- image: vulpemventures/bitcoin:latest
+ image: ghcr.io/vulpemventures/bitcoin:latest
container_name: bitcoin
+ command:
+ - -datadir=config
ports:
- - ${BITCOIN_PEER_PORT}:19000
- - ${BITCOIN_NODE_PORT}:19001
+ - 18443:18433
+ - 18444:18444
volumes:
- - ./volumes/liquidregtest/config/:/config
+ - ./volumes/bitcoin/:/config
restart: unless-stopped
+
liquid:
image: ghcr.io/vulpemventures/elements:latest
container_name: liquid
command:
- -datadir=config
ports:
- - ${LIQUID_NODE_PORT}:18884
- - ${LIQUID_PEER_PORT}:18886
+ - 18884:18884
+ - 18886:18886
volumes:
- - ./volumes/liquidregtest/liquid-config/:/config
+ - ./volumes/elements/:/config
restart: unless-stopped
- # Block explorer REST servers
+
+ # Block explorer server
electrs:
- image: vulpemventures/electrs:latest
+ image: ghcr.io/vulpemventures/electrs:latest
container_name: electrs
entrypoint:
- /build/electrs
@@ -34,25 +38,26 @@ services:
- --daemon-dir
- /config
- --daemon-rpc-addr
- - bitcoin:19001
+ - bitcoin:18443
- --cookie
- admin1:123
- --http-addr
- - 0.0.0.0:3002
+ - 0.0.0.0:30000
- --electrum-rpc-addr
- - 0.0.0.0:60401
+ - 0.0.0.0:50000
- --cors
- "*"
depends_on:
- bitcoin
ports:
- - ${BITCOIN_ELECTRS_RPC_PORT}:60401
- - ${BITCOIN_ELECTRS_PORT}:3002
+ - 50000:50000
+ - 30000:30000
volumes:
- - ./volumes/liquidregtest/config/:/config
+ - ./volumes/bitcoin/:/config
restart: unless-stopped
+
electrs-liquid:
- image: vulpemventures/electrs-liquid:latest
+ image: ghcr.io/vulpemventures/electrs-liquid:latest
container_name: electrs-liquid
entrypoint:
- /build/electrs
@@ -69,62 +74,65 @@ services:
- --cookie
- admin1:123
- --http-addr
- - 0.0.0.0:3002
+ - 0.0.0.0:30001
- --electrum-rpc-addr
- - 0.0.0.0:60401
+ - 0.0.0.0:50001
- --cors
- "*"
depends_on:
- liquid
ports:
- - ${LIQUID_ELECTRS_RPC_PORT}:60401
- - ${LIQUID_ELECTRS_PORT}:3002
+ - 50001:50001
+ - 30001:30001
volumes:
- - ./volumes/liquidregtest/liquid-config/:/config
+ - ./volumes/elements/:/config
restart: unless-stopped
- # Block explorer frontends
+
+ # Block explorer frontend
esplora:
- image: vulpemventures/esplora:latest
+ image: ghcr.io/vulpemventures/esplora:latest
container_name: esplora
depends_on:
- chopsticks
- environment:
- API_URL: ${BITCOIN_ESPLORA_URL}
+ environment:
+ API_URL: http://localhost:3000
ports:
- - ${BITCOIN_ESPLORA_PORT}:5000
+ - 5000:5000
restart: unless-stopped
+
esplora-liquid:
- image: vulpemventures/esplora:latest
+ image: ghcr.io/vulpemventures/esplora:latest
container_name: esplora-liquid
depends_on:
- chopsticks-liquid
environment:
- API_URL: ${LIQUID_ESPLORA_URL}
+ API_URL: http://localhost:3001
ports:
- - ${LIQUID_ESPLORA_PORT}:5000
+ - 5001:5000
restart: unless-stopped
# Chopsticks
chopsticks:
- image: vulpemventures/nigiri-chopsticks:latest
+ image: ghcr.io/vulpemventures/nigiri-chopsticks:latest
container_name: chopsticks
command:
- --use-faucet
- --use-mining
- --use-logger
- --rpc-addr
- - bitcoin:19001
+ - bitcoin:18443
- --electrs-addr
- - electrs:3002
+ - electrs:30000
- --addr
- 0.0.0.0:3000
depends_on:
- bitcoin
- electrs
ports:
- - ${BITCOIN_CHOPSTICKS_PORT}:3000
+ - 3000:3000
restart: unless-stopped
+
chopsticks-liquid:
- image: vulpemventures/nigiri-chopsticks:latest
+ image: ghcr.io/vulpemventures/nigiri-chopsticks:latest
container_name: chopsticks-liquid
command:
- --use-faucet
@@ -133,7 +141,7 @@ services:
- --rpc-addr
- liquid:18884
- --electrs-addr
- - electrs-liquid:3002
+ - electrs-liquid:30001
- --addr
- 0.0.0.0:3000
- --chain
@@ -142,8 +150,9 @@ services:
- liquid
- electrs-liquid
ports:
- - ${LIQUID_CHOPSTICKS_PORT}:3000
+ - 3001:3000
restart: unless-stopped
+
networks:
default:
name: nigiri
diff --git a/cmd/nigiri/resources/elements.conf b/cmd/nigiri/resources/elements.conf
index 728379b..32b70d5 100644
--- a/cmd/nigiri/resources/elements.conf
+++ b/cmd/nigiri/resources/elements.conf
@@ -3,8 +3,8 @@ listen=1
txindex=1
[liquidregtest]
-port=18844
-rpcport=18843
+port=18886
+rpcport=18884
rpcuser=admin1
rpcpassword=123
rpcallowip=0.0.0.0/0
diff --git a/cmd/nigiri/state.go b/cmd/nigiri/state.go
index 78031f8..a9c79bb 100644
--- a/cmd/nigiri/state.go
+++ b/cmd/nigiri/state.go
@@ -58,7 +58,7 @@ func setState(data map[string]string) error {
}
func merge(maps ...map[string]string) map[string]string {
- merge := make(map[string]string, 0)
+ merge := make(map[string]string)
for _, m := range maps {
for k, v := range m {
merge[k] = v
From a5e14d2d2606ca9e0a52716a1644c3ae47c17126 Mon Sep 17 00:00:00 2001
From: Marco Argentieri <3596602+tiero@users.noreply.github.com>
Date: Tue, 3 Aug 2021 15:38:16 +0200
Subject: [PATCH 04/28] check if is running already
---
cmd/nigiri/main.go | 13 +++------
cmd/nigiri/start.go | 20 +++++++++++++-
cmd/nigiri/state.go | 20 ++++++++++++++
cmd/nigiri/stop.go | 64 +++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 106 insertions(+), 11 deletions(-)
diff --git a/cmd/nigiri/main.go b/cmd/nigiri/main.go
index 47b1b2e..760cb76 100644
--- a/cmd/nigiri/main.go
+++ b/cmd/nigiri/main.go
@@ -26,6 +26,7 @@ var (
"datadir": defaultDataDir,
"network": "regtest",
"ready": strconv.FormatBool(false),
+ "running": strconv.FormatBool(false),
}
regtestCompose = "docker-compose-regtest.yml"
@@ -60,6 +61,7 @@ func main() {
app.Commands = append(
app.Commands,
&start,
+ &stop,
)
// check the datadirectory
@@ -98,16 +100,7 @@ func getCompose(isLiquid bool) string {
}
func provisionResourcesToDatadir() error {
- stateConfig, err := getState()
- if err != nil {
- return err
- }
-
- if _, ok := stateConfig["ready"]; !ok {
- return errors.New("missing config file in data directory")
- }
-
- isReady, err := strconv.ParseBool(stateConfig["ready"])
+ isReady, err := getBoolFromState("ready")
if err != nil {
return err
}
diff --git a/cmd/nigiri/start.go b/cmd/nigiri/start.go
index 526b252..5ddf206 100644
--- a/cmd/nigiri/start.go
+++ b/cmd/nigiri/start.go
@@ -1,15 +1,17 @@
package main
import (
+ "errors"
"os"
"os/exec"
+ "strconv"
"github.com/urfave/cli/v2"
)
var start = cli.Command{
Name: "start",
- Usage: "start nigiri box",
+ Usage: "start nigiri",
Action: startAction,
Flags: []cli.Flag{
&liquidFlag,
@@ -18,6 +20,15 @@ var start = cli.Command{
func startAction(ctx *cli.Context) error {
+ isRunning, err := getBoolFromState("running")
+ if err != nil {
+ return err
+ }
+
+ if isRunning {
+ return errors.New("nigiri is already running, please stop it first")
+ }
+
isLiquid := ctx.Bool("liquid")
composePath := getCompose(isLiquid)
@@ -29,5 +40,12 @@ func startAction(ctx *cli.Context) error {
return err
}
+ if err := setState(map[string]string{
+ "attachliquid": strconv.FormatBool(isLiquid),
+ "running": strconv.FormatBool(true),
+ }); err != nil {
+ return err
+ }
+
return nil
}
diff --git a/cmd/nigiri/state.go b/cmd/nigiri/state.go
index a9c79bb..4fb7981 100644
--- a/cmd/nigiri/state.go
+++ b/cmd/nigiri/state.go
@@ -2,9 +2,11 @@ package main
import (
"encoding/json"
+ "errors"
"fmt"
"io/ioutil"
"os"
+ "strconv"
)
func getState() (map[string]string, error) {
@@ -66,3 +68,21 @@ func merge(maps ...map[string]string) map[string]string {
}
return merge
}
+
+func getBoolFromState(key string) (bool, error) {
+ stateConfig, err := getState()
+ if err != nil {
+ return false, err
+ }
+
+ if _, ok := stateConfig[key]; !ok {
+ return false, errors.New("config: missing key " + key)
+ }
+
+ value, err := strconv.ParseBool(stateConfig[key])
+ if err != nil {
+ return false, err
+ }
+
+ return value, nil
+}
diff --git a/cmd/nigiri/stop.go b/cmd/nigiri/stop.go
index 06ab7d0..88bb015 100644
--- a/cmd/nigiri/stop.go
+++ b/cmd/nigiri/stop.go
@@ -1 +1,65 @@
package main
+
+import (
+ "fmt"
+ "os"
+ "os/exec"
+ "strconv"
+
+ "github.com/urfave/cli/v2"
+)
+
+var stop = cli.Command{
+ Name: "stop",
+ Usage: "stop nigiri",
+ Action: stopAction,
+ Flags: []cli.Flag{
+ &cli.BoolFlag{
+ Name: "delete",
+ Usage: "clean node data directories",
+ Value: false,
+ },
+ },
+}
+
+func stopAction(ctx *cli.Context) error {
+
+ delete := ctx.Bool("delete")
+ isLiquid, err := getBoolFromState("attachliquid")
+ if err != nil {
+ return err
+ }
+ composePath := getCompose(isLiquid)
+
+ bashCmd := exec.Command("docker-compose", "-f", composePath, "stop")
+ if delete {
+ bashCmd = exec.Command("docker-compose", "-f", composePath, "down", "--volumes")
+ }
+ bashCmd.Stdout = os.Stdout
+ bashCmd.Stderr = os.Stderr
+
+ if err := bashCmd.Run(); err != nil {
+ return err
+ }
+
+ if delete {
+ fmt.Println("Removing data from volumes...")
+ if err := os.RemoveAll(defaultDataDir); err != nil {
+ return err
+ }
+
+ if err := provisionResourcesToDatadir(); err != nil {
+ return err
+ }
+
+ fmt.Println("Nigiri has been cleaned up successfully.")
+ } else {
+ if err := setState(map[string]string{
+ "running": strconv.FormatBool(false),
+ }); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
From ecdcf0fc7b3f8c02934720cddbc1b53edbe93a10 Mon Sep 17 00:00:00 2001
From: Marco Argentieri <3596602+tiero@users.noreply.github.com>
Date: Tue, 3 Aug 2021 16:17:07 +0200
Subject: [PATCH 05/28] Add rpc command
---
cmd/nigiri/faucet.go | 1 -
cmd/nigiri/logs.go | 1 -
cmd/nigiri/main.go | 4 ++--
cmd/nigiri/mint.go | 1 -
cmd/nigiri/push.go | 1 -
cmd/nigiri/rpc.go | 52 +++++++++++++++++++++++++++++++++++++++++++
cmd/nigiri/version.go | 1 -
7 files changed, 54 insertions(+), 7 deletions(-)
delete mode 100644 cmd/nigiri/faucet.go
delete mode 100644 cmd/nigiri/logs.go
delete mode 100644 cmd/nigiri/mint.go
delete mode 100644 cmd/nigiri/push.go
delete mode 100644 cmd/nigiri/version.go
diff --git a/cmd/nigiri/faucet.go b/cmd/nigiri/faucet.go
deleted file mode 100644
index 06ab7d0..0000000
--- a/cmd/nigiri/faucet.go
+++ /dev/null
@@ -1 +0,0 @@
-package main
diff --git a/cmd/nigiri/logs.go b/cmd/nigiri/logs.go
deleted file mode 100644
index 06ab7d0..0000000
--- a/cmd/nigiri/logs.go
+++ /dev/null
@@ -1 +0,0 @@
-package main
diff --git a/cmd/nigiri/main.go b/cmd/nigiri/main.go
index 760cb76..cba6fac 100644
--- a/cmd/nigiri/main.go
+++ b/cmd/nigiri/main.go
@@ -43,7 +43,6 @@ var liquidFlag = cli.BoolFlag{
//go:embed resources/docker-compose-regtest-liquid.yml
//go:embed resources/bitcoin.conf
//go:embed resources/elements.conf
-
var f embed.FS
func init() {
@@ -57,11 +56,12 @@ func main() {
app.Version = formatVersion()
app.Name = "nigiri CLI"
- app.Usage = "Create your dockerized environment with a bitcoin and liquid node, with a block explorer and developer tools"
+ app.Usage = "create your dockerized environment with a bitcoin and liquid node, with a block explorer and developer tools"
app.Commands = append(
app.Commands,
&start,
&stop,
+ &rpc,
)
// check the datadirectory
diff --git a/cmd/nigiri/mint.go b/cmd/nigiri/mint.go
deleted file mode 100644
index 06ab7d0..0000000
--- a/cmd/nigiri/mint.go
+++ /dev/null
@@ -1 +0,0 @@
-package main
diff --git a/cmd/nigiri/push.go b/cmd/nigiri/push.go
deleted file mode 100644
index 06ab7d0..0000000
--- a/cmd/nigiri/push.go
+++ /dev/null
@@ -1 +0,0 @@
-package main
diff --git a/cmd/nigiri/rpc.go b/cmd/nigiri/rpc.go
index 06ab7d0..f733440 100644
--- a/cmd/nigiri/rpc.go
+++ b/cmd/nigiri/rpc.go
@@ -1 +1,53 @@
package main
+
+import (
+ "errors"
+ "os"
+ "os/exec"
+
+ "github.com/urfave/cli/v2"
+)
+
+var rpc = cli.Command{
+ Name: "rpc",
+ Usage: "invoke bitcoin-cli or elements-cli",
+ Action: rpcAction,
+ Flags: []cli.Flag{
+ &liquidFlag,
+ &cli.StringFlag{
+ Name: "rpcwallet",
+ Usage: "rpcwallet to be used for node JSONRPC commands",
+ Value: "",
+ },
+ },
+}
+
+func rpcAction(ctx *cli.Context) error {
+
+ isRunning, err := getBoolFromState("running")
+ if err != nil {
+ return err
+ }
+
+ if !isRunning {
+ return errors.New("nigiri is not running")
+ }
+
+ isLiquid := ctx.Bool("liquid")
+ rpcWallet := ctx.String("rpcwallet")
+
+ rpcArgs := []string{"exec", "bitcoin", "bitcoin-cli", "-datadir=config", "-rpcwallet=" + rpcWallet}
+ if isLiquid {
+ rpcArgs = []string{"exec", "liquid", "elements-cli", "-datadir=config", "-rpcwallet=" + rpcWallet}
+ }
+ cmdArgs := append(rpcArgs, ctx.Args().Slice()...)
+ bashCmd := exec.Command("docker", cmdArgs...)
+ bashCmd.Stdout = os.Stdout
+ bashCmd.Stderr = os.Stderr
+
+ if err := bashCmd.Run(); err != nil {
+ return err
+ }
+
+ return nil
+}
diff --git a/cmd/nigiri/version.go b/cmd/nigiri/version.go
deleted file mode 100644
index 06ab7d0..0000000
--- a/cmd/nigiri/version.go
+++ /dev/null
@@ -1 +0,0 @@
-package main
From 20a8af4b59c7eb2518f8f88cb1da1f0f6bbe5cdb Mon Sep 17 00:00:00 2001
From: Marco Argentieri <3596602+tiero@users.noreply.github.com>
Date: Tue, 3 Aug 2021 17:26:10 +0200
Subject: [PATCH 06/28] Add logs and faucet commands
---
cmd/nigiri/faucet.go | 85 +++++++++++++++++++++
cmd/nigiri/logs.go | 49 ++++++++++++
cmd/nigiri/main.go | 2 +
go.mod | 1 +
go.sum | 152 ++++++++++++++++++++++++++++++++++++++
internal/docker/docker.go | 67 +++++++++++++++++
6 files changed, 356 insertions(+)
create mode 100644 cmd/nigiri/faucet.go
create mode 100644 cmd/nigiri/logs.go
create mode 100644 internal/docker/docker.go
diff --git a/cmd/nigiri/faucet.go b/cmd/nigiri/faucet.go
new file mode 100644
index 0000000..eeb2c6b
--- /dev/null
+++ b/cmd/nigiri/faucet.go
@@ -0,0 +1,85 @@
+package main
+
+import (
+ "bytes"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io/ioutil"
+ "net/http"
+ "strings"
+
+ "github.com/urfave/cli/v2"
+ "github.com/vulpemventures/nigiri/internal/docker"
+)
+
+var faucet = cli.Command{
+ Name: "faucet",
+ Usage: "generate and send bitcoin to given address",
+ ArgsUsage: " [amount] [asset]",
+ Action: faucetAction,
+ Flags: []cli.Flag{
+ &liquidFlag,
+ },
+}
+
+func faucetAction(ctx *cli.Context) error {
+
+ isRunning, err := getBoolFromState("running")
+ if err != nil {
+ return err
+ }
+
+ if !isRunning {
+ return errors.New("nigiri is not running")
+ }
+
+ if ctx.NArg() < 1 || ctx.NArg() > 3 {
+ return errors.New("missing arguments")
+ }
+
+ isLiquid := ctx.Bool("liquid")
+ composePath := getCompose(isLiquid)
+
+ var serviceName string = "chopsticks"
+ if isLiquid {
+ serviceName = "chopsticks-liquid"
+ }
+
+ portSlice, err := docker.GetPortsForService(composePath, serviceName)
+ if err != nil {
+ return err
+ }
+ mappedPorts := strings.Split(portSlice[0], ":")
+
+ request := map[string]interface{}{
+ "address": ctx.Args().First(),
+ }
+ requestPort := mappedPorts[0]
+ payload, err := json.Marshal(request)
+ if err != nil {
+ return err
+ }
+ res, err := http.Post("http://127.0.0.1:"+requestPort+"/faucet", "application/json", bytes.NewBuffer(payload))
+ if err != nil {
+ return err
+ }
+ data, err := ioutil.ReadAll(res.Body)
+ if err != nil {
+ return err
+ }
+ if res.StatusCode != http.StatusOK {
+ return errors.New(string(data))
+ }
+
+ var dat map[string]string
+ if err := json.Unmarshal([]byte(data), &dat); err != nil {
+ return errors.New("internal error, please try again")
+ }
+ if dat["txId"] == "" {
+ return errors.New("not successful")
+ }
+ fmt.Println("txId: " + dat["txId"])
+
+ return nil
+}
diff --git a/cmd/nigiri/logs.go b/cmd/nigiri/logs.go
new file mode 100644
index 0000000..7920912
--- /dev/null
+++ b/cmd/nigiri/logs.go
@@ -0,0 +1,49 @@
+package main
+
+import (
+ "errors"
+ "os"
+ "os/exec"
+
+ "github.com/urfave/cli/v2"
+)
+
+var logs = cli.Command{
+ Name: "logs",
+ Usage: "check Service logs",
+ Action: logsAction,
+ Flags: []cli.Flag{
+ &liquidFlag,
+ },
+}
+
+func logsAction(ctx *cli.Context) error {
+
+ isRunning, err := getBoolFromState("running")
+ if err != nil {
+ return err
+ }
+
+ if !isRunning {
+ return errors.New("nigiri is not running")
+ }
+
+ if ctx.NArg() != 1 {
+ return errors.New("missing service name")
+ }
+
+ serviceName := ctx.Args().First()
+
+ isLiquid := ctx.Bool("liquid")
+ composePath := getCompose(isLiquid)
+
+ bashCmd := exec.Command("docker-compose", "-f", composePath, "logs", serviceName)
+ bashCmd.Stdout = os.Stdout
+ bashCmd.Stderr = os.Stderr
+
+ if err := bashCmd.Run(); err != nil {
+ return err
+ }
+
+ return nil
+}
diff --git a/cmd/nigiri/main.go b/cmd/nigiri/main.go
index cba6fac..8671c4d 100644
--- a/cmd/nigiri/main.go
+++ b/cmd/nigiri/main.go
@@ -62,6 +62,8 @@ func main() {
&start,
&stop,
&rpc,
+ &logs,
+ &faucet,
)
// check the datadirectory
diff --git a/go.mod b/go.mod
index 7338946..bfc1812 100644
--- a/go.mod
+++ b/go.mod
@@ -5,6 +5,7 @@ go 1.16
require (
github.com/btcsuite/btcd v0.21.0-beta // indirect
github.com/btcsuite/btcutil v1.0.2
+ github.com/compose-spec/compose-go v0.0.0-20210729195839-de56f4f0cb3c
github.com/urfave/cli/v2 v2.3.0
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad // indirect
)
diff --git a/go.sum b/go.sum
index 6b32a74..5bd5dbc 100644
--- a/go.sum
+++ b/go.sum
@@ -1,5 +1,18 @@
+cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
+github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
+github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
+github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
+github.com/aws/aws-sdk-go v1.34.9/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
+github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
+github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
+github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
+github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA=
+github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
+github.com/bshuster-repo/logrus-logstash-hook v1.0.0/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk=
github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
github.com/btcsuite/btcd v0.21.0-beta h1:At9hIZdJW0s9E/fAz28nrz6AmcNlSVucCH796ZteX1M=
github.com/btcsuite/btcd v0.21.0-beta/go.mod h1:ZSWyehm27aAuS9bvkATT+Xte3hjHZ+MRgMY/8NJ7K94=
@@ -14,49 +27,188 @@ github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku
github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY=
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
+github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8=
+github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50=
+github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE=
+github.com/compose-spec/compose-go v0.0.0-20210729195839-de56f4f0cb3c h1:lSR4wokZlq+Q8uJpgZuFMs3VoLaYVV07cJOZHa1zRBg=
+github.com/compose-spec/compose-go v0.0.0-20210729195839-de56f4f0cb3c/go.mod h1:5V65rPnTvvQagtoMxTneJ2QicLq6ZRQQ7fOgPN226fo=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218=
+github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0=
+github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
+github.com/distribution/distribution/v3 v3.0.0-20210316161203-a01c71e2477e h1:n81KvOMrLZa+VWHwST7dun9f0G98X3zREHS1ztYzZKU=
+github.com/distribution/distribution/v3 v3.0.0-20210316161203-a01c71e2477e/go.mod h1:xpWTC2KnJMiDLkoawhsPQcXjvwATEBcbq0xevG2YR9M=
+github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
+github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
+github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
+github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=
+github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw=
+github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
+github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
+github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
+github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
+github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
+github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
+github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
+github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
+github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/gomodule/redigo v1.8.2/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0=
+github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
+github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q=
+github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
+github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
+github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
+github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
+github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik=
+github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
+github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
+github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
+github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
+github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho=
+github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk=
+github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
+github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
+github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
+github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag=
+github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A=
+github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
+github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
+github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
+github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
+github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
+github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
+github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
+github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
+github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
+github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
+github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
+github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
+github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
+github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
+github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
+github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
+github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
+github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
+github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
+github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
+github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
+github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
+github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
+github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M=
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
+github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
+github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
+github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
+github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
+github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
+github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
+github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs=
+github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA=
+github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY=
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
+golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
+golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
+google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk=
+google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
+gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789 h1:NMiUjDZiD6qDVeBOzpImftxXzQHCp2Y2QLdmaqU9MRk=
+gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
+gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=
+gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
diff --git a/internal/docker/docker.go b/internal/docker/docker.go
new file mode 100644
index 0000000..a506f75
--- /dev/null
+++ b/internal/docker/docker.go
@@ -0,0 +1,67 @@
+package docker
+
+import (
+ "errors"
+ "io/ioutil"
+
+ "github.com/compose-spec/compose-go/loader"
+)
+
+func GetServices(composeFile string) ([]string, error) {
+
+ composeBytes, err := ioutil.ReadFile(composeFile)
+ if err != nil {
+ return nil, err
+ }
+
+ parsed, err := loader.ParseYAML(composeBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ if _, ok := parsed["services"]; !ok {
+ return nil, errors.New("missing services in compose")
+ }
+
+ serviceMap := parsed["services"].(map[string]interface{})
+
+ var services []string
+ for k := range serviceMap {
+ services = append(services, k)
+ }
+
+ return services, nil
+}
+
+func GetPortsForService(composeFile string, serviceName string) ([]string, error) {
+
+ composeBytes, err := ioutil.ReadFile(composeFile)
+ if err != nil {
+ return nil, err
+ }
+
+ parsed, err := loader.ParseYAML(composeBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ if _, ok := parsed["services"]; !ok {
+ return nil, errors.New("missing services in compose")
+ }
+
+ serviceMap := parsed["services"].(map[string]interface{})
+
+ var ports []string
+ for k, v := range serviceMap {
+ if k == serviceName {
+ m := v.(map[string]interface{})
+ i := m["ports"].([]interface{})
+ for _, j := range i {
+ port := j.(string)
+ ports = append(ports, port)
+ }
+ }
+ }
+
+ return ports, nil
+}
From 40a2986f732f9d784d90109900948c7cee52d811 Mon Sep 17 00:00:00 2001
From: Marco Argentieri <3596602+tiero@users.noreply.github.com>
Date: Tue, 3 Aug 2021 17:36:13 +0200
Subject: [PATCH 07/28] Add mint command
---
cmd/nigiri/faucet.go | 2 +-
cmd/nigiri/main.go | 1 +
cmd/nigiri/mint.go | 103 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 105 insertions(+), 1 deletion(-)
create mode 100644 cmd/nigiri/mint.go
diff --git a/cmd/nigiri/faucet.go b/cmd/nigiri/faucet.go
index eeb2c6b..a168bb3 100644
--- a/cmd/nigiri/faucet.go
+++ b/cmd/nigiri/faucet.go
@@ -35,7 +35,7 @@ func faucetAction(ctx *cli.Context) error {
}
if ctx.NArg() < 1 || ctx.NArg() > 3 {
- return errors.New("missing arguments")
+ return errors.New("wrong number of arguments")
}
isLiquid := ctx.Bool("liquid")
diff --git a/cmd/nigiri/main.go b/cmd/nigiri/main.go
index 8671c4d..763e19a 100644
--- a/cmd/nigiri/main.go
+++ b/cmd/nigiri/main.go
@@ -63,6 +63,7 @@ func main() {
&stop,
&rpc,
&logs,
+ &mint,
&faucet,
)
diff --git a/cmd/nigiri/mint.go b/cmd/nigiri/mint.go
new file mode 100644
index 0000000..ba103bf
--- /dev/null
+++ b/cmd/nigiri/mint.go
@@ -0,0 +1,103 @@
+package main
+
+import (
+ "bytes"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io/ioutil"
+ "net/http"
+ "strconv"
+ "strings"
+
+ "github.com/urfave/cli/v2"
+ "github.com/vulpemventures/nigiri/internal/docker"
+)
+
+var mint = cli.Command{
+ Name: "mint",
+ Usage: "liquid only: issue and send a given quantity of an asset",
+ ArgsUsage: " [name] [ticker]",
+ Action: mintAction,
+}
+
+func mintAction(ctx *cli.Context) error {
+
+ isRunning, err := getBoolFromState("running")
+ if err != nil {
+ return err
+ }
+
+ if !isRunning {
+ return errors.New("nigiri is not running")
+ }
+
+ if ctx.NArg() < 2 || ctx.NArg() > 5 {
+ return errors.New("wrong number of arguments")
+ }
+
+ composePath := getCompose(true)
+
+ serviceName := "chopsticks-liquid"
+
+ portSlice, err := docker.GetPortsForService(composePath, serviceName)
+ if err != nil {
+ return err
+ }
+ mappedPorts := strings.Split(portSlice[0], ":")
+
+ var request struct {
+ Address string `json:"address"`
+ Quantity int `json:"quantity"`
+ Name string `json:"name"`
+ Ticker string `json:"ticker"`
+ }
+ request.Address = ctx.Args().First()
+ request.Quantity, _ = strconv.Atoi(ctx.Args().Get(1))
+ if ctx.Args().Len() >= 3 {
+ request.Name = ctx.Args().Get(2)
+ }
+ if ctx.Args().Len() == 4 {
+ request.Ticker = ctx.Args().Get(3)
+ }
+
+ requestPort := mappedPorts[0]
+ payload, err := json.Marshal(request)
+ if err != nil {
+ return err
+ }
+ res, err := http.Post("http://127.0.0.1:"+requestPort+"/mint", "application/json", bytes.NewBuffer(payload))
+ if err != nil {
+ return err
+ }
+
+ data, err := ioutil.ReadAll(res.Body)
+ if err != nil {
+ return err
+ }
+ if res.StatusCode != http.StatusOK {
+ return errors.New(string(data))
+ }
+ var dat map[string]interface{}
+ var resp string
+ if err := json.Unmarshal([]byte(data), &dat); err != nil {
+ return errors.New("internal error try again")
+ }
+ if dat["txId"] == "" {
+ return errors.New("not successful")
+ }
+ for key, element := range dat {
+ if key == "issuance_txin" {
+ myMap := element.(map[string]interface{})
+ resp += key + ":\n"
+ for key2, element2 := range myMap {
+ resp += " "
+ resp += key2 + ": " + fmt.Sprintf("%v", element2) + "\n"
+ }
+ continue
+ }
+ resp += key + ": " + fmt.Sprintf("%v", element) + "\n"
+ }
+ fmt.Println(resp[:len(resp)-1])
+ return nil
+}
From 4d2a1699b4823557e3d8ccad6f53dcbd7d783efa Mon Sep 17 00:00:00 2001
From: Marco Argentieri <3596602+tiero@users.noreply.github.com>
Date: Tue, 3 Aug 2021 17:43:44 +0200
Subject: [PATCH 08/28] Add push command
---
cmd/nigiri/main.go | 1 +
cmd/nigiri/push.go | 73 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 74 insertions(+)
create mode 100644 cmd/nigiri/push.go
diff --git a/cmd/nigiri/main.go b/cmd/nigiri/main.go
index 763e19a..c2b99c4 100644
--- a/cmd/nigiri/main.go
+++ b/cmd/nigiri/main.go
@@ -64,6 +64,7 @@ func main() {
&rpc,
&logs,
&mint,
+ &push,
&faucet,
)
diff --git a/cmd/nigiri/push.go b/cmd/nigiri/push.go
new file mode 100644
index 0000000..a8ce358
--- /dev/null
+++ b/cmd/nigiri/push.go
@@ -0,0 +1,73 @@
+package main
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "io/ioutil"
+ "net/http"
+ "strings"
+
+ "github.com/urfave/cli/v2"
+ "github.com/vulpemventures/nigiri/internal/docker"
+)
+
+var push = cli.Command{
+ Name: "push",
+ Usage: "broadcast raw transaction",
+ ArgsUsage: "",
+ Action: pushAction,
+ Flags: []cli.Flag{
+ &liquidFlag,
+ },
+}
+
+func pushAction(ctx *cli.Context) error {
+
+ isRunning, err := getBoolFromState("running")
+ if err != nil {
+ return err
+ }
+
+ if !isRunning {
+ return errors.New("nigiri is not running")
+ }
+
+ if ctx.NArg() != 1 {
+ return errors.New("wrong number of arguments")
+ }
+
+ isLiquid := ctx.Bool("liquid")
+ composePath := getCompose(isLiquid)
+
+ var serviceName string = "chopsticks"
+ if isLiquid {
+ serviceName = "chopsticks-liquid"
+ }
+
+ portSlice, err := docker.GetPortsForService(composePath, serviceName)
+ if err != nil {
+ return err
+ }
+ mappedPorts := strings.Split(portSlice[0], ":")
+ requestPort := mappedPorts[0]
+ hex := []byte(ctx.Args().First())
+
+ res, err := http.Post("http://127.0.0.1:"+requestPort+"/tx", "application/string", bytes.NewBuffer(hex))
+ if err != nil {
+ return err
+ }
+ data, err := ioutil.ReadAll(res.Body)
+ if err != nil {
+ return err
+ }
+ if res.StatusCode != http.StatusOK {
+ return errors.New(string(data))
+ }
+
+ if string(data) == "" {
+ return errors.New("not successful")
+ }
+ fmt.Println("\ntxId: " + string(data))
+ return nil
+}
From f4764df0256eec69b3ee743fd0232e26f9967950 Mon Sep 17 00:00:00 2001
From: Marco Argentieri <3596602+tiero@users.noreply.github.com>
Date: Wed, 4 Aug 2021 10:44:10 +0200
Subject: [PATCH 09/28] Move state into dedicated pkg
---
cmd/nigiri/faucet.go | 2 +-
cmd/nigiri/logs.go | 2 +-
cmd/nigiri/main.go | 8 +++-
cmd/nigiri/mint.go | 2 +-
cmd/nigiri/push.go | 2 +-
cmd/nigiri/rpc.go | 2 +-
cmd/nigiri/start.go | 4 +-
cmd/nigiri/state.go | 88 ------------------------------------
cmd/nigiri/stop.go | 4 +-
pkg/state/state.go | 104 +++++++++++++++++++++++++++++++++++++++++++
10 files changed, 119 insertions(+), 99 deletions(-)
delete mode 100644 cmd/nigiri/state.go
create mode 100644 pkg/state/state.go
diff --git a/cmd/nigiri/faucet.go b/cmd/nigiri/faucet.go
index a168bb3..a4d35d1 100644
--- a/cmd/nigiri/faucet.go
+++ b/cmd/nigiri/faucet.go
@@ -25,7 +25,7 @@ var faucet = cli.Command{
func faucetAction(ctx *cli.Context) error {
- isRunning, err := getBoolFromState("running")
+ isRunning, err := nigiriState.GetBool("running")
if err != nil {
return err
}
diff --git a/cmd/nigiri/logs.go b/cmd/nigiri/logs.go
index 7920912..1388d4f 100644
--- a/cmd/nigiri/logs.go
+++ b/cmd/nigiri/logs.go
@@ -19,7 +19,7 @@ var logs = cli.Command{
func logsAction(ctx *cli.Context) error {
- isRunning, err := getBoolFromState("running")
+ isRunning, err := nigiriState.GetBool("running")
if err != nil {
return err
}
diff --git a/cmd/nigiri/main.go b/cmd/nigiri/main.go
index c2b99c4..630c6dd 100644
--- a/cmd/nigiri/main.go
+++ b/cmd/nigiri/main.go
@@ -11,6 +11,7 @@ import (
"github.com/btcsuite/btcutil"
"github.com/urfave/cli/v2"
+ "github.com/vulpemventures/nigiri/pkg/state"
)
var (
@@ -29,6 +30,8 @@ var (
"running": strconv.FormatBool(false),
}
+ nigiriState = state.New(statePath, initialState)
+
regtestCompose = "docker-compose-regtest.yml"
regtestLiquidCompose = "docker-compose-regtest-liquid.yml"
)
@@ -104,7 +107,8 @@ func getCompose(isLiquid bool) string {
}
func provisionResourcesToDatadir() error {
- isReady, err := getBoolFromState("ready")
+
+ isReady, err := nigiriState.GetBool("ready")
if err != nil {
return err
}
@@ -150,7 +154,7 @@ func provisionResourcesToDatadir() error {
return err
}
- if err := setState(map[string]string{"ready": strconv.FormatBool(true)}); err != nil {
+ if err := nigiriState.Set(map[string]string{"ready": strconv.FormatBool(true)}); err != nil {
return err
}
diff --git a/cmd/nigiri/mint.go b/cmd/nigiri/mint.go
index ba103bf..2cb99ec 100644
--- a/cmd/nigiri/mint.go
+++ b/cmd/nigiri/mint.go
@@ -23,7 +23,7 @@ var mint = cli.Command{
func mintAction(ctx *cli.Context) error {
- isRunning, err := getBoolFromState("running")
+ isRunning, err := nigiriState.GetBool("running")
if err != nil {
return err
}
diff --git a/cmd/nigiri/push.go b/cmd/nigiri/push.go
index a8ce358..1bfb103 100644
--- a/cmd/nigiri/push.go
+++ b/cmd/nigiri/push.go
@@ -24,7 +24,7 @@ var push = cli.Command{
func pushAction(ctx *cli.Context) error {
- isRunning, err := getBoolFromState("running")
+ isRunning, err := nigiriState.GetBool("running")
if err != nil {
return err
}
diff --git a/cmd/nigiri/rpc.go b/cmd/nigiri/rpc.go
index f733440..7618cde 100644
--- a/cmd/nigiri/rpc.go
+++ b/cmd/nigiri/rpc.go
@@ -24,7 +24,7 @@ var rpc = cli.Command{
func rpcAction(ctx *cli.Context) error {
- isRunning, err := getBoolFromState("running")
+ isRunning, err := nigiriState.GetBool("running")
if err != nil {
return err
}
diff --git a/cmd/nigiri/start.go b/cmd/nigiri/start.go
index 5ddf206..98f5bbd 100644
--- a/cmd/nigiri/start.go
+++ b/cmd/nigiri/start.go
@@ -20,7 +20,7 @@ var start = cli.Command{
func startAction(ctx *cli.Context) error {
- isRunning, err := getBoolFromState("running")
+ isRunning, err := nigiriState.GetBool("running")
if err != nil {
return err
}
@@ -40,7 +40,7 @@ func startAction(ctx *cli.Context) error {
return err
}
- if err := setState(map[string]string{
+ if err := nigiriState.Set(map[string]string{
"attachliquid": strconv.FormatBool(isLiquid),
"running": strconv.FormatBool(true),
}); err != nil {
diff --git a/cmd/nigiri/state.go b/cmd/nigiri/state.go
deleted file mode 100644
index 4fb7981..0000000
--- a/cmd/nigiri/state.go
+++ /dev/null
@@ -1,88 +0,0 @@
-package main
-
-import (
- "encoding/json"
- "errors"
- "fmt"
- "io/ioutil"
- "os"
- "strconv"
-)
-
-func getState() (map[string]string, error) {
- file, err := ioutil.ReadFile(statePath)
- if err != nil {
- if !os.IsNotExist(err) {
- return nil, err
- }
- if err := setState(initialState); err != nil {
- return nil, err
- }
- return initialState, nil
- }
-
- data := map[string]string{}
- json.Unmarshal(file, &data)
-
- return data, nil
-}
-
-func setState(data map[string]string) error {
- if _, err := os.Stat(defaultDataDir); os.IsNotExist(err) {
- os.Mkdir(defaultDataDir, os.ModeDir|0755)
- }
-
- file, err := os.OpenFile(statePath, os.O_RDONLY|os.O_CREATE, 0644)
- if err != nil {
- return err
- }
- if err := file.Close(); err != nil {
- return err
- }
-
- currentData, err := getState()
- if err != nil {
- return err
- }
-
- mergedData := merge(currentData, data)
-
- jsonString, err := json.Marshal(mergedData)
- if err != nil {
- return err
- }
- err = ioutil.WriteFile(statePath, jsonString, 0755)
- if err != nil {
- return fmt.Errorf("writing to file: %w", err)
- }
-
- return nil
-}
-
-func merge(maps ...map[string]string) map[string]string {
- merge := make(map[string]string)
- for _, m := range maps {
- for k, v := range m {
- merge[k] = v
- }
- }
- return merge
-}
-
-func getBoolFromState(key string) (bool, error) {
- stateConfig, err := getState()
- if err != nil {
- return false, err
- }
-
- if _, ok := stateConfig[key]; !ok {
- return false, errors.New("config: missing key " + key)
- }
-
- value, err := strconv.ParseBool(stateConfig[key])
- if err != nil {
- return false, err
- }
-
- return value, nil
-}
diff --git a/cmd/nigiri/stop.go b/cmd/nigiri/stop.go
index 88bb015..b4e1bfa 100644
--- a/cmd/nigiri/stop.go
+++ b/cmd/nigiri/stop.go
@@ -25,7 +25,7 @@ var stop = cli.Command{
func stopAction(ctx *cli.Context) error {
delete := ctx.Bool("delete")
- isLiquid, err := getBoolFromState("attachliquid")
+ isLiquid, err := nigiriState.GetBool("attachliquid")
if err != nil {
return err
}
@@ -54,7 +54,7 @@ func stopAction(ctx *cli.Context) error {
fmt.Println("Nigiri has been cleaned up successfully.")
} else {
- if err := setState(map[string]string{
+ if err := nigiriState.Set(map[string]string{
"running": strconv.FormatBool(false),
}); err != nil {
return err
diff --git a/pkg/state/state.go b/pkg/state/state.go
new file mode 100644
index 0000000..1dca7f0
--- /dev/null
+++ b/pkg/state/state.go
@@ -0,0 +1,104 @@
+package state
+
+import (
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "strconv"
+)
+
+type State struct {
+ directory string
+ filePath string
+ initialState map[string]string
+}
+
+func New(filePath string, initialState map[string]string) *State {
+ dir := filepath.Dir(filePath)
+ return &State{
+ directory: dir,
+ filePath: filePath,
+ initialState: initialState,
+ }
+}
+
+func (s *State) Get() (map[string]string, error) {
+ file, err := ioutil.ReadFile(s.filePath)
+ if err != nil {
+ if !os.IsNotExist(err) {
+ return nil, err
+ }
+ if err := s.Set(s.initialState); err != nil {
+ return nil, err
+ }
+ return s.initialState, nil
+ }
+
+ data := map[string]string{}
+ json.Unmarshal(file, &data)
+
+ return data, nil
+}
+
+func (s *State) Set(data map[string]string) error {
+ if _, err := os.Stat(s.directory); os.IsNotExist(err) {
+ os.Mkdir(s.directory, os.ModeDir|0755)
+ }
+
+ file, err := os.OpenFile(s.filePath, os.O_RDONLY|os.O_CREATE, 0644)
+ if err != nil {
+ return err
+ }
+ if err := file.Close(); err != nil {
+ return err
+ }
+
+ currentData, err := s.Get()
+ if err != nil {
+ return err
+ }
+
+ mergedData := merge(currentData, data)
+
+ jsonString, err := json.Marshal(mergedData)
+ if err != nil {
+ return err
+ }
+ err = ioutil.WriteFile(s.filePath, jsonString, 0755)
+ if err != nil {
+ return fmt.Errorf("writing to file: %w", err)
+ }
+
+ return nil
+}
+
+func (s *State) GetBool(key string) (bool, error) {
+ stateData, err := s.Get()
+ if err != nil {
+ return false, err
+ }
+
+ if _, ok := stateData[key]; !ok {
+ return false, errors.New("config: missing key " + key)
+ }
+
+ value, err := strconv.ParseBool(stateData[key])
+ if err != nil {
+ return false, err
+ }
+
+ return value, nil
+}
+
+func merge(maps ...map[string]string) map[string]string {
+ merge := make(map[string]string)
+ for _, m := range maps {
+ for k, v := range m {
+ merge[k] = v
+ }
+ }
+ return merge
+}
From 05b5a11102cc013cbcef7daa15e7424db3cd0795 Mon Sep 17 00:00:00 2001
From: Marco Argentieri <3596602+tiero@users.noreply.github.com>
Date: Wed, 4 Aug 2021 11:01:50 +0200
Subject: [PATCH 10/28] less code for isRunning check
---
cmd/nigiri/faucet.go | 7 +------
cmd/nigiri/logs.go | 7 +------
cmd/nigiri/main.go | 20 ++------------------
cmd/nigiri/mint.go | 7 +------
cmd/nigiri/push.go | 7 +------
cmd/nigiri/rpc.go | 7 +------
cmd/nigiri/start.go | 7 +------
7 files changed, 8 insertions(+), 54 deletions(-)
diff --git a/cmd/nigiri/faucet.go b/cmd/nigiri/faucet.go
index a4d35d1..5a8bf76 100644
--- a/cmd/nigiri/faucet.go
+++ b/cmd/nigiri/faucet.go
@@ -25,12 +25,7 @@ var faucet = cli.Command{
func faucetAction(ctx *cli.Context) error {
- isRunning, err := nigiriState.GetBool("running")
- if err != nil {
- return err
- }
-
- if !isRunning {
+ if isRunning, _ := nigiriState.GetBool("running"); !isRunning {
return errors.New("nigiri is not running")
}
diff --git a/cmd/nigiri/logs.go b/cmd/nigiri/logs.go
index 1388d4f..6dd5c0b 100644
--- a/cmd/nigiri/logs.go
+++ b/cmd/nigiri/logs.go
@@ -19,12 +19,7 @@ var logs = cli.Command{
func logsAction(ctx *cli.Context) error {
- isRunning, err := nigiriState.GetBool("running")
- if err != nil {
- return err
- }
-
- if !isRunning {
+ if isRunning, _ := nigiriState.GetBool("running"); !isRunning {
return errors.New("nigiri is not running")
}
diff --git a/cmd/nigiri/main.go b/cmd/nigiri/main.go
index 630c6dd..6b7ea9f 100644
--- a/cmd/nigiri/main.go
+++ b/cmd/nigiri/main.go
@@ -2,7 +2,6 @@ package main
import (
"embed"
- "errors"
"fmt"
"io/ioutil"
"os"
@@ -71,30 +70,14 @@ func main() {
&faucet,
)
- // check the datadirectory
-
err := app.Run(os.Args)
if err != nil {
fatal(err)
}
}
-type invalidUsageError struct {
- ctx *cli.Context
- command string
-}
-
-func (e *invalidUsageError) Error() string {
- return fmt.Sprintf("invalid usage of command %s", e.command)
-}
-
func fatal(err error) {
- var e *invalidUsageError
- if errors.As(err, &e) {
- _ = cli.ShowCommandHelp(e.ctx, e.command)
- } else {
- _, _ = fmt.Fprintf(os.Stderr, "[nigiri] %v\n", err)
- }
+ _, _ = fmt.Fprintf(os.Stderr, "[nigiri] %v\n", err)
os.Exit(1)
}
@@ -106,6 +89,7 @@ func getCompose(isLiquid bool) string {
return filepath.Join(defaultDataDir, regtestCompose)
}
+// Provisioning Nigiri reosurces
func provisionResourcesToDatadir() error {
isReady, err := nigiriState.GetBool("ready")
diff --git a/cmd/nigiri/mint.go b/cmd/nigiri/mint.go
index 2cb99ec..10e7675 100644
--- a/cmd/nigiri/mint.go
+++ b/cmd/nigiri/mint.go
@@ -23,12 +23,7 @@ var mint = cli.Command{
func mintAction(ctx *cli.Context) error {
- isRunning, err := nigiriState.GetBool("running")
- if err != nil {
- return err
- }
-
- if !isRunning {
+ if isRunning, _ := nigiriState.GetBool("running"); !isRunning {
return errors.New("nigiri is not running")
}
diff --git a/cmd/nigiri/push.go b/cmd/nigiri/push.go
index 1bfb103..d5bf23f 100644
--- a/cmd/nigiri/push.go
+++ b/cmd/nigiri/push.go
@@ -24,12 +24,7 @@ var push = cli.Command{
func pushAction(ctx *cli.Context) error {
- isRunning, err := nigiriState.GetBool("running")
- if err != nil {
- return err
- }
-
- if !isRunning {
+ if isRunning, _ := nigiriState.GetBool("running"); !isRunning {
return errors.New("nigiri is not running")
}
diff --git a/cmd/nigiri/rpc.go b/cmd/nigiri/rpc.go
index 7618cde..55b9d65 100644
--- a/cmd/nigiri/rpc.go
+++ b/cmd/nigiri/rpc.go
@@ -24,12 +24,7 @@ var rpc = cli.Command{
func rpcAction(ctx *cli.Context) error {
- isRunning, err := nigiriState.GetBool("running")
- if err != nil {
- return err
- }
-
- if !isRunning {
+ if isRunning, _ := nigiriState.GetBool("running"); !isRunning {
return errors.New("nigiri is not running")
}
diff --git a/cmd/nigiri/start.go b/cmd/nigiri/start.go
index 98f5bbd..f447688 100644
--- a/cmd/nigiri/start.go
+++ b/cmd/nigiri/start.go
@@ -20,12 +20,7 @@ var start = cli.Command{
func startAction(ctx *cli.Context) error {
- isRunning, err := nigiriState.GetBool("running")
- if err != nil {
- return err
- }
-
- if isRunning {
+ if isRunning, _ := nigiriState.GetBool("running"); isRunning {
return errors.New("nigiri is already running, please stop it first")
}
From 2dd42bde1ef074fe75272631d560b5140cf6dd79 Mon Sep 17 00:00:00 2001
From: Marco Argentieri <3596602+tiero@users.noreply.github.com>
Date: Wed, 4 Aug 2021 11:58:00 +0200
Subject: [PATCH 11/28] Add --ci flag to start command
---
cmd/nigiri/start.go | 15 +++++++++++++++
cmd/nigiri/stop.go | 1 +
2 files changed, 16 insertions(+)
diff --git a/cmd/nigiri/start.go b/cmd/nigiri/start.go
index f447688..0d55ce1 100644
--- a/cmd/nigiri/start.go
+++ b/cmd/nigiri/start.go
@@ -15,6 +15,11 @@ var start = cli.Command{
Action: startAction,
Flags: []cli.Flag{
&liquidFlag,
+ &cli.BoolFlag{
+ Name: "ci",
+ Usage: "runs in headless mode without esplora for continuous integration environments",
+ Value: false,
+ },
},
}
@@ -27,7 +32,17 @@ func startAction(ctx *cli.Context) error {
isLiquid := ctx.Bool("liquid")
composePath := getCompose(isLiquid)
+ // spin up all the services in the compose file
bashCmd := exec.Command("docker-compose", "-f", composePath, "up", "-d")
+ if ctx.Bool("ci") {
+ //this will only run chopsticks and servives it depends on
+ bashCmd = exec.Command("docker-compose", "-f", composePath, "up", "-d", "chopsticks")
+ if isLiquid {
+ //this will only run chopsticks & chopsticks-liquid and servives they depends on
+ bashCmd = exec.Command("docker-compose", "-f", composePath, "up", "-d", "chopsticks", "chopsticks-liquid")
+ }
+ }
+
bashCmd.Stdout = os.Stdout
bashCmd.Stderr = os.Stderr
diff --git a/cmd/nigiri/stop.go b/cmd/nigiri/stop.go
index b4e1bfa..4369711 100644
--- a/cmd/nigiri/stop.go
+++ b/cmd/nigiri/stop.go
@@ -14,6 +14,7 @@ var stop = cli.Command{
Usage: "stop nigiri",
Action: stopAction,
Flags: []cli.Flag{
+ &liquidFlag,
&cli.BoolFlag{
Name: "delete",
Usage: "clean node data directories",
From 8648d7c8b4a8e7c570ac9e6f90fe4814eb60530a Mon Sep 17 00:00:00 2001
From: Marco Argentieri <3596602+tiero@users.noreply.github.com>
Date: Wed, 4 Aug 2021 12:14:25 +0200
Subject: [PATCH 12/28] Add NIGIRI_DATADIR env var
---
cmd/nigiri/main.go | 58 +++++++++++++++++++++++++++++++++++++---------
cmd/nigiri/stop.go | 2 +-
2 files changed, 48 insertions(+), 12 deletions(-)
diff --git a/cmd/nigiri/main.go b/cmd/nigiri/main.go
index 6b7ea9f..8ee9da7 100644
--- a/cmd/nigiri/main.go
+++ b/cmd/nigiri/main.go
@@ -5,8 +5,10 @@ import (
"fmt"
"io/ioutil"
"os"
+ "os/user"
"path/filepath"
"strconv"
+ "strings"
"github.com/btcsuite/btcutil"
"github.com/urfave/cli/v2"
@@ -18,12 +20,13 @@ var (
commit = "none"
date = "unknown"
- defaultDataDir = btcutil.AppDataDir("nigiri-new", false)
+ stateFilename = "nigiri.config.json"
+ nigiriDataDir = btcutil.AppDataDir("nigiri-new", false)
+ statePath = filepath.Join(nigiriDataDir, stateFilename)
- statePath = filepath.Join(defaultDataDir, "nigiri.config.json")
initialState = map[string]string{
"attachliquid": strconv.FormatBool(false),
- "datadir": defaultDataDir,
+ "datadir": nigiriDataDir,
"network": "regtest",
"ready": strconv.FormatBool(false),
"running": strconv.FormatBool(false),
@@ -48,6 +51,13 @@ var liquidFlag = cli.BoolFlag{
var f embed.FS
func init() {
+ dataDir := cleanAndExpandPath(os.Getenv("NIGIRI_DATADIR"))
+ if len(dataDir) > 0 {
+ nigiriDataDir = dataDir
+ statePath = filepath.Join(nigiriDataDir, stateFilename)
+ nigiriState = state.New(statePath, initialState)
+ }
+
if err := provisionResourcesToDatadir(); err != nil {
fatal(err)
}
@@ -83,10 +93,10 @@ func fatal(err error) {
func getCompose(isLiquid bool) string {
if isLiquid {
- return filepath.Join(defaultDataDir, regtestLiquidCompose)
+ return filepath.Join(nigiriDataDir, regtestLiquidCompose)
}
- return filepath.Join(defaultDataDir, regtestCompose)
+ return filepath.Join(nigiriDataDir, regtestCompose)
}
// Provisioning Nigiri reosurces
@@ -102,38 +112,38 @@ func provisionResourcesToDatadir() error {
}
// create folders in volumes/{bitcoin,elements} for node datadirs
- if err := makeDirectoryIfNotExists(filepath.Join(defaultDataDir, "volumes", "bitcoin")); err != nil {
+ if err := makeDirectoryIfNotExists(filepath.Join(nigiriDataDir, "volumes", "bitcoin")); err != nil {
return err
}
- if err := makeDirectoryIfNotExists(filepath.Join(defaultDataDir, "volumes", "elements")); err != nil {
+ if err := makeDirectoryIfNotExists(filepath.Join(nigiriDataDir, "volumes", "elements")); err != nil {
return err
}
// copy resources into the Nigiri data directory
if err := copyFromResourcesToDatadir(
filepath.Join("resources", regtestCompose),
- filepath.Join(defaultDataDir, regtestCompose),
+ filepath.Join(nigiriDataDir, regtestCompose),
); err != nil {
return err
}
if err := copyFromResourcesToDatadir(
filepath.Join("resources", regtestLiquidCompose),
- filepath.Join(defaultDataDir, regtestLiquidCompose),
+ filepath.Join(nigiriDataDir, regtestLiquidCompose),
); err != nil {
return err
}
if err := copyFromResourcesToDatadir(
filepath.Join("resources", "bitcoin.conf"),
- filepath.Join(defaultDataDir, "volumes", "bitcoin", "bitcoin.conf"),
+ filepath.Join(nigiriDataDir, "volumes", "bitcoin", "bitcoin.conf"),
); err != nil {
return err
}
if err := copyFromResourcesToDatadir(
filepath.Join("resources", "elements.conf"),
- filepath.Join(defaultDataDir, "volumes", "elements", "elements.conf"),
+ filepath.Join(nigiriDataDir, "volumes", "elements", "elements.conf"),
); err != nil {
return err
}
@@ -171,3 +181,29 @@ func makeDirectoryIfNotExists(path string) error {
}
return nil
}
+
+// cleanAndExpandPath expands environment variables and leading ~ in the
+// passed path, cleans the result, and returns it.
+// This function is taken from https://github.com/btcsuite/btcd
+func cleanAndExpandPath(path string) string {
+ if path == "" {
+ return ""
+ }
+
+ // Expand initial ~ to OS specific home directory.
+ if strings.HasPrefix(path, "~") {
+ var homeDir string
+ u, err := user.Current()
+ if err == nil {
+ homeDir = u.HomeDir
+ } else {
+ homeDir = os.Getenv("HOME")
+ }
+
+ path = strings.Replace(path, "~", homeDir, 1)
+ }
+
+ // NOTE: The os.ExpandEnv doesn't work with Windows-style %VARIABLE%,
+ // but the variables can still be expanded via POSIX-style $VARIABLE.
+ return filepath.Clean(os.ExpandEnv(path))
+}
diff --git a/cmd/nigiri/stop.go b/cmd/nigiri/stop.go
index 4369711..c8beb3a 100644
--- a/cmd/nigiri/stop.go
+++ b/cmd/nigiri/stop.go
@@ -45,7 +45,7 @@ func stopAction(ctx *cli.Context) error {
if delete {
fmt.Println("Removing data from volumes...")
- if err := os.RemoveAll(defaultDataDir); err != nil {
+ if err := os.RemoveAll(nigiriDataDir); err != nil {
return err
}
From 8b13f3096c12f635a06afbbce57ccaa540d1fdeb Mon Sep 17 00:00:00 2001
From: Marco Argentieri <3596602+tiero@users.noreply.github.com>
Date: Wed, 4 Aug 2021 12:22:54 +0200
Subject: [PATCH 13/28] add update command
---
cmd/nigiri/main.go | 5 +++--
cmd/nigiri/update.go | 28 ++++++++++++++++++++++++++++
2 files changed, 31 insertions(+), 2 deletions(-)
create mode 100644 cmd/nigiri/update.go
diff --git a/cmd/nigiri/main.go b/cmd/nigiri/main.go
index 8ee9da7..2e13a6d 100644
--- a/cmd/nigiri/main.go
+++ b/cmd/nigiri/main.go
@@ -71,12 +71,13 @@ func main() {
app.Usage = "create your dockerized environment with a bitcoin and liquid node, with a block explorer and developer tools"
app.Commands = append(
app.Commands,
- &start,
- &stop,
&rpc,
+ &stop,
&logs,
&mint,
&push,
+ &start,
+ &update,
&faucet,
)
diff --git a/cmd/nigiri/update.go b/cmd/nigiri/update.go
new file mode 100644
index 0000000..59aa84b
--- /dev/null
+++ b/cmd/nigiri/update.go
@@ -0,0 +1,28 @@
+package main
+
+import (
+ "os"
+ "os/exec"
+
+ "github.com/urfave/cli/v2"
+)
+
+var update = cli.Command{
+ Name: "update",
+ Usage: "check for updates and pull new docker images",
+ Action: updateAction,
+}
+
+func updateAction(ctx *cli.Context) error {
+ composePath := getCompose(true)
+
+ bashCmd := exec.Command("docker-compose", "-f", composePath, "pull")
+ bashCmd.Stdout = os.Stdout
+ bashCmd.Stderr = os.Stderr
+
+ if err := bashCmd.Run(); err != nil {
+ return err
+ }
+
+ return nil
+}
From 045ee5dd41901d317b2f92a707afc34753ee6b32 Mon Sep 17 00:00:00 2001
From: Marco Argentieri <3596602+tiero@users.noreply.github.com>
Date: Wed, 4 Aug 2021 12:38:32 +0200
Subject: [PATCH 14/28] Update readme, makefile and goreleaser
---
.dockerignore | 1 +
.github/workflows/release.yml | 2 +-
.github/workflows/test.yml | 1 -
.gitignore | 6 ++++++
.goreleaser.yml | 24 ++++++++++++++++++++++++
Makefile | 22 +++++++++-------------
README.md | 25 +++++++++++++++++--------
scripts/build | 16 ++++++++++++++++
8 files changed, 74 insertions(+), 23 deletions(-)
create mode 100644 .dockerignore
create mode 100644 .gitignore
create mode 100644 .goreleaser.yml
create mode 100755 scripts/build
diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..6eca100
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1 @@
+/.git/
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 9812c8f..7abceee 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -16,7 +16,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v2
with:
- go-version: 1.15.x
+ go-version: 1.16.x
- name: Cache Go modules
uses: actions/cache@v1
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index b6f4cd0..a5d0c46 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -25,5 +25,4 @@ jobs:
run: |
make fmt
make install
- sudo chmod -R 777 .
make test-ci
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..41a780b
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,6 @@
+.DS_Store
+.env
+
+vendor/
+build/
+dist/
diff --git a/.goreleaser.yml b/.goreleaser.yml
new file mode 100644
index 0000000..85ace71
--- /dev/null
+++ b/.goreleaser.yml
@@ -0,0 +1,24 @@
+builds:
+ - main: ./cmd/nigiri
+ ldflags:
+ - -s -w -X github.com/vulpemventures/nigiri/cli/cmd.version={{.Version}} -X github.com/vulpemventures/nigiri/cli/cmd.commit={{.Commit}} -X github.com/vulpemventures/nigiri/cli/cmd.date={{.Date}}
+ env:
+ - CGO_ENABLED=0
+ goos:
+ - linux
+ - darwin
+ goarch:
+ - amd64
+checksum:
+ name_template: "checksums.txt"
+snapshot:
+ name_template: "{{ .Tag }}-next"
+changelog:
+ sort: asc
+ filters:
+ exclude:
+ - "^docs:"
+ - "^test:"
+archives:
+ - format: binary
+ name_template: "{{ .ProjectName }}-{{ .Os }}-{{ .Arch }}"
diff --git a/Makefile b/Makefile
index 20393ae..1dadd6e 100644
--- a/Makefile
+++ b/Makefile
@@ -1,14 +1,17 @@
-.PHONY: install build release dry-release clean cov fmt help vet test
+.PHONY: install clean build release dry-release cov fmt help vet test
## install: installs dependencies
install:
- export GO111MODULE=on
- chmod u+x ./scripts/install
- ./scripts/install
+ go mod download
+ go mod tidy
-## build: build binary for ARM
+## clean: cleans the binary
+clean:
+ @echo "Cleaning..."
+ go clean
+
+## build: build binary
build:
- export GO111MODULE=on
chmod u+x ./scripts/build
./scripts/build
@@ -18,13 +21,6 @@ release:
dry-release:
goreleaser --snapshot --skip-publish --rm-dist
-## clean: cleans the binary
-clean:
- @echo "Cleaning..."
- export GO111MODULE=on
- chmod u+x ./scripts/clean
- ./scripts/clean
-
## help: prints this help message
help:
@echo "Usage: \n"
diff --git a/README.md b/README.md
index 5bdbe4e..ff529e3 100644
--- a/README.md
+++ b/README.md
@@ -6,8 +6,6 @@ It offers a [JSON HTTP proxy passtrough](https://github.com/vulpemventures/nigir
You can have Elements too with the `--liquid` flag.
-Are you looking to spin-up Nigiri in Travis or Github Action? Look [here](https://github.com/vulpemventures/nigiri-travis)
-
# No time to make a Nigiri yourself?
## Pre-built binary
@@ -51,7 +49,6 @@ $ nigiri rpc --liquid getnewaddress "" "bech32"
el1qqwwx9gyrcrjrhgnrnjq9dq9t4hykmr6ela46ej63dnkdkcg8veadrvg5p0xg0zd6j3aug74cv9m4cf4jslwdqnha2w2nsg9x3
```
-
# Make from scratch
## Utensils
@@ -83,14 +80,11 @@ $ git clone https://github.com/vulpemventures/nigiri.git
$ make install
```
-This will create `~/.nigiri` copying there the `{bitcoin|elements}.conf` you can modify.
* Build binary
+
```
-# MacOSX
-$ make build-mac
-# Linux
-$ make build-linux
+$ make build
```
Done! You should be able to find the binary in the local `./build` folder. Give it permission to execute and move/rename into your PATH.
@@ -187,6 +181,21 @@ $ nigiri rpc --liquid getnewaddress "" "bech32"
el1qqwwx9gyrcrjrhgnrnjq9dq9t4hykmr6ela46ej63dnkdkcg8veadrvg5p0xg0zd6j3aug74cv9m4cf4jslwdqnha2w2nsg9x3
```
+* Run in headless mode (without Esplora)
+If you are looking to spin-up Nigiri in Travis or Github Action you can use the `--ci` flag.
+
+```
+$ nigiri start --ci [--liquid]
+```
+
+
+* Update the docker images
+
+```
+$ nigiri update
+```
+
+
Nigiri uses the default directory `~/.nigiri` to store configuration files and docker-compose files.
diff --git a/scripts/build b/scripts/build
new file mode 100755
index 0000000..2901324
--- /dev/null
+++ b/scripts/build
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+set -e
+
+PARENT_PATH=$(dirname $(
+ cd $(dirname $0)
+ pwd -P
+))
+
+OS=$(eval "go env GOOS")
+ARCH=$(eval "go env GOARCH")
+
+pushd $PARENT_PATH
+mkdir -p build
+GO111MODULE=on CGO_ENABLED=0 go build -ldflags="-s -w" -o build/nigiri-$OS-$ARCH cmd/nigiri/*.go
+popd
From 2b054eb322b8eaf20b1503ea980328f6ad337117 Mon Sep 17 00:00:00 2001
From: Marco Argentieri <3596602+tiero@users.noreply.github.com>
Date: Wed, 4 Aug 2021 12:42:04 +0200
Subject: [PATCH 15/28] update test gh action
---
.github/workflows/test.yml | 19 +++++++++++++++----
Makefile | 2 +-
2 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index a5d0c46..0e0cc6a 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -11,12 +11,23 @@ jobs:
name: Unit Tests
runs-on: ubuntu-latest
steps:
- - name: Set up Go 1.x
+ - name: Checkout
+ uses: actions/checkout@v2
+ with:
+ fetch-depth: 0
+
+ - name: Set up Go
uses: actions/setup-go@v2
- id: go
+ with:
+ go-version: 1.16.x
- - name: Check out code into the Go module directory
- uses: actions/checkout@v2
+ - name: Cache Go modules
+ uses: actions/cache@v1
+ with:
+ path: ~/go/pkg/mod
+ key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
+ restore-keys: |
+ ${{ runner.os }}-go-
- name: Get dependencies
run: go get -v -t -d ./...
diff --git a/Makefile b/Makefile
index 1dadd6e..78c2c3d 100644
--- a/Makefile
+++ b/Makefile
@@ -42,7 +42,7 @@ test: clean install
go test -v -count=1 -race ./...
## test-ci: runs travis tests
-test-ci:
+test-ci: clean
@echo "Testing..."
go test -short -v ./...
From 90e30581dc816dc3a6cf5938e5290ddd3cfc2252 Mon Sep 17 00:00:00 2001
From: Marco Argentieri <3596602+tiero@users.noreply.github.com>
Date: Wed, 4 Aug 2021 13:33:21 +0200
Subject: [PATCH 16/28] skip tests
---
cmd/nigiri/main.go | 20 ++-----
internal/config/config.go | 22 ++++++++
test/start_stop_test.go | 115 ++++++++++++++++++++++++++++++++++++++
3 files changed, 141 insertions(+), 16 deletions(-)
create mode 100644 internal/config/config.go
create mode 100644 test/start_stop_test.go
diff --git a/cmd/nigiri/main.go b/cmd/nigiri/main.go
index 2e13a6d..25f2005 100644
--- a/cmd/nigiri/main.go
+++ b/cmd/nigiri/main.go
@@ -10,8 +10,8 @@ import (
"strconv"
"strings"
- "github.com/btcsuite/btcutil"
"github.com/urfave/cli/v2"
+ "github.com/vulpemventures/nigiri/internal/config"
"github.com/vulpemventures/nigiri/pkg/state"
)
@@ -20,19 +20,8 @@ var (
commit = "none"
date = "unknown"
- stateFilename = "nigiri.config.json"
- nigiriDataDir = btcutil.AppDataDir("nigiri-new", false)
- statePath = filepath.Join(nigiriDataDir, stateFilename)
-
- initialState = map[string]string{
- "attachliquid": strconv.FormatBool(false),
- "datadir": nigiriDataDir,
- "network": "regtest",
- "ready": strconv.FormatBool(false),
- "running": strconv.FormatBool(false),
- }
-
- nigiriState = state.New(statePath, initialState)
+ nigiriDataDir = config.DefaultDatadir
+ nigiriState = state.New(config.DefaultPath, config.InitialState)
regtestCompose = "docker-compose-regtest.yml"
regtestLiquidCompose = "docker-compose-regtest-liquid.yml"
@@ -53,9 +42,8 @@ var f embed.FS
func init() {
dataDir := cleanAndExpandPath(os.Getenv("NIGIRI_DATADIR"))
if len(dataDir) > 0 {
+ nigiriState = state.New(filepath.Join(dataDir, config.DefaultName), config.InitialState)
nigiriDataDir = dataDir
- statePath = filepath.Join(nigiriDataDir, stateFilename)
- nigiriState = state.New(statePath, initialState)
}
if err := provisionResourcesToDatadir(); err != nil {
diff --git a/internal/config/config.go b/internal/config/config.go
new file mode 100644
index 0000000..a56d046
--- /dev/null
+++ b/internal/config/config.go
@@ -0,0 +1,22 @@
+package config
+
+import (
+ "path/filepath"
+ "strconv"
+
+ "github.com/btcsuite/btcutil"
+)
+
+var (
+ DefaultName = "nigiri.config.json"
+ DefaultDatadir = btcutil.AppDataDir("nigiri", false)
+ DefaultPath = filepath.Join(DefaultDatadir, DefaultName)
+
+ InitialState = map[string]string{
+ "attachliquid": strconv.FormatBool(false),
+ "datadir": DefaultDatadir,
+ "network": "regtest",
+ "ready": strconv.FormatBool(false),
+ "running": strconv.FormatBool(false),
+ }
+)
diff --git a/test/start_stop_test.go b/test/start_stop_test.go
new file mode 100644
index 0000000..8066612
--- /dev/null
+++ b/test/start_stop_test.go
@@ -0,0 +1,115 @@
+package test
+
+import (
+ "fmt"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "testing"
+ "time"
+
+ "github.com/vulpemventures/nigiri/internal/config"
+ "github.com/vulpemventures/nigiri/pkg/state"
+)
+
+const (
+ liquid = true
+ bitcoin = false
+ delete = true
+)
+
+var (
+ stopCmd = "stop"
+ // deleteCmd = append(stopCmd, "--delete")
+ startCmd = "start"
+ // liquidStartCmd = append(startCmd, "--liquid")
+ tmpDatadir = filepath.Join(os.TempDir(), "nigiri-tmp")
+ nigiriState = state.New(filepath.Join(tmpDatadir, config.DefaultName), config.InitialState)
+)
+
+func TestStartStopLiquid(t *testing.T) {
+ if testing.Short() {
+ t.Skip("skipping testing in short mode")
+ }
+ // Start/Stop
+ testStart(t, liquid)
+ testStop(t)
+ // Start/Delete
+ testStart(t, liquid)
+ testDelete(t)
+}
+
+func TestStartStopBitcoin(t *testing.T) {
+ if testing.Short() {
+ t.Skip("skipping testing in short mode")
+ }
+ // Start/Stop
+ testStart(t, bitcoin)
+ testStop(t)
+ // Start/Delete
+ testStart(t, bitcoin)
+ testDelete(t)
+}
+
+func testStart(t *testing.T, flag bool) {
+
+ if err := testCommand("start", "", flag); err != nil {
+ t.Fatal(err)
+ }
+ //Give some time to nigiri to be ready before calling
+ time.Sleep(5 * time.Second)
+ if isRunning, err := nigiriState.GetBool("running"); err != nil {
+ t.Fatal(err)
+ } else if !isRunning {
+ t.Fatal("Nigiri should have been started but services have not been found among running containers")
+ }
+}
+
+func testStop(t *testing.T) {
+
+ if err := testCommand("stop", "", !delete); err != nil {
+ t.Fatal(err)
+ }
+ //Give some time to nigiri to be ready before calling
+ time.Sleep(5 * time.Second)
+ if isRunning, err := nigiriState.GetBool("running"); err != nil {
+ t.Fatal(err)
+ } else if isRunning {
+ t.Fatal("Nigiri should have been stopped but services have not been found among stopped containers")
+ }
+}
+
+func testDelete(t *testing.T) {
+
+ if err := testCommand("stop", "", delete); err != nil {
+ t.Fatal(err)
+ }
+ if isRunning, err := nigiriState.GetBool("running"); err != nil {
+ t.Fatal(err)
+ } else if isRunning {
+ t.Fatal("Nigiri should have been terminated at this point but services have been found among stopped containers")
+ }
+}
+
+func testCommand(command, arg string, flag bool) error {
+
+ cmd := exec.Command("go", "run", "./cmd/nigiri")
+ env := "NIGIRI_DATADIR=" + tmpDatadir
+ cmd.Env = []string{env}
+ cmd.Stderr = os.Stderr
+ cmd.Stdout = os.Stdout
+
+ if command == "start" {
+ cmd.Args = append(cmd.Args, startCmd, fmt.Sprintf("--liquid=%t", flag))
+ }
+ if command == "stop" {
+ cmd.Args = append(cmd.Args, stopCmd, fmt.Sprintf("--delete=%t", flag))
+ }
+
+ err := cmd.Start()
+ if err != nil {
+ fmt.Errorf("name: %v, args: %v, err: %v", command, arg, err.Error())
+ }
+
+ return nil
+}
From cb56ff25a46b37fd5b1e4c6519fb5c928472aa66 Mon Sep 17 00:00:00 2001
From: Marco Argentieri <3596602+tiero@users.noreply.github.com>
Date: Wed, 4 Aug 2021 13:48:37 +0200
Subject: [PATCH 17/28] print endpoint in start command
---
cmd/nigiri/start.go | 14 ++++++++++++++
internal/docker/docker.go | 13 +++++++++++--
2 files changed, 25 insertions(+), 2 deletions(-)
diff --git a/cmd/nigiri/start.go b/cmd/nigiri/start.go
index 0d55ce1..dd1e25d 100644
--- a/cmd/nigiri/start.go
+++ b/cmd/nigiri/start.go
@@ -2,11 +2,13 @@ package main
import (
"errors"
+ "fmt"
"os"
"os/exec"
"strconv"
"github.com/urfave/cli/v2"
+ "github.com/vulpemventures/nigiri/internal/docker"
)
var start = cli.Command{
@@ -57,5 +59,17 @@ func startAction(ctx *cli.Context) error {
return err
}
+ services, err := docker.GetServices(composePath)
+ if err != nil {
+ return err
+ }
+
+ fmt.Println()
+ fmt.Println("ENDPOINTS")
+
+ for _, endpoint := range services {
+ fmt.Println(endpoint)
+ }
+
return nil
}
diff --git a/internal/docker/docker.go b/internal/docker/docker.go
index a506f75..c8b38d7 100644
--- a/internal/docker/docker.go
+++ b/internal/docker/docker.go
@@ -3,6 +3,7 @@ package docker
import (
"errors"
"io/ioutil"
+ "strings"
"github.com/compose-spec/compose-go/loader"
)
@@ -26,8 +27,16 @@ func GetServices(composeFile string) ([]string, error) {
serviceMap := parsed["services"].(map[string]interface{})
var services []string
- for k := range serviceMap {
- services = append(services, k)
+ for k, v := range serviceMap {
+ m := v.(map[string]interface{})
+ i := m["ports"].([]interface{})
+ for _, j := range i {
+ port := j.(string)
+ exposedPorts := strings.Split(port, ":")
+ endpoint := k + " localhost:" + exposedPorts[0]
+ services = append(services, endpoint)
+ }
+
}
return services, nil
From 5e01c055e916e84c8b3759aa02874dc4c0bb6f1b Mon Sep 17 00:00:00 2001
From: Philipp Hoenisch
Date: Fri, 16 Jul 2021 08:26:24 +1000
Subject: [PATCH 18/28] Add a default network to docker compose file.
Containers started through this docker compose file will be in this isolated network.
Note: the minimum version for the docker compose file format is 3.5 which introduces `name` for networks. This file format requires a docker engine version of 17.12.0+.
From 9317f68d7b3d084b6a593714541ac70ead61b7dd Mon Sep 17 00:00:00 2001
From: Marco Argentieri <3596602+tiero@users.noreply.github.com>
Date: Thu, 5 Aug 2021 16:04:23 +0200
Subject: [PATCH 19/28] add prerelease: auto
---
.goreleaser.yml | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/.goreleaser.yml b/.goreleaser.yml
index 85ace71..a92094f 100644
--- a/.goreleaser.yml
+++ b/.goreleaser.yml
@@ -9,10 +9,13 @@ builds:
- darwin
goarch:
- amd64
+
checksum:
name_template: "checksums.txt"
+
snapshot:
name_template: "{{ .Tag }}-next"
+
changelog:
sort: asc
filters:
@@ -22,3 +25,6 @@ changelog:
archives:
- format: binary
name_template: "{{ .ProjectName }}-{{ .Os }}-{{ .Arch }}"
+
+release:
+ prerelease: auto
From ad39de391d98886dfd261be8cdf821a3561de714 Mon Sep 17 00:00:00 2001
From: Marco Argentieri <3596602+tiero@users.noreply.github.com>
Date: Thu, 5 Aug 2021 16:38:22 +0200
Subject: [PATCH 20/28] makefile: release commands
---
Makefile | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Makefile b/Makefile
index 78c2c3d..763dabb 100644
--- a/Makefile
+++ b/Makefile
@@ -15,9 +15,11 @@ build:
chmod u+x ./scripts/build
./scripts/build
+## release: build and upload binaries to Github Releases
release:
goreleaser
+## dry-release: build and test goreleaser
dry-release:
goreleaser --snapshot --skip-publish --rm-dist
From bf8ae18ae8df76b4c47b26949fa3b28da53f548e Mon Sep 17 00:00:00 2001
From: Marco Argentieri <3596602+tiero@users.noreply.github.com>
Date: Thu, 5 Aug 2021 17:07:16 +0200
Subject: [PATCH 21/28] go version
---
.goreleaser.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.goreleaser.yml b/.goreleaser.yml
index a92094f..4b96041 100644
--- a/.goreleaser.yml
+++ b/.goreleaser.yml
@@ -1,7 +1,7 @@
builds:
- main: ./cmd/nigiri
ldflags:
- - -s -w -X github.com/vulpemventures/nigiri/cli/cmd.version={{.Version}} -X github.com/vulpemventures/nigiri/cli/cmd.commit={{.Commit}} -X github.com/vulpemventures/nigiri/cli/cmd.date={{.Date}}
+ - -s -X 'main.version={{.Version}}' -X 'main.commit={{.Commit}}' -X 'main.date={{.Date}}'
env:
- CGO_ENABLED=0
goos:
From 25e7de94fde9801e0f5ad2741dca3ee6cc6cbbc3 Mon Sep 17 00:00:00 2001
From: Marco Argentieri <3596602+tiero@users.noreply.github.com>
Date: Fri, 6 Aug 2021 15:10:04 +0200
Subject: [PATCH 22/28] use global flag --datadir for the folder
---
cmd/nigiri/faucet.go | 3 ++-
cmd/nigiri/logs.go | 3 ++-
cmd/nigiri/main.go | 59 +++++++++++++++++++++++++------------------
cmd/nigiri/mint.go | 3 ++-
cmd/nigiri/push.go | 3 ++-
cmd/nigiri/start.go | 3 ++-
cmd/nigiri/stop.go | 7 ++---
cmd/nigiri/update.go | 3 ++-
cmd/nigiri/version.go | 18 +++++++++++++
9 files changed, 69 insertions(+), 33 deletions(-)
create mode 100644 cmd/nigiri/version.go
diff --git a/cmd/nigiri/faucet.go b/cmd/nigiri/faucet.go
index 5a8bf76..72ef423 100644
--- a/cmd/nigiri/faucet.go
+++ b/cmd/nigiri/faucet.go
@@ -34,7 +34,8 @@ func faucetAction(ctx *cli.Context) error {
}
isLiquid := ctx.Bool("liquid")
- composePath := getCompose(isLiquid)
+ datadir := ctx.String("datadir")
+ composePath := getCompose(datadir, isLiquid)
var serviceName string = "chopsticks"
if isLiquid {
diff --git a/cmd/nigiri/logs.go b/cmd/nigiri/logs.go
index 6dd5c0b..7c4484d 100644
--- a/cmd/nigiri/logs.go
+++ b/cmd/nigiri/logs.go
@@ -30,7 +30,8 @@ func logsAction(ctx *cli.Context) error {
serviceName := ctx.Args().First()
isLiquid := ctx.Bool("liquid")
- composePath := getCompose(isLiquid)
+ datadir := ctx.String("datadir")
+ composePath := getCompose(datadir, isLiquid)
bashCmd := exec.Command("docker-compose", "-f", composePath, "logs", serviceName)
bashCmd.Stdout = os.Stdout
diff --git a/cmd/nigiri/main.go b/cmd/nigiri/main.go
index 25f2005..55a2429 100644
--- a/cmd/nigiri/main.go
+++ b/cmd/nigiri/main.go
@@ -20,8 +20,7 @@ var (
commit = "none"
date = "unknown"
- nigiriDataDir = config.DefaultDatadir
- nigiriState = state.New(config.DefaultPath, config.InitialState)
+ nigiriState = state.New(config.DefaultPath, config.InitialState)
regtestCompose = "docker-compose-regtest.yml"
regtestLiquidCompose = "docker-compose-regtest-liquid.yml"
@@ -33,30 +32,25 @@ var liquidFlag = cli.BoolFlag{
Value: false,
}
+var datadirFlag = cli.StringFlag{
+ Name: "datadir",
+ Usage: "use different data directory",
+ Value: config.DefaultDatadir,
+}
+
//go:embed resources/docker-compose-regtest.yml
//go:embed resources/docker-compose-regtest-liquid.yml
//go:embed resources/bitcoin.conf
//go:embed resources/elements.conf
var f embed.FS
-func init() {
- dataDir := cleanAndExpandPath(os.Getenv("NIGIRI_DATADIR"))
- if len(dataDir) > 0 {
- nigiriState = state.New(filepath.Join(dataDir, config.DefaultName), config.InitialState)
- nigiriDataDir = dataDir
- }
-
- if err := provisionResourcesToDatadir(); err != nil {
- fatal(err)
- }
-}
-
func main() {
app := cli.NewApp()
app.Version = formatVersion()
app.Name = "nigiri CLI"
app.Usage = "create your dockerized environment with a bitcoin and liquid node, with a block explorer and developer tools"
+ app.Flags = append(app.Flags, &datadirFlag)
app.Commands = append(
app.Commands,
&rpc,
@@ -67,8 +61,25 @@ func main() {
&start,
&update,
&faucet,
+ &versionCmd,
)
+ app.Before = func(ctx *cli.Context) error {
+
+ dataDir := config.DefaultDatadir
+
+ if ctx.IsSet("datadir") {
+ dataDir = cleanAndExpandPath(ctx.String("datadir"))
+ nigiriState = state.New(filepath.Join(dataDir, config.DefaultName), config.InitialState)
+ }
+
+ if err := provisionResourcesToDatadir(dataDir); err != nil {
+ return err
+ }
+
+ return nil
+ }
+
err := app.Run(os.Args)
if err != nil {
fatal(err)
@@ -80,16 +91,16 @@ func fatal(err error) {
os.Exit(1)
}
-func getCompose(isLiquid bool) string {
+func getCompose(datadir string, isLiquid bool) string {
if isLiquid {
- return filepath.Join(nigiriDataDir, regtestLiquidCompose)
+ return filepath.Join(cleanAndExpandPath(datadir), regtestLiquidCompose)
}
- return filepath.Join(nigiriDataDir, regtestCompose)
+ return filepath.Join(cleanAndExpandPath(datadir), regtestCompose)
}
// Provisioning Nigiri reosurces
-func provisionResourcesToDatadir() error {
+func provisionResourcesToDatadir(datadir string) error {
isReady, err := nigiriState.GetBool("ready")
if err != nil {
@@ -101,38 +112,38 @@ func provisionResourcesToDatadir() error {
}
// create folders in volumes/{bitcoin,elements} for node datadirs
- if err := makeDirectoryIfNotExists(filepath.Join(nigiriDataDir, "volumes", "bitcoin")); err != nil {
+ if err := makeDirectoryIfNotExists(filepath.Join(datadir, "volumes", "bitcoin")); err != nil {
return err
}
- if err := makeDirectoryIfNotExists(filepath.Join(nigiriDataDir, "volumes", "elements")); err != nil {
+ if err := makeDirectoryIfNotExists(filepath.Join(datadir, "volumes", "elements")); err != nil {
return err
}
// copy resources into the Nigiri data directory
if err := copyFromResourcesToDatadir(
filepath.Join("resources", regtestCompose),
- filepath.Join(nigiriDataDir, regtestCompose),
+ filepath.Join(datadir, regtestCompose),
); err != nil {
return err
}
if err := copyFromResourcesToDatadir(
filepath.Join("resources", regtestLiquidCompose),
- filepath.Join(nigiriDataDir, regtestLiquidCompose),
+ filepath.Join(datadir, regtestLiquidCompose),
); err != nil {
return err
}
if err := copyFromResourcesToDatadir(
filepath.Join("resources", "bitcoin.conf"),
- filepath.Join(nigiriDataDir, "volumes", "bitcoin", "bitcoin.conf"),
+ filepath.Join(datadir, "volumes", "bitcoin", "bitcoin.conf"),
); err != nil {
return err
}
if err := copyFromResourcesToDatadir(
filepath.Join("resources", "elements.conf"),
- filepath.Join(nigiriDataDir, "volumes", "elements", "elements.conf"),
+ filepath.Join(datadir, "volumes", "elements", "elements.conf"),
); err != nil {
return err
}
diff --git a/cmd/nigiri/mint.go b/cmd/nigiri/mint.go
index 10e7675..30256a6 100644
--- a/cmd/nigiri/mint.go
+++ b/cmd/nigiri/mint.go
@@ -31,7 +31,8 @@ func mintAction(ctx *cli.Context) error {
return errors.New("wrong number of arguments")
}
- composePath := getCompose(true)
+ datadir := ctx.String("datadir")
+ composePath := getCompose(datadir, true)
serviceName := "chopsticks-liquid"
diff --git a/cmd/nigiri/push.go b/cmd/nigiri/push.go
index d5bf23f..950e1a2 100644
--- a/cmd/nigiri/push.go
+++ b/cmd/nigiri/push.go
@@ -33,7 +33,8 @@ func pushAction(ctx *cli.Context) error {
}
isLiquid := ctx.Bool("liquid")
- composePath := getCompose(isLiquid)
+ datadir := ctx.String("datadir")
+ composePath := getCompose(datadir, isLiquid)
var serviceName string = "chopsticks"
if isLiquid {
diff --git a/cmd/nigiri/start.go b/cmd/nigiri/start.go
index dd1e25d..aa475ec 100644
--- a/cmd/nigiri/start.go
+++ b/cmd/nigiri/start.go
@@ -32,7 +32,8 @@ func startAction(ctx *cli.Context) error {
}
isLiquid := ctx.Bool("liquid")
- composePath := getCompose(isLiquid)
+ datadir := ctx.String("datadir")
+ composePath := getCompose(datadir, isLiquid)
// spin up all the services in the compose file
bashCmd := exec.Command("docker-compose", "-f", composePath, "up", "-d")
diff --git a/cmd/nigiri/stop.go b/cmd/nigiri/stop.go
index c8beb3a..5acacde 100644
--- a/cmd/nigiri/stop.go
+++ b/cmd/nigiri/stop.go
@@ -30,7 +30,8 @@ func stopAction(ctx *cli.Context) error {
if err != nil {
return err
}
- composePath := getCompose(isLiquid)
+ datadir := ctx.String("datadir")
+ composePath := getCompose(datadir, isLiquid)
bashCmd := exec.Command("docker-compose", "-f", composePath, "stop")
if delete {
@@ -45,11 +46,11 @@ func stopAction(ctx *cli.Context) error {
if delete {
fmt.Println("Removing data from volumes...")
- if err := os.RemoveAll(nigiriDataDir); err != nil {
+ if err := os.RemoveAll(ctx.String("datadir")); err != nil {
return err
}
- if err := provisionResourcesToDatadir(); err != nil {
+ if err := provisionResourcesToDatadir(ctx.String("datadir")); err != nil {
return err
}
diff --git a/cmd/nigiri/update.go b/cmd/nigiri/update.go
index 59aa84b..1987e7b 100644
--- a/cmd/nigiri/update.go
+++ b/cmd/nigiri/update.go
@@ -14,7 +14,8 @@ var update = cli.Command{
}
func updateAction(ctx *cli.Context) error {
- composePath := getCompose(true)
+ datadir := ctx.String("datadir")
+ composePath := getCompose(datadir, true)
bashCmd := exec.Command("docker-compose", "-f", composePath, "pull")
bashCmd.Stdout = os.Stdout
diff --git a/cmd/nigiri/version.go b/cmd/nigiri/version.go
new file mode 100644
index 0000000..21c926d
--- /dev/null
+++ b/cmd/nigiri/version.go
@@ -0,0 +1,18 @@
+package main
+
+import (
+ "fmt"
+
+ "github.com/urfave/cli/v2"
+)
+
+var versionCmd = cli.Command{
+ Name: "version",
+ Action: versionAction,
+}
+
+func versionAction(ctx *cli.Context) error {
+ fmt.Println("nigiri CLI version")
+ fmt.Println(formatVersion())
+ return nil
+}
From b349e4dfea957710906afbdc3d5553f4f8dde44d Mon Sep 17 00:00:00 2001
From: Marco Argentieri <3596602+tiero@users.noreply.github.com>
Date: Fri, 6 Aug 2021 15:15:24 +0200
Subject: [PATCH 23/28] wrap datadir in variable
---
cmd/nigiri/stop.go | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/cmd/nigiri/stop.go b/cmd/nigiri/stop.go
index 5acacde..8737f29 100644
--- a/cmd/nigiri/stop.go
+++ b/cmd/nigiri/stop.go
@@ -46,11 +46,13 @@ func stopAction(ctx *cli.Context) error {
if delete {
fmt.Println("Removing data from volumes...")
- if err := os.RemoveAll(ctx.String("datadir")); err != nil {
+
+ datadir := ctx.String("datadir")
+ if err := os.RemoveAll(datadir); err != nil {
return err
}
- if err := provisionResourcesToDatadir(ctx.String("datadir")); err != nil {
+ if err := provisionResourcesToDatadir(datadir); err != nil {
return err
}
From 2e90b53e8d86edec3db4fc024529680c2f6138ff Mon Sep 17 00:00:00 2001
From: Marco Argentieri <3596602+tiero@users.noreply.github.com>
Date: Fri, 6 Aug 2021 16:26:16 +0200
Subject: [PATCH 24/28] use single compose file & move state to internal
---
cmd/nigiri/faucet.go | 4 +-
cmd/nigiri/logs.go | 5 +-
cmd/nigiri/main.go | 27 +-----
cmd/nigiri/mint.go | 4 +-
cmd/nigiri/push.go | 4 +-
.../resources/docker-compose-regtest.yml | 82 -------------------
...-regtest-liquid.yml => docker-compose.yml} | 0
cmd/nigiri/start.go | 11 ++-
cmd/nigiri/stop.go | 8 +-
cmd/nigiri/update.go | 4 +-
internal/config/config.go | 2 +
{pkg => internal}/state/state.go | 0
test/start_stop_test.go | 2 +-
13 files changed, 34 insertions(+), 119 deletions(-)
delete mode 100644 cmd/nigiri/resources/docker-compose-regtest.yml
rename cmd/nigiri/resources/{docker-compose-regtest-liquid.yml => docker-compose.yml} (100%)
rename {pkg => internal}/state/state.go (100%)
diff --git a/cmd/nigiri/faucet.go b/cmd/nigiri/faucet.go
index 72ef423..f073640 100644
--- a/cmd/nigiri/faucet.go
+++ b/cmd/nigiri/faucet.go
@@ -7,9 +7,11 @@ import (
"fmt"
"io/ioutil"
"net/http"
+ "path/filepath"
"strings"
"github.com/urfave/cli/v2"
+ "github.com/vulpemventures/nigiri/internal/config"
"github.com/vulpemventures/nigiri/internal/docker"
)
@@ -35,7 +37,7 @@ func faucetAction(ctx *cli.Context) error {
isLiquid := ctx.Bool("liquid")
datadir := ctx.String("datadir")
- composePath := getCompose(datadir, isLiquid)
+ composePath := filepath.Join(datadir, config.DefaultCompose)
var serviceName string = "chopsticks"
if isLiquid {
diff --git a/cmd/nigiri/logs.go b/cmd/nigiri/logs.go
index 7c4484d..e485276 100644
--- a/cmd/nigiri/logs.go
+++ b/cmd/nigiri/logs.go
@@ -4,8 +4,10 @@ import (
"errors"
"os"
"os/exec"
+ "path/filepath"
"github.com/urfave/cli/v2"
+ "github.com/vulpemventures/nigiri/internal/config"
)
var logs = cli.Command{
@@ -29,9 +31,8 @@ func logsAction(ctx *cli.Context) error {
serviceName := ctx.Args().First()
- isLiquid := ctx.Bool("liquid")
datadir := ctx.String("datadir")
- composePath := getCompose(datadir, isLiquid)
+ composePath := filepath.Join(datadir, config.DefaultCompose)
bashCmd := exec.Command("docker-compose", "-f", composePath, "logs", serviceName)
bashCmd.Stdout = os.Stdout
diff --git a/cmd/nigiri/main.go b/cmd/nigiri/main.go
index 55a2429..6a1d66d 100644
--- a/cmd/nigiri/main.go
+++ b/cmd/nigiri/main.go
@@ -12,7 +12,7 @@ import (
"github.com/urfave/cli/v2"
"github.com/vulpemventures/nigiri/internal/config"
- "github.com/vulpemventures/nigiri/pkg/state"
+ "github.com/vulpemventures/nigiri/internal/state"
)
var (
@@ -21,9 +21,6 @@ var (
date = "unknown"
nigiriState = state.New(config.DefaultPath, config.InitialState)
-
- regtestCompose = "docker-compose-regtest.yml"
- regtestLiquidCompose = "docker-compose-regtest-liquid.yml"
)
var liquidFlag = cli.BoolFlag{
@@ -38,8 +35,7 @@ var datadirFlag = cli.StringFlag{
Value: config.DefaultDatadir,
}
-//go:embed resources/docker-compose-regtest.yml
-//go:embed resources/docker-compose-regtest-liquid.yml
+//go:embed resources/docker-compose.yml
//go:embed resources/bitcoin.conf
//go:embed resources/elements.conf
var f embed.FS
@@ -91,14 +87,6 @@ func fatal(err error) {
os.Exit(1)
}
-func getCompose(datadir string, isLiquid bool) string {
- if isLiquid {
- return filepath.Join(cleanAndExpandPath(datadir), regtestLiquidCompose)
- }
-
- return filepath.Join(cleanAndExpandPath(datadir), regtestCompose)
-}
-
// Provisioning Nigiri reosurces
func provisionResourcesToDatadir(datadir string) error {
@@ -121,15 +109,8 @@ func provisionResourcesToDatadir(datadir string) error {
// copy resources into the Nigiri data directory
if err := copyFromResourcesToDatadir(
- filepath.Join("resources", regtestCompose),
- filepath.Join(datadir, regtestCompose),
- ); err != nil {
- return err
- }
-
- if err := copyFromResourcesToDatadir(
- filepath.Join("resources", regtestLiquidCompose),
- filepath.Join(datadir, regtestLiquidCompose),
+ filepath.Join("resources", config.DefaultCompose),
+ filepath.Join(datadir, config.DefaultCompose),
); err != nil {
return err
}
diff --git a/cmd/nigiri/mint.go b/cmd/nigiri/mint.go
index 30256a6..fb3f84c 100644
--- a/cmd/nigiri/mint.go
+++ b/cmd/nigiri/mint.go
@@ -7,10 +7,12 @@ import (
"fmt"
"io/ioutil"
"net/http"
+ "path/filepath"
"strconv"
"strings"
"github.com/urfave/cli/v2"
+ "github.com/vulpemventures/nigiri/internal/config"
"github.com/vulpemventures/nigiri/internal/docker"
)
@@ -32,7 +34,7 @@ func mintAction(ctx *cli.Context) error {
}
datadir := ctx.String("datadir")
- composePath := getCompose(datadir, true)
+ composePath := filepath.Join(datadir, config.DefaultCompose)
serviceName := "chopsticks-liquid"
diff --git a/cmd/nigiri/push.go b/cmd/nigiri/push.go
index 950e1a2..b72947a 100644
--- a/cmd/nigiri/push.go
+++ b/cmd/nigiri/push.go
@@ -6,9 +6,11 @@ import (
"fmt"
"io/ioutil"
"net/http"
+ "path/filepath"
"strings"
"github.com/urfave/cli/v2"
+ "github.com/vulpemventures/nigiri/internal/config"
"github.com/vulpemventures/nigiri/internal/docker"
)
@@ -34,7 +36,7 @@ func pushAction(ctx *cli.Context) error {
isLiquid := ctx.Bool("liquid")
datadir := ctx.String("datadir")
- composePath := getCompose(datadir, isLiquid)
+ composePath := filepath.Join(datadir, config.DefaultCompose)
var serviceName string = "chopsticks"
if isLiquid {
diff --git a/cmd/nigiri/resources/docker-compose-regtest.yml b/cmd/nigiri/resources/docker-compose-regtest.yml
deleted file mode 100644
index 69e9d03..0000000
--- a/cmd/nigiri/resources/docker-compose-regtest.yml
+++ /dev/null
@@ -1,82 +0,0 @@
-version: '3.5'
-services:
- # RPC daemon
- bitcoin:
- image: ghcr.io/vulpemventures/bitcoin:latest
- container_name: bitcoin
- command:
- - -datadir=config
- ports:
- - 18443:18433
- - 18444:18444
- volumes:
- - ./volumes/bitcoin/:/config
- restart: unless-stopped
-
- # Block explorer server
- electrs:
- image: ghcr.io/vulpemventures/electrs:latest
- container_name: electrs
- entrypoint:
- - /build/electrs
- command:
- - -vvvv
- - --network
- - regtest
- - --daemon-dir
- - /config
- - --daemon-rpc-addr
- - bitcoin:18443
- - --cookie
- - admin1:123
- - --http-addr
- - 0.0.0.0:30000
- - --electrum-rpc-addr
- - 0.0.0.0:50000
- - --cors
- - "*"
- depends_on:
- - bitcoin
- ports:
- - 50000:50000
- - 30000:30000
- volumes:
- - ./volumes/bitcoin/:/config
- restart: unless-stopped
-
- # Block explorer frontend
- esplora:
- image: ghcr.io/vulpemventures/esplora:latest
- container_name: esplora
- depends_on:
- - chopsticks
- environment:
- API_URL: http://localhost:3000
- ports:
- - 5000:5000
- restart: unless-stopped
-
- # Chopsticks
- chopsticks:
- image: ghcr.io/vulpemventures/nigiri-chopsticks:latest
- container_name: chopsticks
- command:
- - --use-faucet
- - --use-mining
- - --use-logger
- - --rpc-addr
- - bitcoin:18443
- - --electrs-addr
- - electrs:30000
- - --addr
- - 0.0.0.0:3000
- depends_on:
- - bitcoin
- - electrs
- ports:
- - 3000:3000
- restart: unless-stopped
-
-networks:
- default:
- name: nigiri
diff --git a/cmd/nigiri/resources/docker-compose-regtest-liquid.yml b/cmd/nigiri/resources/docker-compose.yml
similarity index 100%
rename from cmd/nigiri/resources/docker-compose-regtest-liquid.yml
rename to cmd/nigiri/resources/docker-compose.yml
diff --git a/cmd/nigiri/start.go b/cmd/nigiri/start.go
index aa475ec..15dcacb 100644
--- a/cmd/nigiri/start.go
+++ b/cmd/nigiri/start.go
@@ -5,9 +5,11 @@ import (
"fmt"
"os"
"os/exec"
+ "path/filepath"
"strconv"
"github.com/urfave/cli/v2"
+ "github.com/vulpemventures/nigiri/internal/config"
"github.com/vulpemventures/nigiri/internal/docker"
)
@@ -33,10 +35,15 @@ func startAction(ctx *cli.Context) error {
isLiquid := ctx.Bool("liquid")
datadir := ctx.String("datadir")
- composePath := getCompose(datadir, isLiquid)
+ composePath := filepath.Join(datadir, config.DefaultCompose)
// spin up all the services in the compose file
- bashCmd := exec.Command("docker-compose", "-f", composePath, "up", "-d")
+ bashCmd := exec.Command("docker-compose", "-f", composePath, "up", "-d", "esplora")
+ if isLiquid {
+ //this will only run chopsticks & chopsticks-liquid and servives they depends on
+ bashCmd = exec.Command("docker-compose", "-f", composePath, "up", "-d", "esplora", "esplora-liquid")
+ }
+
if ctx.Bool("ci") {
//this will only run chopsticks and servives it depends on
bashCmd = exec.Command("docker-compose", "-f", composePath, "up", "-d", "chopsticks")
diff --git a/cmd/nigiri/stop.go b/cmd/nigiri/stop.go
index 8737f29..1cfb6e7 100644
--- a/cmd/nigiri/stop.go
+++ b/cmd/nigiri/stop.go
@@ -4,9 +4,11 @@ import (
"fmt"
"os"
"os/exec"
+ "path/filepath"
"strconv"
"github.com/urfave/cli/v2"
+ "github.com/vulpemventures/nigiri/internal/config"
)
var stop = cli.Command{
@@ -26,12 +28,8 @@ var stop = cli.Command{
func stopAction(ctx *cli.Context) error {
delete := ctx.Bool("delete")
- isLiquid, err := nigiriState.GetBool("attachliquid")
- if err != nil {
- return err
- }
datadir := ctx.String("datadir")
- composePath := getCompose(datadir, isLiquid)
+ composePath := filepath.Join(datadir, config.DefaultCompose)
bashCmd := exec.Command("docker-compose", "-f", composePath, "stop")
if delete {
diff --git a/cmd/nigiri/update.go b/cmd/nigiri/update.go
index 1987e7b..0ad9463 100644
--- a/cmd/nigiri/update.go
+++ b/cmd/nigiri/update.go
@@ -3,8 +3,10 @@ package main
import (
"os"
"os/exec"
+ "path/filepath"
"github.com/urfave/cli/v2"
+ "github.com/vulpemventures/nigiri/internal/config"
)
var update = cli.Command{
@@ -15,7 +17,7 @@ var update = cli.Command{
func updateAction(ctx *cli.Context) error {
datadir := ctx.String("datadir")
- composePath := getCompose(datadir, true)
+ composePath := filepath.Join(datadir, config.DefaultCompose)
bashCmd := exec.Command("docker-compose", "-f", composePath, "pull")
bashCmd.Stdout = os.Stdout
diff --git a/internal/config/config.go b/internal/config/config.go
index a56d046..4e9b1df 100644
--- a/internal/config/config.go
+++ b/internal/config/config.go
@@ -9,6 +9,8 @@ import (
var (
DefaultName = "nigiri.config.json"
+ DefaultCompose = "docker-compose.yml"
+
DefaultDatadir = btcutil.AppDataDir("nigiri", false)
DefaultPath = filepath.Join(DefaultDatadir, DefaultName)
diff --git a/pkg/state/state.go b/internal/state/state.go
similarity index 100%
rename from pkg/state/state.go
rename to internal/state/state.go
diff --git a/test/start_stop_test.go b/test/start_stop_test.go
index 8066612..682de4d 100644
--- a/test/start_stop_test.go
+++ b/test/start_stop_test.go
@@ -8,8 +8,8 @@ import (
"testing"
"time"
+ "github.com/vulpemventures/nigiri/interal/state"
"github.com/vulpemventures/nigiri/internal/config"
- "github.com/vulpemventures/nigiri/pkg/state"
)
const (
From a63d172aa3243f20ad4bb8b3bb22e271107db057 Mon Sep 17 00:00:00 2001
From: Marco Argentieri <3596602+tiero@users.noreply.github.com>
Date: Fri, 6 Aug 2021 16:30:24 +0200
Subject: [PATCH 25/28] remove unused state keys
---
cmd/nigiri/start.go | 3 +--
internal/config/config.go | 8 +++-----
2 files changed, 4 insertions(+), 7 deletions(-)
diff --git a/cmd/nigiri/start.go b/cmd/nigiri/start.go
index 15dcacb..b16ed15 100644
--- a/cmd/nigiri/start.go
+++ b/cmd/nigiri/start.go
@@ -61,8 +61,7 @@ func startAction(ctx *cli.Context) error {
}
if err := nigiriState.Set(map[string]string{
- "attachliquid": strconv.FormatBool(isLiquid),
- "running": strconv.FormatBool(true),
+ "running": strconv.FormatBool(true),
}); err != nil {
return err
}
diff --git a/internal/config/config.go b/internal/config/config.go
index 4e9b1df..3456244 100644
--- a/internal/config/config.go
+++ b/internal/config/config.go
@@ -15,10 +15,8 @@ var (
DefaultPath = filepath.Join(DefaultDatadir, DefaultName)
InitialState = map[string]string{
- "attachliquid": strconv.FormatBool(false),
- "datadir": DefaultDatadir,
- "network": "regtest",
- "ready": strconv.FormatBool(false),
- "running": strconv.FormatBool(false),
+ "network": "regtest",
+ "ready": strconv.FormatBool(false),
+ "running": strconv.FormatBool(false),
}
)
From 58c1d713e293c0576a639fe996e5b8c917559173 Mon Sep 17 00:00:00 2001
From: Marco Argentieri <3596602+tiero@users.noreply.github.com>
Date: Fri, 6 Aug 2021 16:31:50 +0200
Subject: [PATCH 26/28] return err in test
---
test/start_stop_test.go | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/test/start_stop_test.go b/test/start_stop_test.go
index 682de4d..6f7acf3 100644
--- a/test/start_stop_test.go
+++ b/test/start_stop_test.go
@@ -8,8 +8,8 @@ import (
"testing"
"time"
- "github.com/vulpemventures/nigiri/interal/state"
"github.com/vulpemventures/nigiri/internal/config"
+ "github.com/vulpemventures/nigiri/internal/state"
)
const (
@@ -108,7 +108,7 @@ func testCommand(command, arg string, flag bool) error {
err := cmd.Start()
if err != nil {
- fmt.Errorf("name: %v, args: %v, err: %v", command, arg, err.Error())
+ return fmt.Errorf("name: %v, args: %v, err: %v", command, arg, err.Error())
}
return nil
From 423bbe44660d3ee5d81c87e6d618baea5276f7a0 Mon Sep 17 00:00:00 2001
From: Marco Argentieri <3596602+tiero@users.noreply.github.com>
Date: Fri, 6 Aug 2021 16:32:20 +0200
Subject: [PATCH 27/28] docker-compose: use latest version
---
cmd/nigiri/resources/docker-compose.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/cmd/nigiri/resources/docker-compose.yml b/cmd/nigiri/resources/docker-compose.yml
index e7be3da..95c30e3 100644
--- a/cmd/nigiri/resources/docker-compose.yml
+++ b/cmd/nigiri/resources/docker-compose.yml
@@ -1,4 +1,4 @@
-version: '3.5'
+version: '3.7'
services:
# RPC daemon
bitcoin:
From fbbf7e4cd4ffb187852eb5e935a53d205c808c18 Mon Sep 17 00:00:00 2001
From: Marco Argentieri <3596602+tiero@users.noreply.github.com>
Date: Fri, 6 Aug 2021 17:59:00 +0200
Subject: [PATCH 28/28] print endpoint of services based on --liquid flag
---
cmd/nigiri/start.go | 12 ++++++++++--
internal/docker/docker.go | 8 ++++----
2 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/cmd/nigiri/start.go b/cmd/nigiri/start.go
index b16ed15..d006992 100644
--- a/cmd/nigiri/start.go
+++ b/cmd/nigiri/start.go
@@ -7,6 +7,7 @@ import (
"os/exec"
"path/filepath"
"strconv"
+ "strings"
"github.com/urfave/cli/v2"
"github.com/vulpemventures/nigiri/internal/config"
@@ -74,8 +75,15 @@ func startAction(ctx *cli.Context) error {
fmt.Println()
fmt.Println("ENDPOINTS")
- for _, endpoint := range services {
- fmt.Println(endpoint)
+ for _, nameAndEndpoint := range services {
+ name := nameAndEndpoint[0]
+ endpoint := nameAndEndpoint[1]
+
+ if !isLiquid && strings.Contains(name, "liquid") {
+ continue
+ }
+
+ fmt.Println(name + " " + endpoint)
}
return nil
diff --git a/internal/docker/docker.go b/internal/docker/docker.go
index c8b38d7..121d10d 100644
--- a/internal/docker/docker.go
+++ b/internal/docker/docker.go
@@ -8,7 +8,7 @@ import (
"github.com/compose-spec/compose-go/loader"
)
-func GetServices(composeFile string) ([]string, error) {
+func GetServices(composeFile string) ([][]string, error) {
composeBytes, err := ioutil.ReadFile(composeFile)
if err != nil {
@@ -26,15 +26,15 @@ func GetServices(composeFile string) ([]string, error) {
serviceMap := parsed["services"].(map[string]interface{})
- var services []string
+ var services [][]string
for k, v := range serviceMap {
m := v.(map[string]interface{})
i := m["ports"].([]interface{})
for _, j := range i {
port := j.(string)
exposedPorts := strings.Split(port, ":")
- endpoint := k + " localhost:" + exposedPorts[0]
- services = append(services, endpoint)
+ endpoint := "localhost:" + exposedPorts[0]
+ services = append(services, []string{k, endpoint})
}
}