├── .github └── workflows │ ├── php.yml │ └── tests.yml ├── .gitignore ├── .styleci.yml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── composer.json ├── config └── etherscan.php ├── phpunit.xml ├── src ├── EtherServiceProvider.php ├── Exception │ ├── ErrorException.php │ ├── MissingApiKey.php │ └── MissingArgumentException.php ├── Resources │ └── Balance.php └── Services │ └── EtherScanService.php └── tests ├── Feature └── EtherScanTest.php └── Unit └── TestCase.php /.github/workflows/php.yml: -------------------------------------------------------------------------------- 1 | name: PHP Composer 2 | 3 | on: 4 | push: 5 | branches: [ "main" ] 6 | pull_request: 7 | branches: [ "main" ] 8 | 9 | permissions: 10 | contents: read 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v3 19 | 20 | - name: Validate composer.json and composer.lock 21 | run: composer validate --strict 22 | 23 | - name: Cache Composer packages 24 | id: composer-cache 25 | uses: actions/cache@v3 26 | with: 27 | path: vendor 28 | key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }} 29 | restore-keys: | 30 | ${{ runner.os }}-php- 31 | 32 | - name: Install dependencies 33 | run: composer install --prefer-dist --no-progress 34 | 35 | # Add a test script to composer.json, for instance: "test": "vendor/bin/phpunit" 36 | # Docs: https://getcomposer.org/doc/articles/scripts.md 37 | 38 | # - name: Run test suite 39 | # run: composer run-script test 40 | -------------------------------------------------------------------------------- /.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | 3 | on: 4 | push: 5 | branches: [ "main" ] 6 | pull_request: 7 | branches: [ "main" ] 8 | 9 | permissions: 10 | contents: read 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v3 19 | 20 | - name: Validate composer.json and composer.lock 21 | run: composer validate --strict 22 | 23 | - name: Cache Composer packages 24 | id: composer-cache 25 | uses: actions/cache@v3 26 | with: 27 | path: vendor 28 | key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }} 29 | restore-keys: | 30 | ${{ runner.os }}-php- 31 | 32 | - name: Install dependencies 33 | run: composer install --prefer-dist --no-progress 34 | 35 | # Add a test script to composer.json, for instance: "test": "vendor/bin/phpunit" 36 | # Docs: https://getcomposer.org/doc/articles/scripts.md 37 | 38 | # - name: Run test suite 39 | # run: composer run-script test 40 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .php_cs 3 | .php-cs-fixer.cache 4 | .phpunit.result.cache 5 | build 6 | composer.lock 7 | coverage 8 | docs 9 | psalm.xml 10 | vendor -------------------------------------------------------------------------------- /.styleci.yml: -------------------------------------------------------------------------------- 1 | preset: laravel -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slvler/etherscan-service/c5d630f16916a1d208231cd5afccee9bafce1633/CHANGELOG.md -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slvler/etherscan-service/c5d630f16916a1d208231cd5afccee9bafce1633/CONTRIBUTING.md -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2022 slvler 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Etherscan Service 2 | [![tests](https://github.com/slvler/etherscan-service/actions/workflows/tests.yml/badge.svg)](https://github.com/slvler/etherscan-service/actions/workflows/tests.yml) 3 | [![Latest Stable Version](https://img.shields.io/packagist/v/slvler/ether.svg)](https://packagist.org/packages/slvler/ether) 4 | [![License](https://poser.pugx.org/slvler/ether/license)](https://packagist.org/packages/slvler/ether) 5 | [![Total Downloads](https://poser.pugx.org/slvler/ether/downloads)](https://packagist.org/packages/slvler/ether) 6 | 7 | An api service for etherscan.io 8 | 9 | ## Requirements 10 | - PHP 8.2 11 | - Laravel 9.x | 10.x | 11.x 12 | 13 | ## Installation 14 | To install this package tou can use composer: 15 | ```bash 16 | composer require slvler/ether 17 | ``` 18 | 19 | ## Usage 20 | - First, you should extract the config/etherscan.php file to the config folder. 21 | ```php 22 | php artisan vendor:publish --tag=ether 23 | ``` 24 | - First of all we'll add the API key and API Url of the service we're using to our .env file of our project. If you don't have an account yet on api.etherscan.io, you should create one. Once you have an account you can copy your API key from the dashboard page and put it into you .env file. 25 | ```php 26 | ETHERSCAN_BASE_URL=https://api.etherscan.io/ 27 | ETHERSCAN_API_KEY=YOUR-API-KEY 28 | ``` 29 | - This is how you can connect to the etherscan api service. 30 | - Returns the Ether balance of a given address. 31 | ```php 32 | $ether = new EtherScanService(); 33 | $ether->balance('0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae'); 34 | ``` 35 | - Returns the balance of the accounts from a list of addresses. 36 | ```php 37 | $data = [ 38 | '0xddbd2b932c763ba5b1b7ae3b362eac3e8d40121a', 39 | '0x63a9975ba31b0b9626b34300f7f627147df1f526', 40 | '0x198ef1ec325a96cc354c7266a038be8b5c558f67' 41 | ]; 42 | $ether = new EtherScanService(); 43 | $ether->balance_multiple($data); 44 | ``` 45 | - Returns the list of transactions performed by an address, with optional pagination. 46 | ```php 47 | $ether = new EtherScanService(); 48 | $ether->transactions_normal('0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae'); 49 | ``` 50 | - Returns the list of internal transactions performed by an address, with optional pagination. 51 | ```php 52 | $ether = new EtherScanService(); 53 | $ether->transactions_internal('0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae'); 54 | ``` 55 | - Returns the list of internal transactions performed within a transaction. 56 | ```php 57 | $ether = new EtherScanService(); 58 | $ether->transactions_internal_hash('0x40eb908387324f2b575b4879cd9d7188f69c8fc9d87c901b9e2daaea4b442170'); 59 | ``` 60 | - Returns the list of internal transactions performed within a block range, with optional pagination. 61 | ```php 62 | $ether = new EtherScanService(); 63 | $ether->transactions_internal_block_range(); 64 | ``` 65 | - Returns the list of ERC-20 tokens transferred by an address, with optional filtering by token contract. 66 | ```php 67 | $ether = new EtherScanService(); 68 | $ether->token_transfer_events_erc20(); 69 | ``` 70 | - Returns the list of ERC-721 ( NFT ) tokens transferred by an address, with optional filtering by token contract. 71 | ```php 72 | $ether = new EtherScanService(); 73 | $ether->token_transfer_events_erc721(); 74 | ``` 75 | - Returns the list of ERC-1155 ( Multi Token Standard ) tokens transferred by an address, with optional filtering by token contract. 76 | ```php 77 | $ether = new EtherScanService(); 78 | $ether->token_transfer_events_erc1155(); 79 | ``` 80 | - Returns the list of blocks mined by an address. 81 | ```php 82 | $ether = new EtherScanService(); 83 | $ether->address_blocks_mined(); 84 | ``` 85 | - Returns the balance of an address at a certain block height. - PRO 86 | ```php 87 | $ether = new EtherScanService(); 88 | $ether->balance_single_adress(); 89 | ``` 90 | 91 | ### Testing 92 | ```bash 93 | composer test 94 | ``` 95 | 96 | ## Credits 97 | - [slvler](https://github.com/slvler) 98 | 99 | ## License 100 | The MIT License (MIT). Please see [License File](https://github.com/slvler/etherscan-service/blob/main/LICENSE.md) for more information. 101 | 102 | ## Contributing 103 | You're very welcome to contribute. 104 | Please see [CONTRIBUTING](https://github.com/slvler/etherscan-service/blob/main/CONTRIBUTING.md) for details. 105 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "slvler/ether", 3 | "description": "Laravel etherscan.io api service", 4 | "license": "MIT", 5 | "keywords": [ 6 | "etherscan", 7 | "multichain", 8 | "laravel", 9 | "php" 10 | ], 11 | "authors": [ 12 | { 13 | "name": "slvler", 14 | "email": "slvler@proton.me" 15 | } 16 | ], 17 | "homepage": "https://github.com/slvler/etherscan-service", 18 | "require": { 19 | "php": "^8.2", 20 | "guzzlehttp/guzzle": "^7.2", 21 | "illuminate/support": "^9.0|^10.0|^11.0" 22 | }, 23 | "require-dev": { 24 | "friendsofphp/php-cs-fixer": "^3.6", 25 | "orchestra/testbench": "^7.0", 26 | "phpunit/phpunit": "^9.5.8", 27 | "laravel/pint": "^1.18" 28 | }, 29 | "autoload": { 30 | "psr-4": { 31 | "Slvler\\Ether\\": "src/" 32 | } 33 | }, 34 | "autoload-dev": { 35 | "psr-4": { 36 | "Slvler\\Ether\\Tests\\": "tests/" 37 | } 38 | }, 39 | "extra": { 40 | "laravel": { 41 | "providers": [ 42 | "Slvler\\Ether\\EtherServiceProvider" 43 | ] 44 | } 45 | }, 46 | "scripts": { 47 | "test": "vendor/bin/phpunit tests --colors=always", 48 | "test-coverage": "vendor/bin/phpunit --coverage-html coverage", 49 | "pint": "vendor/bin/pint", 50 | "post-create-project-cmd": [ 51 | "@php artisan key:generate --ansi" 52 | ] 53 | }, 54 | "minimum-stability": "stable", 55 | "prefer-stable": true 56 | } 57 | -------------------------------------------------------------------------------- /config/etherscan.php: -------------------------------------------------------------------------------- 1 | [ 14 | 'base_url' => env('ETHERSCAN_BASE_URL'), 15 | 'api_key' => env('ETHERSCAN_API_KEY'), 16 | ], 17 | ]; 18 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | ./tests/Unit 10 | 11 | 12 | ./tests/Feature 13 | 14 | 15 | 16 | 17 | ./src 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/EtherServiceProvider.php: -------------------------------------------------------------------------------- 1 | app->runningInConsole()) { 12 | $this->publishResources(); 13 | } 14 | } 15 | 16 | protected function publishResources() 17 | { 18 | $this->publishes([ 19 | __DIR__.'/../config/etherscan.php' => config_path('etherscan.php'), 20 | ], 'ether'); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Exception/ErrorException.php: -------------------------------------------------------------------------------- 1 | $this->status, 19 | 'message' => $this->message, 20 | 'result' => $this->result, 21 | ]; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Services/EtherScanService.php: -------------------------------------------------------------------------------- 1 | base_url = config('etherscan.ether.base_url'); 24 | $this->api_key = $apiKey; 25 | 26 | $this->client = new \GuzzleHttp\Client( 27 | ['base_uri' => $this->base_url] 28 | ); 29 | } 30 | 31 | public function balance($adress): Balance 32 | { 33 | try { 34 | $res = $this->client->request('GET', 'api', [ 35 | 'query' => [ 36 | 'module' => 'account', 37 | 'action' => 'balance', 38 | 'address' => $adress, 39 | 'tag' => 'latest', 40 | 'apikey' => $this->api_key, 41 | ], 42 | ]); 43 | $statuscode = $res->getStatusCode(); 44 | if ($statuscode == 200) { 45 | return new Balance(json_decode($res->getBody()->getContents())); 46 | } 47 | } catch (\GuzzleHttp\Exception\ClientException $e) { 48 | $response = $e->getResponse(); 49 | $responseBodyAsString = $response->getBody()->getContents(); 50 | 51 | return $responseBodyAsString; 52 | } catch (\GuzzleHttp\Exception\ConnectException $e) { 53 | $response = $e->getResponse(); 54 | 55 | return $response; 56 | } 57 | } 58 | 59 | public function balance_multiple($data = []) 60 | { 61 | try { 62 | $res = $this->client->request('GET', 'api', [ 63 | 'query' => [ 64 | 'module' => 'account', 65 | 'action' => 'balancemulti', 66 | 'address' => implode(',', $data), 67 | 'tag' => 'latest', 68 | 'apikey' => $this->api_key, 69 | ], 70 | ]); 71 | $statuscode = $res->getStatusCode(); 72 | if ($statuscode == 200) { 73 | $content = $res->getBody()->getContents(); 74 | 75 | return $content; 76 | } 77 | } catch (\GuzzleHttp\Exception\ClientException $e) { 78 | $response = $e->getResponse(); 79 | $responseBodyAsString = $response->getBody()->getContents(); 80 | 81 | return $responseBodyAsString; 82 | } catch (\GuzzleHttp\Exception\ConnectException $e) { 83 | $response = $e->getResponse(); 84 | 85 | return $response; 86 | } 87 | } 88 | 89 | public function transactions_normal($adress) 90 | { 91 | try { 92 | $res = $this->client->request('GET', 'api', [ 93 | 'query' => [ 94 | 'module' => 'account', 95 | 'action' => 'txlist', 96 | 'address' => $adress, 97 | 'startblock' => '0', 98 | 'endblock' => '99999999', 99 | 'page' => '1', 100 | 'offset' => '10', 101 | 'sort' => 'asc', 102 | 'apikey' => $this->api_key, 103 | ], 104 | ]); 105 | $statuscode = $res->getStatusCode(); 106 | if ($statuscode == 200) { 107 | $content = $res->getBody()->getContents(); 108 | 109 | return $content; 110 | } 111 | } catch (\GuzzleHttp\Exception\ClientException $e) { 112 | $response = $e->getResponse(); 113 | $responseBodyAsString = $response->getBody()->getContents(); 114 | 115 | return $responseBodyAsString; 116 | } catch (\GuzzleHttp\Exception\ConnectException $e) { 117 | $response = $e->getResponse(); 118 | 119 | return $response; 120 | } 121 | } 122 | 123 | public function transactions_internal($adress) 124 | { 125 | try { 126 | $res = $this->client->request('GET', 'api', [ 127 | 'query' => [ 128 | 'module' => 'account', 129 | 'action' => 'txlistinternal', 130 | 'address' => $adress, 131 | 'startblock' => '0', 132 | 'endblock' => '99999999', 133 | 'page' => '1', 134 | 'offset' => '10', 135 | 'sort' => 'asc', 136 | 'apikey' => $this->api_key, 137 | ], 138 | ]); 139 | $statuscode = $res->getStatusCode(); 140 | if ($statuscode == 200) { 141 | $content = $res->getBody()->getContents(); 142 | 143 | return $content; 144 | } 145 | } catch (\GuzzleHttp\Exception\ClientException $e) { 146 | $response = $e->getResponse(); 147 | $responseBodyAsString = $response->getBody()->getContents(); 148 | 149 | return $responseBodyAsString; 150 | } catch (\GuzzleHttp\Exception\ConnectException $e) { 151 | $response = $e->getResponse(); 152 | 153 | return $response; 154 | } 155 | } 156 | 157 | public function transactions_internal_hash($txhash) 158 | { 159 | try { 160 | $res = $this->client->request('GET', 'api', [ 161 | 'query' => [ 162 | 'module' => 'account', 163 | 'action' => 'txlistinternal', 164 | 'txhash' => $txhash, 165 | 'apikey' => $this->api_key, 166 | ], 167 | ]); 168 | $statuscode = $res->getStatusCode(); 169 | if ($statuscode == 200) { 170 | $content = $res->getBody()->getContents(); 171 | 172 | return $content; 173 | } 174 | } catch (\GuzzleHttp\Exception\ClientException $e) { 175 | $response = $e->getResponse(); 176 | $responseBodyAsString = $response->getBody()->getContents(); 177 | 178 | return $responseBodyAsString; 179 | } catch (\GuzzleHttp\Exception\ConnectException $e) { 180 | $response = $e->getResponse(); 181 | 182 | return $response; 183 | } 184 | } 185 | 186 | public function transactions_internal_block_range() 187 | { 188 | try { 189 | $res = $this->client->request('GET', 'api', [ 190 | 'query' => [ 191 | 'module' => 'account', 192 | 'action' => 'txlistinternal', 193 | 'startblock' => '13481773', 194 | 'endblock' => '13491773', 195 | 'page' => '1', 196 | 'offset' => '10', 197 | 'sort' => 'asc', 198 | 'apikey' => $this->api_key, 199 | ], 200 | ]); 201 | $statuscode = $res->getStatusCode(); 202 | if ($statuscode == 200) { 203 | $content = $res->getBody()->getContents(); 204 | 205 | return $content; 206 | } 207 | } catch (\GuzzleHttp\Exception\ClientException $e) { 208 | $response = $e->getResponse(); 209 | $responseBodyAsString = $response->getBody()->getContents(); 210 | 211 | return $responseBodyAsString; 212 | } catch (\GuzzleHttp\Exception\ConnectException $e) { 213 | $response = $e->getResponse(); 214 | 215 | return $response; 216 | } 217 | } 218 | 219 | public function token_transfer_events_erc20() 220 | { 221 | try { 222 | $res = $this->client->request('GET', 'api', [ 223 | 'query' => [ 224 | 'module' => 'account', 225 | 'action' => 'tokentx', 226 | 'contractaddress' => '0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2', 227 | 'address' => '0x4e83362442b8d1bec281594cea3050c8eb01311c', 228 | 'page' => '1', 229 | 'offset' => '10', 230 | 'startblock' => '0', 231 | 'endblock' => '27025780', 232 | 'sort' => 'asc', 233 | 'apikey' => $this->api_key, 234 | ], 235 | ]); 236 | $statuscode = $res->getStatusCode(); 237 | if ($statuscode == 200) { 238 | $content = $res->getBody()->getContents(); 239 | 240 | return $content; 241 | } 242 | } catch (\GuzzleHttp\Exception\ClientException $e) { 243 | $response = $e->getResponse(); 244 | $responseBodyAsString = $response->getBody()->getContents(); 245 | 246 | return $responseBodyAsString; 247 | } catch (\GuzzleHttp\Exception\ConnectException $e) { 248 | $response = $e->getResponse(); 249 | 250 | return $response; 251 | } 252 | } 253 | 254 | public function token_transfer_events_erc721() 255 | { 256 | try { 257 | $res = $this->client->request('GET', 'api', [ 258 | 'query' => [ 259 | 'module' => 'account', 260 | 'action' => 'tokennfttx', 261 | 'contractaddress' => '0x06012c8cf97bead5deae237070f9587f8e7a266d', 262 | 'address' => '0x6975be450864c02b4613023c2152ee0743572325', 263 | 'page' => '1', 264 | 'offset' => '100', 265 | 'startblock' => '0', 266 | 'endblock' => '27025780', 267 | 'sort' => 'asc', 268 | 'apikey' => $this->api_key, 269 | ], 270 | ]); 271 | $statuscode = $res->getStatusCode(); 272 | if ($statuscode == 200) { 273 | $content = $res->getBody()->getContents(); 274 | 275 | return $content; 276 | } 277 | } catch (\GuzzleHttp\Exception\ClientException $e) { 278 | $response = $e->getResponse(); 279 | $responseBodyAsString = $response->getBody()->getContents(); 280 | 281 | return $responseBodyAsString; 282 | } catch (\GuzzleHttp\Exception\ConnectException $e) { 283 | $response = $e->getResponse(); 284 | 285 | return $response; 286 | } 287 | } 288 | 289 | public function token_transfer_events_erc1155() 290 | { 291 | try { 292 | $res = $this->client->request('GET', 'api', [ 293 | 'query' => [ 294 | 'module' => 'account', 295 | 'action' => 'token1155tx', 296 | 'contractaddress' => '0x76be3b62873462d2142405439777e971754e8e77', 297 | 'address' => '0x83f564d180b58ad9a02a449105568189ee7de8cb', 298 | 'page' => '1', 299 | 'offset' => '100', 300 | 'startblock' => '0', 301 | 'endblock' => '99999999', 302 | 'sort' => 'asc', 303 | 'apikey' => $this->api_key, 304 | ], 305 | ]); 306 | $statuscode = $res->getStatusCode(); 307 | if ($statuscode == 200) { 308 | $content = $res->getBody()->getContents(); 309 | 310 | return $content; 311 | } 312 | } catch (\GuzzleHttp\Exception\ClientException $e) { 313 | $response = $e->getResponse(); 314 | $responseBodyAsString = $response->getBody()->getContents(); 315 | 316 | return $responseBodyAsString; 317 | } catch (\GuzzleHttp\Exception\ConnectException $e) { 318 | $response = $e->getResponse(); 319 | 320 | return $response; 321 | } 322 | } 323 | 324 | public function address_blocks_mined() 325 | { 326 | try { 327 | $res = $this->client->request('GET', 'api', [ 328 | 'query' => [ 329 | 'module' => 'account', 330 | 'action' => 'getminedblocks', 331 | 'address' => '0x9dd134d14d1e65f84b706d6f205cd5b1cd03a46b', 332 | 'blocktype' => 'blocks', 333 | 'page' => '1', 334 | 'offset' => '10', 335 | 'apikey' => $this->api_key, 336 | ], 337 | ]); 338 | $statuscode = $res->getStatusCode(); 339 | if ($statuscode == 200) { 340 | $content = $res->getBody()->getContents(); 341 | 342 | return $content; 343 | } 344 | } catch (\GuzzleHttp\Exception\ClientException $e) { 345 | $response = $e->getResponse(); 346 | $responseBodyAsString = $response->getBody()->getContents(); 347 | 348 | return $responseBodyAsString; 349 | } catch (\GuzzleHttp\Exception\ConnectException $e) { 350 | $response = $e->getResponse(); 351 | 352 | return $response; 353 | } 354 | } 355 | 356 | public function balance_single_adress() 357 | { 358 | try { 359 | $res = $this->client->request('GET', 'api', [ 360 | 'query' => [ 361 | 'module' => 'account', 362 | 'action' => 'balancehistory', 363 | 'address' => '0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae', 364 | 'blockno' => '8000000', 365 | 'apikey' => $this->api_key, 366 | ], 367 | ]); 368 | $statuscode = $res->getStatusCode(); 369 | if ($statuscode == 200) { 370 | $content = $res->getBody()->getContents(); 371 | 372 | return $content; 373 | } 374 | } catch (\GuzzleHttp\Exception\ClientException $e) { 375 | $response = $e->getResponse(); 376 | $responseBodyAsString = $response->getBody()->getContents(); 377 | 378 | return $responseBodyAsString; 379 | } catch (\GuzzleHttp\Exception\ConnectException $e) { 380 | $response = $e->getResponse(); 381 | 382 | return $response; 383 | } 384 | } 385 | } 386 | -------------------------------------------------------------------------------- /tests/Feature/EtherScanTest.php: -------------------------------------------------------------------------------- 1 | assertIsObject($ether->balance('0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae')); 17 | } 18 | 19 | /** 20 | * @test 21 | */ 22 | public function test_balance_multiple() 23 | { 24 | $ether = new EtherScanService(); 25 | $data = ['0xddbd2b932c763ba5b1b7ae3b362eac3e8d40121a', '0x63a9975ba31b0b9626b34300f7f627147df1f526', '0x198ef1ec325a96cc354c7266a038be8b5c558f67']; 26 | $this->assertJson($ether->balance_multiple($data)); 27 | } 28 | 29 | /** 30 | * @test 31 | */ 32 | public function test_transactions_normal() 33 | { 34 | $ether = new EtherScanService(); 35 | $this->assertJson($ether->transactions_normal('0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae')); 36 | } 37 | 38 | /** 39 | * @test 40 | */ 41 | public function test_transactions_internal() 42 | { 43 | $ether = new EtherScanService(); 44 | $this->assertJson($ether->transactions_internal('0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae')); 45 | } 46 | 47 | /** 48 | * @test 49 | */ 50 | public function test_transactions_internal_hash() 51 | { 52 | $ether = new EtherScanService(); 53 | $this->assertJson($ether->transactions_internal_hash('0x40eb908387324f2b575b4879cd9d7188f69c8fc9d87c901b9e2daaea4b442170')); 54 | } 55 | 56 | /** 57 | * @test 58 | */ 59 | public function test_transactions_internal_block_range() 60 | { 61 | $ether = new EtherScanService(); 62 | $this->assertJson($ether->transactions_internal_block_range()); 63 | } 64 | 65 | /** 66 | * @test 67 | */ 68 | public function test_token_transfer_events_erc20() 69 | { 70 | $ether = new EtherScanService(); 71 | $this->assertJson($ether->token_transfer_events_erc20()); 72 | } 73 | 74 | /** 75 | * @test 76 | */ 77 | public function test_token_transfer_events_erc721() 78 | { 79 | $ether = new EtherScanService(); 80 | $this->assertJson($ether->token_transfer_events_erc721()); 81 | } 82 | 83 | /** 84 | * @test 85 | */ 86 | public function test_token_transfer_events_erc1155() 87 | { 88 | $ether = new EtherScanService(); 89 | $this->assertJson($ether->token_transfer_events_erc1155()); 90 | } 91 | 92 | /** 93 | * @test 94 | */ 95 | public function test_address_blocks_mined() 96 | { 97 | $ether = new EtherScanService(); 98 | $this->assertJson($ether->address_blocks_mined()); 99 | } 100 | 101 | /** 102 | * @test 103 | */ 104 | public function test_balance_single_adress() 105 | { 106 | $ether = new EtherScanService(); 107 | $this->assertJson($ether->balance_single_adress()); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /tests/Unit/TestCase.php: -------------------------------------------------------------------------------- 1 |