


Implementation of the Stratum protocol (for electrum and mining) using ReactPHP
The Client class is used to make a connection to a host. It takes aConnectorInterface
andRequestFactory
.
react/socket-client
provides a number of connectors, which can be combinedto produce the desired functionality.
use \BitWasp\Stratum\Client;use \BitWasp\Stratum\Connection;use \BitWasp\Stratum\Request\RequestFactory;$loop = \React\EventLoop\Factory::create();$resolver =new \React\Dns\Resolver\Factory();// Raw TCP, cannot perform DNS resolution$tcp =new \React\SocketClient\TcpConnector($loop);// TCP Connector with a DNS resolver$dns =new \React\SocketClient\DnsConnector($tcp,$resolver->create('8.8.8.8',$loop));// Encrypted connection$context_options = [];$tls =new \React\SocketClient\SecureConnector($dns,$loop,$context_options);$requests =newRequestFactory;$client =newClient($tls,$requests);$host ='';$port ='';$client->connect($host,$port)->then(function (Connection$conn) {/* success */},function (\Exception$e) {/* error */print_r($e->getMessage());});$loop->run();
The SecureConnector initiates a TLS session to encrypt your connection. $context_options is an optionalvalue, but many Electrum servers have misconfigured SSL certificates! (incorrect CN field, or are self-signed)These will not be accepted with the default verification settings, and can be disabled by changing the $context_options
$context_options = ["verify_name" => false, "allow_self_signed" => true];
AConnection
represents a connection to a peer.
Requests can be sent to the peer usingConnection::request($method, $params = [])
,which returns a Promise for the pending result. When a response with the same ID isreceived, the promise will resolve this as the result.
$conn->request('server.banner')->then(function (Response$response) {print_r($response->getResult());},function (\Exception$e) {echo$e->getMessage();});
Request
instances can be sent usingConnection::sendRequest(Request $request)
which also returns a promise.
For a list of methods for the electrum and mining clients, see the respective Api classes.The constants are method's for these APIs.
$conn->sendRequest(newRequest(null,'server.banner'))->then(function (Response$response) {print_r($response->getResult());},function (\Exception$e) {echo$e->getMessage();});
NotificationInterface
's can be sent usingConnection::sendNotify(NotificationInterface $note)
Notifications are not requests, and don't receive a response. This method is only relevant ifusingConnection
from a servers perspective.
$conn->sendNotification(newNumBlocksNotification(123123));
The Stratum protocol is implemented by electrum servers and stratum mining pools.Their methods are exposed byElectrumClient
andMiningClient
respectively.
The api methods cause a Request to be sent, returning a promise to capture the result.
use \BitWasp\Stratum\Api\ElectrumClient;use \BitWasp\Stratum\Client;use \BitWasp\Stratum\Connection;use \BitWasp\Stratum\Request\Response;use \BitWasp\Stratum\Request\RequestFactory;$loop = \React\EventLoop\Factory::create();$tcp =new \React\SocketClient\TcpConnector($loop) ;$resolver =new \React\Dns\Resolver\Factory();$dns =new \React\SocketClient\DnsConnector($tcp,$resolver->create('8.8.8.8',$loop));$tls =new \React\SocketClient\SecureConnector($dns,$loop);$requests =newRequestFactory;$client =newClient($tls,$requests);$host ='anduck.net';$port =50002;$client->connect($host,$port)->then(function (Connection$conn) {$electrum =newElectrumClient($conn);$electrum->addressListUnspent('1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L')->then(function (Response$response) {print_r($response->getResult()); });},function (\Exception$e) {echo'error';echo$e->getMessage().PHP_EOL;/* error */});$loop->run();
Connection
emits amessage
event when a message is received whichwas not initiated by a Request. These messages are typically due to subscriptions.
The following events are emitted automatically by the library when encountered.The event name is the method used to enable the subscription.
- 'blockchain.headers.subscribe' emits a
HeadersNotification
- 'blockchain.address.subscribe' emits a
AddressNotification
- 'blockchain.numblocks.subscribe' emits a
NumBlocksNotification
- 'mining.subscribe' emits a
MiningNotification
- 'mining.set_difficulty' emits a
SetDifficultyNotification
use \BitWasp\Stratum\Api\ElectrumClient;use \BitWasp\Stratum\Client;use \BitWasp\Stratum\Connection;use \BitWasp\Stratum\Notification\AddressNotification;use \BitWasp\Stratum\Request\RequestFactory;$loop =React\EventLoop\Factory::create();$tcp =new \React\SocketClient\TcpConnector($loop);$resolver =new \React\Dns\Resolver\Factory();$dns =new \React\SocketClient\DnsConnector($tcp,$resolver->create('8.8.8.8',$loop));$tls =new \React\SocketClient\SecureConnector($dns,$loop);$requests =newRequestFactory;$client =newClient($tls,$requests);$host ='anduck.net';$port =50002;$client->connect($host,$port)->then(function (Connection$conn) {$conn->on('message',function ($message) {echo"Message received:".PHP_EOL;print_r($message); });$conn->on(ElectrumClient::ADDRESS_SUBSCRIBE,function (AddressNotification$address) {echo"Received address update\n"; });$electrum =newElectrumClient($conn);$electrum->subscribeAddress('1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L')->then(function () {echo"subscribed\n"; });},function (\Exception$e) {echo"ERROR:" .$e->getMessage().PHP_EOL;});$loop->run();