Skip to content

Commit

Permalink
Merge branch 'master' into ws_subs_abs
Browse files Browse the repository at this point in the history
  • Loading branch information
shazbert committed Jan 15, 2025
2 parents dc72434 + 4c7f48a commit 5ce010d
Show file tree
Hide file tree
Showing 132 changed files with 234,352 additions and 160,598 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/proto-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
- uses: bufbuild/buf-setup-action@v1.46.0
- uses: bufbuild/buf-setup-action@v1.49.0

- name: buf generate
working-directory: ./gctrpc
Expand Down
42 changes: 42 additions & 0 deletions .github/workflows/stale.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: stale-checks
on:
schedule:
- cron: '0 0 * * 1-5'
workflow_dispatch:

permissions:
contents: read

env:
DAYS_BEFORE_STALE: ${{ vars.DAYS_BEFORE_STALE }}
DAYS_BEFORE_CLOSE: ${{ vars.DAYS_BEFORE_CLOSE }}
EXEMPT_ISSUE_LABELS: ${{ vars.EXEMPT_ISSUE_LABELS }}
EXEMPT_PR_LABELS: ${{ vars.EXEMPT_PR_LABELS }}

jobs:
stale:
name: Stale issues and PRs check
runs-on: ubuntu-latest
environment: ci
permissions:
issues: write
pull-requests: write
steps:
- uses: actions/stale@v9
with:
# General settings
days-before-stale: ${{ env.DAYS_BEFORE_STALE }}
days-before-close: ${{ env.DAYS_BEFORE_CLOSE }}
exempt-issue-labels: ${{ env.EXEMPT_ISSUE_LABELS }}
exempt-pr-labels: ${{ env.EXEMPT_PR_LABELS }}
enable-statistics: true

# Issue settings
stale-issue-message: 'This issue is stale because it has been open ${{ env.DAYS_BEFORE_STALE }} days with no activity. Please provide an update or this issue will be automatically closed in ${{ env.DAYS_BEFORE_CLOSE }} days.'
close-issue-message: 'This issue was closed because it has been stalled for ${{ env.DAYS_BEFORE_CLOSE }} days with no activity.'
stale-issue-label: 'stale'

# PR settings
stale-pr-message: 'This PR is stale because it has been open ${{ env.DAYS_BEFORE_STALE }} days with no activity. Please provide an update on the progress of this PR.'
days-before-pr-close: -1
stale-pr-label: 'stale'
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ jobs:
GOARCH: ${{ matrix.goarch }}

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
uses: codecov/codecov-action@v5
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

Expand Down
3 changes: 3 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,9 @@ issues:
- text: "Expect WriteFile permissions to be 0600 or less"
linters:
- gosec
- text: 'shadow: declaration of "err" shadows declaration at'
linters: [ govet ]


exclude-dirs:
- vendor
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,11 @@ Binaries will be published once the codebase reaches a stable condition.

|User|Contribution Amount|
|--|--|
| [thrasher-](https://github.com/thrasher-) | 700 |
| [shazbert](https://github.com/shazbert) | 345 |
| [dependabot[bot]](https://github.com/apps/dependabot) | 317 |
| [gloriousCode](https://github.com/gloriousCode) | 234 |
| [gbjk](https://github.com/gbjk) | 93 |
| [thrasher-](https://github.com/thrasher-) | 703 |
| [shazbert](https://github.com/shazbert) | 355 |
| [dependabot[bot]](https://github.com/apps/dependabot) | 331 |
| [gloriousCode](https://github.com/gloriousCode) | 236 |
| [gbjk](https://github.com/gbjk) | 107 |
| [dependabot-preview[bot]](https://github.com/apps/dependabot-preview) | 88 |
| [xtda](https://github.com/xtda) | 47 |
| [lrascao](https://github.com/lrascao) | 27 |
Expand Down
203 changes: 149 additions & 54 deletions cmd/config/config.go
Original file line number Diff line number Diff line change
@@ -1,82 +1,177 @@
package main

import (
"encoding/json"
"errors"
"flag"
"log"
"fmt"
"os"
"slices"
"strings"

"github.com/buger/jsonparser"
"github.com/thrasher-corp/gocryptotrader/common/file"
"github.com/thrasher-corp/gocryptotrader/config"
)

// EncryptOrDecrypt returns a string from a boolean
func EncryptOrDecrypt(encrypt bool) string {
if encrypt {
return "encrypted"
}
return "decrypted"
}
var commands = []string{"upgrade", "encrypt", "decrypt"}

func main() {
var inFile, outFile, key string
var encrypt bool
fmt.Println("GoCryptoTrader: config-helper tool")

defaultCfgFile := config.DefaultFilePath()
flag.StringVar(&inFile, "infile", defaultCfgFile, "The config input file to process.")
flag.StringVar(&outFile, "outfile", defaultCfgFile+".out", "The config output file.")
flag.BoolVar(&encrypt, "encrypt", true, "Whether to encrypt or decrypt.")
flag.StringVar(&key, "key", "", "The key to use for AES encryption.")
flag.Parse()

log.Println("GoCryptoTrader: config-helper tool.")

if key == "" {
result, err := config.PromptForConfigKey(false)
if err != nil {
log.Fatalf("Unable to obtain encryption/decryption key: %s", err)
}
key = string(result)

var in, out, keyStr string
var inplace bool

fs := flag.NewFlagSet("config", flag.ExitOnError)
fs.Usage = func() { usage(fs) }
fs.StringVar(&in, "in", defaultCfgFile, "The config input file to process")
fs.StringVar(&out, "out", "[in].out", "The config output file")
fs.BoolVar(&inplace, "edit", false, "Edit; Save result to the original file")
fs.StringVar(&keyStr, "key", "", "The key to use for AES encryption")

cmd, args := parseCommand(os.Args[1:])
if cmd == "" {
usage(fs)
os.Exit(2)
}

if err := fs.Parse(args); err != nil {
fatal(err.Error())
}

if inplace {
out = in
} else if out == "[in].out" {
out = in + ".out"
}

key := []byte(keyStr)
var err error
switch cmd {
case "upgrade":
err = upgradeFile(in, out, key)
case "decrypt":
err = encryptWrapper(in, out, key, false, decryptFile)
case "encrypt":
err = encryptWrapper(in, out, key, true, encryptFile)
}

fileData, err := os.ReadFile(inFile)
if err != nil {
log.Fatalf("Unable to read input file %s. Error: %s.", inFile, err)
fatal(err.Error())
}

if config.ConfirmECS(fileData) && encrypt {
log.Println("File is already encrypted. Decrypting..")
encrypt = false
fmt.Println("Success! File written to " + out)
}

func upgradeFile(in, out string, key []byte) error {
c := &config.Config{
EncryptionKeyProvider: func(_ bool) ([]byte, error) {
if len(key) != 0 {
return key, nil
}
return config.PromptForConfigKey(false)
},
}

if !config.ConfirmECS(fileData) && !encrypt {
var result interface{}
errf := json.Unmarshal(fileData, &result)
if errf != nil {
log.Fatal(errf)
}
log.Println("File is already decrypted. Encrypting..")
encrypt = true
if err := c.ReadConfigFromFile(in, true); err != nil {
return err
}

var data []byte
if encrypt {
data, err = config.EncryptConfigFile(fileData, []byte(key))
if err != nil {
log.Fatalf("Unable to encrypt config data. Error: %s.", err)
}
} else {
data, err = config.DecryptConfigFile(fileData, []byte(key))
if err != nil {
log.Fatalf("Unable to decrypt config data. Error: %s.", err)
return c.SaveConfigToFile(out)
}

type encryptFunc func(string, []byte) ([]byte, error)

func encryptWrapper(in, out string, key []byte, confirmKey bool, fn encryptFunc) error {
if len(key) == 0 {
var err error
if key, err = config.PromptForConfigKey(confirmKey); err != nil {
return err
}
}
outData, err := fn(in, key)
if err != nil {
return err
}
if err := file.Write(out, outData); err != nil {
return fmt.Errorf("unable to write output file %s; Error: %w", out, err)
}
return nil
}

func encryptFile(in string, key []byte) ([]byte, error) {
if config.IsFileEncrypted(in) {
return nil, errors.New("file is already encrypted")
}
outData, err := config.EncryptConfigFile(readFile(in), key)
if err != nil {
return nil, fmt.Errorf("unable to encrypt config data. Error: %w", err)
}
return outData, nil
}

func decryptFile(in string, key []byte) ([]byte, error) {
if !config.IsFileEncrypted(in) {
return nil, errors.New("file is already decrypted")
}
outData, err := config.DecryptConfigFile(readFile(in), key)
if err != nil {
return nil, fmt.Errorf("unable to decrypt config data. Error: %w", err)
}
if outData, err = jsonparser.Set(outData, []byte("-1"), "encryptConfig"); err != nil {
return nil, fmt.Errorf("unable to decrypt config data. Error: %w", err)
}
return outData, nil
}

err = file.Write(outFile, data)
func readFile(in string) []byte {
fileData, err := os.ReadFile(in)
if err != nil {
log.Fatalf("Unable to write output file %s. Error: %s", outFile, err)
fatal("Unable to read input file " + in + "; Error: " + err.Error())
}
log.Printf(
"Successfully %s input file %s and wrote output to %s.\n",
EncryptOrDecrypt(encrypt), inFile, outFile,
)
return fileData
}

func fatal(msg string) {
fmt.Fprintln(os.Stderr, msg)
os.Exit(2)
}

// parseCommand will return the single non-flag parameter from os.Args, and return the remaining args
// If none is provided, too many, usage() will be called and exit 1
func parseCommand(a []string) (cmd string, args []string) {
cmds, rem := []string{}, []string{}
for _, s := range a {
if slices.Contains(commands, s) {
cmds = append(cmds, s)
} else {
rem = append(rem, s)
}
}
switch len(cmds) {
case 0:
fmt.Fprintln(os.Stderr, "No command provided")
case 1: //
return cmds[0], rem
default:
fmt.Fprintln(os.Stderr, "Too many commands provided: "+strings.Join(cmds, ", "))
}
return "", nil
}

// usage prints command usage and exits 1
func usage(fs *flag.FlagSet) {
//nolint:dupword // deliberate duplication of commands
fmt.Fprintln(os.Stderr, `
Usage:
config [arguments] <command>
The commands are:
encrypt encrypt infile and write to outfile
decrypt decrypt infile and write to outfile
upgrade upgrade the version of a decrypted config file
The arguments are:`)
fs.PrintDefaults()
}
18 changes: 0 additions & 18 deletions cmd/config/config_test.go

This file was deleted.

21 changes: 16 additions & 5 deletions cmd/documentation/exchanges_templates/deribit.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,23 @@ if err != nil {
}
```

### How to do Websocket public/private calls
### Subscriptions

```go
// Exchanges will be abstracted out in further updates and examples will be
// supplied then
```
All default subscriptions are for all enabled assets.

Default Public Subscriptions:
- Candles ( Timeframe: 1 day )
- Orderbook ( Full depth @ Interval: 100ms )
- Ticker ( Interval: 100ms )
- All Trades ( Interval: 100ms )

Default Authenticated Subscriptions:
- My Account Orders
- My Account Trades

kline.Raw Interval configurable for a raw orderbook subscription when authenticated

Subscriptions are subject to enabled assets and pairs.

### Please click GoDocs chevron above to view current GoDoc information for this package
{{template "contributions"}}
Expand Down
22 changes: 17 additions & 5 deletions cmd/documentation/exchanges_templates/hitbtc.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,24 @@ if err != nil {
}
```

### How to do Websocket public/private calls
### Subscriptions

```go
// Exchanges will be abstracted out in further updates and examples will be
// supplied then
```
Subscriptions are for [v2 api](https://hitbtc-com.github.io/hitbtc-api/#socket-api-reference)

All subscriptions are for spot.

Default Public Subscriptions:
- Ticker
- Orderbook
- Candles ( Interval: 30 minutes, History: 100 )
- All Trades ( History: 100 )

Default Authenticated Subscriptions:
- My Account events

Subscriptions are subject to enabled assets and pairs.

Configure Levels for number of history entries to return for applicable APIs.

### Please click GoDocs chevron above to view current GoDoc information for this package
{{template "contributions"}}
Expand Down
Loading

0 comments on commit 5ce010d

Please sign in to comment.