/ src / RpcClient.php
RpcClient.php
 1  <?php
 2  
 3  namespace BitcoindRPC;
 4  
 5  use GuzzleHttp\Client;
 6  use GuzzleHttp\Exception\RequestException;
 7  use BitcoindRPC\Exceptions\RpcException;
 8  
 9  class RpcClient
10  {
11      private Client $client;
12      private array $config;
13  
14      public function __construct(array $config = [])
15      {
16          $this->config = array_merge([
17              'scheme' => 'http',
18              'host' => '127.0.0.1',
19              'port' => 8332,
20              'user' => '',
21              'password' => '',
22              'path' => null,
23              'timeout' => 30,
24              'verify' => false,
25          ], $config);
26      }
27  
28      private function beforeCall(): void
29      {
30          $baseUri = null === $this->config['path'] 
31              ? "{$this->config['scheme']}://{$this->config['host']}:{$this->config['port']}" 
32              : "{$this->config['scheme']}://{$this->config['host']}:{$this->config['port']}{$this->config['path']}";
33  
34          $this->client = new Client([
35              'base_uri' => "{$this->config['scheme']}://{$this->config['host']}:{$this->config['port']}",
36              'auth' => [$this->config['user'], $this->config['password']],
37              'timeout' => $this->config['timeout'],
38              'verify' => $this->config['verify'],
39              'headers' => [
40                  'Content-Type' => 'application/json',
41              ],
42          ]);
43      }
44  
45      public function call(string $method, array $params = []): RpcResponse
46      {
47          $this->beforeCall();
48  
49          $payload = [
50              'jsonrpc' => '1.0',
51              'id' => 'php-bitcoin-rpc',
52              'method' => $method,
53              'params' => $params,
54          ];
55  
56          try {
57              $response = $this->client->post('', [
58                  'json' => $payload,
59              ]);
60  
61              $data = json_decode($response->getBody()->getContents(), true);
62  
63              return new RpcResponse(
64                  data: $data['result'] ?? null,
65                  error: $data['error'] ?? null,
66                  statusCode: $response->getStatusCode()
67              );
68  
69          } catch (RequestException $e) {
70              $statusCode = $e->getResponse() ? $e->getResponse()->getStatusCode() : 500;
71              $message = $e->getMessage();
72  
73              return new RpcResponse(
74                  data: null,
75                  error: $message,
76                  statusCode: $statusCode
77              );
78          } catch (\Exception $e) {
79              return new RpcResponse(
80                  data: null,
81                  error: $e->getMessage(),
82                  statusCode: 500
83              );
84          }
85      }
86  
87      public function getConfig(): array
88      {
89          return $this->config;
90      }
91  
92      public function setPath(string $path): void
93      {
94          $this->config['path'] = $path;
95      }
96  }