diff --git a/src/Eth.php b/src/Eth.php index 0ba5e99..5f6e463 100644 --- a/src/Eth.php +++ b/src/Eth.php @@ -3,6 +3,9 @@ namespace Web3; use Web3\Providers\Provider; +use Web3\Providers\HttpProvider; +use Web3\RequestManagers\RequestManager; +use Web3\RequestManagers\HttpRequestManager; class Eth { @@ -13,10 +16,19 @@ class Eth */ protected $provider; + /** + * methods + * + * @var array + */ + private $methods = [ + 'eth_protocolVersion' => [], + ]; + /** * construct * - * @param mixed string | provider $provider + * @param mixed string | Web3\Providers\Provider $provider * @return void */ public function __construct($provider) @@ -24,7 +36,9 @@ class Eth if (is_string($provider) && (filter_var($provider, FILTER_VALIDATE_URL) !== false)) { // check the uri schema if (preg_match('/^https?:\/\//', $provider) === 1) { - $this->provider = $provider; + $requestManeger = new HttpRequestManager($provider); + + $this->provider = new HttpProvider($requestManeger); } } else if ($provider instanceof Provider) { $this->provider = $provider; @@ -40,7 +54,39 @@ class Eth */ public function __call($name, $arguments) { - // + if (empty($this->provider)) { + return; + } + + $class = explode('\\', get_class()); + + if (strtolower($class[1]) === 'eth' && preg_match('/^[a-zA-Z0-9]+$/', $name) === 1) { + $method = strtolower($class[1]) . '_' . $name; + + if (!array_key_exists($method, $this->methods)) { + throw new \RuntimeException('Unallowed rpc method: ' . $method); + } + $allowedMethod = $this->methods[$method]; + + if (isset($allowedMethod['params'])) { + // validate params + foreach ($allowedMethod['params'] as $key => $rule) { + if (call_user_func([$rule, 'validate'], $arguments[$key]) === false) { + throw new \RuntimeException('Wrong type of ' . $name . ' method argument ' . $key . '.'); + } + } + } + if ($this->provider->isBatch) { + $this->provider->send($method, $arguments, null); + } else { + $callback = array_pop($arguments); + + if (is_callable($callback) !== true) { + throw new \InvalidArgumentException('The last param must be callback function.'); + } + $this->provider->send($method, $arguments, $callback); + } + } } /** diff --git a/src/Web3.php b/src/Web3.php index 1667316..329df17 100644 --- a/src/Web3.php +++ b/src/Web3.php @@ -74,7 +74,7 @@ class Web3 $class = explode('\\', get_class()); - if (strtolower($class[0]) === 'web3' && preg_match('/^[a-zA-Z0-9]+$/', $name) === 1) { + if (strtolower($class[1]) === 'web3' && preg_match('/^[a-zA-Z0-9]+$/', $name) === 1) { $method = strtolower($class[1]) . '_' . $name; if (!array_key_exists($method, $this->methods)) { diff --git a/test/unit/EthTest.php b/test/unit/EthTest.php new file mode 100644 index 0000000..65a75d3 --- /dev/null +++ b/test/unit/EthTest.php @@ -0,0 +1,75 @@ +web3 = $web3; + } + + /** + * testSend + * + * @return void + */ + public function testSend() + { + $eth = $this->web3->eth; + + $eth->protocolVersion(function ($err, $version) { + if ($err !== null) { + return $this->fail($err->getMessage()); + } + if (isset($version->result)) { + $this->assertTrue(is_string($version->result)); + } else { + $this->fail($version->error->message); + } + }); + } + + /** + * testUnallowedMethod + * + * @return void + */ + public function testUnallowedMethod() + { + $this->expectException(RuntimeException::class); + + $eth = $this->web3->eth; + + $eth->hello(function ($err, $hello) { + if ($err !== null) { + return $this->fail($err->getMessage()); + } + if (isset($hello->result)) { + $this->assertTrue(true); + } else { + $this->fail($hello->error->message); + } + }); + } +} \ No newline at end of file