Develop Bitcoin Price Feed Plugin Using .Net Core

Crypto currency has become household topic of discussions. Especially with how NFT (non-fungible tokens) assets are being talked about, more and more people want to know about crypto currencies. There are a lot of crypto currencies out there. But the currency that people mostly talk about is Bitcoin. A lot more people are trading Bitcoins and other crypto currencies. A topic that people have on their mind is to know the current price of Bitcoin.

I decided to develop a plugin for my latest Blog framework. This plugin fetches current Bitcoin price from CoinDesk.

Bitcoin price plugin

See it in action at World of Hobby Craft blog site.

You can get the latest price by making a GET request for https://api.coindesk.com/v1/bpi/currentprice.json. This returns the data in following Json structure.

{"time":{"updated":"Sep 18, 2013 17:27:00 UTC",
"updatedISO":"2013-09-18T17:27:00+00:00"},
"disclaimer":"This data was produced from the CoinDesk Bitcoin Price Index. Non-USD currency 
data converted using hourly conversion rate from openexchangerates.org",
"bpi":{"USD":{"code":"USD","symbol":"$","rate":"126.5235",
"description":"United States Dollar",
"rate_float":126.5235},
"GBP":{"code":"GBP","symbol":"£","rate":"79.2495",
"description":"British Pound Sterling",
"rate_float":79.2495},
"EUR":{"code":"EUR","symbol":"€","rate":"94.7398",
"description":"Euro","rate_float":94.7398}}}

The price data is returned as a dictionary of currency and rates inside bpi property. Here is the code that I have put together fetch the feed and then serialize into a proper C# class.

Feed Data Structures

public record CoindeskFeedModel:BaseAmgrModel
    {
        [JsonProperty("time")]
        public PriceIndexUpdateTime UpdateTime { get; set; }
        [JsonProperty("bpi")]
        public Dictionary PriceIndexValueDictionary { get; set; }

        public record PriceIndexUpdateTime
        {
            [JsonProperty("updated")]
            public string UpdateTimeUtc { get; set; }
        }
        public record PriceIndexValue
        {
            [JsonProperty("code")]
            public string Code { get; set; }
            [JsonProperty("description")]
            public string Description { get; set; }
            [JsonProperty("symbol")]
            public string Symbol { get; set; }
            [JsonProperty("rate")]
            public double Rate { get; set; }
        }
    }

.Net Core Http Client To Fetch Bitcoin Price

public class BitcoinPriceController: BasePluginController
    {
        #region Fields

        private readonly IHttpClientFactory _httpClientFactory;
        private readonly ILogger _logger;
        private readonly CoindeskFeedSettings _feedSettings;
        private const string PriceIndexFeedUrl = "https://api.coindesk.com/v1/bpi/currentprice.json";
        #endregion

        public BitcoinPriceController(IHttpClientFactory httpClientFactory,
            CoindeskFeedSettings feedSettings,
            ILogger logger)
        {
            _httpClientFactory = httpClientFactory;
            _feedSettings = feedSettings;
            _logger = logger;
        }
        [HttpPost]
        public async Task<IActionResult> LatestPrice()
        {
            try
            {
                var httpClient = _httpClientFactory.CreateClient(AmgrHttpDefaults.DefaultHttpClient);
                var priceFeed = await httpClient.GetStringAsync(string.IsNullOrEmpty
                  (_feedSettings.PriceFeedUrl) ? PriceIndexFeedUrl: _feedSettings.PriceFeedUrl);
                var coinDeskPriceIndexModel = JsonConvert.DeserializeObject<CoindeskFeedModel>(priceFeed);
                var priceIndexValues = new List<BitcoinPriceModel>();
                if (null == coinDeskPriceIndexModel) return Json(priceIndexValues);
                foreach (var priceIndexModel in coinDeskPriceIndexModel.PriceIndexValueDictionary)
                {
                    var dictionaryValue = coinDeskPriceIndexModel.PriceIndexValueDictionary[priceIndexModel.Key];
                    priceIndexValues.Add(new BitcoinPriceModel
                    {
                        UpdatedAtUtc = coinDeskPriceIndexModel.UpdateTime.UpdateTimeUtc,
                        Price = dictionaryValue.Rate,
                        Currency = dictionaryValue.Code,
                        CurrencySymbol = dictionaryValue.Symbol
                    });
                }

                return Json(priceIndexValues);
            }
            catch (Exception ex)
            {
                await _logger.ErrorAsync($"Error getting latest bitcoin price", ex);
            }

            return Json("");
        }
    }

I have wrapped the client side implementation in a jQuery ajax call that refreshes the data on a fixed interval.

<script asp-location="Footer" type="text/javascript">
    var bitCoinPriceUpdateInProgress = false;
    function getBitcoinPrices() {
        if (bitCoinPriceUpdateInProgress) return;
        bitCoinPriceUpdateInProgress = true;
        $.ajax({
            cache: false,
            type: "POST",
            url: "@Html.Raw(Url.RouteUrl("BitcoinPriceFeed"))",
            success: function (data, textStatus, jqXHR) {
                bitCoinPriceUpdateInProgress = false;
                if (null != data && data.length !== 0) {
                    var priceListElement = $("#bitcoin-price-list");
                    var updateTimeElement = $("#bitcoin-price-updatetime");
                    $(priceListElement).empty();
                    for (var i = 0; i < data.length; i++) {
                        var priceIndexValue = data[i];
                        $(priceListElement).append
                             ($("<li class='g-mb-2'><strong class='d-block g-font-size-30 g-line-height-1_2'>" 
                           + priceIndexValue.CurrencySymbol + priceIndexValue.Price + "</strong></li>"));
                        $(updateTimeElement).text(priceIndexValue.UpdatedAtUtc);
                    }
                }
            },
            error:function(jqXHR) {
                bitCoinPriceUpdateInProgress = false;
            },
            complete: function (jqXHR, textStatus) {
                bitCoinPriceUpdateInProgress = false;
                setTimeout(getBitcoinPrices, @refreshFrequency);
            }
        });
    }

    setTimeout(getBitcoinPrices, 0);
</script>

The plugin is developed along the guidelines of nopCommerce platform. If you are interested in including this in your nopCommerce plugin list, feel free to contact me. I can share the complete plugin with you. You will to have make some changes to adapt to namespace used by nopCommerce framework.

Search

Social

Weather

13.1 °C / 55.6 °F

weather conditions Clouds

Monthly Posts

Blog Tags