Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend support for conversion to more fiat currencies #6

Merged
merged 3 commits into from
Jun 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 18 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

> Implement CoinDesk Bitcoin Price Index (BPI) on Laravel apps

This package allows you to query for the Bitcoin exchange rates in supported [CoinDesk's](https://www.coindesk.com) fiat currencies in [Laravel](https://laravel.com) applications.
This package allows you to query for the Bitcoin exchange rates in supported [CoinDesk's](https://www.coindesk.com) fiat [currencies](https://api.coindesk.com/v1/bpi/supported-currencies.json) in [Laravel](https://laravel.com) applications.

## Requirements

Expand All @@ -20,82 +20,59 @@ composer require gabrielandy/coindesk

## Usage

You can get the current price of Bitcoin in any currency supported by Coindesk.
Currently, Coindesk supports USD, GBP and EUR.

### To get the price of Bitcoin in USD

### To get the price of a Bitcoin value in any supported fiat currency
``` php
use Coindesk;

/**
* Convert from Bitcoin to Coindesk's supported fiat currency (USD, GBP, EUR).
* Convert from Bitcoin to Coindesk's supported fiat currency (USD, GBP, EUR, NGN, GHC).
*
* @example Coindesk::toFiatCurrency('USD', 1);
* @example Coindesk::toFiatCurrency('USD', 1)
*
* @param string $currency_code - The ISO 4217 fiat currency you wish to convert Bitcoin to
* @param int $bitcoin_amount = 1 - The value of Bitcoin in float/numeric
* @param int $bitcoin_amount - The value of Bitcoin in float/numeric
* @return float
*/
Coindesk::toFiatCurrency($currency_code, $bitcoin_amount);

Coindesk::toFiatCurrency('USD', 1); // This will return `57553.52` stating that BTC 1 = $57,553.52
Coindesk::toFiatCurrency('EUR', 1); // This will return `47321.11` stating that BTC 1 = €47,321.11
Coindesk::toFiatCurrency('USD', 1); // This will return 34381.5206 stating that ₿1 = $34,381.5206
Coindesk::toFiatCurrency('EUR', 1); // This will return 28431.5957 stating that ₿1 = €28,431.5957
Coindesk::toFiatCurrency('NGN', 1); // This will return 14261794.0186 stating that ₿1 = ₦14,261,794.0186
```

### To convert any Coindesk's supported currency to Bitcoin
### To convert any Coindesk's supported fiat currency value to Bitcoin
```php
use Coindesk;

/**
* Convert any supported Coindesk's currency to Bitcoin.
* Convert any supported Coindesk's fiat currency to Bitcoin.
*
* @example Coindesk::toBtc(1, 'USD');
* @param int $amount = 1 : The amount of the currency in integer/numeric
* @param string $currency = USD : The currency you wish to convert to Bitcoin
* @return float
* @example Coindesk::toBtc(1, 'USD')
*
* @param int $amount - The amount of the currency in integer/numeric
* @param string $currency = USD - The currency you wish to convert to Bitcoin
* @return string
*/
Coindesk::toBtc($amount, $currency_code);

Coindesk::toBtc(1, 'USD'); // This will return '0.000017; stating that $1 = BTC 0.000017
```

You can get the price of Bitcoin in any local currency other than the supported ones (USD, GBP and EUR)

```php
use Coindesk;

// Get current Bitcoin price in USD
$bitcoinUSDPrice = Coindesk::toCurrency('USD', 1); // $57,250.03

// Set exchange rate of local currency to USD
$exchangeRate = 440 // usign $1 = ₦440

// Compute conversion
$computed = $bitcoinUSDPrice * $exchangeRate; // 57250.03 * 440

// Computed result returns float
echo $computed; // N25,190,013.20

Coindesk::toBtc(1, 'USD'); // This will return 2.8881896998808E-5
Coindesk::toBtc(1, 'EUR'); // This will return 3.5258494994032E-5
Coindesk::toBtc(1, 'NGN'); // This will return 7.0297483496097E-8
```

## Changelog

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

## Contributing

Please visit the [Contributing](CONTRIBUTING.md) page for details.

## Security
If you discover any security related issues, please email master@andikangabriel.com instead of using the issue tracker.

## License

The MIT License. Please see [License](LICENSE.md) file for details.

## Disclaimer

This project is not affiliated in any way with CoinDesk. It is intended to provide a useful service and comes with no warranty or any kind. The author is not responsible for any damages or problems incurred during usage of the API.

You are free to use this package to consume Coindesk's API as you see fit, as long as each page or app that uses it includes the text "Powered by [CoinDesk](https://www.coindesk.com/price/bitcoin)", linking to Coindesk's [pricing page](https://www.coindesk.com/price/bitcoin).
11 changes: 3 additions & 8 deletions config/coindesk.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,10 @@
/*
* Coindesk's endpoint.
*/
'endpoint' => 'https://api.coindesk.com/v1/bpi/currentprice.json',
'endpoint' => 'https://api.coindesk.com/v1/bpi/currentprice',

/*
* Precision for the conversion of fiat currency to bitcoin.
* Coindesk's supported currencies endpoint.
*/
'fiat_btc_precision' => 6,

/*
* Precision for the conversion of bitcoin to fiat currency.
*/
'btc_fiat_precision' => 2,
'supported_currency_endpoint' => 'https://api.coindesk.com/v1/bpi/supported-currencies.json',
];
100 changes: 62 additions & 38 deletions src/Coindesk.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use GabrielAndy\Coindesk\Exceptions\UnsupportedCurrencyCode;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Support\Str;

class Coindesk
{
Expand All @@ -25,16 +26,23 @@ class Coindesk
protected $endpoint;

/**
* Coindesk's supported currencies.
* Supported currencies in which conversion
* takes place per minute.
*
* @var array
*/
protected $supportedCurrencies = [
protected $bpiCurrencies = [
'USD',
'GBP',
'EUR',
];

/**
*
* @var bool
*/
protected $bpiCurrencyMode = false;

/**
* Create a new Coindesk instance.
*
Expand Down Expand Up @@ -69,25 +77,53 @@ public function setEndpoint(string $endpoint)
*/
public function retrieveRate($currencyCode)
{
if (! in_array(
strtoupper($currencyCode), $this->supportedCurrencies
)) {
throw new UnsupportedCurrencyCode(
"The currency, '{$currencyCode}' is not supported by Coindesk."
);
$this->currency = Str::upper($currencyCode);

if (in_array($this->currency, $this->bpiCurrencies)) {
$this->bpiCurrencyMode = true;
} else {
if (! in_array($this->currency, $this->supportedCurrencies())) {
throw new UnsupportedCurrencyCode(
"The currency, '{$currencyCode}' is not supported by Coindesk."
);
}
}

$exchangeRates = $this->getExchangeRates();
return $this->getExchangeRates()[$this->currency];
}

/**
* Get currencies supported by Coindesk.
*
* @return array
*
* @throws \GabrielAndy\Coindesk\Exceptions\HttpException
*/
protected function supportedCurrencies(): array
{
try {
$response = $this->client
->request('GET', config('coindesk.supported_currency_endpoint'))
->getBody();

$supportedCurrencies = json_decode($response, true);

return $exchangeRates[strtoupper($currencyCode)];
foreach ($supportedCurrencies as $currency) {
$currencies[] = $currency['currency'];
}

return $currencies;
} catch (GuzzleException $e) {
throw new HttpException($e->getMessage());
}
}

/**
* Get Bitcoin exchange rates in an associative array.
* Get Bitcoin exchange rates.
*
* @return array
*/
protected function getExchangeRates()
protected function getExchangeRates(): array
{
if (empty($this->exchangeRates)) {
$this->setExchangeRates($this->retrieveExchangeRates());
Expand All @@ -99,20 +135,20 @@ protected function getExchangeRates()
/**
* Set exchange rates.
*
* @param array $exchangeRatesArray
* @param array $exchangeRates
* @return void
*/
protected function setExchangeRates($exchangeRatesArray)
protected function setExchangeRates(array $exchangeRates)
{
$this->exchangeRates = $exchangeRatesArray;
$this->exchangeRates = $exchangeRates;
}

/**
* Retrieve exchange rates.
*
* @return array
*/
protected function retrieveExchangeRates()
protected function retrieveExchangeRates(): array
{
$exchangeRatesArray = $this->parseToExchangeRatesArray(
$this->fetchExchangeRates()
Expand All @@ -126,12 +162,14 @@ protected function retrieveExchangeRates()
*
* @return string
*
* @throws \GabrielAndy\Coindesk\Exceptions\CoindeskException
* @throws \GabrielAndy\Coindesk\Exceptions\HttpException
*/
protected function fetchExchangeRates()
protected function fetchExchangeRates(): string
{
try {
$response = $this->client->request('GET', $this->endpoint);
$response = ($this->bpiCurrencyMode == true)
? $this->client->request('GET', "$this->endpoint.json")
: $this->client->request('GET', "$this->endpoint/$this->currency.json");

return $response->getBody();
} catch (GuzzleException $e) {
Expand Down Expand Up @@ -162,11 +200,11 @@ protected function parseToExchangeRatesArray($rawJsonData)
*
* @param string $currencyCode
* @param float $btcAmount
* @return string
* @return float
*
* @throws \GabrielAndy\Coindesk\Exceptions\CoindeskException
*/
public function toFiatCurrency($currencyCode, $btcAmount)
public function toFiatCurrency($currencyCode, $btcAmount): float
{
if (! is_numeric($btcAmount)) {
throw new CoindeskException("
Expand All @@ -176,14 +214,7 @@ public function toFiatCurrency($currencyCode, $btcAmount)

$rate = $this->retrieveRate($currencyCode);

$value = $this->computeCurrencyValue($btcAmount, $rate);

return number_format(
$value,
config('coindesk.btc_fiat_precision'),
'.',
''
);
return $this->computeCurrencyValue($btcAmount, $rate);
}

/**
Expand All @@ -207,7 +238,7 @@ public function computeCurrencyValue($btcAmount, $rate)
* @param string $currency
* @return string
*/
public function toBtc($amount, $currencyCode)
public function toBtc($amount, $currencyCode): string
{
if (! is_numeric($amount)) {
throw new CoindeskException("
Expand All @@ -217,14 +248,7 @@ public function toBtc($amount, $currencyCode)

$rate = $this->retrieveRate($currencyCode);

$value = $this->computeBtcValue($amount, $rate);

return number_format(
$value,
config('coindesk.fiat_btc_precision'),
'.',
''
);
return $this->computeBtcValue($amount, $rate);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion tests/CurrencyConversionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public function it_throws_exception_for_unsupported_currency()
{
$this->expectException(UnsupportedCurrencyCode::class);

Coindesk::toBtc(1, 'NGN');
Coindesk::toBtc(1, 'LED');
}

/**
Expand Down