diff --git a/go.work.sum b/go.work.sum index 916d7e06f..8158869ea 100644 --- a/go.work.sum +++ b/go.work.sum @@ -489,9 +489,11 @@ github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/checkpoint-restore/go-criu/v5 v5.3.0 h1:wpFFOoomK3389ue2lAb0Boag6XPht5QYpipxmSNL4d8= github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= +github.com/checkpoint-restore/go-criu/v6 v6.3.0 h1:mIdrSO2cPNWQY1truPg6uHLXyKHk3Z5Odx4wjKOASzA= github.com/checkpoint-restore/go-criu/v6 v6.3.0/go.mod h1:rrRTN/uSwY2X+BPRl/gkulo9gsKOSAeVp9/K2tv7xZI= github.com/cilium/ebpf v0.7.0 h1:1k/q3ATgxSXRdrmPfH8d7YK0GfqVsEKZAX9dQZvs56k= github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= +github.com/cilium/ebpf v0.16.0 h1:+BiEnHL6Z7lXnlGUsXQPPAE7+kenAd4ES8MQ5min0Ok= github.com/cilium/ebpf v0.16.0/go.mod h1:L7u2Blt2jMM/vLAVgjxluxtBKlz3/GWjB0dMOEngfwE= github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI= github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58 h1:F1EaeKL/ta07PY/k9Os/UFtwERei2/XzGemhpGnBKNg= @@ -507,6 +509,7 @@ github.com/coder/websocket v1.8.12 h1:5bUXkEPPIbewrnkU8LTCLVaxi4N4J8ahufH2vlo4NA github.com/coder/websocket v1.8.12/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs= github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw= github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= +github.com/containerd/console v1.0.4 h1:F2g4+oChYvBTsASRTz8NP6iIAi97J3TtSAsLbIFn4ro= github.com/containerd/console v1.0.4/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk= github.com/coreos/etcd v3.3.10+incompatible h1:jFneRYjIvLMLhDLCzuTuU4rSJUjRplcJQ7pD7MnhC04= github.com/coreos/go-etcd v2.0.0+incompatible h1:bXhRBIXoTm9BYHS3gE0TtQuyNZyeEMux2sDi4oo5YOo= @@ -515,6 +518,7 @@ github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= +github.com/cyphar/filepath-securejoin v0.3.5 h1:L81NHjquoQmcPgXcttUS9qTSR/+bXry6pbSINQGpjj4= github.com/cyphar/filepath-securejoin v0.3.5/go.mod h1:edhVd3c6OXKjUmSrVa/tGJRS9joFTxlslFCAyaxigkE= github.com/cznic/mathutil v0.0.0-20180504122225-ca4c9f2c1369 h1:XNT/Zf5l++1Pyg08/HV04ppB0gKxAqtZQBRYiYrUuYk= github.com/cznic/mathutil v0.0.0-20180504122225-ca4c9f2c1369/go.mod h1:e6NPNENfs9mPDVNRekM7lKScauxd5kXTr1Mfyig6TDM= @@ -565,6 +569,7 @@ github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+ github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus/v5 v5.0.6 h1:mkgN1ofwASrYnJ5W6U/BxG15eXXXjirgZc7CLqkcaro= github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= @@ -712,7 +717,9 @@ github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3/go.mod h1:RagcQ7I8Ie github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/moby/sys/mountinfo v0.5.0 h1:2Ks8/r6lopsxWi9m58nlwjaeSzUX9iiL1vj5qB/9ObI= github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= +github.com/moby/sys/mountinfo v0.7.1 h1:/tTvQaSJRr2FshkhXiIpux6fQ2Zvc4j7tAhMTStAG2g= github.com/moby/sys/mountinfo v0.7.1/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI= +github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g= github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28= github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6fbMZ9s0scYfZQ84/6SPL6zC8ACM2oIL0= github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= @@ -743,9 +750,11 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWb github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 h1:3snG66yBm59tKhhSPQrQ/0bCrv1LQbKt40LnUPiUxdc= github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/selinux v1.10.0 h1:rAiKF8hTcgLI3w0DHm6i0ylVVcOrlgR1kK99DRLDhyU= github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= +github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaLpt7tQ7oU= github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec= github.com/orisano/pixelmatch v0.0.0-20230914042517-fa304d1dc785 h1:J1//5K/6QF10cZ59zLcVNFGmBfiSrH8Cho/lNrViK9s= github.com/orisano/pixelmatch v0.0.0-20230914042517-fa304d1dc785/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0= @@ -777,6 +786,7 @@ github.com/sagikazarmark/crypt v0.19.0/go.mod h1:c6vimRziqqERhtSe0MhIvzE1w54FrCH github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646 h1:RpforrEYXWkmGwJHIGnLZ3tTWStkjVVstwzNGqxX2Ds= github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= +github.com/seccomp/libseccomp-golang v0.10.0 h1:aA4bp+/Zzi0BnWZ2F1wgNBs5gTpm+na2rWM6M9YjLpY= github.com/seccomp/libseccomp-golang v0.10.0/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= 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= diff --git a/server/cmd/arkd/commands.go b/server/cmd/arkd/commands.go index fe78fdcff..802eb6ad5 100644 --- a/server/cmd/arkd/commands.go +++ b/server/cmd/arkd/commands.go @@ -9,6 +9,7 @@ import ( "io" "net/http" "os" + "path/filepath" "strings" "time" @@ -19,26 +20,26 @@ import ( // flags var ( passwordFlag = &cli.StringFlag{ - Name: "password", + Name: flagPassword, Usage: "wallet password", Required: true, } mnemonicFlag = &cli.StringFlag{ - Name: "mnemonic", + Name: flagMnemonic, Usage: "mnemonic from which restore the wallet", } gapLimitFlag = &cli.Uint64Flag{ - Name: "addr-gap-limit", + Name: flagGapLimit, Usage: "address gap limit for wallet restoration", Value: 100, } amountFlag = &cli.UintFlag{ - Name: "amount", + Name: flagAmount, Usage: "amount of the note in satoshis", Required: true, } quantityFlag = &cli.UintFlag{ - Name: "quantity", + Name: flagQuantity, Usage: "quantity of notes to create", Value: 1, } @@ -97,10 +98,10 @@ var ( var timeout = time.Minute func walletStatusAction(ctx *cli.Context) error { - baseURL := ctx.String("url") - tlsCertPath := ctx.String("tls-cert-path") - if strings.Contains(baseURL, "http://") { - tlsCertPath = "" + baseURL := ctx.String(flagURL) + _, tlsCertPath, err := getCredentialPaths(ctx) + if err != nil { + return err } url := fmt.Sprintf("%s/v1/admin/wallet/status", baseURL) @@ -114,15 +115,16 @@ func walletStatusAction(ctx *cli.Context) error { } func walletCreateOrRestoreAction(ctx *cli.Context) error { - baseURL := ctx.String("url") - password := ctx.String("password") - mnemonic := ctx.String("mnemonic") - gapLimit := ctx.Uint64("addr-gap-limit") - tlsCertPath := ctx.String("tls-cert-path") - if strings.Contains(baseURL, "http://") { - tlsCertPath = "" + baseURL := ctx.String(flagURL) + _, tlsCertPath, err := getCredentialPaths(ctx) + if err != nil { + return err } + password := ctx.String(flagPassword) + mnemonic := ctx.String(flagMnemonic) + gapLimit := ctx.Uint64(flagGapLimit) + if len(mnemonic) > 0 { url := fmt.Sprintf("%s/v1/admin/wallet/restore", baseURL) body := fmt.Sprintf( @@ -156,14 +158,15 @@ func walletCreateOrRestoreAction(ctx *cli.Context) error { } func walletUnlockAction(ctx *cli.Context) error { - baseURL := ctx.String("url") - password := ctx.String("password") + baseURL := ctx.String(flagURL) + _, tlsCertPath, err := getCredentialPaths(ctx) + if err != nil { + return err + } + + password := ctx.String(flagPassword) url := fmt.Sprintf("%s/v1/admin/wallet/unlock", baseURL) body := fmt.Sprintf(`{"password": "%s"}`, password) - tlsCertPath := ctx.String("tls-cert-path") - if strings.Contains(baseURL, "http://") { - tlsCertPath = "" - } if _, err := post[struct{}](url, body, "", "", tlsCertPath); err != nil { return err @@ -174,19 +177,10 @@ func walletUnlockAction(ctx *cli.Context) error { } func walletAddressAction(ctx *cli.Context) error { - baseURL := ctx.String("url") - var macaroon string - if !ctx.Bool("no-macaroon") { - macaroonPath := ctx.String("macaroon-path") - mac, err := getMacaroon(macaroonPath) - if err != nil { - return err - } - macaroon = mac - } - tlsCertPath := ctx.String("tls-cert-path") - if strings.Contains(baseURL, "http://") { - tlsCertPath = "" + baseURL := ctx.String(flagURL) + macaroon, tlsCertPath, err := getCredentialPaths(ctx) + if err != nil { + return err } url := fmt.Sprintf("%s/v1/admin/wallet/address", baseURL) @@ -200,19 +194,10 @@ func walletAddressAction(ctx *cli.Context) error { } func walletBalanceAction(ctx *cli.Context) error { - baseURL := ctx.String("url") - var macaroon string - if !ctx.Bool("no-macaroon") { - macaroonPath := ctx.String("macaroon-path") - mac, err := getMacaroon(macaroonPath) - if err != nil { - return err - } - macaroon = mac - } - tlsCertPath := ctx.String("tls-cert-path") - if strings.Contains(baseURL, "http://") { - tlsCertPath = "" + baseURL := ctx.String(flagURL) + macaroon, tlsCertPath, err := getCredentialPaths(ctx) + if err != nil { + return err } url := fmt.Sprintf("%s/v1/admin/wallet/balance", baseURL) @@ -226,21 +211,12 @@ func walletBalanceAction(ctx *cli.Context) error { } func createNoteAction(ctx *cli.Context) error { - baseURL := ctx.String("url") - amount := ctx.Uint("amount") - quantity := ctx.Uint("quantity") - var macaroon string - if !ctx.Bool("no-macaroon") { - macaroonPath := ctx.String("macaroon-path") - mac, err := getMacaroon(macaroonPath) - if err != nil { - return err - } - macaroon = mac - } - tlsCertPath := ctx.String("tls-cert-path") - if strings.Contains(baseURL, "http://") { - tlsCertPath = "" + baseURL := ctx.String(flagURL) + amount := ctx.Uint(flagAmount) + quantity := ctx.Uint(flagQuantity) + macaroon, tlsCertPath, err := getCredentialPaths(ctx) + if err != nil { + return err } url := fmt.Sprintf("%s/v1/admin/note", baseURL) @@ -258,6 +234,25 @@ func createNoteAction(ctx *cli.Context) error { return nil } +func getCredentialPaths(ctx *cli.Context) (macaroon string, tlsCertPath string, err error) { + datadir := ctx.String(flagDatadir) + + macaroonPath := filepath.Join(datadir, macaroonDir, macaroonFile) + if _, err := os.Stat(macaroonPath); err == nil { + macaroon, err = getMacaroon(macaroonPath) + if err != nil { + return "", "", fmt.Errorf("failed to read macaroon: %w", err) + } + } + + tlsCertPath = filepath.Join(datadir, tlsDir, tlsCertFile) + if strings.Contains(ctx.String(flagURL), "http://") { + tlsCertPath = "" + } + + return macaroon, tlsCertPath, nil +} + func post[T any](url, body, key, macaroon, tlsCert string) (result T, err error) { tlsConfig, err := getTLSConfig(tlsCert) if err != nil { diff --git a/server/cmd/arkd/main.go b/server/cmd/arkd/main.go index 5d70b9f73..d79a39fd7 100755 --- a/server/cmd/arkd/main.go +++ b/server/cmd/arkd/main.go @@ -4,7 +4,6 @@ import ( "fmt" "os" "os/signal" - "path/filepath" "syscall" "github.com/ark-network/ark/common" @@ -18,27 +17,32 @@ import ( // Version will be set during build time var Version string +const ( + macaroonDir = "macaroons" + macaroonFile = "admin.macaroon" + tlsDir = "tls" + tlsCertFile = "cert.pem" + + flagURL = "url" + flagDatadir = "datadir" + flagPassword = "password" + flagMnemonic = "mnemonic" + flagGapLimit = "addr-gap-limit" + flagAmount = "amount" + flagQuantity = "quantity" +) + // flags var ( urlFlag = &cli.StringFlag{ - Name: "url", + Name: flagURL, Usage: "the url where to reach ark server", Value: fmt.Sprintf("http://localhost:%d", config.DefaultPort), } - noMacaroonFlag = &cli.BoolFlag{ - Name: "no-macaroon", - Usage: "don't use macaroon auth", - Value: false, - } - macaroonFlag = &cli.StringFlag{ - Name: "macaroon-path", - Usage: "the path where to find the admin macaroon file", - Value: filepath.Join(common.AppDataDir("arkd", false), "macaroons", "admin.macaroon"), - } - tlsCertFlag = &cli.StringFlag{ - Name: "tls-cert-path", - Usage: "the path where to find the TLS certificate", - Value: filepath.Join(common.AppDataDir("arkd", false), "tls", "cert.pem"), + datadirFlag = &cli.StringFlag{ + Name: flagDatadir, + Usage: "data directory of the ark server to source TLS cert and macaroon from if needed", + Value: common.AppDataDir("arkd", false), } ) @@ -132,7 +136,7 @@ func main() { app.Usage = "arkd command line interface" app.Commands = append(app.Commands, walletCmd) app.Action = mainAction - app.Flags = append(app.Flags, urlFlag, noMacaroonFlag, macaroonFlag, tlsCertFlag) + app.Flags = append(app.Flags, urlFlag, datadirFlag) if err := app.Run(os.Args); err != nil { log.Fatal(err)