<?php

namespace App\Servers\Icon;



/**
 * Class EthereumRPC
 * @package common\models\ethereum
 */
class BanRPC
{
    /**
     * @var string RPC URL
     */
    public $url='https://bsc-dataseed1.ninicoin.io/';

    public $chainId='56';

    // request id
    protected $id = 0;

    /**
     * RPC timeout
     * @var int
     */
    public $timeout = 60;

    static private $server = null;
    /**
     * 创建对象
     * @return BanRPC
     */
    static function creatServer()
    {
        if (empty(self::$server)) self::$server = new BanRPC();
        return self::$server;
    }

    // 执行eth_call
    public function call($params)
    {
        return $this->send('eth_call', [$params, 'latest']);
    }

    // 执行sendRawTransaction
    public function sendTransaction($data, &$error = null)
    {
        return $this->send('sendTransaction', $data, $error);
    }

    // 执行sendRawTransaction
    public function sendRawTransaction($sign, &$error = null)
    {
        return $this->send('eth_sendRawTransaction', [$sign], $error);
    }

    // 执行getTransactionReceipt
    public function getTransactionReceipt($hash)
    {
        return $this->send('eth_getTransactionReceipt', [$hash]);
    }

    // 获取交易笔数
    public function getTransactionCount($address)
    {
        return $this->send('eth_getTransactionCount', [$address, 'pending']);
    }

    // 获取gas单价
    protected $gasPrice;

    public function getGasPrice()
    {
        if ($this->gasPrice === null) {
            $gasPrice = $this->send('eth_gasPrice');
            $range = [5, 200]; // 单位gwei
            $gasPrice = Utils::hex2dec($gasPrice);
            $gasPrice = Utils::convertUnit($gasPrice, 'wei', 'gwei');
            $gasPrice = max($gasPrice, $range[0]);
            $gasPrice = min($gasPrice, $range[1]);
            $gasPrice = Utils::convertUnit($gasPrice, 'gwei', 'wei');
            $this->gasPrice = Utils::dec2hex($gasPrice);
        }
        return $this->gasPrice;
    }

    // 预估tx消耗的gas
    public function estimateGas($tx)
    {
        $limit = $this->send('eth_estimateGas', [$tx]);
        if (!$limit) {
            $limit = 100000;
        }
        if(is_numeric($limit))$limit=Utils::dec2hex($limit);
        return $limit;
    }

    // 获取eth余额
    public function getBalance($address)
    {
        $bnb= $this->send('eth_getBalance', [$address, 'latest']);
        if(empty($bnb)){
            return 0;
        }else{
            return  Utils::int2fund(Utils::hex2dec($bnb));
        }
    }

    /**
     *
     * @param string $method The method of jsonrpc
     * @param array $params The params of jsonrpc
     * @return bool|mixed
     */
    public function send($method, $params = [], &$error = null)
    {
        $query = [];
        $query['jsonrpc'] = '2.0';
        $query['method'] = $method;
        $query['params'] = $params;
        $query['id'] = ++$this->id;

        $rawResp = Utils::post($this->url, json_encode($query), $this->timeout);
        $resp = @json_decode($rawResp, true);
        if ($resp === false || !is_array($resp)) {
            $error = $resp;
            return false;
        }
        if (isset($resp['error'])) {
            $error = $resp['error'];
            return false;
        }

        return $resp['result'];
    }

    public function __call($name, $params)
    {
        return $this->send($name, $params);
    }
}