Issues (7)

src/WalletAPI.php (7 issues)

Labels
Severity
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * Package: PHP Bitaps API
7
 *
8
 * (c) Eldar Gazaliev <[email protected]>
9
 *
10
 *  Link: <https://github.com/MyZik>
11
 *
12
 * For the full copyright and license information, please view the LICENSE file
13
 * that was distributed with this source code.
14
 */
15
16
namespace Bitaps\WalletAPI;
17
18
use Bitaps\WalletAPI\Exception\BitapsAPIException;
19
use Bitaps\WalletAPI\Request\CreateWalletAddressRequest;
20
use Bitaps\WalletAPI\Request\CreateWalletRequest;
21
use Bitaps\WalletAPI\Request\AddressesRequest;
22
use Bitaps\WalletAPI\Request\AddressTransactionsRequest;
23
use Bitaps\WalletAPI\Request\SendPaymentRequest;
24
use Bitaps\WalletAPI\Request\WalletDailyStatisticsRequest;
25
use Bitaps\WalletAPI\Request\WalletStateRequest;
26
use Bitaps\WalletAPI\Request\WalletTransactionsRequest;
27
use Bitaps\WalletAPI\Response\CreateWallet\CreateWalletResponse;
28
use Bitaps\WalletAPI\Response\Addresses\GetAddressesResponse;
29
use Bitaps\WalletAPI\Response\CreateWalletAddress\CreateWalletAddressResponse;
30
use Bitaps\WalletAPI\Response\AddressTransactions\AddressTransactionsResponse;
31
use Bitaps\WalletAPI\Response\SendPayment\SendPaymentResponse;
32
use Bitaps\WalletAPI\Response\WalletDailyStatistics\WalletDailyStatisticsResponse;
33
use Bitaps\WalletAPI\Response\WalletState\WalletStateResponse;
34
use Symfony\Component\HttpClient\HttpClient;
35
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
36
use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface;
37
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
38
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
39
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
40
41
class WalletAPI
42
{
43
    /**
44
     * @var string
45
     */
46
    private string $endpoint;
47
48
    /**
49
     * @var string|null
50
     */
51
    private ?string $walletId;
52
53
    /**
54
     * @var string|null
55
     */
56
    private ?string $password;
57
58
    /**
59
     * Receivers list for sendPayment method
60
     *
61
     * @var array
62
     */
63
    private array $receiversList;
64
65
    /**
66
     * @param string      $endpoint
67
     * @param string|null $walletId
68
     * @param string|null $password
69
     */
70
    public function __construct(string $endpoint, string $walletId = null, string $password = null)
71
    {
72
        $this->endpoint = $endpoint;
73
        $this->walletId = $walletId;
74
        $this->password = $password;
75
    }
76
77
    /**
78
     * @param string $path
79
     * @param string $method
80
     * @param array  $headers
81
     * @param array  $body
82
     *
83
     * @return string
84
     * @throws BitapsAPIException
85
     * @throws ClientExceptionInterface
86
     * @throws DecodingExceptionInterface
87
     * @throws RedirectionExceptionInterface
88
     * @throws ServerExceptionInterface
89
     * @throws TransportExceptionInterface
90
     */
91
    private function call(string $path, string $method, array $headers = [], array $body = []): string
92
    {
93
        $client   = HttpClient::create();
94
        $fullPath = sprintf('%s%s', $this->endpoint, $path);
95
96
        $options = [];
97
98
        if (!empty($headers)) {
99
            $options['headers'] = $headers;
100
        }
101
102
        if (!empty($body)) {
103
            $options['json'] = $body;
104
        }
105
106
        $request  = $client->request($method, $fullPath, $options);
107
        $response = $request->toArray(false);
108
109
        if (isset($response['error_code'])) {
110
            throw new BitapsAPIException(sprintf('Got an error response with message: %s.', $response['message']));
111
        }
112
113
        return $request->getContent();
114
    }
115
116
    /**
117
     * @return array
118
     */
119
    private function getAccess(): array
120
    {
121
        $nonce     = round(microtime(true) * 1000);
122
        $key       = hash('sha256', hash('sha256', $this->walletId . $this->password, true), true);
123
        $msg       = $this->walletId . $nonce;
124
        $signature = hash_hmac('sha256', $msg, $key);
125
126
        return [$nonce, $signature];
127
    }
128
129
    /**
130
     * @param string|null $callbackLink
131
     * @param string|null $password
132
     *
133
     * @return CreateWalletResponse
134
     * @throws BitapsAPIException
135
     * @throws ClientExceptionInterface
136
     * @throws DecodingExceptionInterface
137
     * @throws RedirectionExceptionInterface
138
     * @throws ServerExceptionInterface
139
     * @throws TransportExceptionInterface
140
     * @throws \JsonException
141
     */
142
    public function createWallet(string $callbackLink = null, string $password = null): CreateWalletResponse
143
    {
144
        $request = new CreateWalletRequest($callbackLink, $password);
145
146
        $response = $this->call($request->getPathParams(), 'POST', $request->getHeaders(), $request->getBody());
147
148
        return CreateWalletResponse::fromJson($response);
149
    }
150
151
    /**
152
     * @param string|null $callbackLink
153
     * @param int         $confirmations
154
     *
155
     * @return CreateWalletAddressResponse
156
     * @throws BitapsAPIException
157
     * @throws ClientExceptionInterface
158
     * @throws DecodingExceptionInterface
159
     * @throws RedirectionExceptionInterface
160
     * @throws ServerExceptionInterface
161
     * @throws TransportExceptionInterface
162
     * @throws \JsonException
163
     */
164
    public function addAddress(string $callbackLink = null, int $confirmations = 3): CreateWalletAddressResponse
165
    {
166
        $request = new CreateWalletAddressRequest($this->walletId, $callbackLink, $confirmations);
0 ignored issues
show
It seems like $this->walletId can also be of type null; however, parameter $walletId of Bitaps\WalletAPI\Request...sRequest::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

166
        $request = new CreateWalletAddressRequest(/** @scrutinizer ignore-type */ $this->walletId, $callbackLink, $confirmations);
Loading history...
167
168
        $response = $this->call($request->getPathParams(), 'POST', $request->getHeaders(), $request->getBody());
169
170
        return CreateWalletAddressResponse::fromJson($response);
171
    }
172
173
    /**
174
     * @param string $address
175
     * @param int    $amount
176
     *
177
     * @return $this
178
     */
179
    public function &addPayment(string $address, int $amount): WalletAPI
180
    {
181
        $this->receiversList[] = [
182
            'address' => $address,
183
            'amount' => $amount
184
        ];
185
186
        return $this;
187
    }
188
189
    /**
190
     * @return SendPaymentResponse
191
     * @throws BitapsAPIException
192
     * @throws ClientExceptionInterface
193
     * @throws DecodingExceptionInterface
194
     * @throws RedirectionExceptionInterface
195
     * @throws ServerExceptionInterface
196
     * @throws TransportExceptionInterface
197
     * @throws \JsonException
198
     */
199
    public function pay(): SendPaymentResponse
200
    {
201
        [$nonce, $signature] = $this->getAccess();
202
        $request = new SendPaymentRequest($this->walletId, $this->receiversList, $nonce, $signature);
0 ignored issues
show
It seems like $this->walletId can also be of type null; however, parameter $walletId of Bitaps\WalletAPI\Request...tRequest::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

202
        $request = new SendPaymentRequest(/** @scrutinizer ignore-type */ $this->walletId, $this->receiversList, $nonce, $signature);
Loading history...
203
204
        $response = $this->call($request->getPathParams(), 'POST', $request->getHeaders(), $request->getBody());
205
206
        return SendPaymentResponse::fromJson($response);
207
    }
208
209
    /**
210
     * @return WalletStateResponse
211
     *
212
     * @throws BitapsAPIException
213
     * @throws ClientExceptionInterface
214
     * @throws DecodingExceptionInterface
215
     * @throws RedirectionExceptionInterface
216
     * @throws ServerExceptionInterface
217
     * @throws TransportExceptionInterface
218
     * @throws \JsonException
219
     */
220
    public function getWalletState(): WalletStateResponse
221
    {
222
        [$nonce, $signature] = $this->getAccess();
223
        $request = new WalletStateRequest($this->walletId, $nonce, $signature);
0 ignored issues
show
It seems like $this->walletId can also be of type null; however, parameter $walletId of Bitaps\WalletAPI\Request...eRequest::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

223
        $request = new WalletStateRequest(/** @scrutinizer ignore-type */ $this->walletId, $nonce, $signature);
Loading history...
224
225
        $response = $this->call($request->getPathParams(), 'GET', $request->getHeaders(), $request->getBody());
226
227
        return WalletStateResponse::fromJson($response);
228
    }
229
230
    /**
231
     * @param int|null $from
232
     * @param int|null $to
233
     * @param int|null $limit
234
     * @param int|null $page
235
     *
236
     * @return AddressTransactionsResponse
237
     * @throws BitapsAPIException
238
     * @throws ClientExceptionInterface
239
     * @throws DecodingExceptionInterface
240
     * @throws RedirectionExceptionInterface
241
     * @throws ServerExceptionInterface
242
     * @throws TransportExceptionInterface
243
     * @throws \JsonException
244
     */
245
    public function getTransactions(
246
        int $from = null,
247
        int $to = null,
248
        int $limit = null,
249
        int $page = null
250
    ): AddressTransactionsResponse {
251
        [$nonce, $signature] = $this->getAccess();
252
        $request = new WalletTransactionsRequest($this->walletId, $nonce, $signature, $from, $to, $limit, $page);
0 ignored issues
show
It seems like $this->walletId can also be of type null; however, parameter $walletId of Bitaps\WalletAPI\Request...sRequest::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

252
        $request = new WalletTransactionsRequest(/** @scrutinizer ignore-type */ $this->walletId, $nonce, $signature, $from, $to, $limit, $page);
Loading history...
253
254
        $response = $this->call($request->getPathParams(), 'GET', $request->getHeaders(), $request->getBody());
255
256
        return AddressTransactionsResponse::fromJson($response);
257
    }
258
259
    /**
260
     * @param int|null $from
261
     * @param int|null $to
262
     * @param int|null $limit
263
     * @param int|null $page
264
     *
265
     * @return GetAddressesResponse
266
     * @throws BitapsAPIException
267
     * @throws ClientExceptionInterface
268
     * @throws DecodingExceptionInterface
269
     * @throws RedirectionExceptionInterface
270
     * @throws ServerExceptionInterface
271
     * @throws TransportExceptionInterface
272
     * @throws \JsonException
273
     */
274
    public function getAddresses(
275
        int $from = null,
276
        int $to = null,
277
        int $limit = null,
278
        int $page = null
279
    ): GetAddressesResponse {
280
        [$nonce, $signature] = $this->getAccess();
281
        $request = new AddressesRequest($this->walletId, $nonce, $signature, $from, $to, $limit, $page);
0 ignored issues
show
It seems like $this->walletId can also be of type null; however, parameter $walletId of Bitaps\WalletAPI\Request...sRequest::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

281
        $request = new AddressesRequest(/** @scrutinizer ignore-type */ $this->walletId, $nonce, $signature, $from, $to, $limit, $page);
Loading history...
282
283
        $response = $this->call($request->getPathParams(), 'GET', $request->getHeaders(), $request->getBody());
284
285
        return GetAddressesResponse::fromJson($response);
286
    }
287
288
    /**
289
     * @param string   $address
290
     * @param int|null $from
291
     * @param int|null $to
292
     * @param int|null $limit
293
     * @param int|null $page
294
     *
295
     * @return AddressTransactionsResponse
296
     * @throws BitapsAPIException
297
     * @throws ClientExceptionInterface
298
     * @throws DecodingExceptionInterface
299
     * @throws RedirectionExceptionInterface
300
     * @throws ServerExceptionInterface
301
     * @throws TransportExceptionInterface
302
     * @throws \JsonException
303
     */
304
    public function getAddressTransactions(
305
        string $address,
306
        int $from = null,
307
        int $to = null,
308
        int $limit = null,
309
        int $page = null
310
    ): AddressTransactionsResponse {
311
        [$nonce, $signature] = $this->getAccess();
312
        $request = new AddressTransactionsRequest(
313
            $this->walletId,
0 ignored issues
show
It seems like $this->walletId can also be of type null; however, parameter $walletId of Bitaps\WalletAPI\Request...sRequest::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

313
            /** @scrutinizer ignore-type */ $this->walletId,
Loading history...
314
            $address,
315
            $nonce,
316
            $signature,
317
            $from,
318
            $to,
319
            $limit,
320
            $page
321
        );
322
323
        $response = $this->call($request->getPathParams(), 'GET', $request->getHeaders(), $request->getBody());
324
325
        return AddressTransactionsResponse::fromJson($response);
326
    }
327
328
    /**
329
     * @param int|null $from
330
     * @param int|null $to
331
     * @param int|null $limit
332
     * @param int|null $page
333
     *
334
     * @return WalletDailyStatisticsResponse
335
     * @throws BitapsAPIException
336
     * @throws ClientExceptionInterface
337
     * @throws DecodingExceptionInterface
338
     * @throws RedirectionExceptionInterface
339
     * @throws ServerExceptionInterface
340
     * @throws TransportExceptionInterface
341
     */
342
    public function getDailyStatistics(
343
        int $from = null,
344
        int $to = null,
345
        int $limit = null,
346
        int $page = null
347
    ): WalletDailyStatisticsResponse {
348
        [$nonce, $signature] = $this->getAccess();
349
        $request = new WalletDailyStatisticsRequest($this->walletId, $nonce, $signature, $from, $to, $limit, $page);
0 ignored issues
show
It seems like $this->walletId can also be of type null; however, parameter $walletId of Bitaps\WalletAPI\Request...sRequest::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

349
        $request = new WalletDailyStatisticsRequest(/** @scrutinizer ignore-type */ $this->walletId, $nonce, $signature, $from, $to, $limit, $page);
Loading history...
350
351
        $response = $this->call($request->getPathParams(), 'GET', $request->getHeaders(), $request->getBody());
352
353
        return WalletDailyStatisticsResponse::fromJson($response);
354
    }
355
}
356