package sati import ( "fmt" "time" "github.com/mitchellh/mapstructure" "github.com/shopspring/decimal" ) type Config struct { ReconnectionInterval time.Duration Endpoint string Debug bool Token string } func NewConfig(token string) Config { return Config{ ReconnectionInterval: time.Second, Debug: false, Endpoint: "wss://api.sati.ac/ws", Token: token, } } type Api struct { socket *socket } func (a *Api) CreateTask(task AnyTask) (*CreateTaskResult, error) { result := &CreateTaskResult{} if err := a.socket.call("createTask", task.serialize(), result); err != nil { return nil, err } return result, nil } func (a *Api) Solve(task AnyTask, result any) (*TaskEntity, error) { createdTask, err := a.CreateTask(task) if err != nil { return nil, err } resultCh := make(chan *TaskUpdateEvent) handler, err := a.socket.events.On("taskUpdate", func(data any) { e := data.(TaskUpdateEvent) if createdTask.Id == e.Id && (e.State == "error" || e.State == "success") { resultCh <- &e } }) if err != nil { return nil, err } solvedTask := <-resultCh handler.Off() if solvedTask.State == "error" { return nil, fmt.Errorf("sati: failed to solve task") } if err := mapstructure.Decode(solvedTask.Result, result); err != nil { return nil, err } return (*TaskEntity)(solvedTask), nil } func (a *Api) GetBalance() (*decimal.Decimal, error) { result := GetBalanceResult{} if err := a.socket.call("getBalance", &GetBalanceRequest{}, &result); err != nil { return nil, err } balance, err := decimal.NewFromString(result.Balance) if err != nil { return nil, err } return &balance, nil } func (a *Api) Dispose() { a.socket.close() } func NewApi(config Config) *Api { return &Api{ socket: newSocket(config), } }