Files
ynab-portfolio-monitor/providers/bitcoinElectrum/fiat.go

64 lines
1.9 KiB
Go
Raw Normal View History

2025-09-30 22:49:16 -06:00
package bitcoinElectrum
import (
"encoding/json"
"fmt"
"io"
"net/http"
"time"
)
const fiatConvertURL = "https://api.coingecko.com/api/v3/coins/bitcoin?localization=false&tickers=false&market_data=true&community_data=false&developer_data=false&sparkline=false"
type coinGeckoResponse struct {
MarketData struct {
CurrentPrice struct {
CAD int `json:"cad"`
} `json:"current_price"`
} `json:"market_data"`
}
func convertBTCToCAD(amount int64, coinGeckoApiKey string) (int64, error) {
2025-09-30 22:49:16 -06:00
coinGeckoData := &coinGeckoResponse{}
req, err := http.NewRequest("GET", fmt.Sprintf("%s&x-cg-demo-api-key=%s", fiatConvertURL, coinGeckoApiKey), nil)
if err != nil {
return 0, fmt.Errorf("failed to create new GET request: %v", err)
}
client := http.Client{Transport: &http.Transport{ResponseHeaderTimeout: 15 * time.Second}}
res, err := client.Do(req)
if err != nil {
return 0, fmt.Errorf("http GET request failed: %v", err)
}
err = processResponse(res, coinGeckoData)
if err != nil {
return 0, fmt.Errorf("failed to process response: %v", err)
}
return (amount * int64(coinGeckoData.MarketData.CurrentPrice.CAD*1000)) / 100000000, nil // one BTC = one hundred million satoshi's
2025-09-30 22:49:16 -06:00
}
// processResponse takes the body of an HTTP response, and either returns
// the error code, or unmarshalls the JSON response, extracts
// rate limit info, and places it into the object
// output parameter. This function closes the response body after reading it.
func processResponse(res *http.Response, out interface{}) error {
body, err := io.ReadAll(res.Body)
res.Body.Close()
if err != nil {
return fmt.Errorf("failed to read response body: %v", err)
}
if res.StatusCode != 200 && res.StatusCode != 201 {
return fmt.Errorf("unexpected http status code '%d': %v", res.StatusCode, err)
}
err = json.Unmarshal(body, out)
if err != nil {
return fmt.Errorf("failed to unmarshal response body: %v", err)
}
return nil
}