/
main.go
172 lines (144 loc) · 7.08 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
package main
import (
"fmt"
"os"
"reflect"
"github.com/spf13/cobra"
"github.com/HyperspaceApp/Hyperspace/build"
"github.com/HyperspaceApp/Hyperspace/node/api/client"
)
var (
// Flags.
hostContractOutputType string // output type for host contracts
hostVerbose bool // display additional host info
initForce bool // destroy and re-encrypt the wallet on init if it already exists
initPassword bool // supply a custom password when creating a wallet
renterAllContracts bool // Show all active and expired contracts
renterDownloadAsync bool // Downloads files asynchronously
renterListVerbose bool // Show additional info about uploaded files.
renterShowHistory bool // Show download history in addition to download queue.
walletRawTxn bool // Encode/decode transactions in base64-encoded binary.
)
var (
// Globals.
rootCmd *cobra.Command // Root command cobra object, used by bash completion cmd.
httpClient client.Client
)
// Exit codes.
// inspired by sysexits.h
const (
exitCodeGeneral = 1 // Not in sysexits.h, but is standard practice.
exitCodeUsage = 64 // EX_USAGE in sysexits.h
)
// post makes an API call and discards the response. An error is returned if
// the response status is not 2xx.
// wrap wraps a generic command with a check that the command has been
// passed the correct number of arguments. The command must take only strings
// as arguments.
func wrap(fn interface{}) func(*cobra.Command, []string) {
fnVal, fnType := reflect.ValueOf(fn), reflect.TypeOf(fn)
if fnType.Kind() != reflect.Func {
panic("wrapped function has wrong type signature")
}
for i := 0; i < fnType.NumIn(); i++ {
if fnType.In(i).Kind() != reflect.String {
panic("wrapped function has wrong type signature")
}
}
return func(cmd *cobra.Command, args []string) {
if len(args) != fnType.NumIn() {
cmd.UsageFunc()(cmd)
os.Exit(exitCodeUsage)
}
argVals := make([]reflect.Value, fnType.NumIn())
for i := range args {
argVals[i] = reflect.ValueOf(args[i])
}
fnVal.Call(argVals)
}
}
// die prints its arguments to stderr, then exits the program with the default
// error code.
func die(args ...interface{}) {
fmt.Fprintln(os.Stderr, args...)
os.Exit(exitCodeGeneral)
}
func main() {
root := &cobra.Command{
Use: os.Args[0],
Short: "Hyperspace Client v" + build.Version,
Long: "Hyperspace Client v" + build.Version,
Run: wrap(consensuscmd),
}
rootCmd = root
// create command tree
root.AddCommand(versionCmd)
root.AddCommand(stopCmd)
root.AddCommand(updateCmd)
updateCmd.AddCommand(updateCheckCmd)
root.AddCommand(hostCmd)
hostCmd.AddCommand(hostConfigCmd, hostAnnounceCmd, hostFolderCmd, hostContractCmd, hostSectorCmd)
hostFolderCmd.AddCommand(hostFolderAddCmd, hostFolderRemoveCmd, hostFolderResizeCmd)
hostSectorCmd.AddCommand(hostSectorDeleteCmd)
hostCmd.Flags().BoolVarP(&hostVerbose, "verbose", "v", false, "Display detailed host info")
hostContractCmd.Flags().StringVarP(&hostContractOutputType, "type", "t", "value", "Select output type")
root.AddCommand(hostdbCmd)
hostdbCmd.AddCommand(hostdbViewCmd)
hostdbCmd.Flags().IntVarP(&hostdbNumHosts, "numhosts", "n", 0, "Number of hosts to display from the hostdb")
hostdbCmd.Flags().BoolVarP(&hostdbVerbose, "verbose", "v", false, "Display full hostdb information")
root.AddCommand(minerCmd)
minerCmd.AddCommand(minerStartCmd, minerStopCmd)
root.AddCommand(poolCmd)
poolCmd.AddCommand(poolConfigCmd, poolClientsCmd)
root.AddCommand(stratumminerCmd)
stratumminerCmd.AddCommand(stratumminerStartCmd, stratumminerStopCmd)
root.AddCommand(walletCmd)
walletCmd.AddCommand(walletAddressesCmd, walletChangepasswordCmd, walletGetAddressCmd, walletInitCmd, walletInitSeedCmd,
walletLoadCmd, walletLockCmd, walletNewAddressCmd, walletSeedsCmd, walletSendCmd, walletSweepCmd, walletSignCmd,
walletBalanceCmd, walletBroadcastCmd, walletTransactionsCmd, walletUnlockCmd)
walletInitCmd.Flags().BoolVarP(&initPassword, "password", "p", false, "Prompt for a custom password")
walletInitCmd.Flags().BoolVarP(&initForce, "force", "", false, "destroy the existing wallet and re-encrypt")
walletInitSeedCmd.Flags().BoolVarP(&initForce, "force", "", false, "destroy the existing wallet")
walletLoadCmd.AddCommand(walletLoadSeedCmd, walletLoadSiagCmd)
walletSendCmd.AddCommand(walletSendSiacoinsCmd)
walletUnlockCmd.Flags().BoolVarP(&initPassword, "password", "p", false, "Display interactive password prompt even if HYPERSPACE_WALLET_PASSWORD is set")
walletBroadcastCmd.Flags().BoolVarP(&walletRawTxn, "raw", "", false, "Decode transaction as base64 instead of JSON")
walletSignCmd.Flags().BoolVarP(&walletRawTxn, "raw", "", false, "Encode signed transaction as base64 instead of JSON")
root.AddCommand(renterCmd)
renterCmd.AddCommand(renterFilesDeleteCmd, renterFilesDownloadCmd,
renterDownloadsCmd, renterAllowanceCmd, renterSetAllowanceCmd,
renterContractsCmd, renterFilesListCmd, renterFilesRenameCmd,
renterFilesUploadCmd, renterUploadsCmd, renterExportCmd,
renterPricesCmd)
renterContractsCmd.AddCommand(renterContractsViewCmd)
renterAllowanceCmd.AddCommand(renterAllowanceCancelCmd)
renterCmd.Flags().BoolVarP(&renterListVerbose, "verbose", "v", false, "Show additional file info such as redundancy")
renterContractsCmd.Flags().BoolVarP(&renterAllContracts, "all", "A", false, "Show all expired contracts in addition to active contracts")
renterDownloadsCmd.Flags().BoolVarP(&renterShowHistory, "history", "H", false, "Show download history in addition to the download queue")
renterFilesDownloadCmd.Flags().BoolVarP(&renterDownloadAsync, "async", "A", false, "Download file asynchronously")
renterFilesListCmd.Flags().BoolVarP(&renterListVerbose, "verbose", "v", false, "Show additional file info such as redundancy")
renterExportCmd.AddCommand(renterExportContractTxnsCmd)
root.AddCommand(gatewayCmd)
gatewayCmd.AddCommand(gatewayConnectCmd, gatewayDisconnectCmd, gatewayAddressCmd, gatewayListCmd)
root.AddCommand(consensusCmd)
root.AddCommand(bashcomplCmd)
root.AddCommand(mangenCmd)
// initialize client
root.PersistentFlags().StringVarP(&httpClient.Address, "addr", "a", "localhost:5580", "which host/port to communicate with (i.e. the host/port hsd is listening on)")
root.PersistentFlags().StringVarP(&httpClient.Password, "apipassword", "", "", "the password for the API's http authentication")
root.PersistentFlags().StringVarP(&httpClient.UserAgent, "useragent", "", "Hyperspace-Agent", "the useragent used by hsc to connect to the daemon's API")
// Check if the api password environment variable is set.
apiPassword := os.Getenv("HYPERSPACE_API_PASSWORD")
if apiPassword != "" {
httpClient.Password = apiPassword
fmt.Println("Using HYPERSPACE_API_PASSWORD environment variable")
}
// run
if err := root.Execute(); err != nil {
// Since no commands return errors (all commands set Command.Run instead of
// Command.RunE), Command.Execute() should only return an error on an
// invalid command or flag. Therefore Command.Usage() was called (assuming
// Command.SilenceUsage is false) and we should exit with exitCodeUsage.
os.Exit(exitCodeUsage)
}
}