├── src ├── Poloniex.php ├── PoloniexServiceProvider.php ├── ClientContract.php ├── PoloniexManager.php └── Client.php ├── composer.json ├── config └── poloniex.php ├── LICENSE.md └── README.md /src/Poloniex.php: -------------------------------------------------------------------------------- 1 | =7.0.0", 15 | "ext-curl": "*", 16 | "laravel/framework": ">=5.3" 17 | }, 18 | "autoload": { 19 | "psr-4": { 20 | "Htunlogic\\Poloniex\\": "src/" 21 | } 22 | }, 23 | "minimum-stability": "dev" 24 | } 25 | -------------------------------------------------------------------------------- /src/PoloniexServiceProvider.php: -------------------------------------------------------------------------------- 1 | publishes([ 16 | __DIR__.'/../config/poloniex.php' => config_path('poloniex.php') 17 | ], 'config'); 18 | } 19 | 20 | /** 21 | * Register the application services. 22 | * 23 | * @return void 24 | */ 25 | public function register() 26 | { 27 | $this->app->singleton('poloniex', function () { 28 | return new PoloniexManager; 29 | }); 30 | } 31 | } -------------------------------------------------------------------------------- /config/poloniex.php: -------------------------------------------------------------------------------- 1 | [ 14 | 'key' => env('POLONIEX_KEY', ''), 15 | 'secret' => env('POLONIEX_SECRET', ''), 16 | ], 17 | 18 | /* 19 | |-------------------------------------------------------------------------- 20 | | Api URLS 21 | |-------------------------------------------------------------------------- 22 | | 23 | | Urls for Poloniex public and trading API 24 | | 25 | */ 26 | 27 | 'urls' => [ 28 | 'trading' => 'https://poloniex.com/tradingApi', 29 | 'public' => 'https://poloniex.com/public', 30 | ], 31 | 32 | ]; -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) Tibor Hudik 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 | -------------------------------------------------------------------------------- /src/ClientContract.php: -------------------------------------------------------------------------------- 1 | [ 9 | 10 | Htunlogic\Poloniex\PoloniexServiceProvider::class, 11 | 12 | ], 13 | ``` 14 | 15 | ...run `php artisan vendor:publish` to copy the config file. 16 | 17 | Edit the `config/poloniex.php` or add Poloniex api and secret in your `.env` file 18 | 19 | ``` 20 | POLONIEX_KEY={YOUR_API_KEY} 21 | POLONIEX_SECRET={YOUR_API_SECRET} 22 | 23 | ``` 24 | 25 | Optionally you can add alias to your `config/app.php`: 26 | 27 | ``` 28 | 'aliases' => [ 29 | 30 | 'Poloniex' => Htunlogic\Poloniex\Poloniex::class, 31 | 32 | ], 33 | ``` 34 | 35 | Usage examples: 36 | ``` 37 | use Htunlogic\Poloniex\Poloniex; 38 | ``` 39 | ``` 40 | Poloniex::getBalanceFor('BTC'); 41 | Poloniex::getOpenOrders('BTC_XMR'); 42 | Poloniex::getMyTradeHistory('BTC_XMR'); 43 | Poloniex::buy('BTC_XMR', 0.013, 1, 'postOnly'); 44 | Poloniex::sell('BTC_XMR', 0.013, 1, 'postOnly'); 45 | Poloniex::cancelOrder('BTC_XMR', 123); 46 | Poloniex::withdraw('BTC', 1, '14PJdqimDkCqWCH1oXy4sVV6nwweqXYDjt'); 47 | Poloniex::getTradeHistory('BTC_XMR'); 48 | Poloniex::getOrderBook('BTC_XMR'); 49 | Poloniex::getVolumeFor('BTC_XMR'); 50 | Poloniex::getTradingPairs(); 51 | Poloniex::getTicker("BTC_XMR"); 52 | Poloniex::getBalances(); 53 | Poloniex::getVolume(); 54 | Poloniex::getTickers(); 55 | ``` 56 | -------------------------------------------------------------------------------- /src/PoloniexManager.php: -------------------------------------------------------------------------------- 1 | with( 17 | config('poloniex.auth') 18 | ); 19 | } 20 | 21 | /** 22 | * Package version. 23 | * 24 | * @return string 25 | */ 26 | public function version() 27 | { 28 | return '1.1'; 29 | } 30 | 31 | /** 32 | * Load the custom Client interface. 33 | * 34 | * @param ClientContract $client 35 | * @return $this 36 | */ 37 | public function withCustomClient(ClientContract $client) 38 | { 39 | $this->client = $client; 40 | 41 | return $this; 42 | } 43 | 44 | /** 45 | * Create new client instance with given credentials. 46 | * 47 | * @param array $auth 48 | * @param array $urls 49 | * @return $this 50 | */ 51 | public function with(array $auth, array $urls = null) 52 | { 53 | $urls = $urls ?: config('poloniex.urls'); 54 | 55 | $this->client = new Client($auth, $urls); 56 | 57 | return $this; 58 | } 59 | 60 | /** 61 | * Dynamically call methods on the client. 62 | * 63 | * @param $method 64 | * @param $parameters 65 | * @return mixed 66 | */ 67 | public function __call($method, $parameters) 68 | { 69 | if (! method_exists($this->client, $method)) { 70 | abort(500, "Method $method does not exist"); 71 | } 72 | 73 | return call_user_func_array([$this->client, $method], $parameters); 74 | } 75 | } -------------------------------------------------------------------------------- /src/Client.php: -------------------------------------------------------------------------------- 1 | tradingUrl = array_get($urls, 'trading'); 35 | $this->publicUrl = array_get($urls, 'public'); 36 | 37 | $this->key = array_get($auth, 'key'); 38 | $this->secret = array_get($auth, 'secret'); 39 | } 40 | 41 | /** 42 | * Get my balances. 43 | * 44 | * @return float 45 | */ 46 | public function getBalanceFor($currency) 47 | { 48 | return array_get( 49 | $this->getBalances(), strtoupper($currency) 50 | ); 51 | } 52 | 53 | /** 54 | * Get my open orders. 55 | * 56 | * @param string $pair 57 | * @return array 58 | */ 59 | public function getOpenOrders($pair) 60 | { 61 | return $this->trading([ 62 | 'command' => 'returnOpenOrders', 63 | 'currencyPair' => strtoupper($pair) 64 | ]); 65 | } 66 | 67 | /** 68 | * Get my trade history. 69 | * 70 | * @param string $pair 71 | * @return mixed 72 | */ 73 | public function getMyTradeHistory($pair) 74 | { 75 | return $this->trading([ 76 | 'command' => 'returnTradeHistory', 77 | 'currencyPair' => strtoupper($pair) 78 | ]); 79 | } 80 | 81 | /** 82 | * Buy pair at rate. 83 | * 84 | * @param string $pair 85 | * @param float $rate 86 | * @param float $amount 87 | * @param string|null $type 88 | * @return array 89 | */ 90 | public function buy($pair, $rate, $amount, $type = null) 91 | { 92 | return $this->buyOrSell('buy', $pair, $rate, $amount, $type); 93 | } 94 | 95 | /** 96 | * Sell pair at rate. 97 | * 98 | * @param string $pair 99 | * @param float $rate 100 | * @param float $amount 101 | * @param string|null $type 102 | * @return array 103 | */ 104 | public function sell($pair, $rate, $amount, $type = null) 105 | { 106 | return $this->buyOrSell('sell', $pair, $rate, $amount, $type); 107 | } 108 | 109 | /** 110 | * Cancel order on a pair by its id. 111 | * 112 | * @param string $pair 113 | * @param int $id 114 | * @return mixed 115 | */ 116 | public function cancelOrder($pair, $id) 117 | { 118 | return $this->trading([ 119 | 'command' => 'cancelOrder', 120 | 'currencyPair' => strtoupper($pair), 121 | 'orderNumber' => $id 122 | ]); 123 | } 124 | 125 | /** 126 | * Withdraw the currency amount to address. 127 | * 128 | * @param string $currency 129 | * @param string $amount 130 | * @param string $address 131 | * @return mixed 132 | */ 133 | public function withdraw($currency, $amount, $address) 134 | { 135 | return $this->trading([ 136 | 'command' => 'withdraw', 137 | 'currency' => strtoupper($currency), 138 | 'amount' => $amount, 139 | 'address' => $address 140 | ]); 141 | } 142 | 143 | /** 144 | * Trade history for given currency pair. 145 | * 146 | * @param string $pair 147 | * @param string|null $start 148 | * @param string|null $end 149 | * @param string|null $period 150 | * @return array 151 | */ 152 | public function getTradeHistory($pair, $start = null, $end = null, $period = null) 153 | { 154 | return $this->public(array_merge([ 155 | 'command' => 'returnTradeHistory', 156 | 'currencyPair' => strtoupper($pair), 157 | 'period' => $period 158 | ], $this->formatDates($start, $end))); 159 | } 160 | 161 | /** 162 | * Order book for given currency pair. 163 | * 164 | * @param string $pair 165 | * @param int $depth 166 | * @return array 167 | */ 168 | public function getOrderBook($pair, $depth = 10) 169 | { 170 | return $this->public([ 171 | 'command' => 'returnOrderBook', 172 | 'currencyPair' => strtoupper($pair), 173 | 'depth' => $depth 174 | ]); 175 | } 176 | 177 | /** 178 | * Returns the trading volume. 179 | * 180 | * @param string $pair 181 | * @return array|null 182 | */ 183 | public function getVolumeFor($pair) 184 | { 185 | $pair = strtoupper($pair); 186 | 187 | return array_get($this->getVolume(), $pair); 188 | } 189 | 190 | /** 191 | * Get trading pairs. 192 | * 193 | * @return array 194 | */ 195 | public function getTradingPairs() 196 | { 197 | return array_keys($this->public([ 198 | 'command' => 'returnTicker' 199 | ])); 200 | } 201 | 202 | /** 203 | * Get trading pairs. 204 | * 205 | * @param string $pair 206 | * @return array|null 207 | */ 208 | public function getTicker($pair) 209 | { 210 | $pair = strtoupper($pair); 211 | 212 | return array_get($this->getTickers(), $pair); 213 | } 214 | 215 | /** 216 | * @inheritdoc 217 | */ 218 | public function getBalances() 219 | { 220 | return array_map(function ($balance) { 221 | return (float) $balance; 222 | }, $this->trading([ 223 | 'command' => 'returnBalances' 224 | ])); 225 | } 226 | 227 | /** 228 | * @inheritdoc 229 | */ 230 | public function getVolume() 231 | { 232 | return $this->public([ 233 | 'command' => 'return24hVolume' 234 | ]); 235 | } 236 | 237 | /** 238 | * @inheritdoc 239 | */ 240 | public function getTickers() 241 | { 242 | return $this->public([ 243 | 'command' => 'returnTicker' 244 | ]); 245 | } 246 | 247 | /** 248 | * @inheritdoc 249 | */ 250 | public function buyOrSell($command, $pair, $rate, $amount, $type = null) 251 | { 252 | $parameters = [ 253 | 'command' => $command, 254 | 'currencyPair' => strtoupper($pair), 255 | 'rate' => $rate, 256 | 'amount' => $amount 257 | ]; 258 | 259 | if ($type == 'fillOrKill') { 260 | $parameters['fillOrKill'] = 1; 261 | } 262 | else if ($type == 'immediateOrCancel') { 263 | $parameters['immediateOrCancel'] = 1; 264 | } 265 | else if ($type == 'postOnly') { 266 | $parameters['postOnly'] = 1; 267 | } 268 | 269 | return $this->trading($parameters); 270 | } 271 | 272 | /** 273 | * @inheritdoc 274 | */ 275 | public function formatDates($start = null, $end = null) 276 | { 277 | if (is_object($start) && property_exists($start, 'timestamp')) { 278 | $start = $start->timestamp; 279 | } 280 | else if (! is_numeric($start) && ! is_null($start)) { 281 | $start = strtotime($start); 282 | } 283 | 284 | if (is_object($end) && property_exists($end, 'timestamp')) { 285 | $end = $end->timestamp; 286 | } 287 | else if (! is_numeric($end) && ! is_null($end)) { 288 | $end = strtotime($end); 289 | } 290 | 291 | return [ 292 | 'start' => $start, 293 | 'end' => $end 294 | ]; 295 | } 296 | 297 | /** 298 | * @inheritdoc 299 | */ 300 | public function public(array $parameters) 301 | { 302 | $options = [ 303 | 'http' => [ 304 | 'method' => 'GET', 305 | 'timeout' => 10 306 | ] 307 | ]; 308 | 309 | $url = $this->publicUrl . '?' . http_build_query(array_filter($parameters)); 310 | 311 | $feed = file_get_contents( 312 | $url, false, stream_context_create($options) 313 | ); 314 | 315 | return json_decode($feed, true); 316 | } 317 | 318 | /** 319 | * @inheritdoc 320 | */ 321 | public function trading(array $parameters = []) 322 | { 323 | $mt = (string) microtime(true); 324 | $parameters['nonce'] = intval(substr(str_replace('.', '', $mt), 0, 13)); 325 | 326 | $post = http_build_query(array_filter($parameters), '', '&'); 327 | $sign = hash_hmac('sha512', $post, $this->secret); 328 | 329 | $headers = [ 330 | 'Key: '.$this->key, 331 | 'Sign: '.$sign, 332 | ]; 333 | 334 | static $ch = null; 335 | 336 | if (is_null($ch)) { 337 | $ch = curl_init(); 338 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 339 | curl_setopt($ch, CURLOPT_USERAGENT, 340 | 'Mozilla/4.0 (compatible; Poloniex PHP-Laravel Client; '.php_uname('a').'; PHP/'.phpversion().')' 341 | ); 342 | } 343 | 344 | curl_setopt($ch, CURLOPT_URL, $this->tradingUrl); 345 | curl_setopt($ch, CURLOPT_POSTFIELDS, $post); 346 | curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); 347 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 348 | 349 | $response = curl_exec($ch); 350 | 351 | if ($response === false) { 352 | throw new Exception('Curl error: '.curl_error($ch)); 353 | } 354 | 355 | return json_decode($response, true); 356 | } 357 | } --------------------------------------------------------------------------------