From b8dfa443d33a041ffc9aac2464c6609682d4e061 Mon Sep 17 00:00:00 2001 From: Adrian Gallagher Date: Mon, 3 Feb 2020 12:44:46 +1100 Subject: [PATCH] Huobi: Add deposit address and withdraw quota API support (#433) * Add Huobi deposit and withdraw quota API support Plus perform come code deduplication * Go mod tidy --- exchanges/huobi/huobi.go | 344 ++++++++++++++----------------- exchanges/huobi/huobi_test.go | 21 +- exchanges/huobi/huobi_types.go | 32 +++ exchanges/huobi/huobi_wrapper.go | 4 +- go.mod | 2 - go.sum | 17 +- 6 files changed, 210 insertions(+), 210 deletions(-) diff --git a/exchanges/huobi/huobi.go b/exchanges/huobi/huobi.go index 430d0717..7d19fded 100644 --- a/exchanges/huobi/huobi.go +++ b/exchanges/huobi/huobi.go @@ -24,8 +24,9 @@ import ( ) const ( - huobiAPIURL = "https://api.huobi.pro" - huobiAPIVersion = "1" + huobiAPIURL = "https://api.huobi.pro" + huobiAPIVersion = "1" + huobiAPIVersion2 = "2" huobiMarketHistoryKline = "market/history/kline" huobiMarketDetail = "market/detail" @@ -39,6 +40,8 @@ const ( huobiTimestamp = "common/timestamp" huobiAccounts = "account/accounts" huobiAccountBalance = "account/accounts/%s/balance" + huobiAccountDepositAddress = "account/deposit/address" + huobiAccountWithdrawQuota = "account/withdraw/quota" huobiAggregatedBalance = "subuser/aggregate-balance" huobiOrderPlace = "order/orders/place" huobiOrderCancel = "order/orders/%s/submitcancel" @@ -60,6 +63,8 @@ const ( huobiAuthRate = 100 huobiUnauthRate = 100 + + huobiStatusError = "error" ) // HUOBI is the overarching type across this package @@ -287,61 +292,38 @@ func (h *HUOBI) GetTimestamp() (int64, error) { // GetAccounts returns the Huobi user accounts func (h *HUOBI) GetAccounts() ([]Account, error) { - type response struct { - Response - AccountData []Account `json:"data"` - } - - var result response - err := h.SendAuthenticatedHTTPRequest(http.MethodGet, huobiAccounts, url.Values{}, nil, &result) - - if result.ErrorMessage != "" { - return nil, errors.New(result.ErrorMessage) - } - return result.AccountData, err + result := struct { + Accounts []Account `json:"data"` + }{} + err := h.SendAuthenticatedHTTPRequest(http.MethodGet, huobiAccounts, url.Values{}, nil, &result, false) + return result.Accounts, err } // GetAccountBalance returns the users Huobi account balance func (h *HUOBI) GetAccountBalance(accountID string) ([]AccountBalanceDetail, error) { - type response struct { - Response + result := struct { AccountBalanceData AccountBalance `json:"data"` - } - - var result response + }{} endpoint := fmt.Sprintf(huobiAccountBalance, accountID) - v := url.Values{} v.Set("account-id", accountID) - - err := h.SendAuthenticatedHTTPRequest(http.MethodGet, endpoint, v, nil, &result) - - if result.ErrorMessage != "" { - return nil, errors.New(result.ErrorMessage) - } + err := h.SendAuthenticatedHTTPRequest(http.MethodGet, endpoint, v, nil, &result, false) return result.AccountBalanceData.AccountBalanceDetails, err } // GetAggregatedBalance returns the balances of all the sub-account aggregated. func (h *HUOBI) GetAggregatedBalance() ([]AggregatedBalance, error) { - type response struct { - Response + result := struct { AggregatedBalances []AggregatedBalance `json:"data"` - } - - var result response - + }{} err := h.SendAuthenticatedHTTPRequest( http.MethodGet, huobiAggregatedBalance, nil, nil, &result, + false, ) - - if result.ErrorMessage != "" { - return nil, errors.New(result.ErrorMessage) - } return result.AggregatedBalances, err } @@ -370,35 +352,28 @@ func (h *HUOBI) SpotNewOrder(arg SpotNewOrderRequestParams) (int64, error) { data.Source = arg.Source } - type response struct { - Response + result := struct { OrderID int64 `json:"data,string"` - } - - var result response - err := h.SendAuthenticatedHTTPRequest(http.MethodPost, huobiOrderPlace, nil, data, &result) - - if result.ErrorMessage != "" { - return 0, errors.New(result.ErrorMessage) - } + }{} + err := h.SendAuthenticatedHTTPRequest( + http.MethodPost, + huobiOrderPlace, + nil, + data, + &result, + false, + ) return result.OrderID, err } // CancelExistingOrder cancels an order on Huobi func (h *HUOBI) CancelExistingOrder(orderID int64) (int64, error) { - type response struct { - Response + resp := struct { OrderID int64 `json:"data,string"` - } - - var result response + }{} endpoint := fmt.Sprintf(huobiOrderCancel, strconv.FormatInt(orderID, 10)) - err := h.SendAuthenticatedHTTPRequest(http.MethodPost, endpoint, url.Values{}, nil, &result) - - if result.ErrorMessage != "" { - return 0, errors.New(result.ErrorMessage) - } - return result.OrderID, err + err := h.SendAuthenticatedHTTPRequest(http.MethodPost, endpoint, url.Values{}, nil, &resp, false) + return resp.OrderID, err } // CancelOrderBatch cancels a batch of orders -- to-do @@ -409,7 +384,7 @@ func (h *HUOBI) CancelOrderBatch(_ []int64) ([]CancelOrderBatch, error) { } var result response - err := h.SendAuthenticatedHTTPRequest(http.MethodPost, huobiOrderCancelBatch, url.Values{}, nil, &result) + err := h.SendAuthenticatedHTTPRequest(http.MethodPost, huobiOrderCancelBatch, url.Values{}, nil, &result, false) if result.ErrorMessage != "" { return nil, errors.New(result.ErrorMessage) @@ -432,7 +407,7 @@ func (h *HUOBI) CancelOpenOrdersBatch(accountID, symbol string) (CancelOpenOrder Symbol: symbol, } - err := h.SendAuthenticatedHTTPRequest(http.MethodPost, huobiBatchCancelOpenOrders, url.Values{}, data, &result) + err := h.SendAuthenticatedHTTPRequest(http.MethodPost, huobiBatchCancelOpenOrders, url.Values{}, data, &result, false) if result.Data.FailedCount > 0 { return result, fmt.Errorf("there were %v failed order cancellations", result.Data.FailedCount) } @@ -442,45 +417,35 @@ func (h *HUOBI) CancelOpenOrdersBatch(accountID, symbol string) (CancelOpenOrder // GetOrder returns order information for the specified order func (h *HUOBI) GetOrder(orderID int64) (OrderInfo, error) { - type response struct { - Response + resp := struct { Order OrderInfo `json:"data"` - } - - var result response + }{} urlVal := url.Values{} urlVal.Set("clientOrderId", strconv.FormatInt(orderID, 10)) - err := h.SendAuthenticatedHTTPRequest(http.MethodGet, huobiGetOrder, urlVal, nil, &result) - - if result.ErrorMessage != "" { - return result.Order, errors.New(result.ErrorMessage) - } - return result.Order, err + err := h.SendAuthenticatedHTTPRequest(http.MethodGet, + huobiGetOrder, + urlVal, + nil, + &resp, + false) + return resp.Order, err } // GetOrderMatchResults returns matched order info for the specified order func (h *HUOBI) GetOrderMatchResults(orderID int64) ([]OrderMatchInfo, error) { - type response struct { - Response + resp := struct { Orders []OrderMatchInfo `json:"data"` - } - - var result response + }{} endpoint := fmt.Sprintf(huobiGetOrderMatch, strconv.FormatInt(orderID, 10)) - err := h.SendAuthenticatedHTTPRequest(http.MethodGet, endpoint, url.Values{}, nil, &result) - - if result.ErrorMessage != "" { - return nil, errors.New(result.ErrorMessage) - } - return result.Orders, err + err := h.SendAuthenticatedHTTPRequest(http.MethodGet, endpoint, url.Values{}, nil, &resp, false) + return resp.Orders, err } // GetOrders returns a list of orders func (h *HUOBI) GetOrders(symbol, types, start, end, states, from, direct, size string) ([]OrderInfo, error) { - type response struct { - Response + resp := struct { Orders []OrderInfo `json:"data"` - } + }{} vals := url.Values{} vals.Set("symbol", symbol) @@ -510,21 +475,15 @@ func (h *HUOBI) GetOrders(symbol, types, start, end, states, from, direct, size vals.Set("size", size) } - var result response - err := h.SendAuthenticatedHTTPRequest(http.MethodGet, huobiGetOrders, vals, nil, &result) - - if result.ErrorMessage != "" { - return nil, errors.New(result.ErrorMessage) - } - return result.Orders, err + err := h.SendAuthenticatedHTTPRequest(http.MethodGet, huobiGetOrders, vals, nil, &resp, false) + return resp.Orders, err } // GetOpenOrders returns a list of orders func (h *HUOBI) GetOpenOrders(accountID, symbol, side string, size int64) ([]OrderInfo, error) { - type response struct { - Response + resp := struct { Orders []OrderInfo `json:"data"` - } + }{} vals := url.Values{} vals.Set("symbol", symbol) @@ -534,22 +493,15 @@ func (h *HUOBI) GetOpenOrders(accountID, symbol, side string, size int64) ([]Ord } vals.Set("size", strconv.FormatInt(size, 10)) - var result response - err := h.SendAuthenticatedHTTPRequest(http.MethodGet, huobiGetOpenOrders, vals, nil, &result) - - if result.ErrorMessage != "" { - return nil, errors.New(result.ErrorMessage) - } - - return result.Orders, err + err := h.SendAuthenticatedHTTPRequest(http.MethodGet, huobiGetOpenOrders, vals, nil, &resp, false) + return resp.Orders, err } // GetOrdersMatch returns a list of matched orders func (h *HUOBI) GetOrdersMatch(symbol, types, start, end, from, direct, size string) ([]OrderMatchInfo, error) { - type response struct { - Response + resp := struct { Orders []OrderMatchInfo `json:"data"` - } + }{} vals := url.Values{} vals.Set("symbol", symbol) @@ -578,13 +530,8 @@ func (h *HUOBI) GetOrdersMatch(symbol, types, start, end, from, direct, size str vals.Set("size", size) } - var result response - err := h.SendAuthenticatedHTTPRequest(http.MethodGet, huobiGetOrdersMatch, vals, nil, &result) - - if result.ErrorMessage != "" { - return nil, errors.New(result.ErrorMessage) - } - return result.Orders, err + err := h.SendAuthenticatedHTTPRequest(http.MethodGet, huobiGetOrdersMatch, vals, nil, &resp, false) + return resp.Orders, err } // MarginTransfer transfers assets into or out of the margin account @@ -604,18 +551,11 @@ func (h *HUOBI) MarginTransfer(symbol, currency string, amount float64, in bool) path = huobiMarginTransferOut } - type response struct { - Response + resp := struct { TransferID int64 `json:"data"` - } - - var result response - err := h.SendAuthenticatedHTTPRequest(http.MethodPost, path, nil, data, &result) - - if result.ErrorMessage != "" { - return 0, errors.New(result.ErrorMessage) - } - return result.TransferID, err + }{} + err := h.SendAuthenticatedHTTPRequest(http.MethodPost, path, nil, data, &resp, false) + return resp.TransferID, err } // MarginOrder submits a margin order application @@ -630,18 +570,11 @@ func (h *HUOBI) MarginOrder(symbol, currency string, amount float64) (int64, err Amount: strconv.FormatFloat(amount, 'f', -1, 64), } - type response struct { - Response + resp := struct { MarginOrderID int64 `json:"data"` - } - - var result response - err := h.SendAuthenticatedHTTPRequest(http.MethodPost, huobiMarginOrders, nil, data, &result) - - if result.ErrorMessage != "" { - return 0, errors.New(result.ErrorMessage) - } - return result.MarginOrderID, err + }{} + err := h.SendAuthenticatedHTTPRequest(http.MethodPost, huobiMarginOrders, nil, data, &resp, false) + return resp.MarginOrderID, err } // MarginRepayment repays a margin amount for a margin ID @@ -652,19 +585,13 @@ func (h *HUOBI) MarginRepayment(orderID int64, amount float64) (int64, error) { Amount: strconv.FormatFloat(amount, 'f', -1, 64), } - type response struct { - Response + resp := struct { MarginOrderID int64 `json:"data"` - } + }{} - var result response endpoint := fmt.Sprintf(huobiMarginRepay, strconv.FormatInt(orderID, 10)) - err := h.SendAuthenticatedHTTPRequest(http.MethodPost, endpoint, nil, data, &result) - - if result.ErrorMessage != "" { - return 0, errors.New(result.ErrorMessage) - } - return result.MarginOrderID, err + err := h.SendAuthenticatedHTTPRequest(http.MethodPost, endpoint, nil, data, &resp, false) + return resp.MarginOrderID, err } // GetMarginLoanOrders returns the margin loan orders @@ -697,47 +624,31 @@ func (h *HUOBI) GetMarginLoanOrders(symbol, currency, start, end, states, from, vals.Set("size", size) } - type response struct { - Response + resp := struct { MarginLoanOrders []MarginOrder `json:"data"` - } - - var result response - err := h.SendAuthenticatedHTTPRequest(http.MethodGet, huobiMarginLoanOrders, vals, nil, &result) - - if result.ErrorMessage != "" { - return nil, errors.New(result.ErrorMessage) - } - return result.MarginLoanOrders, err + }{} + err := h.SendAuthenticatedHTTPRequest(http.MethodGet, huobiMarginLoanOrders, vals, nil, &resp, false) + return resp.MarginLoanOrders, err } // GetMarginAccountBalance returns the margin account balances func (h *HUOBI) GetMarginAccountBalance(symbol string) ([]MarginAccountBalance, error) { - type response struct { - Response + resp := struct { Balances []MarginAccountBalance `json:"data"` - } - + }{} vals := url.Values{} if symbol != "" { vals.Set("symbol", symbol) } - - var result response - err := h.SendAuthenticatedHTTPRequest(http.MethodGet, huobiMarginAccountBalance, vals, nil, &result) - - if result.ErrorMessage != "" { - return nil, errors.New(result.ErrorMessage) - } - return result.Balances, err + err := h.SendAuthenticatedHTTPRequest(http.MethodGet, huobiMarginAccountBalance, vals, nil, &resp, false) + return resp.Balances, err } // Withdraw withdraws the desired amount and currency func (h *HUOBI) Withdraw(c currency.Code, address, addrTag string, amount, fee float64) (int64, error) { - type response struct { - Response + resp := struct { WithdrawID int64 `json:"data"` - } + }{} data := struct { Address string `json:"address"` @@ -759,33 +670,56 @@ func (h *HUOBI) Withdraw(c currency.Code, address, addrTag string, amount, fee f data.AddrTag = addrTag } - var result response - err := h.SendAuthenticatedHTTPRequest(http.MethodPost, huobiWithdrawCreate, nil, data, &result) - - if result.ErrorMessage != "" { - return 0, errors.New(result.ErrorMessage) - } - return result.WithdrawID, err + err := h.SendAuthenticatedHTTPRequest(http.MethodPost, huobiWithdrawCreate, nil, data, &resp.WithdrawID, false) + return resp.WithdrawID, err } // CancelWithdraw cancels a withdraw request func (h *HUOBI) CancelWithdraw(withdrawID int64) (int64, error) { - type response struct { - Response + resp := struct { WithdrawID int64 `json:"data"` - } - + }{} vals := url.Values{} vals.Set("withdraw-id", strconv.FormatInt(withdrawID, 10)) - var result response endpoint := fmt.Sprintf(huobiWithdrawCancel, strconv.FormatInt(withdrawID, 10)) - err := h.SendAuthenticatedHTTPRequest(http.MethodPost, endpoint, vals, nil, &result) + err := h.SendAuthenticatedHTTPRequest(http.MethodPost, endpoint, vals, nil, &resp, false) + return resp.WithdrawID, err +} - if result.ErrorMessage != "" { - return 0, errors.New(result.ErrorMessage) +// QueryDepositAddress returns the deposit address for a specified currency +func (h *HUOBI) QueryDepositAddress(cryptocurrency string) (DepositAddress, error) { + resp := struct { + DepositAddress []DepositAddress `json:"data"` + }{} + + vals := url.Values{} + vals.Set("currency", cryptocurrency) + + err := h.SendAuthenticatedHTTPRequest(http.MethodGet, huobiAccountDepositAddress, vals, nil, &resp, true) + if err != nil { + return DepositAddress{}, err } - return result.WithdrawID, err + if len(resp.DepositAddress) == 0 { + return DepositAddress{}, errors.New("deposit address data isn't populated") + } + return resp.DepositAddress[0], nil +} + +// QueryWithdrawQuotas returns the users cryptocurrency withdraw quotas +func (h *HUOBI) QueryWithdrawQuotas(cryptocurrency string) (WithdrawQuota, error) { + resp := struct { + WithdrawQuota WithdrawQuota `json:"data"` + }{} + + vals := url.Values{} + vals.Set("currency", cryptocurrency) + + err := h.SendAuthenticatedHTTPRequest(http.MethodGet, huobiAccountWithdrawQuota, vals, nil, &resp, true) + if err != nil { + return WithdrawQuota{}, err + } + return resp.WithdrawQuota, nil } // SendHTTPRequest sends an unauthenticated HTTP request @@ -803,7 +737,7 @@ func (h *HUOBI) SendHTTPRequest(path string, result interface{}) error { } // SendAuthenticatedHTTPRequest sends authenticated requests to the HUOBI API -func (h *HUOBI) SendAuthenticatedHTTPRequest(method, endpoint string, values url.Values, data, result interface{}) error { +func (h *HUOBI) SendAuthenticatedHTTPRequest(method, endpoint string, values url.Values, data, result interface{}, isVersion2API bool) error { if !h.AllowAuthenticatedRequest() { return fmt.Errorf(exchange.WarningAuthenticatedRequestWithoutCredentialsSet, h.Name) } @@ -817,7 +751,12 @@ func (h *HUOBI) SendAuthenticatedHTTPRequest(method, endpoint string, values url values.Set("SignatureVersion", "2") values.Set("Timestamp", time.Now().UTC().Format("2006-01-02T15:04:05")) - endpoint = fmt.Sprintf("/v%s/%s", huobiAPIVersion, endpoint) + if isVersion2API { + endpoint = fmt.Sprintf("/v%s/%s", huobiAPIVersion2, endpoint) + } else { + endpoint = fmt.Sprintf("/v%s/%s", huobiAPIVersion, endpoint) + } + payload := fmt.Sprintf("%s\napi.huobi.pro\n%s\n%s", method, endpoint, values.Encode()) @@ -864,26 +803,45 @@ func (h *HUOBI) SendAuthenticatedHTTPRequest(method, endpoint string, values url urlPath := h.API.Endpoints.URL + common.EncodeURLValues(endpoint, values) var body []byte - if data != nil { encoded, err := json.Marshal(data) if err != nil { return fmt.Errorf("%s unable to marshal data: %s", h.Name, err) } - body = encoded } - return h.SendPayload(method, + interim := json.RawMessage{} + err := h.SendPayload(method, urlPath, headers, - bytes.NewReader(body), - result, + bytes.NewBuffer(body), + &interim, true, false, h.Verbose, h.HTTPDebugging, h.HTTPRecording) + if err != nil { + return err + } + + if isVersion2API { + var errCap ResponseV2 + if err = json.Unmarshal(interim, &errCap); err == nil { + if errCap.Code != 200 && errCap.Message != "" { + return errors.New(errCap.Message) + } + } + } else { + var errCap Response + if err = json.Unmarshal(interim, &errCap); err == nil { + if errCap.Status == huobiStatusError && errCap.ErrorMessage != "" { + return errors.New(errCap.ErrorMessage) + } + } + } + return json.Unmarshal(interim, result) } // GetFee returns an estimate of fee based on type of transaction diff --git a/exchanges/huobi/huobi_test.go b/exchanges/huobi/huobi_test.go index d29b6312..49e9fc1b 100644 --- a/exchanges/huobi/huobi_test.go +++ b/exchanges/huobi/huobi_test.go @@ -634,10 +634,23 @@ func TestWithdrawInternationalBank(t *testing.T) { } } -func TestGetDepositAddress(t *testing.T) { - _, err := h.GetDepositAddress(currency.BTC, "") - if err == nil { - t.Error("GetDepositAddress() error cannot be nil") +func TestQueryDepositAddress(t *testing.T) { + _, err := h.QueryDepositAddress(currency.BTC.Lower().String()) + if !areTestAPIKeysSet() && err == nil { + t.Error("Expecting an error when no keys are set") + } + if areTestAPIKeysSet() && err != nil { + t.Error(err) + } +} + +func TestQueryWithdrawQuota(t *testing.T) { + _, err := h.QueryWithdrawQuotas(currency.BTC.Lower().String()) + if !areTestAPIKeysSet() && err == nil { + t.Error("Expecting an error when no keys are set") + } + if areTestAPIKeysSet() && err != nil { + t.Error(err) } } diff --git a/exchanges/huobi/huobi_types.go b/exchanges/huobi/huobi_types.go index 9ad0f9f2..acd7d0a2 100644 --- a/exchanges/huobi/huobi_types.go +++ b/exchanges/huobi/huobi_types.go @@ -9,6 +9,12 @@ type Response struct { ErrorMessage string `json:"err-msg"` } +// ResponseV2 stores the Huobi generic response info +type ResponseV2 struct { + Code int32 `json:"code"` + Message string `json:"message"` +} + // KlineItem stores a kline item type KlineItem struct { ID int64 `json:"id"` @@ -246,6 +252,32 @@ type SpotNewOrderRequestParams struct { Type SpotNewOrderRequestParamsType `json:"type"` // 订单类型, buy-market: 市价买, sell-market: 市价卖, buy-limit: 限价买, sell-limit: 限价卖 } +// DepositAddress stores the users deposit address info +type DepositAddress struct { + Currency string `json:"currency"` + Address string `json:"address"` + AddressTag string `json:"addressTag"` + Chain string `json:"chain"` +} + +// ChainQuota stores the users currency chain quota +type ChainQuota struct { + Chain string `json:"chain"` + MaxWithdrawAmount float64 `json:"maxWithdrawAmt,string"` + WithdrawQuotaPerDay float64 `json:"withdrawQuotaPerDay,string"` + RemainingWithdrawQuotaPerDay float64 `json:"remainWithdrawQuotaPerDay,string"` + WithdrawQuotaPerYear float64 `json:"withdrawQuotaPerYear,string"` + RemainingWithdrawQuotaPerYear float64 `json:"remainWithdrawQuotaPerYear,string"` + WithdrawQuotaTotal float64 `json:"withdrawQuotaTotal,string"` + RemainingWithdrawQuotaTotal float64 `json:"remainWithdrawQuotaTotal,string"` +} + +// WithdrawQuota stores the users withdraw quotas +type WithdrawQuota struct { + Currency string `json:"currency"` + Chains []ChainQuota `json:"chains"` +} + // SpotNewOrderRequestParamsType order type type SpotNewOrderRequestParamsType string diff --git a/exchanges/huobi/huobi_wrapper.go b/exchanges/huobi/huobi_wrapper.go index 89fb29a1..f4df4fb4 100644 --- a/exchanges/huobi/huobi_wrapper.go +++ b/exchanges/huobi/huobi_wrapper.go @@ -87,6 +87,7 @@ func (h *HUOBI) SetDefaults() { CancelOrders: true, CancelOrder: true, SubmitOrder: true, + CryptoDeposit: true, CryptoWithdrawal: true, TradeFee: true, }, @@ -652,7 +653,8 @@ func (h *HUOBI) GetOrderInfo(orderID string) (order.Detail, error) { // GetDepositAddress returns a deposit address for a specified currency func (h *HUOBI) GetDepositAddress(cryptocurrency currency.Code, accountID string) (string, error) { - return "", common.ErrFunctionNotSupported + resp, err := h.QueryDepositAddress(cryptocurrency.Lower().String()) + return resp.Address, err } // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is diff --git a/go.mod b/go.mod index f43bc6e8..816f7847 100644 --- a/go.mod +++ b/go.mod @@ -23,9 +23,7 @@ require ( github.com/urfave/cli v1.22.2 github.com/volatiletech/null v8.0.0+incompatible golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5 - golang.org/x/net v0.0.0-20190606173856-1492cefac77f // indirect golang.org/x/sys v0.0.0-20191003212358-c178f38b412c // indirect google.golang.org/genproto v0.0.0-20191002211648-c459b9ce5143 google.golang.org/grpc v1.27.0 - gopkg.in/yaml.v2 v2.2.4 // indirect ) diff --git a/go.sum b/go.sum index 1c7e9004..b0808c53 100644 --- a/go.sum +++ b/go.sum @@ -69,9 +69,11 @@ github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= @@ -85,8 +87,6 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.1.0 h1:THDBEeQ9xZ8JEaCLyLQqXMMdR github.com/grpc-ecosystem/go-grpc-middleware v1.1.0/go.mod h1:f5nM7jw/oeRSadq3xCzHAvxcr8HZnzsqU6ILg/0NiiE= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.11.3 h1:h8+NsYENhxNTuq+dobk3+ODoJtwY4Fu0WQXsxJfL8aM= -github.com/grpc-ecosystem/grpc-gateway v1.11.3/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.12.2 h1:D0EVSTwQoQOyfY35QNSuPJA4jpZRtkoGYWQMB7XNg5o= github.com/grpc-ecosystem/grpc-gateway v1.12.2/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= @@ -94,6 +94,7 @@ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kat-co/vala v0.0.0-20170210184112-42e1d8b61f12 h1:DQVOxR9qdYEybJUr/c7ku34r3PfajaMYXZwgDM7KuSk= @@ -116,8 +117,6 @@ github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q= -github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.13.0 h1:LnJI81JidiW9r7pS/hXe6cFeO5EXNq7KbfvoJLRI69c= github.com/mattn/go-sqlite3 v1.13.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= @@ -160,7 +159,9 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5I github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= @@ -187,6 +188,7 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= @@ -199,8 +201,6 @@ github.com/toorop/go-pusher v0.0.0-20180521062818-4521e2eb39fb h1:9kcmLvQdiIecpg github.com/toorop/go-pusher v0.0.0-20180521062818-4521e2eb39fb/go.mod h1:VTLqNCX1tXrur6pdIRCl8Q90FR7nw/mEBdyMkWMcsb0= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw= -github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/volatiletech/inflect v0.0.0-20170731032912-e7201282ae8d h1:gI4/tqP6lCY5k6Sg+4k9qSoBXmPwG+xXgMpK7jivD4M= @@ -233,8 +233,7 @@ golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190606173856-1492cefac77f h1:IWHgpgFqnL5AhBUBZSgBdjl2vkQUEzcY+JNKWfcgAU0= -golang.org/x/net v0.0.0-20190606173856-1492cefac77f/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20191002035440-2ec189313ef0 h1:2mqDk8w/o6UmeUCu5Qiq2y7iMf6anbx+YA8d1JFoFrs= golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -277,8 +276,6 @@ google.golang.org/genproto v0.0.0-20191002211648-c459b9ce5143 h1:tikhlQEJeezbnu0 google.golang.org/genproto v0.0.0-20191002211648-c459b9ce5143/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.21.1 h1:j6XxA85m/6txkUCHvzlV5f+HBNl/1r5cZ2A/3IEFOO8= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= google.golang.org/grpc v1.27.0 h1:rRYRFMVgRv6E0D70Skyfsr28tDXIuuPZyWGMPdMcnXg=