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 int, coinGeckoApiKey string) (int, error) { 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 * int(coinGeckoData.MarketData.CurrentPrice.CAD*1000)) / 100000000, nil // one BTC = one hundred million satoshi's } // 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 }