feat: set up project
This commit is contained in:
143
internal/services/price/conversor.go
Normal file
143
internal/services/price/conversor.go
Normal file
@@ -0,0 +1,143 @@
|
||||
package price
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"gitea.urkob.com/urko/btc-pay-checker/internal/domain"
|
||||
"gitea.urkob.com/urko/btc-pay-checker/kit"
|
||||
)
|
||||
|
||||
type CoinPriceResponse struct {
|
||||
Coins map[string]map[string]interface{} `json:"coins"`
|
||||
}
|
||||
|
||||
type PriceConversor struct {
|
||||
apiUrl string
|
||||
dollarRateApi string
|
||||
client *http.Client
|
||||
}
|
||||
|
||||
func NewPriceConversor(apiUrl, dollarRateApi string) *PriceConversor {
|
||||
return &PriceConversor{
|
||||
apiUrl: apiUrl,
|
||||
client: &http.Client{},
|
||||
dollarRateApi: dollarRateApi,
|
||||
}
|
||||
}
|
||||
|
||||
type usdConversorResponse struct {
|
||||
Result string `json:"result"`
|
||||
Provider string `json:"provider"`
|
||||
Documentation string `json:"documentation"`
|
||||
TermsOfUse string `json:"terms_of_use"`
|
||||
TimeLastUpdateUnix int `json:"time_last_update_unix"`
|
||||
TimeLastUpdateUtc string `json:"time_last_update_utc"`
|
||||
TimeNextUpdateUnix int `json:"time_next_update_unix"`
|
||||
TimeNextUpdateUtc string `json:"time_next_update_utc"`
|
||||
TimeEolUnix int `json:"time_eol_unix"`
|
||||
BaseCode string `json:"base_code"`
|
||||
Rates map[string]float64 `json:"rates"`
|
||||
}
|
||||
|
||||
func (p *PriceConversor) USDTo(c domain.Coin) (float64, error) {
|
||||
usd := 0.0
|
||||
reqURL := fmt.Sprintf(p.dollarRateApi)
|
||||
req, err := http.NewRequest("GET", reqURL, nil)
|
||||
if err != nil {
|
||||
return usd, fmt.Errorf("http.NewRequest: %s", err)
|
||||
}
|
||||
|
||||
kit.WithJSONHeaders(req)
|
||||
|
||||
resp, err := p.client.Do(req)
|
||||
if err != nil {
|
||||
return usd, fmt.Errorf("client.Do: %s", err)
|
||||
}
|
||||
|
||||
bts, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return usd, fmt.Errorf("iokit.ReadAll: %s", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return usd, fmt.Errorf("error %d: %s", resp.StatusCode, string(bts))
|
||||
}
|
||||
|
||||
var respBody usdConversorResponse
|
||||
if err = json.Unmarshal(bts, &respBody); err != nil {
|
||||
return usd, fmt.Errorf("json.Unmarshal: %s", err)
|
||||
}
|
||||
|
||||
v, ok := respBody.Rates[string(c)]
|
||||
if !ok {
|
||||
return usd, fmt.Errorf("coin isn't found")
|
||||
}
|
||||
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func (p *PriceConversor) USD(c domain.Coin) (float64, error) {
|
||||
usd := 0.0
|
||||
reqURL := fmt.Sprintf(p.apiUrl+"/prices/current/%s", c)
|
||||
req, err := http.NewRequest("GET", reqURL, nil)
|
||||
if err != nil {
|
||||
return usd, fmt.Errorf("http.NewRequest: %s", err)
|
||||
}
|
||||
|
||||
kit.WithJSONHeaders(req)
|
||||
|
||||
resp, err := p.client.Do(req)
|
||||
if err != nil {
|
||||
return usd, fmt.Errorf("client.Do: %s", err)
|
||||
}
|
||||
|
||||
bts, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return usd, fmt.Errorf("iokit.ReadAll: %s", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return usd, fmt.Errorf("error %d: %s", resp.StatusCode, string(bts))
|
||||
}
|
||||
|
||||
var respBody CoinPriceResponse
|
||||
if err = json.Unmarshal(bts, &respBody); err != nil {
|
||||
return usd, fmt.Errorf("json.Unmarshal: %s", err)
|
||||
}
|
||||
|
||||
if _, hasKey := respBody.Coins[string(c)]; !hasKey {
|
||||
return usd, fmt.Errorf("coin isn't found")
|
||||
}
|
||||
|
||||
if _, hasKey := respBody.Coins[string(c)]["price"]; !hasKey {
|
||||
return usd, fmt.Errorf("coin price isn't found")
|
||||
}
|
||||
|
||||
usd, ok := respBody.Coins[string(c)]["price"].(float64)
|
||||
if !ok {
|
||||
return usd, fmt.Errorf("cannot cast price to float64")
|
||||
}
|
||||
|
||||
return usd, nil
|
||||
}
|
||||
|
||||
func (p *PriceConversor) UsdToBtc(usdAmount float64) (float64, error) {
|
||||
usd, err := p.USD(domain.CoinBTC)
|
||||
if err != nil {
|
||||
return usdAmount, fmt.Errorf("USDToBtc: %s", err)
|
||||
}
|
||||
|
||||
return usdAmount / usd, nil
|
||||
}
|
||||
|
||||
func (p *PriceConversor) BtcToUsd(btcAmount float64) (float64, error) {
|
||||
usd, err := p.USD(domain.CoinBTC)
|
||||
if err != nil {
|
||||
return btcAmount, fmt.Errorf("USDToBtc: %s", err)
|
||||
}
|
||||
|
||||
return btcAmount * usd, nil
|
||||
}
|
||||
Reference in New Issue
Block a user