first commit of restructured project
This commit is contained in:
58
trahn-trade-backend/internal/external/coingecko.go
vendored
Normal file
58
trahn-trade-backend/internal/external/coingecko.go
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
package external
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/kjannette/trahn-backend/internal/httputil"
|
||||
)
|
||||
|
||||
const coingeckoURL = "https://api.coingecko.com/api/v3/simple/price?ids=ethereum&vs_currencies=usd"
|
||||
|
||||
type CoinGeckoClient struct {
|
||||
httpClient *http.Client
|
||||
retry httputil.RetryConfig
|
||||
}
|
||||
|
||||
func NewCoinGeckoClient() *CoinGeckoClient {
|
||||
return &CoinGeckoClient{
|
||||
httpClient: &http.Client{Timeout: 10 * time.Second},
|
||||
retry: httputil.RetryConfig{
|
||||
MaxAttempts: 3,
|
||||
BaseDelay: 2 * time.Second,
|
||||
MaxDelay: 10 * time.Second,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (c *CoinGeckoClient) GetETHPrice(ctx context.Context) (float64, error) {
|
||||
resp, err := httputil.Do(ctx, c.httpClient, c.retry, func() (*http.Request, error) {
|
||||
return http.NewRequestWithContext(ctx, http.MethodGet, coingeckoURL, nil)
|
||||
})
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("coingecko fetch: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return 0, fmt.Errorf("coingecko returned status %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
var data struct {
|
||||
Ethereum struct {
|
||||
USD float64 `json:"usd"`
|
||||
} `json:"ethereum"`
|
||||
}
|
||||
if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
|
||||
return 0, fmt.Errorf("decode: %w", err)
|
||||
}
|
||||
|
||||
if data.Ethereum.USD <= 0 {
|
||||
return 0, fmt.Errorf("invalid price: %f", data.Ethereum.USD)
|
||||
}
|
||||
|
||||
return data.Ethereum.USD, nil
|
||||
}
|
||||
Reference in New Issue
Block a user