From e632c44bc30a8e5d2bfdc24c437f295970f24fc3 Mon Sep 17 00:00:00 2001 From: Aaron Fiore Date: Sat, 15 Jun 2024 19:07:56 -0700 Subject: [PATCH] php: fetch: prices: coingecko: remove upstream client, add API key support - Removes `codenixsv/coingecko-api` - Adds Pro API support - Related refactoring --- .../internal/fetch/prices/internal/base.php | 19 ++++++++++-- .../prices/internal/prices/coingecko.php | 30 ++++++++++++++----- 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/container/src/finance/lib/internal/fetch/prices/internal/base.php b/container/src/finance/lib/internal/fetch/prices/internal/base.php index fee38a3..582b788 100644 --- a/container/src/finance/lib/internal/fetch/prices/internal/base.php +++ b/container/src/finance/lib/internal/fetch/prices/internal/base.php @@ -24,6 +24,7 @@ */ //! @since docker-finance 1.0.0 + namespace docker_finance\prices\internal { require_once('utils/utils.php'); @@ -138,15 +139,21 @@ namespace docker_finance\prices\internal /** * @brief Request's common implementation * @param string $url REST API URL + * @param array $header Impl-specific header addendum * @return mixed Response data */ - protected function request_impl(string $url): mixed + protected function request_impl(string $url, array $header): mixed { $headers = array( 'Accept: application/json', 'Content-Type: application/json', ); + if (!empty($header)) { + $headers = array_merge($headers, $header); + } + utils\CLI::print_debug($headers); + $ch = curl_init($url); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); @@ -164,7 +171,15 @@ namespace docker_finance\prices\internal utils\CLI::throw_fatal("cURL null response"); } - return $response; + $decoded = json_decode( + $response, + true, + 512, + JSON_PRETTY_PRINT + ); + utils\CLI::print_debug($decoded); + + return $decoded; } //! @brief Impl-specific REST API request diff --git a/container/src/finance/lib/internal/fetch/prices/internal/prices/coingecko.php b/container/src/finance/lib/internal/fetch/prices/internal/prices/coingecko.php index b3c15a3..d3da6a1 100644 --- a/container/src/finance/lib/internal/fetch/prices/internal/prices/coingecko.php +++ b/container/src/finance/lib/internal/fetch/prices/internal/prices/coingecko.php @@ -24,9 +24,9 @@ */ //! @since docker-finance 1.0.0 + namespace docker_finance\prices\internal\prices\coingecko { - require_once('php/vendor/autoload.php'); //!< CoinGecko require_once('prices/internal/base.php'); require_once('utils/utils.php'); @@ -39,13 +39,9 @@ namespace docker_finance\prices\internal\prices\coingecko */ final class CoinGecko extends internal\Impl { - private \Codenixsv\CoinGeckoApi\CoinGeckoClient $api; //!< CoinGecko - public function __construct(utils\Env $env) { parent::__construct($env); - - $this->api = new \Codenixsv\CoinGeckoApi\CoinGeckoClient(); } /** @@ -56,9 +52,27 @@ namespace docker_finance\prices\internal\prices\coingecko */ protected function request(string $id, string $timestamp): mixed { - // TODO(afiore): use request_impl() after removing CoinGeckoClient - $response = $this->api->coins()->getMarketChart($id, 'usd', $timestamp); - return $response['prices']; + // If `key` exists, use Pro API (otherwise, use Public API) + $key = $this->get_env()->get_env('API_PRICES_KEY'); + $domain = 'api.coingecko.com'; + $header = []; + if ($key != 'None') { + $domain = 'pro-' . $domain; + $header = ["x-cg-pro-api-key: $key"]; + } + $vs_currency = 'usd'; + $url = "https://{$domain}/api/v3/coins/{$id}/market_chart?vs_currency={$vs_currency}&days={$timestamp}"; + + $response = $this->request_impl($url, $header); + if (array_key_exists('status', $response)) { + $status = $response['status']; + throw new \Exception($status['error_message'], $status['error_code']); + } + + $prices = $response['prices']; + utils\CLI::print_debug($prices); + + return $prices; } /**