package main import ( "context" "encoding/json" "fmt" "log" "os" "path/filepath" "runtime" "time" "github.com/thrasher-corp/gocryptotrader/common" "github.com/thrasher-corp/gocryptotrader/core" "github.com/thrasher-corp/gocryptotrader/exchanges/account" "github.com/thrasher-corp/gocryptotrader/gctrpc/auth" "github.com/thrasher-corp/gocryptotrader/signaler" "github.com/urfave/cli/v2" "google.golang.org/grpc" "google.golang.org/grpc/credentials" "google.golang.org/grpc/metadata" ) var ( host string username string password string pairDelimiter string certPath string timeout time.Duration exchangeCreds account.Credentials verbose bool ) const defaultTimeout = time.Second * 30 func jsonOutput(in interface{}) { j, err := json.MarshalIndent(in, "", " ") if err != nil { return } fmt.Print(string(j)) } func setupClient(c *cli.Context) (*grpc.ClientConn, context.CancelFunc, error) { creds, err := credentials.NewClientTLSFromFile(certPath, "") if err != nil { return nil, nil, err } opts := []grpc.DialOption{grpc.WithTransportCredentials(creds), grpc.WithPerRPCCredentials(auth.BasicAuth{ Username: username, Password: password, }), } var cancel context.CancelFunc c.Context, cancel = context.WithTimeout(c.Context, timeout) if !exchangeCreds.IsEmpty() { flag, values := exchangeCreds.GetMetaData() c.Context = metadata.AppendToOutgoingContext(c.Context, flag, values) } if verbose { c.Context = metadata.AppendToOutgoingContext(c.Context, "verbose", "true") } conn, err := grpc.DialContext(c.Context, host, opts...) return conn, cancel, err } func main() { app := cli.NewApp() app.Name = "gctcli" app.Version = core.Version(true) app.EnableBashCompletion = true app.Usage = "command line interface for managing the gocryptotrader daemon" app.Flags = []cli.Flag{ &cli.StringFlag{ Name: "rpchost", Value: "localhost:9052", Usage: "the gRPC host to connect to", Destination: &host, }, &cli.StringFlag{ Name: "rpcuser", Value: "admin", Usage: "the gRPC username", Destination: &username, }, &cli.StringFlag{ Name: "rpcpassword", Value: "Password", Usage: "the gRPC password", Destination: &password, }, &cli.StringFlag{ Name: "delimiter", Value: "-", Usage: "the default currency pair delimiter used to standardise currency pair input", Destination: &pairDelimiter, }, &cli.StringFlag{ Name: "cert", Value: filepath.Join(common.GetDefaultDataDir(runtime.GOOS), "tls", "cert.pem"), Usage: "the path to TLS cert of the gRPC server", Destination: &certPath, }, &cli.DurationFlag{ Name: "timeout", Value: defaultTimeout, Usage: "the default context timeout value for requests", Destination: &timeout, }, &cli.StringFlag{ Name: "apikey", Usage: "override config API key for request", Destination: &exchangeCreds.Key, }, &cli.StringFlag{ Name: "apisecret", Usage: "override config API Secret for request", Destination: &exchangeCreds.Secret, }, &cli.StringFlag{ Name: "apisubaccount", Usage: "override config API sub account for request", Destination: &exchangeCreds.SubAccount, }, &cli.StringFlag{ Name: "apiclientid", Usage: "override config API client ID for request", Destination: &exchangeCreds.ClientID, }, &cli.StringFlag{ Name: "apipemkey", Usage: "override config API PEM key for request", Destination: &exchangeCreds.PEMKey, }, &cli.StringFlag{ Name: "apionetimepassword", Usage: "override config API One Time Password (OTP) for request", Destination: &exchangeCreds.OneTimePassword, }, &cli.BoolFlag{ Name: "verbose", Usage: "allows the request to generate a more verbose outputs server side", Destination: &verbose, }, } app.Commands = []*cli.Command{ getInfoCommand, getSubsystemsCommand, enableSubsystemCommand, disableSubsystemCommand, getRPCEndpointsCommand, getCommunicationRelayersCommand, getExchangesCommand, enableExchangeCommand, disableExchangeCommand, getExchangeOTPCommand, getExchangeOTPsCommand, getExchangeInfoCommand, getTickerCommand, getTickersCommand, getAccountInfoCommand, getAccountInfoStreamCommand, updateAccountInfoCommand, getConfigCommand, getPortfolioCommand, getPortfolioSummaryCommand, addPortfolioAddressCommand, removePortfolioAddressCommand, getForexProvidersCommand, getForexRatesCommand, getOrdersCommand, getManagedOrdersCommand, getOrderCommand, submitOrderCommand, simulateOrderCommand, cancelOrderCommand, cancelBatchOrdersCommand, cancelAllOrdersCommand, modifyOrderCommand, getEventsCommand, addEventCommand, removeEventCommand, getCryptocurrencyDepositAddressesCommand, getCryptocurrencyDepositAddressCommand, getAvailableTransferChainsCommand, withdrawCryptocurrencyFundsCommand, withdrawFiatFundsCommand, withdrawalRequestCommand, getLoggerDetailsCommand, setLoggerDetailsCommand, exchangePairManagerCommand, getTickerStreamCommand, getExchangeTickerStreamCommand, getAuditEventCommand, getHistoricCandlesCommand, getHistoricCandlesExtendedCommand, findMissingSavedCandleIntervalsCommand, gctScriptCommand, websocketManagerCommand, tradeCommand, dataHistoryCommands, currencyStateManagementCommand, futuresCommands, shutdownCommand, technicalAnalysisCommand, getMarginRatesHistoryCommand, orderbookCommand, } ctx, cancel := context.WithCancel(context.Background()) go func() { // Capture cancel for interrupt signaler.WaitForInterrupt() cancel() fmt.Println("rpc process interrupted") os.Exit(1) }() err := app.RunContext(ctx, os.Args) if err != nil { log.Fatal(err) } }