Files
gocryptotrader/gctscript/modules/gct/gct.go
Ryan O'Hara-Reid e93ee83563 script: implementation of error insertion on return (#986)
* exchanges/account: shift credentials to account package and segregate funds to keys

* merge: fixes

* linter: fix

* Update exchanges/account/account.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* glorious: nits + protection for string panic

* glorious_suggestion: add method for matching keys

* linter: fix tests

* account: add protected method for credentials minimizing access, display full account details to rpc.

* linter: spelling kweeeeeeen

* accounts/portfolio: clean/check portfolio code and quickly check balances from change. Add protected method for future matching.

* accounts: theres no point in pointerising everything

* linter: ok pointerise this then...

* exchanges: fix regression add in little notes.

* glorious: nits

* Update exchanges/account/credentials.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* Update exchanges/account/credentials_test.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* Update exchanges/account/credentials_test.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* glorious: nits

* gloriously: fix glorious glorious test gloriously

* script: initial implementation of error insertion on return

* script: make script context aware(ish) and update error handle in examples

* script: add tests

* script: add syntax highlighting to readme

* Update gctscript/vm/vm.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* Update gctscript/vm/vm.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* Update gctscript/examples/exchange/account_info.gct

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* Update gctscript/examples/exchange/cancel_order.gct

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* Update gctscript/examples/verbose.gct

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* Update gctscript/modules/gct/gct_test.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* glorious: nits

* rm: bros

* scripts: handle errors in examples when they are going to use the data after fetching

* linter: fix rides again

* SCOTT_SPELL_CHECK_LINTER: fix

* gctscript: fix tests

* glorious: niiiiiiiiiiiiits

* scriptmodules/gct: standardize runtime errors

* Update gctscript/modules/gct/exchange.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* Update gctscript/modules/gct/exchange.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* Update gctscript/modules/gct/exchange.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* Update gctscript/modules/gct/exchange.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* Update gctscript/modules/gct/gct.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* Update gctscript/modules/gct/gct.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* Update gctscript/modules/gct/gct.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* Update gctscript/modules/gct/gct.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* Update gctscript/modules/gct/gct.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* Update gctscript/modules/gct/gct.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* Update gctscript/modules/gct/gct.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* glorious: nits/reverts

* go mod: tidy

Co-authored-by: Ryan O'Hara-Reid <ryan.oharareid@thrasher.io>
Co-authored-by: Scott <gloriousCode@users.noreply.github.com>
2022-08-17 14:18:53 +10:00

211 lines
5.7 KiB
Go

package gct
import (
"context"
objects "github.com/d5/tengo/v2"
"github.com/thrasher-corp/gocryptotrader/exchanges/account"
"github.com/thrasher-corp/gocryptotrader/exchanges/request"
)
const (
setVerboseFunc = "set_verbose"
setAccountFunc = "set_account"
setSubAccountFunc = "set_sub_account"
)
var globalModules = map[string]objects.Object{
setVerboseFunc: &objects.UserFunction{Name: setVerboseFunc, Value: setVerbose},
setAccountFunc: &objects.UserFunction{Name: setAccountFunc, Value: setAccount},
setSubAccountFunc: &objects.UserFunction{Name: setSubAccountFunc, Value: setSubAccount},
}
// AllModuleNames returns a list of all default module names.
func AllModuleNames() []string {
names := make([]string, 0, len(Modules))
for name := range Modules {
names = append(names, name)
}
return names
}
// setVerbose specifically sets verbosity for http rest requests for this script
// Params: scriptCTX
func setVerbose(args ...objects.Object) (objects.Object, error) {
if len(args) != 1 {
return nil, objects.ErrWrongNumArguments
}
ctx, ok := objects.ToInterface(args[0]).(*Context)
if !ok {
return nil, constructRuntimeError(1, setVerboseFunc, "*gct.Context", args[0])
}
if ctx.Value == nil {
ctx.Value = make(map[string]objects.Object)
}
ctx.Value["verbose"] = objects.TrueValue
return ctx, nil
}
// setAccount sets account details which overrides default credentials for
// script account management, api key and secret are required.
// Params: scriptCTX, apiKey, apiSecret, subAccount, clientID, PEMKey, OneTimePassword string
func setAccount(args ...objects.Object) (objects.Object, error) {
if len(args) < 3 || len(args) > 7 {
return nil, objects.ErrWrongNumArguments
}
ctx, ok := objects.ToInterface(args[0]).(*Context)
if !ok {
return nil, constructRuntimeError(1, setAccountFunc, "*gct.Context", args[0])
}
apikey, ok := objects.ToInterface(args[1]).(string)
if !ok {
return nil, constructRuntimeError(2, setAccountFunc, "string", args[1])
}
if ctx.Value == nil {
ctx.Value = make(map[string]objects.Object)
}
ctx.Value["apikey"] = &objects.String{Value: apikey}
apisecret, ok := objects.ToInterface(args[2]).(string)
if !ok {
return nil, constructRuntimeError(3, setAccountFunc, "string", args[2])
}
ctx.Value["apisecret"] = &objects.String{Value: apisecret}
if len(args) > 3 {
var subaccount string
subaccount, ok = objects.ToInterface(args[3]).(string)
if !ok {
return nil, constructRuntimeError(4, setAccountFunc, "string", args[3])
}
if subaccount != "" {
ctx.Value["subaccount"] = &objects.String{Value: subaccount}
}
}
if len(args) > 4 {
var clientID string
clientID, ok = objects.ToInterface(args[4]).(string)
if !ok {
return nil, constructRuntimeError(5, setAccountFunc, "string", args[4])
}
if clientID != "" {
ctx.Value["clientid"] = &objects.String{Value: clientID}
}
}
if len(args) > 5 {
var pemKey string
pemKey, ok = objects.ToInterface(args[5]).(string)
if !ok {
return nil, constructRuntimeError(6, setAccountFunc, "string", args[5])
}
if pemKey != "" {
ctx.Value["pemkey"] = &objects.String{Value: pemKey}
}
}
if len(args) > 5 {
var oneTimePassword string
oneTimePassword, ok = objects.ToInterface(args[6]).(string)
if !ok {
return nil, constructRuntimeError(7, setAccountFunc, "string", args[6])
}
if oneTimePassword != "" {
ctx.Value["otp"] = &objects.String{Value: oneTimePassword}
}
}
return ctx, nil
}
// setSubAccount sets sub account details which overrides default credential
// sub account but uses the same configured api keys.
// Params: scriptCTX, subAccount string
func setSubAccount(args ...objects.Object) (objects.Object, error) {
if len(args) != 2 {
return nil, objects.ErrWrongNumArguments
}
ctx, ok := objects.ToInterface(args[0]).(*Context)
if !ok {
return nil, constructRuntimeError(1, setSubAccountFunc, "*gct.Context", args[0])
}
sub, ok := objects.ToInterface(args[1]).(string)
if !ok {
return nil, constructRuntimeError(2, setSubAccountFunc, "string", args[1])
}
if ctx.Value == nil {
ctx.Value = make(map[string]objects.Object)
}
ctx.Value["subaccount"] = &objects.String{Value: sub}
return ctx, nil
}
func processScriptContext(scriptCtx *Context) context.Context {
ctx := context.Background()
if scriptCtx == nil || scriptCtx.Value == nil {
return ctx
}
var object objects.Object
if object = scriptCtx.Value["verbose"]; object != nil {
ctx = request.WithVerbose(ctx)
}
if object = scriptCtx.Value["apikey"]; object != nil {
key, _ := objects.ToString(object)
var secret string
if object = scriptCtx.Value["apisecret"]; object != nil {
secret, _ = objects.ToString(object)
}
var subAccount string
if object = scriptCtx.Value["subaccount"]; object != nil {
subAccount, _ = objects.ToString(object)
}
var clientID string
if object = scriptCtx.Value["clientid"]; object != nil {
clientID, _ = objects.ToString(object)
}
var pemKey string
if object = scriptCtx.Value["pemkey"]; object != nil {
pemKey, _ = objects.ToString(object)
}
var otp string
if object = scriptCtx.Value["otp"]; object != nil {
otp, _ = objects.ToString(object)
}
ctx = account.DeployCredentialsToContext(ctx, &account.Credentials{
Key: key,
Secret: secret,
SubAccount: subAccount,
ClientID: clientID,
PEMKey: pemKey,
OneTimePassword: otp,
})
} else if object = scriptCtx.Value["subaccount"]; object != nil {
subAccount, _ := objects.ToString(object)
ctx = account.DeploySubAccountOverrideToContext(ctx, subAccount)
}
return ctx
}
// TypeName returns the name of the custom type.
func (c *Context) TypeName() string {
return "scriptContext"
}