<?php
namespace App\Libraries;

/**
 * Developed By Bdtask Ltd.
 * First Release 2021-10-07
 * Network ERC-20 and BEP-20
 * Request Data Object
 * Response Data True,False,Object
 */

class Blockchain_lib
{
    private $endpoints;
    private $explorarurl;

    public function __construct()
    {
        //$this->endpoints    = 'http://139.59.149.48:81/';
        
        $this->db = db_connect();
        $server = $this->db->table('dbt_networking_setting')->select('*')->where('network_type','bsc')->where('status',1)->get()->getRow();
        $this->endpoints    = @$server->ip_address.':'.@$server->port_number.'/';
        $this->explorarurl  = 'https://testnet.bscscan.com/';
    }

    /** User new wallet generates on blockchain */
    public function createWallet(object $data = null)
    {
        if (empty($data)) {
            return false;
        }

        
        $walletinfo = $this->curlExcute('api/account/createWallet', (array)$data);
        $walletinfo = $this->toJsonDecode($walletinfo);
       
        if ($walletinfo) {
            if ($walletinfo->status == 'success') {
                $user_id    = $data->user_id;
                $wallet     = $walletinfo->data->address;
                $privateKey = $walletinfo->data->privateKey;
                $password   = $data->password;
                $ci         = db_connect();
                $checkuser  = $ci->table('dbt_encrypt_data')->select('id')->where('user_id', $user_id)->get()->getRow();
              
                if ($checkuser) {
                    return false;
                }
                
                $encryppassw = $this->encrypt($password);
                
                if ($encryppassw) {
                    $encryptinfo = $this->curlExcute('api/account/privateKeyEncrypt', ['privateKey' => $privateKey, 'password' => $encryppassw,'netWork' => $data->netWork,'RPCurl' => $data->RPCurl]);
                    $encryptinfo = $this->toJsonDecode($encryptinfo);
                    $todaytimes  = date('Y-m-d H:i:s');
                    
                    if ($encryptinfo) {
                        $encryptinsertdata = array(
                            'version'      => $encryptinfo->data->version,
                            'id'           => $encryptinfo->data->id,
                            'address'      => $encryptinfo->data->address,
                            'wallet'       => $wallet,
                            'ciphertext'   => $encryptinfo->data->crypto->ciphertext,
                            'iv'           => $encryptinfo->data->crypto->cipherparams->iv,
                            'cipher'       => $encryptinfo->data->crypto->cipher,
                            'kdf'          => $encryptinfo->data->crypto->kdf,
                            'dklen'        => $encryptinfo->data->crypto->kdfparams->dklen,
                            'salt'         => $encryptinfo->data->crypto->kdfparams->salt,
                            'n'            => $encryptinfo->data->crypto->kdfparams->n,
                            'r'            => $encryptinfo->data->crypto->kdfparams->r,
                            'p'            => $encryptinfo->data->crypto->kdfparams->p,
                            'mac'          => $encryptinfo->data->crypto->mac,
                            'encrypt_val'  => $password,
                            'user_id'      => $user_id,
                            'created_at'   => $todaytimes,
                            'update_at'    => $todaytimes,
                        );
                        $result = $ci->table('dbt_encrypt_data')->insert($encryptinsertdata);

                        if ($result) {
                            return $this->successResponse('Wallet Address Created successfully',$walletinfo);
                        } else {
                            return $this->errorResponse("Something went wrong");
                        }
                    } else {
                        return $this->errorResponse("Something went wrong");
                    }
                } else {
                    return $this->errorResponse("The user's data not found");
                }
            } else {
                return $walletinfo;
            }
        } else {
            return $this->errorResponse("Something went wrong");
        }
    }
    /** Export wallet private key from blockchain */
    public function exportPrivateKey(object $data = null)
    {
        if (empty($data)) {
            return false;
        }

        $password = $this->encrypt($data->encrypt_val);
        //
       
        if ($password) {
            $etherdata = array(
                'version'    => $data->version,
                'id'         => $data->id,
                'address'    => $data->address,
                'ciphertext' => $data->ciphertext,
                'iv'         => $data->iv,
                'cipher'     => $data->cipher,
                'kdf'        => $data->kdf,
                'dklen'      => $data->dklen,
                'salt'       => $data->salt,
                'n'          => $data->n,
                'r'          => $data->r,
                'p'          => $data->p,
                'mac'        => $data->mac,
                'password'   => $password,
                'netWork'   => $data->netWork,
                'RPCurl'    => $data->RPCurl
            );
            $privatekeyinfo = $this->curlExcute('api/account/privateKeyDycrypt', $etherdata);
           
            if ($privatekeyinfo) {
                $privatekeyinfo = $this->toJsonDecode($privatekeyinfo);
                $privatekey     = $privatekeyinfo->data->privateKey;
                return $privatekey;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    /** Encrypt plain text with key by md5 hash method */
    public function encrypt(String $plaintext = null)
    {
        if (empty($plaintext)) {
            return false;
        }

        $key        = "Bdtask@#liplimal@#2022";
        $ciphertext = md5($plaintext . $key);
        return $ciphertext;
    }

    /** Check Blockchain Transaction Status By Hash */
    public function checkTx(String $hash = null,$netWork,$RPCurl)
    {
        if (empty($hash)) {
            return false;
        }

        $txhash = $this->curlExcute('api/transaction/getTransactionReceipt', ['txHash' => $hash,'netWork'=>$netWork,'RPCurl'=>$RPCurl]);
        $txhash = $this->toJsonDecode($txhash);
       
        if ($txhash) {
            if($txhash->status=="success"){
                if($txhash->data){
                    if($txhash->data->status){
                        return $this->successResponse();
                    }
                    else{
                        return $this->cancelResponse();
                    }
                }
                else{
                    $getTranas = $this->curlExcute('api/transaction/getTransaction', ['txHash' => $hash]);
                    $getTranas = $this->toJsonDecode($getTranas);

                    if($getTranas){
                        if($getTranas->status=="success"){
                            if($getTranas->data){
                                return $this->pendingResponse();
                            }
                            else{
                                return $this->wrongResponse('Sorry, We are unable to locate this TxnHash');
                            }
                        }
                        else{
                            return $txhash;
                        }
                    }
                    else{
                        return $this->errorResponse('Something went wrong');
                    }
                }
            }
            else{
                return $txhash;
            }
        } else {
            return $this->errorResponse("Something went wrong");
        }
    }

    /** Send Token From System Wallet */
    public function adminToSendToken(object $data = null)
    {
        if (empty($data)) {
            return false;
        }

        $systeminfo = $this->adminCredential($data->useing_for,$data->netWork,$data->RPCurl);
        
        if ($systeminfo) {

            $fromAddress    = $systeminfo->address;
            $fromPrivateKey = $systeminfo->privatekey;
            $coininfo       = $this->coinInfo($data->netWork);
            $ci             = db_connect();
           
            if ($coininfo) {

                $walletbalance = 0;
                $balanceinfo   = $this->tokenBalance($fromAddress,$data->netWork,$data->RPCurl);
                
                if ($balanceinfo->status=='success') {
                    $walletbalance = $balanceinfo->data->tokenBalance;
                }
                
                if ($walletbalance < $data->send_amount) {
                    
                    $ci->table('dbt_admin_wallet')
                                  ->set(array('status' => 0))
                                  ->where('aw_id',$systeminfo->aw_id)
                                  ->update();
                    return false;
                }

                $tokendata = [
                    'formAddress'      => $fromAddress,
                    'contractAddress'  => $coininfo->contract_address,
                    'toAddress'        => $data->to_address,
                    'sendAmount'       => $data->send_amount,
                    'privateKey'       => $fromPrivateKey,
                    'netWork'          => $data->netWork,
                    'RPCurl'           => $data->RPCurl
                ];
                
                $txinfo  = $this->curlExcute('api/transaction/sendToken', $tokendata);
                $txinfo  = $this->toJsonDecode($txinfo);
               
                
                if ($txinfo) {
                    if ($txinfo->status == "success") {
                        $ci->table('dbt_admin_wallet')
                                  ->set(array('status' => 1))
                                  ->where('aw_id',$systeminfo->aw_id)
                                  ->update();
                    }
                    return $txinfo;
                } else {
                    return false;
                }
            } else {
                return false;
            }
        } else {
            return false;
        }
    }
    /** Find idle system wallet and export private key */
    private function adminCredential(String $usingFor,String $netWork,String $RPCurl)
    {
        $ci          = db_connect();
        $data        = $ci->table('dbt_admin_wallet')->select('*')->where('status', 2)->get()->getRow();

        if ($data) {
            $exportdata = (object)[
                'version'     => $data->version,
                'id'          => $data->id,
                'address'     => $data->address,
                'ciphertext'  => $data->ciphertext,
                'iv'          => $data->iv,
                'cipher'      => $data->cipher,
                'kdf'         => $data->kdf,
                'dklen'       => $data->dklen,
                'salt'        => $data->salt,
                'n'           => $data->n,
                'r'           => $data->r,
                'p'           => $data->p,
                'mac'         => $data->mac,
                'encrypt_val' => $data->encrypt_val,
                'netWork'     => $netWork,
                'RPCurl'      => $RPCurl
            ];
            $privateKey = $this->exportPrivateKey($exportdata);
            
            if ($privateKey) {
                return (object)['address' => $data->wallet, 'privatekey' => $privateKey, 'aw_id' => $data->aw_id];
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    /** Return Token Balance By Wallet Address */
    public function tokenBalance(String $address = null, String $netWork, String $RPCurl)
    {
        if (!$address) {
            return false;
        }

        $coininfo       = $this->coinInfo($netWork);
        if ($coininfo) {
            $tokendata = [
                'address'         => $address,
                'contractAddress' => $coininfo->contract_address,
                'decimal'         => $coininfo->decimal_value,
                'netWork'         => $netWork,
                'RPCurl'          => $RPCurl
            ];

            $txinfo  = $this->curlExcute('api/account/getTokenBalance', $tokendata);
            $txinfo  = $this->toJsonDecode($txinfo);
            
            if ($txinfo) {
                return $txinfo;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    /** Return user internal wallet balance by user Id */
    public function userTokenBalance(String $user_id = null)
    {
        if(empty($user_id)){
            return false;
        }
        $ci         = $this->getCI();
        $walletinfo = $ci->db->select('wallet_address')->from('dbt_user_wallet')->where('user_id',$user_id)->get()->row();

        if(!$walletinfo){
            return false;
        }

        $address = $walletinfo->wallet_address;
        $balance = $this->tokenBalance($address);

        return $balance;
    }

    /** Generate or Import System wallet */
    public function setAdminWallet(object $data = null)
    {
        if (empty($data)) {
            return $this->errorResponse('Wallet setup data is required');
        }
        //walletType = generate,export
        $walletType = $data->walletType;
        $password   = $data->password;
        $useingFor  = $data->account_type;
       
        $ci         = db_connect();

        if ($walletType == 'generate') {

            $walletinfo = $this->curlExcute('api/account/createWallet');
            $walletinfo = $this->toJsonDecode($walletinfo);
            if ($walletinfo) {
                if ($walletinfo->status == 'success') {
                    $address    = $walletinfo->data->address;
                    $privateKey = $walletinfo->data->privateKey;
                } else {
                    return $walletinfo;
                }
            } else {
                return $this->errorResponse('Something went wrong');
            }
        } else {
            $privateKey = $data->privateKey;
            if (empty($privateKey)) {
                return $this->errorResponse('Private key is required');
            }

            $accountinfo  = $this->curlExcute('api/account/privateKeyToAddress', ['privateKey' => $privateKey]);

            $accountinfo  = $this->toJsonDecode($accountinfo);
            
            if ($accountinfo) {

                if ($accountinfo->status == 'success') {
                    $address = $accountinfo->data->address;
                    
                    $checkDuplicate = $ci->table('dbt_admin_wallet')->select('aw_id')->where('wallet',$address)->orWhere('using_for',$useingFor)->get()->getRow();
                    if($checkDuplicate){
                        return $this->errorResponse('Wallet address already exists');
                    }
                } else {

                    return $accountinfo;
                }
            } else {
                return $this->errorResponse('Something went wrong');
            }
        }

        $encryppassw = $this->encrypt($password);

        if ($encryppassw) {
            $encryptinfo = $this->curlExcute('api/account/privateKeyEncrypt', ['privateKey' => $privateKey, 'password' => $encryppassw]);
            $encryptinfo = $this->toJsonDecode($encryptinfo);
            $todaytimes  = date('Y-m-d H:i:s');

            if ($encryptinfo) {
                if($encryptinfo->status=="success"){
                    $encryptinsertdata = array(
                        'version'      => $encryptinfo->data->version,
                        'id'           => $encryptinfo->data->id,
                        'address'      => $encryptinfo->data->address,
                        'ciphertext'   => $encryptinfo->data->crypto->ciphertext,
                        'iv'           => $encryptinfo->data->crypto->cipherparams->iv,
                        'cipher'       => $encryptinfo->data->crypto->cipher,
                        'kdf'          => $encryptinfo->data->crypto->kdf,
                        'dklen'        => $encryptinfo->data->crypto->kdfparams->dklen,
                        'salt'         => $encryptinfo->data->crypto->kdfparams->salt,
                        'n'            => $encryptinfo->data->crypto->kdfparams->n,
                        'r'            => $encryptinfo->data->crypto->kdfparams->r,
                        'p'            => $encryptinfo->data->crypto->kdfparams->p,
                        'mac'          => $encryptinfo->data->crypto->mac,
                        'encrypt_val'  => $password,
                        'wallet'       => $address,
                        'using_for'    => $useingFor,
                        'status'       => 2,
                        'created_at'   => $todaytimes,
                        'update_at'    => $todaytimes,
                    );
                    
                    $result = $ci->table('dbt_admin_wallet')->insert($encryptinsertdata);
                    if($result){
                        return $this->successResponse('System wallet setup successfully',(object)['wallet_address' => $address]);
                    }
                    else{
                        return $this->errorResponse('Something went wrong');
                    }
                }
                else{
                    return $encryptinfo;
                }
            } else {
                return $this->errorResponse('Something went wrong');
            }
        } else {
            return $this->errorResponse('Something went wrong');
        }
    }

    public function getWalletAddress($privateKey){
            $privateKey = $privateKey;
            if (empty($privateKey)) {
                return $this->errorResponse('Private key is required');
            }

            $accountinfo  = $this->curlExcute('api/account/privateKeyToAddress', ['privateKey' => $privateKey]);

            $accountinfo  = $this->toJsonDecode($accountinfo);
            
            if ($accountinfo) {

                return $accountinfo;
               
            } else {
                return $this->errorResponse('Something went wrong');
            }
    }
    /** Return token information by contract address from Blockchain */
    public function tokenInfo(array $data = null)
    {

        $tokeninfo = $this->curlExcute('api/account/getTokenInfo', $data);
        $tokeninfo = $this->toJsonDecode($tokeninfo);
        
        if ($tokeninfo) {
            return $tokeninfo;
        }
        return false;
    }

    /** Transfer Token From User Internal wallet to External wallet */
    public function userToSendToken(object $data = null)
    {
        if (empty($data)) {
            return false;
        }

        $usercredintial = $this->userCredential($data->user_id);

        if ($usercredintial) {
            $privateKey = $usercredintial->privatekey;
            $fromAddress = $data->fromAddress;
            $coininfo   = $this->coinInfo();

            if ($coininfo) {

                //check user wallet token balance
                $walletbalance = 0;
                $balanceinfo   = $this->tokenBalance($fromAddress);
                if ($balanceinfo) {
                    $walletbalance = $balanceinfo->balance;
                }
                if ($walletbalance < $data->send_amount) {
                    return false;
                }

                $tokendata = [
                    'from_address'    => $fromAddress,
                    'contractAddress' => $coininfo->contract_address,
                    'to_address'      => $data->to_address,
                    'amount'          => $data->send_amount,
                    'private_key'     => $privateKey,
                ];
                $txinfo  = $this->curlExcute('api/web3/sendToken', $tokendata);
                $txinfo  = $this->toJsonDecode($txinfo);

                if ($txinfo) {
                    return $txinfo;
                }
            }
        }

        return false;
    }



    /** Export private key from user internal wallet */
   public function userCredential(String $user_id = null,String $RPCurl=null,String $netWork=null)
    {
        
        $ci          = db_connect();
        $userInfo        = $ci->table('dbt_encrypt_data')->select('*')->where('user_id', $user_id)->get()->getRow();
        if ($userInfo) {
            $exportdata = (object)[
                'version'     => $userInfo->version,
                'id'          => $userInfo->id,
                'address'     => $userInfo->address,
                'ciphertext'  => $userInfo->ciphertext,
                'iv'          => $userInfo->iv,
                'cipher'      => $userInfo->cipher,
                'kdf'         => $userInfo->kdf,
                'dklen'       => $userInfo->dklen,
                'salt'        => $userInfo->salt,
                'n'           => $userInfo->n,
                'r'           => $userInfo->r,
                'p'           => $userInfo->p,
                'mac'         => $userInfo->mac,
                'encrypt_val' => $userInfo->encrypt_val,
                'netWork'   => $netWork,
                'RPCurl'    => $RPCurl
            ];
            $privateKey = $this->exportPrivateKey($exportdata);
            if($privateKey){
                return $this->successResponse('Data found',(object)['privatekey' => $privateKey]);
            }
            else{
                return $privateKey;
            }
        }
        else{
            return $this->errorResponse('User Data not found');
        }
    }

    /** reset private key */
    public function updatePrivateKey(object $data = null)
    {
        
        $email        = $data->email;
        $newPassword  = $data->newPassword;

        $ci           = $this->getCI();
        $userInfo     = $ci->db->select('dbt_encrypt_data.*')->from('dbt_encrypt_data')->join('user_registration','dbt_encrypt_data.user_id=user_registration.user_id','left')->where('user_registration.email',$email)->get()->row();
        if($userInfo){
            $privatekey         = $this->exportPrivateKey($userInfo);
            $encryppassw        = $this->encrypt($newPassword);
                 
                if ($encryppassw) {
                    $encryptinfo = $this->curlExcute('api/account/privateKeyHash', ['privatekey' => $privatekey, 'password' => $encryppassw]);
                    $encryptinfo = $this->toJsonDecode($encryptinfo);
                    $todaytimes  = date('Y-m-d H:i:s');

                    if ($encryptinfo) {
                        $encryptinsertdata = array(
                            'version'      => $encryptinfo->encryptDate['version'],
                            'id'           => $encryptinfo->encryptDate['id'],
                            'address'      => $encryptinfo->encryptDate['address'],
                            'ciphertext'   => $encryptinfo->encryptDate['crypto']['ciphertext'],
                            'iv'           => $encryptinfo->encryptDate['crypto']['cipherparams']['iv'],
                            'cipher'       => $encryptinfo->encryptDate['crypto']['cipher'],
                            'kdf'          => $encryptinfo->encryptDate['crypto']['kdf'],
                            'dklen'        => $encryptinfo->encryptDate['crypto']['kdfparams']['dklen'],
                            'salt'         => $encryptinfo->encryptDate['crypto']['kdfparams']['salt'],
                            'n'            => $encryptinfo->encryptDate['crypto']['kdfparams']['n'],
                            'r'            => $encryptinfo->encryptDate['crypto']['kdfparams']['r'],
                            'p'            => $encryptinfo->encryptDate['crypto']['kdfparams']['p'],
                            'mac'          => $encryptinfo->encryptDate['crypto']['mac'],
                            'encrypt_val'  => $newPassword,
                            'user_id'      => $userInfo->user_id,
                            'created_at'   => $todaytimes,
                            'update_at'    => $todaytimes,
                        );
                        $result = $ci->db->where('user_id',$userInfo->user_id)->update('dbt_encrypt_data', $encryptinsertdata);
                        return true;
                    }else{
                        return false;
                    }
                }else{
                    return false;
                }
        }else{
            return false;
        }
    }

    /** Return Transaction Gas Fees Amount */
    public function txFees()
    {
        $txfees  = $this->curlExcute('api/web3/getTransactionFee', ['fees' => 0]);
        $txfees  = $this->toJsonDecode($txfees);

        return $txfees;
    }

    /** Send transaction gas fees */
    public function sendFees(object $data = null)
    {
        if (empty($data)) {
            return false;
        }

        $systeminfo = $this->adminCredential($data->tx_type, $data->useing_for);        

        if ($systeminfo) {

            $fromAddress    = $systeminfo->address;
            $fromPrivateKey = $systeminfo->privatekey;
            $fees           = $data->send_amount;
            $ci             = $this->getCI();

            if ($fromPrivateKey) {

                $basebalanceinfo = $this->baseCoinBalance($fromAddress);
                $balance         = 0;
                if ($basebalanceinfo && $basebalanceinfo->status == 'success') {
                    $balance = $basebalanceinfo->balance;
                }
                else{
                    return false;
                }

                if($balance<=0 || $balance < $fees){
                    $ci->db->where('aw_id', $systeminfo->aw_id)->update('dbt_admin_wallet', ['status' => 0]);
                    return false;
                }

                $tokendata = [
                    'from_address'    => $fromAddress,
                    'to_address'      => $data->to_address,
                    'amount'          => $fees,
                    'private_key'     => $fromPrivateKey,
                ];
                $txinfo  = $this->curlExcute('api/web3/sendBaseCoin', $tokendata);
                $txinfo  = $this->toJsonDecode($txinfo, ['formAddress' => $fromAddress]);
                if ($txinfo) {
                    if ($txinfo->status == "success") {
                        $ci->db->where('aw_id', $systeminfo->aw_id)->update('dbt_admin_wallet', ['status' => 1]);
                    }
                    return $txinfo;
                }
            }
        }

        return false;
    }

    /** Return Transaction Fees For Success transaction */
    public function hasFees(String $address = null)
    {
        if (empty($address)) {
            return false;
        }

        $basebalanceinfo = $this->baseCoinBalance($address);

        $balance         = 0;
        if ($basebalanceinfo && $basebalanceinfo->status == 'success') {
            $balance = $basebalanceinfo->balance;
        }

        $feesinfo = $this->txFees();
        if ($feesinfo) {
            $fees = $feesinfo->fees;

            if ($balance < $fees) {
                $collect_fees = number_format($fees - $balance,8,'.','');
                if($collect_fees>0){
                    $fees_percent = number_format($fees/3,8,'.','');
                    $collect_fees = $collect_fees+$fees_percent;
                    return (object) ['status' => 'error', 'fees' => $collect_fees];
                }
                else{
                    return (object) ['status' => 'error', 'fees' => $fees];
                }
            } else {
                return (object) ['status' => 'success', 'fees' => 0];
            }
        }
        return false;
    }

    /** Return base coin balance (Basecoin-ETH,BNB) */
    public function baseCoinBalance(String $address = null)
    {
        if (empty($address)) {
            return false;
        }

        $balanceinfo  = $this->curlExcute('api/account/getBalance', ['address' => $address]);
        $balanceinfo  = $this->toJsonDecode($balanceinfo);
        if ($balanceinfo) {
            return $balanceinfo;
        }
        return false;
    }

    /** Return ICO coin information */
    public function coinInfo(string $netWork)
    {
        if($netWork=='bsc'){
            $token= "bep20";
        }else if($netWork=='eth'){
            $token= "erc20";
        }
        $ci = db_connect();
        return $ci->table('dbt_coin_info')->where('token_type',$token)->select('*')->get()->getRow();
    }

    /** Return blockchain explorar url */
    public function explorUrl()
    {
        return $this->explorarurl;
    }

    /** Return 4 status Transaction pending data (4 status = 0=cancel, 1=success, 2=pending, 3=hash pending, 4=pause pending) */
    public function queueData4TxPendingStatus(String $table = null, int $limit = 0)
    {
        $datainfo = $this->statusQuery($table, 2, $limit);

        if (!$datainfo) {
            $datainfo = $this->statusQuery($table, 4, $limit);
            if (!$datainfo) {
                return false;
            }
        }
        return $datainfo;
    }

    /** Return hash pending queue */
    public function queueHashPendingData(String $table = null, int $limit = 0)
    {
        $datainfo = $this->statusQuery($table, 3, $limit);
        return $datainfo;
    }

    /** Return hash success queue */
    public function queueHashSuccessData(String $table = null)
    {
        $datainfo = $this->statusQuery($table, 1);
        return $datainfo;
    }

    /** Return 6 status Transaction pending data (4 status = 0=cancel, 1=success, 2=pending, 3=hash pending, 4=pause pending, 5=send gas, 6=important pending) */
    public function queueData6TxPendingStatus(String $table = null, int $limit = 0)
    {
        $datainfo = $this->statusQuery($table, 6, $limit);

        if (!$datainfo) {
            $datainfo = $this->statusQuery($table, 2, $limit);
            if (!$datainfo) {
                $datainfo = $this->statusQuery($table, 4, $limit);
                if (!$datainfo) {
                    return false;
                }
            }
        }

        return $datainfo;
    }

    public function deviceMacAddress(Type $var = null)
    {
        ob_start(); // Turn on output buffering
        system('ipconfig/all'); //Execute external program to display output
        $mycom = ob_get_contents(); // Capture the output into a variable
        ob_clean(); // Clean (erase) the output buffer
        $findme = "Physical Address";
        $pmac = strpos($mycom, $findme);  // Find the position of Physical text
        $mac=substr($mycom, ($pmac+36), 17); // Get Physical Address

        return $mac;
    }

    // Library configration ->

    /** Excute queue query */
    private function statusQuery(String $table = null, int $status = null, $limit = 0)
    {
        $ci = $this->getCI();

        if ($limit) {
            $datainfo = $ci->db->select('*')->from($table)->where('status', $status)->limit($limit)->get()->result();
        } else {
            $datainfo = $ci->db->select('*')->from($table)->where('status', $status)->get()->row();
        }

        return $datainfo;
    }

    /** Convert json to array and merge extra array if exists */
    public function toJsonDecode(String $jsondata = null, array $option = null)
    {
        if (!empty($jsondata)) {

            $result = json_decode($jsondata);

            if (!empty($option)) {
                $result = array_merge($result, $option);
            }

            return (object)$result;
        } else {
            return "";
        }
    }

    /** Access $this object on library */
    private function getCI()
    {
        $ci = db_connect();
        return $ci;
    }

    /** Execute node API */
    public function curlExcute(String $method = null, array $data = null)
    {
        
        $curl = curl_init();

        if(!empty($data)){
            if(!array_key_exists('netWork',$data))
                $data['netWork'] = 'bsc';
            $data = json_encode($data);
        }

        curl_setopt_array($curl, array(
            CURLOPT_URL => $this->endpoints . $method,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => '',
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 0,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => 'POST',
            CURLOPT_POSTFIELDS => $data,
            CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
            )
        );

        $response = curl_exec($curl);
        curl_close($curl);
        return $response;
    }

    /** Convert array to object data */
    public function toObject(array $data = null)
    {
        return (object)$data;
    }

    private function errorResponse(String $msg = null)
    {
        return (object)['status'=>'error','msg'=>$msg];
    }

    private function successResponse(String $msg = null,object $data = null)
    {
        return (object)['status'=>'success','msg'=>$msg,'data'=>$data];
    }

    private function pendingResponse(String $msg = null)
    {
        return (object)['status'=>'pending','msg'=>$msg];
    }

    private function cancelResponse(String $msg = null)
    {
        return (object)['status'=>'cancel','msg'=>$msg];
    }

    public function wrongResponse(String $msg = null)
    {
        return (object)['status'=>'wrong','msg'=>$msg];
    }

    public function requiredResponse(String $msg = null,object $data = null)
    {
        return (object)['status'=>'required','msg'=>$msg,'data'=>$data];
    }


}