PNG  IHDR pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_F@8N ' p @8N@8}' p '#@8N@8N pQ9p!i~}|6-ӪG` VP.@*j>[ K^<֐Z]@8N'KQ<Q(`s" 'hgpKB`R@Dqj '  'P$a ( `D$Na L?u80e J,K˷NI'0eݷ(NI'؀ 2ipIIKp`:O'`ʤxB8Ѥx Ѥx $ $P6 :vRNb 'p,>NB 'P]-->P T+*^h& p '‰a ‰ (ĵt#u33;Nt̵'ޯ; [3W ~]0KH1q@8]O2]3*̧7# *p>us p _6]/}-4|t'|Smx= DoʾM×M_8!)6lq':l7!|4} '\ne t!=hnLn (~Dn\+‰_4k)0e@OhZ`F `.m1} 'vp{F`ON7Srx 'D˸nV`><;yMx!IS钦OM)Ե٥x 'DSD6bS8!" ODz#R >S8!7ّxEh0m$MIPHi$IvS8IN$I p$O8I,sk&I)$IN$Hi$I^Ah.p$MIN$IR8I·N "IF9Ah0m$MIN$IR8IN$I 3jIU;kO$ɳN$+ q.x* tEXtComment

Viewing File: /home/u423589436/domains/magacoin.online/public_html/app/Services/CryptoService.php

<?php

namespace App\Services;

use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;

class CryptoService
{
    private $apis = [
        'binance' => [
            'url' => 'https://api.binance.com/api/v3/ticker/24hr'
        ],
        'kucoin' => [
            'url' => 'https://api.kucoin.com/api/v1/market/allTickers'
        ],
        'huobi' => [
            'url' => 'https://api.huobi.pro/market/tickers'
        ],
        'gateio' => [
            'url' => 'https://api.gateio.ws/api/v4/spot/tickers'
        ]
    ];

    private $icons = [
        'bitcoin' => 'https://www.cryptocompare.com/media/37746251/btc.png',
        'tether' => 'https://www.cryptocompare.com/media/37746338/usdt.png',
        'ethereum' => 'https://www.cryptocompare.com/media/37746238/eth.png',
        'tron' => 'https://www.cryptocompare.com/media/37746879/trx.png',
        'polkadot' => 'https://www.cryptocompare.com/media/39334571/dot.png',
        'xrp' => 'https://resources.cryptocompare.com/asset-management/13/1720685001950.png',
        'bitcoin-cash' => 'https://www.cryptocompare.com/media/37746245/bch.png',
        'litecoin' => 'https://www.cryptocompare.com/media/37746243/ltc.png',
        'stellar' => 'https://www.cryptocompare.com/media/37746346/xlm.png',
        'dash' => 'https://www.cryptocompare.com/media/37746893/dash.png',
        'solana' => 'https://www.cryptocompare.com/media/37747734/sol.png',
        'binancecoin' => 'https://www.cryptocompare.com/media/40485170/bnb.png'
    ];

    private $symbolMap = [
        'BTC' => 'bitcoin',
        'ETH' => 'ethereum',
        'USDT' => 'tether',
        'TRX' => 'tron',
        'BNB' => 'binancecoin',
        'DOT' => 'polkadot',
        'XRP' => 'xrp',
        'BCH' => 'bitcoin-cash',
        'LTC' => 'litecoin',
        'XLM' => 'stellar',
        'DASH' => 'dash',
        'SOL' => 'solana'
    ];

    private $binanceSymbols = [
        'BTCUSDT' => 'bitcoin',
        'ETHUSDT' => 'ethereum',
        'TRXUSDT' => 'tron',
        'BNBUSDT' => 'binancecoin',
        'DOTUSDT' => 'polkadot',
        'XRPUSDT' => 'xrp',
        'BCHUSDT' => 'bitcoin-cash',
        'LTCUSDT' => 'litecoin',
        'XLMUSDT' => 'stellar',
        'DASHUSDT' => 'dash',
        'SOLUSDT' => 'solana'
    ];

    public function getPrices()
    {
        return Cache::remember('crypto_prices', 60, function () {
            try {
                $prices = $this->fetchFromBinance();
                if (!empty($prices)) {
                    return array_merge($this->getDefaultPrices(), $prices);
                }
            } catch (\Exception $e) {
                Log::error("Error fetching prices from Binance", [
                    'error' => $e->getMessage(),
                    'trace' => $e->getTraceAsString()
                ]);
            }

            // If Binance fails, try other providers
            foreach ($this->apis as $provider => $api) {
                if ($provider === 'binance') continue; // Skip Binance as we already tried it

                try {
                    $prices = $this->fetchFromProvider($provider);
                    if (!empty($prices)) {
                        return array_merge($this->getDefaultPrices(), $prices);
                    }
                } catch (\Exception $e) {
                    Log::error("Error fetching prices from {$provider}", [
                        'error' => $e->getMessage(),
                        'trace' => $e->getTraceAsString(),
                        'api' => $api['url']
                    ]);
                    continue;
                }
            }

            Log::warning('All API providers failed, returning default prices');
            return $this->getDefaultPrices();
        });
    }

    private function fetchFromBinance()
    {
        $response = Http::timeout(5)
            ->retry(2, 100)
            ->get($this->apis['binance']['url']);
        
        if (!$response->successful()) {
            Log::warning("Failed to fetch from Binance", [
                'status' => $response->status(),
                'body' => $response->body()
            ]);
            return [];
        }

        $data = $response->json();
        if (empty($data) || !is_array($data)) {
            Log::warning("Empty or invalid response from Binance");
            return [];
        }

        $prices = [];
        foreach ($data as $ticker) {
            if (isset($this->binanceSymbols[$ticker['symbol']])) {
                $coinId = $this->binanceSymbols[$ticker['symbol']];
                $prices[$coinId] = [
                    'usd' => $this->validatePrice($ticker['lastPrice']),
                    'usd_24h_change' => $this->validatePriceChange($ticker['priceChangePercent']),
                    'last_updated' => now()->timestamp
                ];
            }
        }

        // Add USDT with fixed price
        $prices['tether'] = [
            'usd' => 1,
            'usd_24h_change' => 0,
            'last_updated' => now()->timestamp
        ];

        return $prices;
    }

    private function fetchFromProvider($provider)
    {
        $api = $this->apis[$provider];
        $response = Http::timeout(5)
            ->retry(2, 100)
            ->get($api['url']);
        
        if (!$response->successful()) {
            Log::warning("Failed to fetch from {$provider}", [
                'status' => $response->status(),
                'body' => $response->body()
            ]);
            return [];
        }

        $data = $response->json();
        if (empty($data)) {
            Log::warning("Empty response from {$provider}");
            return [];
        }

        return match($provider) {
            'kucoin' => $this->formatKucoinResponse($data),
            'huobi' => $this->formatHuobiResponse($data),
            'gateio' => $this->formatGateioResponse($data),
            default => []
        };
    }

    private function formatKucoinResponse($data)
    {
        if (!isset($data['data']['ticker']) || !is_array($data['data']['ticker'])) {
            return [];
        }

        return collect($data['data']['ticker'])
            ->filter(function ($item) {
                return str_ends_with($item['symbol'], '-USDT');
            })
            ->mapWithKeys(function ($item) {
                $symbol = explode('-', $item['symbol'])[0];
                $changeRate = floatval($item['changeRate']) * 100;
                
                $standardSymbol = $this->getStandardSymbol($symbol);
                if (!$standardSymbol) return [];

                return [
                    $standardSymbol => [
                        'usd' => $this->validatePrice($item['last']),
                        'usd_24h_change' => $this->validatePriceChange($changeRate),
                        'last_updated' => now()->timestamp
                    ]
                ];
            })
            ->toArray();
    }

    private function formatHuobiResponse($data)
    {
        if (!isset($data['data']) || !is_array($data['data'])) {
            return [];
        }

        return collect($data['data'])
            ->filter(function ($item) {
                return str_ends_with($item['symbol'], 'usdt');
            })
            ->mapWithKeys(function ($item) {
                $symbol = str_replace('usdt', '', $item['symbol']);
                $price = floatval($item['close']);
                $open = floatval($item['open']);
                $priceChange = $open > 0 ? (($price - $open) / $open) * 100 : 0;
                
                $standardSymbol = $this->getStandardSymbol($symbol);
                if (!$standardSymbol) return [];

                return [
                    $standardSymbol => [
                        'usd' => $this->validatePrice($price),
                        'usd_24h_change' => $this->validatePriceChange($priceChange),
                        'last_updated' => now()->timestamp
                    ]
                ];
            })
            ->toArray();
    }

    private function formatGateioResponse($data)
    {
        if (!is_array($data)) {
            return [];
        }

        return collect($data)
            ->filter(function ($item) {
                return str_ends_with($item['currency_pair'], '_USDT');
            })
            ->mapWithKeys(function ($item) {
                $symbol = explode('_', $item['currency_pair'])[0];
                
                $standardSymbol = $this->getStandardSymbol($symbol);
                if (!$standardSymbol) return [];

                return [
                    $standardSymbol => [
                        'usd' => $this->validatePrice($item['last']),
                        'usd_24h_change' => $this->validatePriceChange($item['change_percentage']),
                        'last_updated' => now()->timestamp
                    ]
                ];
            })
            ->toArray();
    }

    private function validatePrice($price)
    {
        $price = floatval($price);
        return $price > 0 ? $price : 0;
    }

    private function validatePriceChange($change)
    {
        $change = floatval($change);
        return max(-100, min(1000, $change));
    }

    private function getDefaultPrices()
    {
        $timestamp = now()->timestamp;
        return [
            'bitcoin' => ['usd' => 0, 'usd_24h_change' => 0, 'last_updated' => $timestamp],
            'ethereum' => ['usd' => 0, 'usd_24h_change' => 0, 'last_updated' => $timestamp],
            'tether' => ['usd' => 1, 'usd_24h_change' => 0, 'last_updated' => $timestamp],
            'tron' => ['usd' => 0, 'usd_24h_change' => 0, 'last_updated' => $timestamp],
            'binancecoin' => ['usd' => 0, 'usd_24h_change' => 0, 'last_updated' => $timestamp],
            'polkadot' => ['usd' => 0, 'usd_24h_change' => 0, 'last_updated' => $timestamp],
            'xrp' => ['usd' => 0, 'usd_24h_change' => 0, 'last_updated' => $timestamp],
            'bitcoin-cash' => ['usd' => 0, 'usd_24h_change' => 0, 'last_updated' => $timestamp],
            'litecoin' => ['usd' => 0, 'usd_24h_change' => 0, 'last_updated' => $timestamp],
            'stellar' => ['usd' => 0, 'usd_24h_change' => 0, 'last_updated' => $timestamp],
            'dash' => ['usd' => 0, 'usd_24h_change' => 0, 'last_updated' => $timestamp],
            'solana' => ['usd' => 0, 'usd_24h_change' => 0, 'last_updated' => $timestamp]
        ];
    }

    public function getStandardSymbol($symbol)
    {
        return $this->symbolMap[strtoupper($symbol)] ?? null;
    }

    public function getIconUrl($symbol)
    {
        return $this->icons[strtolower($symbol)] ?? null;
    }

    public function getNetworkIcon($network)
    {
        $networkIcons = [
            'trc20' => $this->getIconUrl('tron'),
            'bep20' => $this->getIconUrl('binancecoin'),
            'erc20' => $this->getIconUrl('ethereum'),
        ];

        return $networkIcons[strtolower($network)] ?? null;
    }
}
Back to Directory=ceiIENDB`