Updates library.php to connect to rpc-wallet
This commit is contained in:
parent
0048b81809
commit
43fa730ca0
@ -1,155 +1,220 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Monero PHP API
|
* library.php
|
||||||
* @author SerHack
|
|
||||||
* @version 0.1
|
|
||||||
* @year 2017
|
|
||||||
*
|
*
|
||||||
|
* Written using the JSON RPC specification -
|
||||||
|
* http://json-rpc.org/wiki/specification
|
||||||
|
*
|
||||||
|
* @author Kacper Rowinski <krowinski@implix.com>
|
||||||
|
* http://implix.com
|
||||||
|
* Modified to work with monero-rpc wallet by Serhack and cryptochangements
|
||||||
*/
|
*/
|
||||||
|
class jsonRPCClient
|
||||||
|
{
|
||||||
|
protected $url = null, $is_debug = false, $parameters_structure = 'array';
|
||||||
|
|
||||||
/* WORK IN PROGRESS */
|
protected $curl_options = array(
|
||||||
|
CURLOPT_CONNECTTIMEOUT => 8,
|
||||||
|
CURLOPT_TIMEOUT => 8
|
||||||
|
);
|
||||||
|
|
||||||
class Monero_Payments{
|
|
||||||
private $url;
|
|
||||||
private $client;
|
|
||||||
private $ip;
|
|
||||||
private $port;
|
|
||||||
|
|
||||||
/**
|
private $httpErrors = array(
|
||||||
* Start the connection with daemon
|
400 => '400 Bad Request',
|
||||||
* @param $ip IP of Monero RPC
|
401 => '401 Unauthorized',
|
||||||
* @param $port Port of Monero RPC
|
403 => '403 Forbidden',
|
||||||
*/
|
404 => '404 Not Found',
|
||||||
function __construct ($ip = '127.0.0.1', $port, $protocol = 'http'){
|
405 => '405 Method Not Allowed',
|
||||||
$this->ip = $ip;
|
406 => '406 Not Acceptable',
|
||||||
$this->port = $port;
|
408 => '408 Request Timeout',
|
||||||
// I need to implement a sort of validating http or https
|
500 => '500 Internal Server Error',
|
||||||
$this->url = $protocol.'://'.$ip.':'.$port.'/json_rpc';
|
502 => '502 Bad Gateway',
|
||||||
$this->client = new jsonRPCClient($this->url);
|
503 => '503 Service Unavailable'
|
||||||
|
);
|
||||||
|
|
||||||
|
public function __construct($pUrl)
|
||||||
|
{
|
||||||
|
$this->validate(false === extension_loaded('curl'), 'The curl extension must be loaded for using this class!');
|
||||||
|
$this->validate(false === extension_loaded('json'), 'The json extension must be loaded for using this class!');
|
||||||
|
|
||||||
|
$this->url = $pUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
private function getHttpErrorMessage($pErrorNumber)
|
||||||
* Run a method or method + parameters
|
{
|
||||||
* @param $method Name of Method
|
return isset($this->httpErrors[$pErrorNumber]) ? $this->httpErrors[$pErrorNumber] : null;
|
||||||
*/
|
|
||||||
private function _run($method,$params = null) {
|
|
||||||
$result = $this->client->_run($method, $params);
|
|
||||||
return $result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function _transform($amount){
|
public function setDebug($pIsDebug)
|
||||||
$new_amount = $amount * 100000000;
|
{
|
||||||
return $new_amount;
|
$this->is_debug = !empty($pIsDebug);
|
||||||
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/* public function setParametersStructure($pParametersStructure)
|
||||||
* Print json (for api)
|
{
|
||||||
* @return $json
|
if (in_array($pParametersStructure, array('array', 'object')))
|
||||||
*/
|
{
|
||||||
public function _print($json){
|
$this->parameters_structure = $pParametersStructure;
|
||||||
$json_parsed = json_encode($json, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
}
|
||||||
echo $json_parsed;
|
else
|
||||||
|
{
|
||||||
|
throw new UnexpectedValueException('Invalid parameters structure type.');
|
||||||
|
}
|
||||||
|
return $this;
|
||||||
|
} */
|
||||||
|
|
||||||
|
public function setCurlOptions($pOptionsArray)
|
||||||
|
{
|
||||||
|
if (is_array($pOptionsArray))
|
||||||
|
{
|
||||||
|
$this->curl_options = $pOptionsArray + $this->curl_options;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new InvalidArgumentException('Invalid options type.');
|
||||||
|
}
|
||||||
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function _run($pMethod, $pParams)
|
||||||
* Print Monero Address as JSON Array
|
{
|
||||||
*/
|
static $requestId = 0;
|
||||||
public function address(){
|
// generating uniuqe id per process
|
||||||
$address = $this->_run('getaddress');
|
$requestId++;
|
||||||
return $address;
|
// check if given params are correct
|
||||||
|
$this->validate(false === is_scalar($pMethod), 'Method name has no scalar value');
|
||||||
|
// $this->validate(false === is_array($pParams), 'Params must be given as array');
|
||||||
|
// send params as an object or an array
|
||||||
|
//$pParams = ($this->parameters_structure == 'object') ? $pParams[0] : array_values($pParams);
|
||||||
|
// Request (method invocation)
|
||||||
|
$request = json_encode(array('jsonrpc' => '2.0', 'method' => $pMethod, 'params' => $pParams, 'id' => $requestId));
|
||||||
|
// if is_debug mode is true then add url and request to is_debug
|
||||||
|
$this->debug('Url: ' . $this->url . "\r\n", false);
|
||||||
|
$this->debug('Request: ' . $request . "\r\n", false);
|
||||||
|
$responseMessage = $this->getResponse($request);
|
||||||
|
// if is_debug mode is true then add response to is_debug and display it
|
||||||
|
$this->debug('Response: ' . $responseMessage . "\r\n", true);
|
||||||
|
// decode and create array ( can be object, just set to false )
|
||||||
|
$responseDecoded = json_decode($responseMessage, true);
|
||||||
|
// check if decoding json generated any errors
|
||||||
|
$jsonErrorMsg = $this->getJsonLastErrorMsg();
|
||||||
|
$this->validate( !is_null($jsonErrorMsg), $jsonErrorMsg . ': ' . $responseMessage);
|
||||||
|
// check if response is correct
|
||||||
|
$this->validate(empty($responseDecoded['id']), 'Invalid response data structure: ' . $responseMessage);
|
||||||
|
$this->validate($responseDecoded['id'] != $requestId, 'Request id: ' . $requestId . ' is different from Response id: ' . $responseDecoded['id']);
|
||||||
|
if (isset($responseDecoded['error']))
|
||||||
|
{
|
||||||
|
$errorMessage = 'Request have return error: ' . $responseDecoded['error']['message'] . '; ' . "\n" .
|
||||||
|
'Request: ' . $request . '; ';
|
||||||
|
if (isset($responseDecoded['error']['data']))
|
||||||
|
{
|
||||||
|
$errorMessage .= "\n" . 'Error data: ' . $responseDecoded['error']['data'];
|
||||||
|
}
|
||||||
|
$this->validate( !is_null($responseDecoded['error']), $errorMessage);
|
||||||
|
}
|
||||||
|
return $responseDecoded['result'];
|
||||||
|
}
|
||||||
|
protected function & getResponse(&$pRequest)
|
||||||
|
{
|
||||||
|
// do the actual connection
|
||||||
|
$ch = curl_init();
|
||||||
|
if ( !$ch)
|
||||||
|
{
|
||||||
|
throw new RuntimeException('Could\'t initialize a cURL session');
|
||||||
|
}
|
||||||
|
curl_setopt($ch, CURLOPT_URL, $this->url);
|
||||||
|
curl_setopt($ch, CURLOPT_POST, 1);
|
||||||
|
curl_setopt($ch, CURLOPT_POSTFIELDS, $pRequest);
|
||||||
|
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: application/json'));
|
||||||
|
curl_setopt($ch, CURLOPT_ENCODING, 'gzip,deflate');
|
||||||
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||||
|
|
||||||
|
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||||
|
if ( !curl_setopt_array($ch, $this->curl_options))
|
||||||
|
{
|
||||||
|
throw new RuntimeException('Error while setting curl options');
|
||||||
|
}
|
||||||
|
// send the request
|
||||||
|
$response = curl_exec($ch);
|
||||||
|
// check http status code
|
||||||
|
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||||
|
if (isset($this->httpErrors[$httpCode]))
|
||||||
|
{
|
||||||
|
throw new RuntimeException('Response Http Error - ' . $this->httpErrors[$httpCode]);
|
||||||
|
}
|
||||||
|
// check for curl error
|
||||||
|
if (0 < curl_errno($ch))
|
||||||
|
{
|
||||||
|
throw new RuntimeException('Unable to connect to '.$this->url . ' Error: ' . curl_error($ch));
|
||||||
|
}
|
||||||
|
// close the connection
|
||||||
|
curl_close($ch);
|
||||||
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
public function validate($pFailed, $pErrMsg)
|
||||||
* Print Monero Balance as JSON Array
|
{
|
||||||
*/
|
if ($pFailed)
|
||||||
public function getbalance(){
|
{
|
||||||
$balance = $this->_run('getbalance');
|
throw new RuntimeException($pErrMsg);
|
||||||
return $balance;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Print Monero Height as JSON Array
|
|
||||||
*/
|
|
||||||
public function getheight(){
|
|
||||||
$height = $this->_run('getheight');
|
|
||||||
return $height;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Incoming Transfer
|
|
||||||
* $type must be All
|
|
||||||
*/
|
|
||||||
public function incoming_transfer($type){
|
|
||||||
$incoming_parameters = array('transfer_type' => $type);
|
|
||||||
$incoming_transfers = $this->_run('incoming_transfers', $incoming_parameters);
|
|
||||||
return $incoming_transfers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function get_transfers($input_type, $input_value){
|
|
||||||
$get_parameters = array($input_type => $input_value);
|
|
||||||
$get_transfers = $this->_run('get_transfers', $get_parameters);
|
|
||||||
return $get_transfers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function view_key(){
|
|
||||||
$query_key = array('key_type' => 'view_key');
|
|
||||||
$query_key_method = $this->_run('query_key', $query_key);
|
|
||||||
return $query_key_method;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* A payment id can be passed as a string
|
|
||||||
A random payment id will be generatd if one is not given */
|
|
||||||
public function make_integrated_address($payment_id){
|
|
||||||
$integrate_address_parameters = array('payment_id' => $payment_id);
|
|
||||||
$integrate_address_method = $this->_run('make_integrated_address', $integrate_address_parameters);
|
|
||||||
return $integrate_address_method;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function split_integrated_address($integrated_address){
|
|
||||||
if(!isset($integrated_address)){
|
|
||||||
echo "Error: Integrated_Address mustn't be null";
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
$split_params = array('integrated_address' => $integrated_address);
|
|
||||||
$split_methods = $this->_run('split_integrated_address', $split_params);
|
|
||||||
return $split_methods;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function make_uri($address, $amount, $recipient_name = null, $description = null){
|
protected function debug($pAdd, $pShow = false)
|
||||||
// If I pass 1, it will be 1 xmr. Then
|
{
|
||||||
$new_amount = $amount * 1000000000000;
|
static $debug, $startTime;
|
||||||
|
// is_debug off return
|
||||||
$uri_params = array('address' => $address, 'amount' => $new_amount, 'payment_id' => '', 'recipient_name' => $recipient_name, 'tx_description' => $description);
|
if (false === $this->is_debug)
|
||||||
$uri = $this->_run('make_uri', $uri_params);
|
{
|
||||||
return $uri;
|
return;
|
||||||
}
|
}
|
||||||
|
// add
|
||||||
|
$debug .= $pAdd;
|
||||||
public function parse_uri($uri){
|
// get starttime
|
||||||
$uri_parameters = array('uri' => $uri);
|
$startTime = empty($startTime) ? array_sum(explode(' ', microtime())) : $startTime;
|
||||||
$parsed_uri = $this->_run('parse_uri', $uri_parameters);
|
if (true === $pShow and !empty($debug))
|
||||||
return $parsed_uri;
|
{
|
||||||
}
|
// get endtime
|
||||||
|
$endTime = array_sum(explode(' ', microtime()));
|
||||||
public function transfer($amount, $address, $mixin = 4){
|
// performance summary
|
||||||
$new_amount = $amount * 1000000000000;
|
$debug .= 'Request time: ' . round($endTime - $startTime, 3) . ' s Memory usage: ' . round(memory_get_usage() / 1024) . " kb\r\n";
|
||||||
$destinations = array('amount' => $new_amount, 'address' => $address);
|
echo nl2br($debug);
|
||||||
$transfer_parameters = array('destinations' => array($destinations), 'mixin' => $mixin, 'get_tx_key' => true, 'unlock_time' => 0, 'payment_id' => '');
|
// send output imidiately
|
||||||
$transfer_method = $this->_run('transfer', $transfer_parameters);
|
flush();
|
||||||
return $transfer_method;
|
// clean static
|
||||||
}
|
$debug = $startTime = null;
|
||||||
|
|
||||||
public function get_payments($payment_id){
|
|
||||||
$get_payments_parameters = array('payment_id' => $payment_id);
|
|
||||||
$get_payments = $this->_run('get_payments', $get_payments_parameters);
|
|
||||||
return $get_payments;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function get_bulk_payments($payment_id, $min_block_height){
|
|
||||||
$get_bulk_payments_parameters = array('payment_id' => $payment_id, 'min_block_height' => $min_block_height);
|
|
||||||
$get_bulk_payments = $this->_run('get_bulk_payments', $get_bulk_payments_parameters);
|
|
||||||
return $get_bulk_payments;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getJsonLastErrorMsg()
|
||||||
|
{
|
||||||
|
if (!function_exists('json_last_error_msg'))
|
||||||
|
{
|
||||||
|
function json_last_error_msg()
|
||||||
|
{
|
||||||
|
static $errors = array(
|
||||||
|
JSON_ERROR_NONE => 'No error',
|
||||||
|
JSON_ERROR_DEPTH => 'Maximum stack depth exceeded',
|
||||||
|
JSON_ERROR_STATE_MISMATCH => 'Underflow or the modes mismatch',
|
||||||
|
JSON_ERROR_CTRL_CHAR => 'Unexpected control character found',
|
||||||
|
JSON_ERROR_SYNTAX => 'Syntax error',
|
||||||
|
JSON_ERROR_UTF8 => 'Malformed UTF-8 characters, possibly incorrectly encoded'
|
||||||
|
);
|
||||||
|
$error = json_last_error();
|
||||||
|
return array_key_exists($error, $errors) ? $errors[$error] : 'Unknown error (' . $error . ')';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fix PHP 5.2 error caused by missing json_last_error function
|
||||||
|
if (function_exists('json_last_error'))
|
||||||
|
{
|
||||||
|
return json_last_error() ? json_last_error_msg() : null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user