├── .gitattributes ├── .github ├── FUNDING.yml ├── SECURITY.md ├── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md └── CONTRIBUTING.md ├── CHANGELOG.md ├── src ├── BinanceApiServiceProvider.php ├── Traits │ └── HandlesResponseErrors.php └── BinanceAPI.php ├── LICENSE.md ├── config └── binance-api.php ├── composer.json ├── CODE_OF_CONDUCT.md └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: TechTailor 4 | liberapay: TechTailor 5 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to `laravel-binance-api` will be documented in this file 4 | 5 | -------------------------------------------------------------------------------- /.github/SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | If you discover any security related issues, please email [**hello@moinuddin.info**](mailto:hello@moinuddin.info) instead of using the issue tracker. 4 | -------------------------------------------------------------------------------- /src/BinanceApiServiceProvider.php: -------------------------------------------------------------------------------- 1 | name('binance-api') 14 | ->hasConfigFile(); 15 | } 16 | 17 | public function packageRegistered() 18 | { 19 | // 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2021 Moinuddin S. Khaja [] 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. 22 | -------------------------------------------------------------------------------- /config/binance-api.php: -------------------------------------------------------------------------------- 1 | [ 15 | 'key' => env('BINANCE_KEY', ''), 16 | 'secret' => env('BINANCE_SECRET', ''), 17 | ], 18 | 19 | /* 20 | |-------------------------------------------------------------------------- 21 | | API URLs 22 | |-------------------------------------------------------------------------- 23 | | 24 | | Binance API endpoints 25 | | 26 | */ 27 | 28 | 'urls' => [ 29 | 'api' => 'https://api.binance.com/api/', 30 | 'sapi' => 'https://api.binance.com/sapi/', 31 | ], 32 | 33 | /* 34 | |-------------------------------------------------------------------------- 35 | | API Settings 36 | |-------------------------------------------------------------------------- 37 | | 38 | | Binance API settings 39 | | 40 | */ 41 | 42 | 'settings' => [ 43 | 'timing' => env('BINANCE_TIMING', 5000), 44 | ], 45 | 46 | ]; 47 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "techtailor/laravel-binance-api", 3 | "description": "A Laravel Wrapper for the Binance API.", 4 | "keywords": [ 5 | "binance", 6 | "binance-api", 7 | "laravel-binance", 8 | "laravel-binance-api" 9 | ], 10 | "homepage": "https://github.com/TechTailor/Laravel-Binance-Api", 11 | "license": "MIT", 12 | "authors": [ 13 | { 14 | "name": "Moinuddin S. Khaja", 15 | "email": "hello@moinuddin.info", 16 | "homepage": "https://moinuddin.info", 17 | "role": "Developer" 18 | } 19 | ], 20 | "require": { 21 | "php": "^7.4|^8.0", 22 | "illuminate/contracts": "^7.0|^8.0", 23 | "illuminate/http": "^7.0|^8.0", 24 | "illuminate/support": "^7.0|^8.0", 25 | "spatie/laravel-package-tools": "^1.9" 26 | }, 27 | "require-dev": { 28 | "orchestra/testbench": "^6.0", 29 | "phpunit/phpunit": "^9.3" 30 | }, 31 | "autoload": { 32 | "psr-4": { 33 | "TechTailor\\BinanceApi\\": "src/" 34 | } 35 | }, 36 | "autoload-dev": { 37 | "psr-4": { 38 | "TechTailor\\BinanceApi\\Tests\\": "tests/" 39 | } 40 | }, 41 | "scripts": { 42 | "psalm": "vendor/bin/psalm", 43 | "test": "vendor/bin/phpunit --colors=always", 44 | "test-coverage": "vendor/bin/phpunit --coverage-html coverage" 45 | }, 46 | "config": { 47 | "sort-packages": true 48 | }, 49 | "extra": { 50 | "laravel": { 51 | "providers": [ 52 | "TechTailor\\BinanceApi\\BinanceApiServiceProvider" 53 | ] 54 | } 55 | }, 56 | "minimum-stability": "dev", 57 | "prefer-stable": true 58 | } 59 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Contributions are **welcome** and will be fully **credited**. 4 | 5 | Please read and understand the contribution guide before creating an issue or pull request. 6 | 7 | ## Etiquette 8 | 9 | This project is open source, and as such, the maintainers give their free time to build and maintain the source code 10 | held within. They make the code freely available in the hope that it will be of use to other developers. It would be 11 | extremely unfair for them to suffer abuse or anger for their hard work. 12 | 13 | Please be considerate towards maintainers when raising issues or presenting pull requests. Let's show the 14 | world that developers are civilized and selfless people. 15 | 16 | It's the duty of the maintainer to ensure that all submissions to the project are of sufficient 17 | quality to benefit the project. Many developers have different skillsets, strengths, and weaknesses. Respect the maintainer's decision, and do not be upset or abusive if your submission is not used. 18 | 19 | ## Viability 20 | 21 | When requesting or submitting new features, first consider whether it might be useful to others. Open 22 | source projects are used by many developers, who may have entirely different needs to your own. Think about 23 | whether or not your feature is likely to be used by other users of the project. 24 | 25 | ## Procedure 26 | 27 | Before filing an issue: 28 | 29 | - Attempt to replicate the problem, to ensure that it wasn't a coincidental incident. 30 | - Check to make sure your feature suggestion isn't already present within the project. 31 | - Check the pull requests tab to ensure that the bug doesn't have a fix in progress. 32 | - Check the pull requests tab to ensure that the feature isn't already in progress. 33 | 34 | Before submitting a pull request: 35 | 36 | - Check the codebase to ensure that your feature doesn't already exist. 37 | - Check the pull requests to ensure that another person hasn't already submitted the feature or fix. 38 | 39 | ## Requirements 40 | 41 | If the project maintainer has any additional requirements, you will find them listed here. 42 | 43 | - **Add tests!** - Your patch won't be accepted if it doesn't have tests. 44 | 45 | - **Document any change in behaviour** - Make sure the `README.md` and any other relevant documentation are kept up-to-date. 46 | 47 | - **Consider our release cycle** - We try to follow [SemVer v2.0.0](https://semver.org/). Randomly breaking public APIs is not an option. 48 | 49 | - **One pull request per feature** - If you want to do more than one thing, send multiple pull requests. 50 | 51 | - **Send coherent history** - Make sure each individual commit in your pull request is meaningful. If you had to make multiple intermediate commits while developing, please [squash them](https://www.git-scm.com/book/en/v2/Git-Tools-Rewriting-History#Changing-Multiple-Commit-Messages) before submitting. 52 | 53 | **Happy coding**! 54 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at hello@spargon.tech. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![](https://banners.beyondco.de/Laravel-Binance-API.png?theme=light&packageManager=composer+require&packageName=techtailor%2Flaravel-binance-api&pattern=architect&style=style_2&description=A+laravel+wrapper+for+the+Binance+API.&md=1&showWatermark=0&fontSize=100px&images=server) 2 | 3 | [![GitHub release](https://img.shields.io/github/release/techtailor/laravel-binance-api.svg?include_prereleases&style=for-the-badge&&colorB=7E57C2)](https://packagist.org/packages/techtailor/laravel-binance-api) 4 | [![GitHub issues](https://img.shields.io/github/issues/TechTailor/Laravel-Binance-Api.svg?style=for-the-badge)](https://github.com/TechTailor/Laravel-Binance-Api/issues) 5 | [![Software License](https://img.shields.io/badge/license-MIT-blue.svg?style=for-the-badge&&colorB=F27E40)](license.md) 6 | [![Total Downloads](https://img.shields.io/packagist/dt/techtailor/laravel-binance-api.svg?style=for-the-badge)](https://packagist.org/packages/techtailor/laravel-binance-api) 7 | 8 | This package provides a Laravel Wrapper for the [Binance API](https://binance-docs.github.io/apidocs/spot/en) and allows you to easily communicate with it. 9 | 10 | --- 11 | #### Important Note 12 | This package is in early development stage. It is not advisable to use it in a production app until **`v1.0`** is released. Feel free to open a PR to contribute to this project and help me reach a production ready build. 13 | 14 | --- 15 | 16 | ### Installation 17 | 18 | You can install the package via composer: 19 | 20 | ```bash 21 | composer require techtailor/laravel-binance-api 22 | ``` 23 | 24 | You can publish the config file with: 25 | ```bash 26 | php artisan vendor:publish --tag="binance-api-config" 27 | ``` 28 | 29 | Open your `.env` file and add the following (replace ``YOUR_API_KEY`` and ``YOUR_SECRET`` with the API Key & Secret you received from [Binance](https://www.binancezh.top/en/support/faq/360002502072)) - 30 | ```php 31 | BINANCE_KEY=YOUR_API_KEY 32 | BINANCE_SECRET=YOUR_SECRET 33 | ``` 34 | Or 35 | 36 | Open the published config file available at `config/binance-api.php` and add your API and Secret Keys: 37 | 38 | ```php 39 | return [ 40 | 'auth' => [ 41 | 'key' => env('BINANCE_KEY', 'YOUR_API_KEY'), 42 | 'secret' => env('BINANCE_SECRET', 'YOUR_SECRET') 43 | ], 44 | ]; 45 | ``` 46 | 47 | ### Usage 48 | 49 | Using this package is very simple. Just initialize the Api and call one of the available methods: 50 | ```php 51 | use TechTailor\BinanceApi\BinanceAPI; 52 | 53 | $binance = new BinanceAPI(); 54 | 55 | $time = $binance->getTime(); 56 | ``` 57 | 58 | You can also set an API & Secret for a user by passing it after initalization (useful when you need to isolate api keys for individual users): 59 | 60 | ```php 61 | $binance = new BinanceApi(); 62 | 63 | $binance->setApi($apiKey, $secretKey); 64 | 65 | $accountInfo = $binance->getAccountInfo(); 66 | ``` 67 | 68 | ### Available Methods 69 | 70 | Available Public Methods (Security Type : `NONE`) **[API Keys Not Required]** 71 | ``` 72 | - getSystemStatus() // returns system status, expect msg to be "normal". 73 | - getTime() // returns server timestamp. 74 | - getExchangeInfo($symbol) // returns current exchange trading rules and symbol information. 75 | - getOrderBook($symbol) // returns the order book for the symbol. 76 | - getAvgPrice($symbol) // returns the average price for a symbol. 77 | - getTicker($symbol) // returns the 24hr ticker for a symbol (if no symbol provided, returns an array of all symbols). 78 | ``` 79 | Available Private Methods (Security Type : `USER_DATA`) **[API Keys Required]** 80 | ``` 81 | - getAccountInfo() // returns current account information. 82 | - getAllOrders() // return all current account orders (active, canceled or filled). 83 | - getOpenOrders($symbol) // returns all current account open orders (Careful when accessing without symbol). 84 | - getTrades($symbol) // returns all trades for a symbol. 85 | - getOrderStatus($symbol, $orderId) // returns status of a given order. 86 | - getUserCoinsInfo() // returns information of all coins available to the user. 87 | - getDepositHistory() // returns the user's deposit history. 88 | - getWithdrawHistory() // returns the user's withdraw history. 89 | ``` 90 | 91 | ### TODO 92 | 93 | List of features or additional functionality we are working on (in no particular order) - 94 | 95 | ```bash 96 | - Improve exception handling. 97 | - Add rate limiting to API Calls. 98 | - Add response for API ban/blacklisting response. 99 | - Improve ReadMe. 100 | ``` 101 | 102 | ### Changelog 103 | 104 | Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently. 105 | 106 | ### Contributing 107 | 108 | Please see [CONTRIBUTING](.github/CONTRIBUTING.md) for details. 109 | 110 | ### Security Vulnerabilities 111 | 112 | Please review [our security policy](../../security/policy) on how to report security vulnerabilities. 113 | 114 | ### Credits 115 | 116 | - [Moinuddin S. Khaja](https://github.com/TechTailor) 117 | - [All Contributors](../../contributors) 118 | 119 | ### License 120 | 121 | The MIT License (MIT). Please see [License File](LICENSE.md) for more information. 122 | -------------------------------------------------------------------------------- /src/Traits/HandlesResponseErrors.php: -------------------------------------------------------------------------------- 1 | '1000', 12 | 'error' => 'Invalid', 13 | 'message' => 'Unable to identify the type of error.', 14 | ]; 15 | 16 | // Return server related errors (500 range). 17 | if ($response->serverError()) { 18 | // TBA 19 | } 20 | // Return client related errors. 21 | elseif ($response->clientError()) { 22 | // If client error has a response code. 23 | if (isset($response['code'])) { 24 | // Switch between known Binance error codes. 25 | switch ($response['code']) { 26 | case '-1000': 27 | $error = [ 28 | 'code' => '-1000', 29 | 'error' => 'UNKNOWN', 30 | 'message' => 'An unknown error occurred while processing the request. ', 31 | ]; 32 | break; 33 | case '-1001': 34 | $error = [ 35 | 'code' => '-1001', 36 | 'error' => 'DISCONNECTED', 37 | 'message' => 'Internal error; unable to process your request. Please try again.', 38 | ]; 39 | break; 40 | case '-1002': 41 | $error = [ 42 | 'code' => '-1002', 43 | 'error' => 'UNAUTHORIZED', 44 | 'message' => 'You are not authorized to execute this request.', 45 | ]; 46 | break; 47 | case '-1003': 48 | $error = [ 49 | 'code' => '-1003', 50 | 'error' => 'TOO_MANY_REQUESTS', 51 | 'message' => 'Too many requests queued.', 52 | ]; 53 | break; 54 | case '-1004': 55 | $error = [ 56 | 'code' => '-1004', 57 | 'error' => 'SERVER_BUSY', 58 | 'message' => 'Server is busy, please wait and try again', 59 | ]; 60 | break; 61 | case '-1006': 62 | $error = [ 63 | 'code' => '-1006', 64 | 'error' => 'UNEXPECTED_RESP', 65 | 'message' => 'An unexpected response was received from the message bus. Execution status unknown.', 66 | ]; 67 | break; 68 | case '-1007': 69 | $error = [ 70 | 'code' => '-1007', 71 | 'error' => 'TIMEOUT', 72 | 'message' => 'Timeout waiting for response from backend server. Send status unknown; execution status unknown.', 73 | ]; 74 | break; 75 | case '-1014': 76 | $error = [ 77 | 'code' => '-1014', 78 | 'error' => 'UNKNOWN_ORDER_COMPOSITION', 79 | 'message' => 'Unsupported order combination.', 80 | ]; 81 | break; 82 | case '-1015': 83 | $error = [ 84 | 'code' => '-1015', 85 | 'error' => 'TOO_MANY_ORDERS', 86 | 'message' => 'Too many new orders.', 87 | ]; 88 | break; 89 | case '-1016': 90 | $error = [ 91 | 'code' => '-1016', 92 | 'error' => 'SERVICE_SHUTTING_DOWN', 93 | 'message' => 'This service is no longer available.', 94 | ]; 95 | break; 96 | case '-1020': 97 | $error = [ 98 | 'code' => '-1020', 99 | 'error' => 'UNSUPPORTED_OPERATION', 100 | 'message' => 'This operation is not supported.', 101 | ]; 102 | break; 103 | case '-1021': 104 | $error = [ 105 | 'code' => '-1021', 106 | 'error' => 'INVALID_TIMESTAMP', 107 | 'message' => 'Timestamp for this request is outside of the recvWindow.', 108 | ]; 109 | break; 110 | case '-1022': 111 | $error = [ 112 | 'code' => '-1022', 113 | 'error' => 'INVALID_SIGNATURE', 114 | 'message' => 'Signature for this request is not valid.', 115 | ]; 116 | break; 117 | case '-1099': 118 | $error = [ 119 | 'code' => '-1099', 120 | 'error' => 'NOT_FOUND', 121 | 'message' => 'Not found, authenticated, or authorized.', 122 | ]; 123 | break; 124 | case '-1100': 125 | $error = [ 126 | 'code' => '-1100', 127 | 'error' => 'INVALID_CHARACTERS', 128 | 'message' => 'Illegal characters found in parameter \'orderId\'; legal range is \'^[0-9]{1,20}$\'.', 129 | ]; 130 | break; 131 | case '-1101': 132 | $error = [ 133 | 'code' => '-1101', 134 | 'error' => 'INVALID_REQUEST', 135 | 'message' => 'Too many parameters; expected 1 and received 3.', 136 | ]; 137 | break; 138 | case '-1102': 139 | $error = [ 140 | 'code' => '-1102', 141 | 'error' => 'INVALID_SYMBOL', 142 | 'message' => 'Mandatory parameter symbol was not sent, was empty/null, or malformed.', 143 | ]; 144 | break; 145 | case '-1104': 146 | $error = [ 147 | 'code' => '-1104', 148 | 'error' => 'INVALID_REQUEST', 149 | 'message' => 'Not all sent parameters were read; read 1 parameter(s) but was sent 2.', 150 | ]; 151 | break; 152 | case '-1121': 153 | $error = [ 154 | 'code' => '-1121', 155 | 'error' => 'INVALID_SYMBOL', 156 | 'message' => 'Invalid symbol.', 157 | ]; 158 | break; 159 | case '-2014': 160 | $error = [ 161 | 'code' => '-2014', 162 | 'error' => 'INVALID_API', 163 | 'message' => 'API-key format invalid.', 164 | ]; 165 | break; 166 | } 167 | } else { 168 | // If client error a response status. 169 | if ($response->status() === 403) { 170 | $error = [ 171 | 'code' => '403', 172 | 'error' => 'Forbidden', 173 | 'message' => "You don't have permission to access this resouce.", 174 | ]; 175 | } 176 | } 177 | 178 | return $error; 179 | } 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /src/BinanceAPI.php: -------------------------------------------------------------------------------- 1 | api_key = (!empty($api_key)) ? $api_key : config('binance-api.auth.key'); 40 | $this->api_secret = (!empty($api_secret)) ? $api_secret : config('binance-api.auth.secret'); 41 | $this->api_url = (!empty($api_url)) ? $api_url : config('binance-api.urls.api'); 42 | $this->recvWindow = (!empty($timing)) ? $timing : config('binance-api.settings.timing'); 43 | } 44 | 45 | /** 46 | * API Key and Secret Key setter function. 47 | * It's required for USER_DATA endpoints. 48 | * https://binance-docs.github.io/apidocs/spot/en/#endpoint-security-type. 49 | * 50 | * @param string $key API Key 51 | * @param string $secret API Secret 52 | */ 53 | public function setAPI($api_key, $api_secret) 54 | { 55 | $this->api_key = $api_key; 56 | $this->api_secret = $api_secret; 57 | } 58 | 59 | //------ PUBLIC API CALLS -------- 60 | //---- Security Type : NONE ------ 61 | /* 62 | * getSystemStatus 63 | * getTime 64 | * getExchangeInfo 65 | * getOrderBook 66 | * getAvgPrice 67 | * getTicker 68 | */ 69 | 70 | /** 71 | * Get Binance System Status. 72 | * Uses Sapi Endpoint. 73 | * 74 | * @return mixed 75 | */ 76 | public function getSystemStatus() 77 | { 78 | $this->api_url = config('binance-api.urls.sapi'); 79 | 80 | return $this->publicRequest('v1/system/status'); 81 | } 82 | 83 | /** 84 | * Get Binance Server Time. 85 | * 86 | * @return mixed 87 | */ 88 | public function getTime() 89 | { 90 | return $this->publicRequest('v3/time'); 91 | } 92 | 93 | /** 94 | * Get Binance Exchange Info. 95 | * 96 | * @param string $symbol Exchange Pair Symbol 97 | * 98 | * @return mixed 99 | */ 100 | public function getExchangeInfo($symbol = null) 101 | { 102 | $data = [ 103 | 'symbol' => $symbol ? strtoupper($symbol) : null, 104 | ]; 105 | 106 | return $this->publicRequest('v3/exchangeInfo', $data); 107 | } 108 | 109 | /** 110 | * Get Binance Order Book for a given symbol. 111 | * 112 | * @param string $symbol Exchange Pair Symbol 113 | * 114 | * @return mixed 115 | */ 116 | public function getOrderBook($symbol) 117 | { 118 | $data = [ 119 | 'symbol' => $symbol ? strtoupper($symbol) : null, 120 | ]; 121 | 122 | return $this->publicRequest('v3/trades', $data); 123 | } 124 | 125 | /** 126 | * Get Average Price for a given symbol. 127 | * 128 | * @param string $symbol Exchange Pair Symbol 129 | * 130 | * @return mixed 131 | */ 132 | public function getAvgPrice($symbol = null) 133 | { 134 | $data = [ 135 | 'symbol' => $symbol ? strtoupper($symbol) : null, 136 | ]; 137 | 138 | return $this->publicRequest('v3/avgPrice', $data); 139 | } 140 | 141 | /** 142 | * Get 24hr Ticker Price Change Statistics. 143 | * If the symbol is not sent, tickers for all symbols will 144 | * be returned in an array. 145 | * 146 | * @param string $symbol Exchange Pair Symbol 147 | * 148 | * @return mixed 149 | */ 150 | public function getTicker($symbol = null) 151 | { 152 | $data = [ 153 | 'symbol' => $symbol ? strtoupper($symbol) : null, 154 | ]; 155 | 156 | return $this->publicRequest('v3/ticker/24hr', $data); 157 | } 158 | 159 | //------ PRIVATE API CALLS ---------- 160 | //--- Security Type : USER_DATA ----- 161 | /* 162 | * getAccountInfo 163 | * getAllOrders 164 | * getOpenOrders 165 | * getTrades 166 | * getOrderStatus 167 | * getUserCoinsInfo 168 | * getDepositHistory 169 | * getWithdrawHistory 170 | */ 171 | 172 | /** 173 | * Get current account information. 174 | * 175 | * @throws \Exception 176 | * 177 | * @return mixed 178 | */ 179 | public function getAccountInfo() 180 | { 181 | $response = $this->privateRequest('v3/account'); 182 | 183 | return $response; 184 | } 185 | 186 | /** 187 | * Get all current account orders; active, canceled, or filled. 188 | * 189 | * @param string $symbol Exchange Pair Symbol 190 | * 191 | * @return mixed 192 | */ 193 | public function getAllOrders($symbol = null) 194 | { 195 | $data = [ 196 | 'symbol' => $symbol ? strtoupper($symbol) : null, 197 | ]; 198 | 199 | return $this->privateRequest('v3/allOrders', $data); 200 | } 201 | 202 | /** 203 | * Get all current account open orders on a symbol. 204 | * Careful when accessing this with no symbol. 205 | * 206 | * @param string $symbol Exchange Pair Symbol 207 | * 208 | * @return mixed 209 | */ 210 | public function getOpenOrders($symbol = null) 211 | { 212 | $data = [ 213 | 'symbol' => $symbol ? strtoupper($symbol) : null, 214 | ]; 215 | 216 | return $this->privateRequest('v3/openOrders', $data); 217 | } 218 | 219 | /** 220 | * Get the trade history for a particular symbol. 221 | * 222 | * @param string $symbol Exchange Pair Symbol 223 | * 224 | * @return mixed 225 | */ 226 | public function getTrades($symbol = null) 227 | { 228 | $data = [ 229 | 'symbol' => $symbol ? strtoupper($symbol) : null, 230 | ]; 231 | 232 | return $this->privateRequest('v3/myTrades', $data); 233 | } 234 | 235 | /** 236 | * Get an order's status. 237 | * 238 | * @param string $symbol Exchange Pair Symbol 239 | * @param string $orderId Exchange Order Id 240 | * 241 | * @return mixed 242 | */ 243 | public function getOrderStatus($symbol = null, $orderId = null) 244 | { 245 | $data = [ 246 | 'symbol' => $symbol ? strtoupper($symbol) : null, 247 | 'orderId' => $orderId, 248 | ]; 249 | 250 | return $this->privateRequest('v3/order', $data); 251 | } 252 | 253 | /** 254 | * Get information of coins (available for deposit and withdraw) for the user. 255 | * Uses Sapi Endpoint. 256 | * 257 | * @return mixed 258 | */ 259 | public function getUserCoinsInfo() 260 | { 261 | $this->api_url = config('binance-api.urls.sapi'); 262 | 263 | return $this->privateRequest('v1/capital/config/getall'); 264 | } 265 | 266 | /** 267 | * Get deposit history of the user account. 268 | * Uses Sapi Endpoint. 269 | * 270 | * @return mixed 271 | */ 272 | public function getDepositHistory() 273 | { 274 | $this->api_url = config('binance-api.urls.sapi'); 275 | 276 | return $this->privateRequest('v1/capital/deposit/hisrec'); 277 | } 278 | 279 | /** 280 | * Get withdraw history of the user account. 281 | * Uses Sapi Endpoint. 282 | * 283 | * @return mixed 284 | */ 285 | public function getWithdrawHistory() 286 | { 287 | $this->api_url = config('binance-api.urls.sapi'); 288 | 289 | return $this->privateRequest('v1/capital/withdraw/history'); 290 | } 291 | 292 | /** 293 | * Make public requests (Security Type: NONE). 294 | * 295 | * @param string $url URL Endpoint 296 | * @param array $params Required and optional parameters 297 | * @param string $method GET, POST, PUT, DELETE 298 | * 299 | * @throws \Exception 300 | * 301 | * @return mixed 302 | */ 303 | private function publicRequest($url, $params = [], $method = 'GET') 304 | { 305 | // Build the POST data string 306 | if (!in_array($url, $this->no_time_needed)) { 307 | $params['timestamp'] = $this->milliseconds(); 308 | $params['recvWindow'] = $this->recvWindow; 309 | } 310 | 311 | $url = $this->api_url.$url; 312 | 313 | // Adding parameters to the url. 314 | $url = $url.'?'.http_build_query($params); 315 | 316 | return $this->sendApiRequest($url, $method); 317 | } 318 | 319 | /** 320 | * Make public requests (Security Type: USER_DATA). 321 | * 322 | * @param string $url URL Endpoint 323 | * @param array $params Required and optional parameters. 324 | */ 325 | private function privateRequest($url, $params = [], $method = 'GET') 326 | { 327 | // Build the POST data string 328 | if (!in_array($url, $this->no_time_needed)) { 329 | $params['recvWindow'] = $this->recvWindow; 330 | $params['timestamp'] = $this->milliseconds(); 331 | } 332 | 333 | // Build the query to pass through. 334 | $query = http_build_query($params, '', '&'); 335 | 336 | // Set API key and sign the message 337 | $signature = hash_hmac('sha256', $query, $this->api_secret); 338 | 339 | $url = $this->api_url.$url.'?'.$query.'&signature='.$signature; 340 | 341 | return $this->sendApiRequest($url, $method); 342 | } 343 | 344 | /** 345 | * Send request to Wazirx API for Public or Private Requests. 346 | * 347 | * @param string $url URL Endpoint with Query & Signature 348 | * @param string $method GET, POST, PUT, DELETE 349 | * 350 | * @throws \Exception 351 | * 352 | * @return mixed 353 | */ 354 | private function sendApiRequest($url, $method) 355 | { 356 | try { 357 | if ($method == 'POST') { 358 | $response = Http::withHeaders([ 359 | 'X-MBX-APIKEY' => $this->api_key, 360 | ])->post($url); 361 | } elseif ($method == 'GET') { 362 | $response = Http::withHeaders([ 363 | 'X-MBX-APIKEY' => $this->api_key, 364 | ])->get($url); 365 | } 366 | } catch (ConnectionException $e) { 367 | return $error = [ 368 | 'code' => $e->getCode(), 369 | 'error' => 'Host Not Found', 370 | 'message' => 'Could not resolve host: '.$this->api_url, 371 | ]; 372 | } catch (Exception $e) { 373 | return $error = [ 374 | 'code' => $e->getCode(), 375 | 'error' => 'cUrl Error', 376 | 'message' => $e->getMessage(), 377 | ]; 378 | } 379 | 380 | // If response if Ok. Return collection. 381 | if ($response->ok()) { 382 | return $response->collect(); 383 | } else { 384 | return $this->handleError($response); 385 | } 386 | } 387 | 388 | /** 389 | * Get the milliseconds from the system clock. 390 | * 391 | * @return int 392 | */ 393 | private function milliseconds() 394 | { 395 | list($msec, $sec) = explode(' ', microtime()); 396 | 397 | return $sec.substr($msec, 2, 3); 398 | } 399 | } 400 | --------------------------------------------------------------------------------