diff --git a/src/Contracts/Validator.php b/src/Contracts/Validator.php new file mode 100644 index 0000000..f4331ac --- /dev/null +++ b/src/Contracts/Validator.php @@ -0,0 +1,27 @@ +>> + */ + public function getLogs($filterObject = []): array + { + FilterObject::validate($filterObject); + + // Accept decimal + if (isset($filterObject['fromBlock']) && is_int($filterObject['fromBlock'])) { + $filterObject['fromBlock'] = BigIntegerToHex::format((string) $filterObject['fromBlock']); + } + if (isset($filterObject['toBlock']) && is_int($filterObject['toBlock'])) { + $filterObject['toBlock'] = BigIntegerToHex::format((string) $filterObject['toBlock']); + } + + $params = empty($filterObject) ? [] : [$filterObject]; + + $result = $this->transporter->request('eth_getLogs', $params); + + /** @var array>> $result */ + assert(is_array($result)); + + /** @var array $log */ + foreach ($result as $logKey => $log) { + foreach (['blockNumber', 'logIndex', 'transactionIndex'] as $key) { + $result[$logKey][$key] = HexToBigInteger::format($log[$key]); + } + } + + return $result; + } + /** * Returns the coinbase address of the client. * diff --git a/src/Validators/FilterObject.php b/src/Validators/FilterObject.php new file mode 100644 index 0000000..c45ce43 --- /dev/null +++ b/src/Validators/FilterObject.php @@ -0,0 +1,40 @@ +> $arg + * @param array $config + * + * @throws ValidatorException + * + * @return bool + */ + public static function validate($arg, array $config = []): bool + { + if (!is_array($arg)) { + throw new ValidatorException('Expected FilterObject to be an array.'); + } + + if (isset($arg['topics']) && !is_array($arg['topics'])) { + throw new ValidatorException('Expected FilterObject topics to be an array.'); + } + + foreach (['address', 'fromBlock', 'toBlock', 'blockhash'] as $key) { + if (isset($arg[$key]) && !is_string($arg[$key])) { + throw new ValidatorException("Expected FilterObject $key value to be string."); + } + } + + return true; + } +} diff --git a/tests/Namespaces/Eth.php b/tests/Namespaces/Eth.php index f6da357..139cb60 100644 --- a/tests/Namespaces/Eth.php +++ b/tests/Namespaces/Eth.php @@ -256,3 +256,67 @@ )) ->toBe(true); }); + +test('get logs', function () { + $this->transporter->shouldReceive('request')->with( + 'eth_getLogs', + [[]] + )->once()->andReturn([ + [ + "address" => "0x1a94fce7ef36bc90959e206ba569a12afbc91ca1", + "blockHash" => "0x7c5a35e9cb3e8ae0e221ab470abae9d446c3a5626ce6689fc777dcffcab52c70", + "blockNumber" => "0x5c29fb", + "data" => "0x0000000000000000000000003e3310720058c51f0de456e273c626cdd35065700000000000000000000000000000000000000000000000000000000000003185000000000000000000000000000000000000000000000000000000000000318200000000000000000000000000000000000000000000000000000000005c2a23", + "logIndex" => "0x1d", + "removed" => false, + "topics" => [ + "0x241ea03ca20251805084d27d4440371c34a0b85ff108f6bb5611248f73818b80" + ], + "transactionHash" => "0x3dc91b98249fa9f2c5c37486a2427a3a7825be240c1c84961dfb3063d9c04d50", + "transactionIndex" => "0x1d" + ], + [ + "address" => "0x06012c8cf97bead5deae237070f9587f8e7a266d", + "blockHash" => "0x7c5a35e9cb3e8ae0e221ab470abae9d446c3a5626ce6689fc777dcffcab52c70", + "blockNumber" => "0x5c29fb", + "data" => "0x00000000000000000000000077ea137625739598666ded665953d26b3d8e374400000000000000000000000000000000000000000000000000000000000749ff00000000000000000000000000000000000000000000000000000000000a749d00000000000000000000000000000000000000000000000000000000005c2a0f", + "logIndex" => "0x57", + "removed" => false, + "topics" => [ + "0x241ea03ca20251805084d27d4440371c34a0b85ff108f6bb5611248f73818b80" + ], + "transactionHash" => "0x788b1442414cb9c9a36dba2abe250763161a6f6395788a2e808f1b34e92beec1", + "transactionIndex" => "0x54" + ] + ]); + + expect($this->eth->getLogs([])) + ->toBe([ + [ + "address" => "0x1a94fce7ef36bc90959e206ba569a12afbc91ca1", + "blockHash" => "0x7c5a35e9cb3e8ae0e221ab470abae9d446c3a5626ce6689fc777dcffcab52c70", + "blockNumber" => "6040059", + "data" => "0x0000000000000000000000003e3310720058c51f0de456e273c626cdd35065700000000000000000000000000000000000000000000000000000000000003185000000000000000000000000000000000000000000000000000000000000318200000000000000000000000000000000000000000000000000000000005c2a23", + "logIndex" => "29", + "removed" => false, + "topics" => [ + "0x241ea03ca20251805084d27d4440371c34a0b85ff108f6bb5611248f73818b80" + ], + "transactionHash" => "0x3dc91b98249fa9f2c5c37486a2427a3a7825be240c1c84961dfb3063d9c04d50", + "transactionIndex" => "29" + ], + [ + "address" => "0x06012c8cf97bead5deae237070f9587f8e7a266d", + "blockHash" => "0x7c5a35e9cb3e8ae0e221ab470abae9d446c3a5626ce6689fc777dcffcab52c70", + "blockNumber" => "6040059", + "data" => "0x00000000000000000000000077ea137625739598666ded665953d26b3d8e374400000000000000000000000000000000000000000000000000000000000749ff00000000000000000000000000000000000000000000000000000000000a749d00000000000000000000000000000000000000000000000000000000005c2a0f", + "logIndex" => "87", + "removed" => false, + "topics" => [ + "0x241ea03ca20251805084d27d4440371c34a0b85ff108f6bb5611248f73818b80" + ], + "transactionHash" => "0x788b1442414cb9c9a36dba2abe250763161a6f6395788a2e808f1b34e92beec1", + "transactionIndex" => "84" + ] + ]); +}); \ No newline at end of file diff --git a/tests/Validators/FilterObject.php b/tests/Validators/FilterObject.php new file mode 100644 index 0000000..161e669 --- /dev/null +++ b/tests/Validators/FilterObject.php @@ -0,0 +1,26 @@ + '0x1a94fce7ef36bc90959e206ba569a12afbc91ca1', + 'fromBlock' => '12', + 'toBlock' => '24', + 'topics' => ['ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef'], + 'blockhash' => '0x7c5a35e9cb3e8ae0e221ab470abae9d446c3a5626ce6689fc777dcffcab52c70', + ]); + expect($result)->toBe(true); +}); + +it('throws errors on invalid filter objects', function () { + $this->expectException(ValidatorException::class); + FilterObject::validate([ + 'address' => '0x1a94fce7ef36bc90959e206ba569a12afbc91ca1', + 'fromBlock' => '12', + 'toBlock' => '24', + 'topics' => 'ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef', + 'blockhash' => '0x7c5a35e9cb3e8ae0e221ab470abae9d446c3a5626ce6689fc777dcffcab52c70', + ]); +});