├── LICENSE
├── README.md
├── composer.json
└── src
└── Minter
├── Contracts
└── MinterTxInterface.php
├── Library
├── ECDSA.php
├── Helper.php
└── Http.php
├── MinterAPI.php
└── SDK
├── MinterCheck.php
├── MinterCoins
├── MinterAddLimitOrderTx.php
├── MinterAddLiquidityTx.php
├── MinterBurnTokenTx.php
├── MinterBuyCoinTx.php
├── MinterBuySwapPoolTx.php
├── MinterCoinTx.php
├── MinterCreateCoinTx.php
├── MinterCreateMultisigTx.php
├── MinterCreateSwapPoolTx.php
├── MinterCreateTokenTx.php
├── MinterDeclareCandidacyTx.php
├── MinterDelegateTx.php
├── MinterEditCandidateCommissionTx.php
├── MinterEditCandidatePublicKeyTx.php
├── MinterEditCandidateTx.php
├── MinterEditCoinOwnerTx.php
├── MinterEditMultisigTx.php
├── MinterLockStakeTx.php
├── MinterLockTx.php
├── MinterMintTokenTx.php
├── MinterMoveStakeTx.php
├── MinterMultiSendTx.php
├── MinterPriceCommissionTx.php
├── MinterRecreateCoinTx.php
├── MinterRecreateTokenTx.php
├── MinterRedeemCheckTx.php
├── MinterRemoveLimitOrderTx.php
├── MinterRemoveLiquidityTx.php
├── MinterSellAllCoinTx.php
├── MinterSellAllSwapPoolTx.php
├── MinterSellCoinTx.php
├── MinterSellSwapPoolTx.php
├── MinterSendCoinTx.php
├── MinterSetCandidateOffTx.php
├── MinterSetCandidateOnTx.php
├── MinterSetHaltBlockTx.php
├── MinterUnbondTx.php
└── MinterVoteUpdateTx.php
├── MinterConverter.php
├── MinterDeepLink.php
├── MinterPrefix.php
├── MinterReward.php
├── MinterSignature.php
├── MinterTx.php
├── MinterTxSigner.php
└── MinterWallet.php
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2018, Respective Authors all rights reserved.
2 |
3 | The MIT License
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 |

2 |
3 | ## About
4 |
5 | This is a pure PHP SDK for working with Minter blockchain
6 |
7 | * [Installation](#installing)
8 | * [Minter Api](#using-minterapi)
9 | - Methods:
10 | - [getBalance](#getbalance)
11 | - [getNonce](#getnonce)
12 | - [send](#send)
13 | - [getAddresses](#getaddresses)
14 | - [getStatus](#getstatus)
15 | - [getValidators](#getvalidators)
16 | - [estimateCoinBuy](#estimatecoinbuy)
17 | - [estimateCoinSell](#estimatecoinsell)
18 | - [estimateCoinSellAll](#estimatecoinsellall)
19 | - [getCoinInfo](#getcoininfo)
20 | - [getBlock](#getblock)
21 | - [getEvents](#getevents)
22 | - [getTransaction](#gettransaction)
23 | - [getCandidate](#getcandidate)
24 | - [getCandidates](#getcandidates)
25 | - [estimateTxCommission](#estimatetxcommission)
26 | - [getTransactions](#gettransactions)
27 | - [getUnconfirmedTxs](#getunconfirmedtxs)
28 | - [getMaxGasPrice](#getmaxgasprice)
29 | - [getMinGasPrice](#getmingasprice)
30 | - [getMissedBlocks](#getmissedblocks)
31 | - [getWaitlist](#getwaitlist)
32 | - [getPriceCommissions](#getPriceCommissions)
33 | - [getPriceVotes](#getPriceVotes)
34 | - [getSwapPool](#getSwapPool)
35 | - [getSwapPoolProvider](#getSwapPoolProvider)
36 | - [getLimitOrder](#getLimitOrder)
37 | - [getLimitOrders](#getLimitOrders)
38 | - [getLimitOrdersByCoins](#getLimitOrdersByCoins)
39 | - [Error handling](#error-handling)
40 |
41 | * [Minter SDK](#using-mintersdk)
42 | - [Sign transaction](#sign-transaction)
43 | - [SendCoin](#example-3)
44 | - [SellCoin](#example-4)
45 | - [SellAllCoin](#example-5)
46 | - [BuyCoin](#example-6)
47 | - [CreateCoin](#example-7)
48 | - [DeclareCandidacy](#example-8)
49 | - [Delegate](#example-9)
50 | - [SetCandidateOn](#example-10)
51 | - [SetCandidateOff](#example-11)
52 | - [RedeemCheck](#example-12)
53 | - [Unbond](#example-13)
54 | - [MultiSend](#example-14)
55 | - [EditCandidate](#example-15)
56 | - [CreateMultisig](#example-16)
57 | - [SetHaltBlock](#example-17)
58 | - [RecreateCoin](#example-18)
59 | - [EditCoinOwner](#example-19)
60 | - [EditMultisig](#example-20)
61 | - [EditCandidatePublicKey](#example-21)
62 | - [AddLiquidity](#example-22)
63 | - [RemoveLiquidity](#example-23)
64 | - [SellSwapPool](#example-24)
65 | - [BuySwapPool](#example-25)
66 | - [SellAllSwapPool](#example-26)
67 | - [EditCandidateCommission](#example-27)
68 | - [MintToken](#example-28)
69 | - [BurnToken](#example-29)
70 | - [CreateToken](#example-30)
71 | - [RecreateToken](#example-31)
72 | - [PriceCommission](#example-32)
73 | - [CreateSwapPool](#example-33)
74 | - [AddLimitOrder](#example-34)
75 | - [RemoveLimitOrder](#example-35)
76 | - [Sign transaction with multisignatures](#sign-transaction-with-multisignatures)
77 | - [Get fee of transaction](#get-fee-of-transaction)
78 | - [Decode Transaction](#decode-transaction)
79 | - [Minter Check](#create-minter-check)
80 | - [Minter Wallet](#minter-wallet)
81 | - [Minter Link](#minter-link)
82 | * [Tests](#tests)
83 |
84 | ## Installing
85 |
86 | ```bash
87 | composer require minter/minter-php-sdk
88 | ```
89 |
90 | ## Using MinterAPI
91 |
92 | You can get all valid responses and full documentation at [Minter Node Api](https://docs.minter.network/)
93 |
94 | Create MinterAPI instance
95 |
96 | ```php
97 | use Minter\MinterAPI;
98 |
99 | $nodeUrl = 'https://minter-node-1.testnet.minter.network:8843/v2/'; // example of a node url
100 |
101 | $api = new MinterAPI($nodeUrl);
102 | ```
103 |
104 | ### getBalance
105 |
106 | Returns coins list, balance and transaction count (for nonce) of an address.
107 |
108 | ``
109 | getBalance(string $minterAddress, ?int $height = null): \stdClass
110 | ``
111 |
112 | ###### Example
113 |
114 | ```php
115 | $api->getBalance('Mxfe60014a6e9ac91618f5d1cab3fd58cded61ee99')
116 |
117 | // {"jsonrpc": "2.0", "id": "", "result": { "balance": { ... }, "transaction_count": "0"}}
118 |
119 | ```
120 |
121 | ### getNonce
122 |
123 | Returns next transaction number (nonce) of an address.
124 |
125 | ``
126 | getNonce(string $minterAddress): int
127 | ``
128 |
129 | ###### Example
130 |
131 | ```php
132 | $api->getNonce('Mxfe60014a6e9ac91618f5d1cab3fd58cded61ee99')
133 | ```
134 |
135 | ### send
136 |
137 | Returns the result of sending signed tx.
138 |
139 | :warning: To ensure that transaction was successfully committed to the blockchain, you need to find the transaction by the hash and ensure that the status code equals to 0.
140 |
141 | ``
142 | send(string $tx): \stdClass
143 | ``
144 |
145 | ###### Example
146 |
147 | ```php
148 | $api->send('f873010101aae98a4d4e540000000000000094fe60014a6e9ac91618f5d1cab3fd58cded61ee99880de0b6b3a764000080801ca0ae0ee912484b9bf3bee785f4cbac118793799450e0de754667e2c18faa510301a04f1e4ed5fad4b489a1065dc1f5255b356ab9a2ce4b24dde35bcb9dc43aba019c')
149 | ```
150 |
151 | ### getAddresses
152 |
153 | Returns addresses balances.
154 |
155 | ``
156 | getAddresses(array $addresses, ?int $height = null): \stdClass
157 | ``
158 |
159 | ### getStatus
160 |
161 | Returns node status info.
162 |
163 | ``
164 | getStatus(): \stdClass
165 | ``
166 |
167 | ### getValidators
168 |
169 | Returns list of active validators.
170 |
171 | ``
172 | getValidators(?int $height = null, ?int $page = 1, ?int $perPage = null): \stdClass
173 | ``
174 |
175 | ### estimateCoinBuy
176 |
177 | Return estimate of buy coin transaction.
178 |
179 | ``
180 | estimateCoinBuy(string $coinToSell, string $valueToBuy, string $coinToBuy, ?int $height = null, string $swapFrom): \stdClass
181 | ``
182 |
183 | ### estimateCoinSell
184 |
185 | Return estimate of sell coin transaction.
186 |
187 | ``
188 | estimateCoinSell(string $coinToSell, string $valueToSell, string $coinToBuy, ?int $height = null, string $swapFrom): \stdClass
189 | ``
190 |
191 | ### estimateCoinSellAll
192 |
193 | Return estimate of sell coin all transaction.
194 |
195 | ``
196 | estimateCoinSellAll(string $coinToSell, string $valueToSell, string $coinToBuy, ?int $height = null, string $swapFrom): \stdClass
197 | ``
198 |
199 | ### getCoinInfo
200 |
201 | Returns information about coin.
202 | Note: this method does not return information about base coins (MNT and BIP).
203 |
204 | ``
205 | getCoinInfo(string $coin, ?int $height = null): \stdClass
206 | ``
207 |
208 | ### getBlock
209 |
210 | Returns block data at given height.
211 |
212 | ``
213 | getBlock(int $height): \stdClass
214 | ``
215 |
216 | ### getEvents
217 |
218 | Returns events at given height.
219 |
220 | ``
221 | getEvents(int $height): \stdClass
222 | ``
223 |
224 | ### getTransaction
225 |
226 | Returns transaction info.
227 |
228 | ``
229 | getTransaction(string $hash): \stdClass
230 | ``
231 |
232 | ### getCandidate
233 |
234 | Returns candidate’s info by provided public_key. It will respond with 404 code if candidate is not found.
235 |
236 | ``
237 | getCandidate(string $publicKey, ?int $height = null): \stdClass
238 | ``
239 |
240 | ### getCandidates
241 |
242 | Returns list of candidates.
243 |
244 | $height is optional parameter.
245 |
246 | ``
247 | getCandidates(?int $height = null, ?bool $includeStakes = false): \stdClass
248 | ``
249 |
250 | ### estimateTxCommission
251 |
252 | Returns estimate of transaction.
253 |
254 | ``
255 | estimateTxCommission(string $tx, ?int $height = null): \stdClass
256 | ``
257 |
258 | ### getTransactions
259 |
260 | Returns transactions by query.
261 |
262 | ``
263 | getTransactions(string $query, ?int $page = null, ?int $perPage = null): \stdClass
264 | ``
265 |
266 | ### getUnconfirmedTxs
267 |
268 | Returns unconfirmed transactions.
269 |
270 | ``
271 | getUnconfirmedTxs(?int $limit = null): \stdClass
272 | ``
273 |
274 | ### getMaxGasPrice
275 |
276 | Returns current max gas price.
277 |
278 | ``
279 | getMaxGasPrice(?int $height = null): \stdClass
280 | ``
281 |
282 | ### getMinGasPrice
283 |
284 | Returns current min gas price.
285 |
286 | ``
287 | getMinGasPrice(): \stdClass
288 | ``
289 |
290 | ### getMissedBlocks
291 |
292 | Returns missed blocks by validator public key.
293 |
294 | ``
295 | getMissedBlocks(string $pubKey, ?int $height = null): \stdClass
296 | ``
297 |
298 | ### getGenesis
299 |
300 | Returns network genesis.
301 |
302 | ``
303 | getGenesis(): \stdClass
304 | ``
305 |
306 | ### getNetworkInfo
307 |
308 | Returns node network information.
309 |
310 | ``
311 | getNetworkInfo(): \stdClass
312 | ``
313 |
314 | ### getWaitlist
315 |
316 | Returns waitlisted stakes by address
317 |
318 | ``
319 | getWaitlist(string $address, ?string $publicKey = null, ?int $height = null): \stdClass
320 | ``
321 |
322 | ### getWaitlist
323 |
324 | Returns waitlisted stakes by address
325 |
326 | ``
327 | getWaitlist(string $address, ?string $publicKey = null, ?int $height = null): \stdClass
328 | ``
329 |
330 | ### getPriceCommissions
331 |
332 | Returns the list of the commissions that are set up on the Minter Network
333 |
334 | ``
335 | getPriceCommissions(?int $height = null): \stdClass
336 | ``
337 |
338 | ### getPriceVotes
339 |
340 | Returns the list of validators' votes for changing commissions on the network
341 |
342 | ``
343 | getPriceVotes(int $height): \stdClass
344 | ``
345 |
346 | ### getSwapPool
347 |
348 | Returns entire liquidity volume of the swap pool
349 |
350 | ``
351 | getSwapPool(string $coin0, string $coin1, ?int $height = null): \stdClass
352 | ``
353 |
354 | ### getSwapPoolProvider
355 |
356 | Returns liquidity volume of the swap pool provided by specified address
357 |
358 | ``
359 | getSwapPoolProvider(string $coin0, string $coin1, string $provider, ?int $height = null): \stdClass
360 | ``
361 |
362 | ### getLimitOrders
363 |
364 | Returns list of limit orders by ids
365 |
366 | ``
367 | getLimitOrders(array $ids, ?int $height = null): \stdClass
368 | ``
369 |
370 | ### getLimitOrder
371 |
372 | Returns limit order details by id
373 |
374 | ``
375 | getLimitOrder(int $limitOrderId, ?int $height = null): \stdClass
376 | ``
377 |
378 | ### getLimitOrdersByCoins
379 |
380 | Returns limit orders related to sell and buy coins
381 |
382 | ``
383 | getLimitOrdersByCoins(string $sellCoin, string $buyCoin, int $limit = null, ?int $height = null): \stdClass
384 | ``
385 |
386 |
387 |
388 | ### Error handling
389 |
390 | Example of how you can handle errors and get the response body.
391 |
392 | ```php
393 | use Minter\MinterAPI;
394 | use GuzzleHttp\Exception\RequestException;
395 |
396 | // create instance
397 | $api = new MinterAPI('node url here');
398 |
399 | try {
400 | // success response
401 | $response = $api->send('signed tx here');
402 | } catch(RequestException $exception) {
403 | // short exception message
404 | $message = $exception->getMessage();
405 |
406 | // error response in json
407 | $content = $exception->getResponse()
408 | ->getBody()
409 | ->getContents();
410 |
411 | // error response as array
412 | $error = json_decode($content, true);
413 | }
414 | ```
415 |
416 |
417 | ## Using MinterSDK
418 |
419 | ### Sign transaction
420 |
421 | Returns a signed tx.
422 |
423 | ###### Example
424 |
425 | * Sign the SendCoin transaction
426 | * Constructor: ```MinterSendCoinTx($coin, $to, $value)```
427 |
428 | ```php
429 | use Minter\SDK\MinterTx;
430 | use Minter\SDK\MinterCoins\MinterSendCoinTx;
431 |
432 | $data = new MinterSendCoinTx($coinID, 'Mxfe60014a6e9ac91618f5d1cab3fd58cded61ee99', '10');
433 | $tx = new MinterTx($nonce, $data);
434 |
435 | $tx->sign('your private key');
436 | ```
437 |
438 | At all type of transactions you can also set optional fields:
439 | gas price, gas coin, payload, serviceData, chain id
440 |
441 | ```php
442 | use Minter\SDK\MinterTx;
443 | use Minter\SDK\MinterCoins\MinterSendCoinTx;
444 |
445 | $data = new MinterSendCoinTx($coinID, 'Mxfe60014a6e9ac91618f5d1cab3fd58cded61ee99', '10');
446 | $tx = (new MinterTx($nonce, $data))
447 | ->setChainID(MinterTx::TESTNET_CHAIN_ID)
448 | ->setGasPrice(1)
449 | ->setGasCoin(MinterTx::BASE_COIN_ID)
450 | ->setPayload('some payload')
451 | ->setServiceData('some data');
452 |
453 | $tx->sign('your private key');
454 | ```
455 |
456 | ###### Example
457 | * Sign the SellCoin transaction
458 | * Constructor: ```MinterSellCoinTx($coinToSell, $valueToSell, $coinToBuy, $minimumValueToBuy)```
459 |
460 | ```php
461 | use Minter\SDK\MinterTx;
462 | use Minter\SDK\MinterCoins\MinterSellCoinTx;
463 |
464 | $data = new MinterSellCoinTx(123, '1', 321, '1');
465 | $tx = new MinterTx($nonce, $data);
466 |
467 | $tx->sign('your private key');
468 | ```
469 |
470 | ###### Example
471 | * Sign the SellAllCoin transaction
472 | * Constructor: ```MinterSellAllCoinTx($coinToSell, $coinToBuy, $minimumValueToBuy)```
473 |
474 | ```php
475 | use Minter\SDK\MinterTx;
476 | use Minter\SDK\MinterCoins\MinterSellAllCoinTx;
477 |
478 | $data = new MinterSellAllCoinTx(123, 321, '1');
479 | $tx = new MinterTx($nonce, $data);
480 |
481 | $tx->sign('your private key');
482 | ```
483 |
484 | ###### Example
485 | * Sign the BuyCoin transaction
486 | * Constructor: ```MinterBuyCoinTx($coinToBuy, $valueToBuy, $coinToSell, $maximumValueToSell)```
487 |
488 | ```php
489 | use Minter\SDK\MinterTx;
490 | use Minter\SDK\MinterCoins\MinterBuyCoinTx;
491 |
492 | $data = new MinterBuyCoinTx(123, '1', 321, '1');
493 | $tx = new MinterTx($nonce, $data);
494 |
495 | $tx->sign('your private key');
496 | ```
497 |
498 | ###### Example
499 | * Sign the CreateCoin transaction
500 | * Constructor: ```MinterCreateCoinTx($name, $symbol, $amount, $reserve, $crr, $maxSupply)```
501 |
502 | ```php
503 | use Minter\SDK\MinterTx;
504 | use Minter\SDK\MinterCoins\MinterCreateCoinTx;
505 |
506 | $data = new MinterCreateCoinTx('TEST COIN', 'TEST', '10000', '10', 10, '10000');
507 | $tx = new MinterTx($nonce, $data);
508 |
509 | $tx->sign('your private key');
510 | ```
511 |
512 | ###### Example
513 | * Sign the DeclareCandidacy transaction
514 | * Constructor: ```MinterDeclareCandidacyTx($address, $publicKey, $commission, $coin, $stake)```
515 |
516 | ```php
517 | use Minter\SDK\MinterTx;
518 | use Minter\SDK\MinterCoins\MinterDeclareCandidacyTx;
519 |
520 | $data = new MinterDeclareCandidacyTx(
521 | 'Mxa7bc33954f1ce855ed1a8c768fdd32ed927def47',
522 | 'Mp023853f15fc1b1073ad7a1a0d4490a3b1fadfac00f36039b6651bc4c7f52ba9c02',
523 | 10, 0, '10000'
524 | );
525 |
526 | $tx = new MinterTx($nonce, $data);
527 | $tx->sign('your private key');
528 | ```
529 |
530 | ###### Example
531 | * Sign the Delegate transaction
532 | * Constructor: ```MinterDelegateTx($publicKey, $coin, $stake)```
533 |
534 | ```php
535 | use Minter\SDK\MinterTx;
536 | use Minter\SDK\MinterCoins\MinterDelegateTx;
537 |
538 | $data = new MinterDelegateTx('Mp0eb98ea04ae466d8d38f490db3c99b3996a90e24243952ce9822c6dc1e2c1a43', 123, '10000');
539 | $tx = new MinterTx($nonce, $data);
540 |
541 | $tx->sign('your private key');
542 | ```
543 |
544 | ###### Example
545 | * Sign the SetCandidateOn transaction
546 | * Constructor: ```MinterSetCandidateOnTx($publicKey)```
547 |
548 | ```php
549 | use Minter\SDK\MinterTx;
550 | use Minter\SDK\MinterCoins\MinterSetCandidateOnTx;
551 |
552 | $data = new MinterSetCandidateOnTx('Mp0eb98ea04ae466d8d38f490db3c99b3996a90e24243952ce9822c6dc1e2c1a43');
553 | $tx = new MinterTx($nonce, $data);
554 |
555 | $tx->sign('your private key');
556 | ```
557 |
558 | ###### Example
559 | * Sign the SetCandidateOff transaction
560 | * Constructor: ```MinterSetCandidateOffTx($publicKey)```
561 |
562 | ```php
563 | use Minter\SDK\MinterTx;
564 | use Minter\SDK\MinterCoins\MinterSetCandidateOffTx;
565 |
566 | $data = new MinterSetCandidateOffTx('Mp0eb98ea04ae466d8d38f490db3c99b3996a90e24243952ce9822c6dc1e2c1a43');
567 | $tx = new MinterTx($nonce, $data);
568 |
569 | $tx->sign('your private key');
570 | ```
571 |
572 | ###### Example
573 | * Sign the RedeemCheck transaction
574 | * Constructor: ```MinterRedeemCheckTx($check, $proof)```
575 |
576 | ```php
577 | use Minter\SDK\MinterTx;
578 | use Minter\SDK\MinterCoins\MinterRedeemCheckTx;
579 |
580 | $data = new MinterRedeemCheckTx('your check', 'created by MinterCheck proof');
581 | $tx = new MinterTx($nonce, $data);
582 |
583 | $tx->sign('your private key');
584 | ```
585 |
586 | ###### Example
587 | * Sign the Unbond transaction
588 | * Constructor: ```MinterUnbondTx($publicKey, $coin, $value)```
589 |
590 | ```php
591 | use Minter\SDK\MinterTx;
592 | use Minter\SDK\MinterCoins\MinterUnbondTx;
593 |
594 | $data = new MinterUnbondTx('Mp....', 123, '10000');
595 | $tx = new MinterTx($nonce, $data);
596 |
597 | $tx->sign('your private key');
598 | ```
599 |
600 | ###### Example
601 | * Sign the MultiSend transaction
602 | * Constructor: ```MinterMultiSendTx($list)```
603 |
604 | ```php
605 | use Minter\SDK\MinterTx;
606 | use Minter\SDK\MinterCoins\MinterSendCoinTx;
607 | use Minter\SDK\MinterCoins\MinterMultiSendTx;
608 |
609 | $data = new MinterMultiSendTx([
610 | new MinterSendCoinTx(0, 'Mxfe60014a6e9ac91618f5d1cab3fd58cded61ee99', '15'),
611 | new MinterSendCoinTx(123, 'Mxfe60014a6e9ac91618f5d1cab3fd58cded61ee92', '10')
612 | ]);
613 |
614 | $tx = new MinterTx($nonce, $data);
615 | $tx->sign('your private key');
616 | ```
617 |
618 | ###### Example
619 | * Sign the EditCandidate transaction
620 | * Constructor: ```MinterEditCandidateTx($publicKey, $rewardAddress, $ownerAddress, $controlAddress)```
621 |
622 | ```php
623 | use Minter\SDK\MinterTx;
624 | use Minter\SDK\MinterCoins\MinterEditCandidateTx;
625 |
626 | $data = new MinterEditCandidateTx('candidate public key', 'Minter address for rewards', 'Minter address of owner', 'Minter address for control');
627 | $tx = new MinterTx($nonce, $data);
628 |
629 | $tx->sign('your private key');
630 | ```
631 |
632 | ###### Example
633 | * Sign the CreateMultisig transaction
634 | * Constructor: ```MinterCreateMultisigTx($threshold, $weights, $addresses)```
635 |
636 | ```php
637 | use Minter\SDK\MinterTx;
638 | use Minter\SDK\MinterCoins\MinterCreateMultisigTx;
639 |
640 | $data = new MinterCreateMultisigTx(7, [1, 3, 5], [
641 | 'Mxee81347211c72524338f9680072af90744333143',
642 | 'Mxee81347211c72524338f9680072af90744333145',
643 | 'Mxee81347211c72524338f9680072af90744333144'
644 | ]);
645 |
646 | $tx = new MinterTx($nonce, $data);
647 | $tx->sign('your private key');
648 | ```
649 |
650 | ###### Example
651 | * Sign the SetHaltBlock transaction
652 | * Constructor: ```MinterSetHaltBlockTx($publicKey, $height)```
653 |
654 | ```php
655 | use Minter\SDK\MinterTx;
656 | use Minter\SDK\MinterCoins\MinterSetHaltBlockTx;
657 |
658 | $data = new MinterSetHaltBlockTx('your public key', 236503);
659 | $tx = new MinterTx($nonce, $data);
660 | $tx->sign('your private key');
661 | ```
662 |
663 | ###### Example
664 | * Sign the RecreateCoin transaction
665 | * Constructor: ```MinterRecreateCoinTx($name, $symbol, $amount, $reserve, $crr, $maxSupply)```
666 |
667 | ```php
668 | use Minter\SDK\MinterTx;
669 | use Minter\SDK\MinterCoins\MinterRecreateCoinTx;
670 |
671 | $data = new MinterRecreateCoinTx('TEST', '10000', '10', 10000, 10, '10000');
672 | $tx = new MinterTx($nonce, $data);
673 | $tx->sign('your private key');
674 | ```
675 |
676 | ###### Example
677 | * Sign the EditCoinOwner transaction
678 | * Constructor: ```MinterEditCoinOwnerTx($symbol, $newOwner)```
679 |
680 | ```php
681 | use Minter\SDK\MinterTx;
682 | use Minter\SDK\MinterCoins\MinterEditCoinOwnerTx;
683 |
684 | $data = new MinterEditCoinOwnerTx('COINSYMBOL', 'Mxee81347211c72524338f9680072af90744333145');
685 | $tx = new MinterTx($nonce, $data);
686 | $tx->sign('your private key');
687 | ```
688 |
689 | ###### Example
690 | * Sign the EditMultisig transaction
691 | * Constructor: ```MinterEditMultisigTx($threshold, $weights, $addresses)```
692 |
693 | ```php
694 | use Minter\SDK\MinterTx;
695 | use Minter\SDK\MinterCoins\MinterEditMultisigTx;
696 |
697 | $data = new MinterEditMultisigTx(1, [1, 2], ['Mxee81347211c72524338f9680072af90744333145', 'Mxee81347211c72524338f9680072af90744333146']);
698 | $tx = new MinterTx($nonce, $data);
699 | $tx->sign('your private key');
700 | ```
701 |
702 | ###### Example
703 | * Sign the EditCandidatePublicKey transaction
704 | * Constructor: ```MinterEditCandidatePublicKeyTx($publicKey, $newPublicKey)```
705 |
706 | ```php
707 | use Minter\SDK\MinterTx;
708 | use Minter\SDK\MinterCoins\MinterEditCandidatePublicKeyTx;
709 |
710 | $data = new MinterEditCandidatePublicKeyTx('public key', 'new public key....');
711 | $tx = new MinterTx($nonce, $data);
712 | $tx->sign('your private key');
713 | ```
714 |
715 | ###### Example
716 | * Sign the AddLiquidity transaction
717 | * Constructor: ```MinterAddLiquidityTx($coin0, $coin1, $volume0, $maximumVolume1)```
718 |
719 | ```php
720 | use Minter\SDK\MinterTx;
721 | use Minter\SDK\MinterCoins\MinterAddLiquidityTx;
722 |
723 | $data = new MinterAddLiquidityTx(0, 1, '1000', '2000');
724 | $tx = new MinterTx($nonce, $data);
725 | $tx->sign('your private key');
726 | ```
727 |
728 | ###### Example
729 | * Sign the RemoveLiquidity transaction
730 | * Constructor: ```MinterRemoveLiquidityTx($coin0, $coin1, $liquidity, $minimumVolume0, $minimumVolume1)```
731 |
732 | ```php
733 | use Minter\SDK\MinterTx;
734 | use Minter\SDK\MinterCoins\MinterRemoveLiquidityTx;
735 |
736 | $data = new MinterRemoveLiquidityTx(0, 1, '2000', '500', '1000');
737 | $tx = new MinterTx($nonce, $data);
738 | $tx->sign('your private key');
739 | ```
740 |
741 | ###### Example
742 | * Sign the SellSwapPool transaction
743 | * Constructor: ```MinterSellSwapPoolTx(array $coins, $valueToSell, $minimumValueToBuy)```
744 |
745 | ```php
746 | use Minter\SDK\MinterTx;
747 | use Minter\SDK\MinterCoins\MinterSellSwapPoolTx;
748 |
749 | $data = new MinterSellSwapPoolTx([1, 2], '20', '2');
750 | $tx = new MinterTx($nonce, $data);
751 | $tx->sign('your private key');
752 | ```
753 |
754 | ###### Example
755 | * Sign the BuySwapPool transaction
756 | * Constructor: ```MinterBuySwapPoolTx($coins, $valueToBuy, $maximumValueToSell)```
757 |
758 | ```php
759 | use Minter\SDK\MinterTx;
760 | use Minter\SDK\MinterCoins\MinterBuySwapPoolTx;
761 |
762 | $data = new MinterBuySwapPoolTx([2, 3], '3', '5000');
763 | $tx = new MinterTx($nonce, $data);
764 | $tx->sign('your private key');
765 | ```
766 |
767 | ###### Example
768 | * Sign the SellAllSwapPool transaction
769 | * Constructor: ```MinterSellAllSwapPoolTx(array $coins, $minimumValueToBuy)```
770 |
771 | ```php
772 | use Minter\SDK\MinterTx;
773 | use Minter\SDK\MinterCoins\MinterSellAllSwapPoolTx;
774 |
775 | $data = new MinterSellAllSwapPoolTx([1, 4, 5], '100');
776 | $tx = new MinterTx($nonce, $data);
777 | $tx->sign('your private key');
778 | ```
779 |
780 | ###### Example
781 | * Sign the EditCandidateCommission transaction
782 | * Constructor: ```MinterEditCandidateCommissionTx($publicKey, $commission)```
783 |
784 | ```php
785 | use Minter\SDK\MinterTx;
786 | use Minter\SDK\MinterCoins\MinterEditCandidateCommissionTx;
787 |
788 | $data = new MinterEditCandidateCommissionTx('public key', 77);
789 | $tx = new MinterTx($nonce, $data);
790 | $tx->sign('your private key');
791 | ```
792 |
793 | ###### Example
794 | * Sign the MintToken transaction
795 | * Constructor: ```MinterMintTokenTx($coin, $value)```
796 |
797 | ```php
798 | use Minter\SDK\MinterTx;
799 | use Minter\SDK\MinterCoins\MinterMintTokenTx;
800 |
801 | $data = new MinterMintTokenTx(2, '3000');
802 | $tx = new MinterTx($nonce, $data);
803 | $tx->sign('your private key')
804 | ```
805 |
806 | ###### Example
807 | * Sign the BurnToken transaction
808 | * Constructor: ```MinterBurnTokenTx($coin, $value)```
809 |
810 | ```php
811 | use Minter\SDK\MinterTx;
812 | use Minter\SDK\MinterCoins\MinterBurnTokenTx;
813 |
814 | $data = new MinterBurnTokenTx(3, '100000');
815 | $tx = new MinterTx($nonce, $data);
816 | $tx->sign('your private key')
817 | ```
818 |
819 | ###### Example
820 | * Sign the CreateToken transaction
821 | * Constructor: ```MinterCreateTokenTx($name, $symbol, $initialAmount, $maxSupply, $mintable, $burnable)```
822 |
823 | ```php
824 | use Minter\SDK\MinterTx;
825 | use Minter\SDK\MinterCoins\MinterCreateTokenTx;
826 |
827 | $data = new MinterCreateTokenTx('TEST COIN IS MINTABLE ONLY', 'TEST', '10000', '50000', true, false);
828 | $tx = new MinterTx($nonce, $data);
829 | $tx->sign('your private key')
830 | ```
831 |
832 | ###### Example
833 | * Sign the RecreateToken transaction
834 | * Constructor: ```MinterRecreateTokenTx($name, $symbol, $initialAmount, $maxSupply, $mintable, $burnable)```
835 |
836 | ```php
837 | use Minter\SDK\MinterTx;
838 | use Minter\SDK\MinterCoins\MinterRecreateTokenTx;
839 |
840 | $data = new MinterRecreateTokenTx('TEST COIN IS TURNED TO BE BURNABLE ONLY', 'TEST', '50000', '50000', false, true);
841 | $tx = new MinterTx($nonce, $data);
842 | $tx->sign('your private key')
843 | ```
844 |
845 | ###### Example
846 | * Sign the PriceCommission transaction
847 | * Constructor: ```MinterPriceCommissionTx(
848 | $pubKey,
849 | $height,
850 | $coin,
851 | $payloadByte,
852 | $send,
853 | $buyBancor,
854 | $sellBancor,
855 | $sellAllBancor,
856 | $buyPoolBase,
857 | $buyPoolDelta,
858 | $sellPoolBase,
859 | $sellPoolDelta,
860 | $sellAllPoolBase,
861 | $sellAllPoolDelta,
862 | $createTicker3,
863 | $createTicker4,
864 | $createTicker5,
865 | $createTicker6,
866 | $createTicker7to10,
867 | $createCoin,
868 | $createToken,
869 | $recreateCoin,
870 | $recreateToken,
871 | $declareCandidacy,
872 | $delegate,
873 | $unbond,
874 | $redeemCheck,
875 | $setCandidateOn,
876 | $setCandidateOff,
877 | $createMultisig,
878 | $multisendBase,
879 | $multisendDelta,
880 | $editCandidate,
881 | $setHaltBlock,
882 | $editTickerOwner,
883 | $editMultisig,
884 | $editCandidatePublicKey,
885 | $createSwapPool,
886 | $addLiquidity,
887 | $removeLiquidity,
888 | $editCandidateCommission,
889 | $burnToken,
890 | $mintToken,
891 | $voteCommission,
892 | $voteUpdate
893 | )```
894 |
895 | ```php
896 | use Minter\SDK\MinterTx;
897 | use Minter\SDK\MinterCoins\MinterPriceCommissionTx;
898 |
899 | $data = new MinterPriceCommissionTx('public key', 100000,0,'1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35','36','37','38','39','40','41', '42');
900 | $tx = new MinterTx($nonce, $data);
901 | $tx->sign('your private key');
902 | ```
903 |
904 | ###### Example
905 | * Sign the CreateSwapPoll transaction
906 | * Constructor: ```MinterCreateSwapPoolTx($coin0, $coin1, $volume0, $volume1)```
907 |
908 | ```php
909 | use Minter\SDK\MinterTx;
910 | use Minter\SDK\MinterCoins\MinterCreateSwapPoolTx;
911 |
912 | $data = new MinterCreateSwapPoolTx(1, 2, '11000', '22000');
913 | $tx = new MinterTx($nonce, $data);
914 | $tx->sign('your private key')
915 | ```
916 |
917 | ###### Example
918 | * Sign the AddLimitOrder transaction
919 | * Constructor: ```MinterAddLimitOrderTx($coinToSell, $valueToSell, $coinToBuy, $valueToBuy)```
920 |
921 | ```php
922 | use Minter\SDK\MinterTx;
923 | use Minter\SDK\MinterCoins\MinterAddLimitOrderTx;
924 |
925 | $data = new MinterAddLimitOrderTx(0, '10', 1841, '7');
926 | $tx = new MinterTx($nonce, $data);
927 | $tx->sign('your private key')
928 | ```
929 |
930 | ###### Example
931 | * Sign the RemoveLimitOrder transaction
932 | * Constructor: ```MinterRemoveLimitOrderTx($id)```
933 |
934 | ```php
935 | use Minter\SDK\MinterTx;
936 | use Minter\SDK\MinterCoins\MinterRemoveLimitOrderTx;
937 |
938 | $data = new MinterRemoveLimitOrderTx($limitOrderId);
939 | $tx = new MinterTx($nonce, $data);
940 | $tx->sign('your private key')
941 | ```
942 |
943 | ### Sign transaction with multisignatures
944 |
945 | Returns a signed tx.
946 |
947 | ###### Example
948 |
949 | * To sign transaction with multisignatures, you need to call signMultisig method
950 | and pass multisig Minter address and his private keys (in any order).
951 |
952 | ```php
953 | use Minter\SDK\MinterTx;
954 | use Minter\SDK\MinterCoins\MinterSendCoinTx;
955 |
956 | $data = new MinterSendCoinTx(123, 'Mxfe60014a6e9ac91618f5d1cab3fd58cded61ee99', '10');
957 | $tx = new MinterTx($nonce, $data);
958 |
959 | $signedTx = $tx->signMultisig('Mxdb4f4b6942cb927e8d7e3a1f602d0f1fb43b5bd2', [
960 | 'b354c3d1d456d5a1ddd65ca05fd710117701ec69d82dac1858986049a0385af9',
961 | '38b7dfb77426247aed6081f769ed8f62aaec2ee2b38336110ac4f7484478dccb',
962 | '94c0915734f92dd66acfdc48f82b1d0b208efd544fe763386160ec30c968b4af'
963 | ])
964 | ```
965 |
966 | ###### Example
967 |
968 | * To get the signature of transaction (not signed transaction)
969 | you need to call createSignature
970 |
971 | ```php
972 | use Minter\SDK\MinterTx;
973 | use Minter\SDK\MinterCoins\MinterSendCoinTx;
974 |
975 | $data = new MinterSendCoinTx(123, 'Mxfe60014a6e9ac91618f5d1cab3fd58cded61ee99', '10');
976 | $tx = new MinterTx($nonce, $data);
977 |
978 | $txSignature = $tx->createSignature($privateKey);
979 | ```
980 |
981 | ###### Example
982 |
983 | * To sign transaction with ready signatures, you need to call signMultisigBySigns method
984 | and pass multisig Minter address and your signatures (in any order).
985 |
986 | ```php
987 | use Minter\SDK\MinterTx;
988 | use Minter\SDK\MinterCoins\MinterSendCoinTx;
989 |
990 | $data = new MinterSendCoinTx(123, 'Mxfe60014a6e9ac91618f5d1cab3fd58cded61ee99', '10');
991 | $tx = new MinterTx($nonce, $data);
992 |
993 | $signature1 = $tx->createSignature($privateKey1);
994 | $signature2 = $tx->createSignature($privateKey2);
995 | $signature3 = $tx->createSignature($privateKey3);
996 |
997 | $signedTx = $tx->signMultisigBySigns('Mxdb4f4b6942cb927e8d7e3a1f602d0f1fb43b5bd2', [
998 | $signature1, $signature2, $signature3
999 | ])
1000 | ```
1001 |
1002 | ### Get fee of transaction
1003 |
1004 | * Calculate fee of transaction. You can get fee AFTER signing or decoding transaction.
1005 | ```php
1006 | use Minter\SDK\MinterTx;
1007 |
1008 | $tx = new MinterTx(...);
1009 | $tx->getFee();
1010 | ```
1011 |
1012 | ### Decode transaction
1013 |
1014 | Returns an array with transaction data.
1015 |
1016 | ###### Example
1017 |
1018 | * Decode transaction
1019 |
1020 | ```php
1021 | use Minter\SDK\MinterTx;
1022 |
1023 | $tx = MinterTx::decode('transaction raw starting from 0x...');
1024 |
1025 | // $tx->getSenderAddress()
1026 | // $tx->getData()
1027 | // $tx->getNonce()
1028 | // $tx->getChainID()
1029 | // $tx->getGasPrice()
1030 | // $tx->getPayload()
1031 | // $tx->getSignatureData()
1032 |
1033 | ```
1034 |
1035 | ### Create Minter Check
1036 |
1037 | ###### Example
1038 |
1039 | * Create check
1040 |
1041 | ```php
1042 | use Minter\SDK\MinterCheck;
1043 |
1044 | $check = new MinterCheck([
1045 | 'nonce' => $nonce,
1046 | 'chainId' => MinterTx::MAINNET_CHAIN_ID, // or MinterTx::TESTNET_CHAIN_ID
1047 | 'dueBlock' => 999999,
1048 | 'coin' => 'MNT',
1049 | 'value' => '10',
1050 | 'gasCoin' => 'MNT'
1051 | ], 'your pass phrase');
1052 |
1053 | echo $check->sign('your private key here');
1054 |
1055 | // Mc.......
1056 |
1057 | ```
1058 |
1059 | * Create proof
1060 |
1061 | ```php
1062 | use Minter\SDK\MinterCheck;
1063 |
1064 | $check = new MinterCheck('your Minter address here', 'your pass phrase');
1065 |
1066 | echo $check->createProof();
1067 | ```
1068 |
1069 | * Decode check
1070 |
1071 | ```php
1072 | use Minter\SDK\MinterCheck;
1073 |
1074 | $check = new MinterCheck('your Minter check here');
1075 |
1076 | $check->getBody(); // check body
1077 |
1078 | $check->getOwnerAddress(); // check owner address
1079 | ```
1080 |
1081 | ### Minter Wallet
1082 |
1083 | ###### Example
1084 |
1085 | * Create wallet.
1086 |
1087 | ```php
1088 | use Minter\SDK\MinterWallet;
1089 |
1090 | $wallet = new MinterWallet();
1091 |
1092 | // $wallet->getPublicKey();
1093 | // $wallet->getPrivateKey();
1094 | // $wallet->getMnemonic();
1095 | // $wallet->getAddress();
1096 | ```
1097 |
1098 | * Create wallet from mnemonic
1099 |
1100 | ```php
1101 | use Minter\SDK\MinterWallet;
1102 |
1103 | $wallet = MinterWallet::createFromMnemonic($mnemonic);
1104 | ```
1105 |
1106 | * Create wallet from private key
1107 |
1108 | ```php
1109 | use Minter\SDK\MinterWallet;
1110 |
1111 | $wallet = MinterWallet::createFromPrivate($privateKey);
1112 | ```
1113 |
1114 | ### Minter Link
1115 |
1116 | ###### Example
1117 |
1118 | * Create Minter deep link.
1119 | * You can pass data of any Minter transaction to the constructor.
1120 |
1121 | ```php
1122 | use Minter\SDK\MinterDeepLink;
1123 | use Minter\SDK\MinterCoins\MinterSendCoinTx;
1124 |
1125 | $txData = new MinterSendCoinTx(123, 'Mx18467bbb64a8edf890201d526c35957d82be3d95', '1.23456789');
1126 | $link = new MinterDeepLink($txData);
1127 | $link->encode(); // returns encoded link as string
1128 | ```
1129 |
1130 | * You can define optional fields such as host, payload, nonce, gas price, gas coin, check password.
1131 |
1132 | ```php
1133 | use Minter\SDK\MinterDeepLink;
1134 | use Minter\SDK\MinterCoins\MinterSendCoinTx;
1135 |
1136 | $txData = new MinterSendCoinTx(123, 'Mx18467bbb64a8edf890201d526c35957d82be3d95', '1.23456789');
1137 | $link = new MinterDeepLink($txData);
1138 |
1139 | $link->setPayload('Hello World')
1140 | ->setNonce($nonce)
1141 | ->setGasPrice($gasPrice)
1142 | ->setGasCoin($gasCoin)
1143 | ->setHost('https://testnet.bip.to/tx')
1144 | ->setPassword('some check password');
1145 |
1146 | $link->encode(); // returns encoded link as string
1147 | ```
1148 |
1149 |
1150 | ## Tests
1151 |
1152 | To run unit tests:
1153 |
1154 | ```bash
1155 | vendor/bin/phpunit tests
1156 | ```
1157 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "minter/minter-php-sdk",
3 | "autoload": {
4 | "psr-0" : {
5 | "Minter\\" : "src"
6 | }
7 | },
8 | "require": {
9 | "php": "^7.1.3|^8.0",
10 | "ext-bcmath": "*",
11 | "ext-json": "*",
12 | "ext-gmp": "*",
13 | "kornrunner/keccak": "^1.0",
14 | "guzzlehttp/guzzle": "^6.3|^7.3",
15 | "minter/minter-php-bip-44": "^1.2",
16 | "bitwasp/bitcoin-lib": "^1.0",
17 | "simplito/elliptic-php": "^1.0",
18 | "minter/php-rlp": "^1.0.0"
19 | },
20 | "require-dev": {
21 | "phpunit/phpunit": "^7|^9.5"
22 | },
23 | "minimum-stability": "dev",
24 | "prefer-stable": true
25 | }
26 |
--------------------------------------------------------------------------------
/src/Minter/Contracts/MinterTxInterface.php:
--------------------------------------------------------------------------------
1 | $privateKey,
31 | 'privEnc' => 'hex'
32 | ]);
33 |
34 | $publicKey = $keyPair->getPublic('hex');
35 |
36 | return substr($publicKey, 2, 130);
37 | }
38 |
39 | /**
40 | * Sign using pure PHP library
41 | *
42 | * @param string $message
43 | * @param string $privateKey
44 | * @return array
45 | */
46 | public static function sign(string $message, string $privateKey): array
47 | {
48 | // create elliptic curve and sign
49 | $ellipticCurve = new EC('secp256k1');
50 | $signature = $ellipticCurve->sign($message, $privateKey, 'hex', ['canonical' => true]);
51 |
52 | // convert to hex
53 | $r = $signature->r->toString('hex');
54 | $s = $signature->s->toString('hex');
55 | $recovery = $signature->recoveryParam;
56 |
57 | return self::encodeSign($r, $s, $recovery);
58 | }
59 |
60 |
61 | /**
62 | * Recover public key using pure PHP library
63 | *
64 | * @param string $msg
65 | * @param EC\Signature $signature
66 | * @return string
67 | * @throws \Exception
68 | */
69 | public static function recover(string $msg, EC\Signature $signature): string
70 | {
71 | // define the recovery param
72 | $recovery = $signature->recoveryParam === self::V_BITS ? 0 : 1;
73 |
74 | // define the signature
75 | $signature = [
76 | 'r' => $signature->r->toString('hex'),
77 | 's' => $signature->s->toString('hex'),
78 | 'recoveryParam' => $recovery
79 | ];
80 |
81 | // create elliptic curve
82 | $ellipticCurve = new EC('secp256k1');
83 | $point = $ellipticCurve->recoverPubKey($msg, $signature, $recovery, 'hex');
84 |
85 | // create key pair from point
86 | $key = new KeyPair($ellipticCurve, [
87 | 'pub' => $point,
88 | 'pubEnc' => 'hex'
89 | ]);
90 |
91 | return substr($key->getPublic('hex'), 2, 130);
92 | }
93 |
94 | /**
95 | * Encore result params (V, R , S)
96 | *
97 | * @param string $r
98 | * @param string $s
99 | * @param int $recovery
100 | * @return array
101 | */
102 | protected static function encodeSign(string $r, string $s, int $recovery): array
103 | {
104 | $r = Helper::padToEven($r);
105 | $s = Helper::padToEven($s);
106 |
107 | return [
108 | 'v' => dechex($recovery + self::V_BITS),
109 | 'r' => $r,
110 | 's' => $s
111 | ];
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/src/Minter/Library/Helper.php:
--------------------------------------------------------------------------------
1 | $value) {
60 | if (is_array($value)) {
61 | $data[$key] = self::hex2binRecursive($value);
62 | } else if (is_string($value) && ctype_xdigit($value)) {
63 | $data[$key] = hex2bin($value);
64 | }
65 | }
66 |
67 | return $data;
68 | }
69 |
70 | /**
71 | * Remove MinterWallet prefix from address or transaction
72 | *
73 | * @param string $string
74 | * @return string
75 | */
76 | public static function removeWalletPrefix(string $string): string
77 | {
78 | return self::removePrefix($string, MinterPrefix::ADDRESS);
79 | }
80 |
81 | /**
82 | * Remove prefix
83 | *
84 | * @param string $string
85 | * @param string $prefix
86 | * @return string
87 | */
88 | public static function removePrefix(string $string, string $prefix): string
89 | {
90 | return substr($string, strlen($prefix));
91 | }
92 |
93 | /**
94 | * Add MinterWallet prefix to address or transaction
95 | *
96 | * @param string $string
97 | * @return string
98 | */
99 | public static function addWalletPrefix(string $string): string
100 | {
101 | return MinterPrefix::ADDRESS . $string;
102 | }
103 |
104 | /**
105 | * Remove 0s from the end
106 | *
107 | * @param $number
108 | * @return string
109 | */
110 | public static function niceNumber($number): string
111 | {
112 | return rtrim(rtrim($number, '0'), '.');
113 | }
114 |
115 | /**
116 | * Add 0 if length of hex string is odd
117 | *
118 | * @param string $hexString
119 | * @return string
120 | */
121 | public static function padToEven(string $hexString): string
122 | {
123 | return strlen($hexString) % 2 !== 0 ? '0' . $hexString : $hexString;
124 | }
125 |
126 | /**
127 | * Create Keccak 256 hash
128 | *
129 | * @param array $tx
130 | * @return string
131 | */
132 | public static function createKeccakHash(string $dataString): string
133 | {
134 | $binaryTx = hex2bin($dataString);
135 |
136 | return Keccak::hash($binaryTx, 256);
137 | }
138 |
139 | /**
140 | * Convert RLP array to hex array
141 | *
142 | * @param string $data
143 | * @return array
144 | */
145 | public static function hex2rlp(string $data): array
146 | {
147 | $rlp = new RLP();
148 | $key = 0;
149 | $decoded = $rlp->decode('0x' . $data);
150 |
151 | return array_map(function ($v) use ($rlp, &$key) {
152 | $key++;
153 | return $key == 6 || $key == 10 ? $rlp->decode('0x' . $v) : (string)$v;
154 | }, $decoded);
155 | }
156 |
157 | /**
158 | * Create buffer from data recursively.
159 | *
160 | * @param $data
161 | * @return array|Buffer
162 | */
163 | public static function hex2buffer($data)
164 | {
165 | if (is_array($data)) {
166 | return array_map(function ($item) {
167 | return self::hex2buffer($item);
168 | }, $data);
169 | }
170 |
171 | return new Buffer($data, 'hex');
172 | }
173 |
174 | /**
175 | * @param string $str
176 | * @return string
177 | */
178 | public static function str2hex(string $str): string
179 | {
180 | $str = unpack('H*', $str);
181 |
182 | return array_shift($str);
183 | }
184 |
185 | /**
186 | * @param string $str
187 | * @return Buffer
188 | */
189 | public static function str2buffer(string $str): Buffer
190 | {
191 | $splitted = str_split($str, 1);
192 | return new Buffer($splitted);
193 | }
194 |
195 | /**
196 | * @param $data
197 | * @return string
198 | */
199 | public static function base64urlEncode($data): string
200 | {
201 | return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
202 | }
203 | }
204 |
--------------------------------------------------------------------------------
/src/Minter/Library/Http.php:
--------------------------------------------------------------------------------
1 | client = $client;
30 | }
31 |
32 | /**
33 | * http get request
34 | *
35 | * @param string $url
36 | * @param array|null $parameters
37 | * @return mixed
38 | * @throws \Exception
39 | * @throws GuzzleException
40 | */
41 | protected function get(string $url, array $parameters = null)
42 | {
43 | try {
44 | $response = $this->client->request('GET', $url, [
45 | 'query' => $parameters
46 | ])->getBody();
47 | } catch (RequestException $exception) {
48 | throw $exception;
49 | }
50 |
51 | return json_decode($response);
52 | }
53 |
54 | /**
55 | * http post request
56 | *
57 | * @param string $url
58 | * @param array $parameters
59 | * @return mixed
60 | * @throws \Exception
61 | * @throws GuzzleException
62 | */
63 | protected function post(string $url, array $parameters = [])
64 | {
65 | try {
66 | $response = $this->client->request('POST', $url, [
67 | 'json' => $parameters
68 | ])->getBody();
69 | } catch (RequestException $exception) {
70 | throw $exception;
71 | }
72 |
73 | return json_decode($response);
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/src/Minter/MinterAPI.php:
--------------------------------------------------------------------------------
1 | setClient($node);
35 | } else {
36 | $client = $this->createDefaultHttpClient($node);
37 | $this->setClient($client);
38 | }
39 | }
40 |
41 | /**
42 | * @param string $baseUri
43 | * @return Client
44 | */
45 | public function createDefaultHttpClient(string $baseUri): Client
46 | {
47 | return new Client([
48 | 'base_uri' => $baseUri,
49 | 'connect_timeout' => self::HTTP_DEFAULT_CONNECT_TIMEOUT,
50 | 'timeout' => self::HTTP_DEFAULT_TIMEOUT,
51 | 'verify' => false
52 | ]);
53 | }
54 |
55 | /**
56 | * Get status of node
57 | *
58 | * @return \stdClass
59 | * @throws Exception
60 | * @throws GuzzleException
61 | */
62 | public function getStatus(): \stdClass
63 | {
64 | return $this->get('status');
65 | }
66 |
67 | /**
68 | * This endpoint shows candidate’s info by provided public_key.
69 | * It will respond with 404 code if candidate is not found.
70 | *
71 | * @param string $publicKey
72 | * @param null|int $height
73 | * @return \stdClass
74 | * @throws Exception
75 | * @throws GuzzleException
76 | */
77 | public function getCandidate(string $publicKey, ?int $height = null): \stdClass
78 | {
79 | if ($height) {
80 | $params = ['height' => $height];
81 | }
82 |
83 | return $this->get('candidate/' . $publicKey, $params ?? null);
84 | }
85 |
86 | /**
87 | * Returns list of active validators
88 | *
89 | * @param null|int $height
90 | * @param int|null $page
91 | * @param int|null $perPage
92 | * @return \stdClass
93 | * @throws GuzzleException
94 | */
95 | public function getValidators(?int $height = null, ?int $page = 1, ?int $perPage = null): \stdClass
96 | {
97 | $params = ['page' => $page];
98 |
99 | if ($height) {
100 | $params['height'] = $height;
101 | }
102 |
103 | if ($perPage) {
104 | $params['per_page'] = $perPage;
105 | }
106 |
107 | return $this->get('validators', $params);
108 | }
109 |
110 | /**
111 | * Returns the balance of given account and the number of outgoing transaction.
112 | *
113 | * @param string $address
114 | * @param null|int $height
115 | * @param bool $delegated
116 | * @return \stdClass
117 | * @throws GuzzleException
118 | */
119 | public function getBalance(string $address, ?int $height = null, bool $delegated = false): \stdClass
120 | {
121 | $params = ['delegated' => $delegated];
122 | if ($height) {
123 | $params['height'] = $height;
124 | }
125 |
126 | return $this->get('address/' . $address, $params);
127 | }
128 |
129 | /**
130 | * Returns addresses balances.
131 | *
132 | * @param array $addresses
133 | * @param int|null $height
134 | * @param bool $delegated
135 | * @return \stdClass
136 | * @throws GuzzleException
137 | */
138 | public function getAddresses(array $addresses, ?int $height = null, bool $delegated = false): \stdClass
139 | {
140 | $params = ['addresses' => json_encode($addresses)];
141 |
142 | if ($height) {
143 | $params['height'] = $height;
144 | }
145 |
146 | return $this->get('addresses', $params);
147 | }
148 |
149 | /**
150 | * Returns nonce.
151 | *
152 | * @param string $address
153 | * @return int
154 | * @throws Exception
155 | * @throws GuzzleException
156 | */
157 | public function getNonce(string $address): int
158 | {
159 | return $this->getBalance($address)->transaction_count + 1;
160 | }
161 |
162 | /**
163 | * Sends transaction to the Minter Network.
164 | *
165 | * @param string $tx
166 | * @return \stdClass
167 | * @throws Exception
168 | * @throws GuzzleException
169 | */
170 | public function send(string $tx): \stdClass
171 | {
172 | return $this->post('send_transaction', ['tx' => $tx]);
173 | }
174 |
175 | /**
176 | * Returns transaction info.
177 | *
178 | * @param string $hash
179 | * @return \stdClass
180 | * @throws Exception
181 | * @throws GuzzleException
182 | */
183 | public function getTransaction(string $hash): \stdClass
184 | {
185 | return $this->get('transaction/' . $hash);
186 | }
187 |
188 | /**
189 | * @param int $height
190 | * @param bool|null $failedTxs
191 | * @return \stdClass
192 | * @throws GuzzleException
193 | */
194 | public function getBlock(int $height, ?bool $failedTxs = false): \stdClass
195 | {
196 | return $this->get('block/' . $height, ($failedTxs ? ['failed_txs' => true] : null));
197 | }
198 |
199 | /**
200 | * Returns events at given height.
201 | *
202 | * @param int $height
203 | * @return \stdClass
204 | * @throws Exception
205 | * @throws GuzzleException
206 | */
207 | public function getEvents(int $height): \stdClass
208 | {
209 | return $this->get('events/' . $height);
210 | }
211 |
212 | /**
213 | * Returns list of candidates.
214 | *
215 | * @param null|int $height
216 | * @param bool|null $includeStakes
217 | * @param string $status
218 | * @return \stdClass
219 | * @throws GuzzleException
220 | */
221 | public function getCandidates(?int $height = null, ?bool $includeStakes = false, string $status = 'all'): \stdClass
222 | {
223 | $params = ['status' => $status];
224 |
225 | if ($includeStakes) {
226 | $params['include_stakes'] = 'true';
227 | }
228 |
229 | if ($height) {
230 | $params['height'] = $height;
231 | }
232 |
233 | return $this->get('candidates', $params);
234 | }
235 |
236 | /**
237 | * Returns information about coin.
238 | * Note: this method does not return information about base coins (MNT and BIP).
239 | *
240 | * @param null|int $height
241 | * @param string $symbol
242 | * @return \stdClass
243 | * @throws Exception
244 | * @throws GuzzleException
245 | */
246 | public function getCoinInfo(string $symbol, ?int $height = null): \stdClass
247 | {
248 | if ($height) {
249 | $params['height'] = $height;
250 | }
251 |
252 | return $this->get('coin_info/' . $symbol, $params ?? null);
253 | }
254 |
255 | /**
256 | * Return estimate of sell coin transaction.
257 | *
258 | * @param string $coinToSell
259 | * @param string $valueToSell
260 | * @param string $coinToBuy
261 | * @param null|int $height
262 | * @param string $swapFrom
263 | * @return \stdClass
264 | * @throws Exception
265 | * @throws GuzzleException
266 | */
267 | public function estimateCoinSell(
268 | string $coinToSell,
269 | string $valueToSell,
270 | string $coinToBuy,
271 | ?int $height = null,
272 | string $swapFrom = 'optimal'
273 | ): \stdClass {
274 | $params = [
275 | 'coin_to_sell' => $coinToSell,
276 | 'value_to_sell' => $valueToSell,
277 | 'coin_to_buy' => $coinToBuy,
278 | 'swap_from' => $swapFrom
279 | ];
280 |
281 | if ($height) {
282 | $params['height'] = $height;
283 | }
284 |
285 | return $this->get('estimate_coin_sell', $params);
286 | }
287 |
288 | /**
289 | * Return estimate of sell all coin transaction.
290 | *
291 | * @param string $coinToSell
292 | * @param string $valueToSell
293 | * @param string $coinToBuy
294 | * @param int|null $height
295 | * @param string $swapFrom
296 | * @return \stdClass
297 | * @throws GuzzleException
298 | */
299 | public function estimateCoinSellAll(
300 | string $coinToSell,
301 | string $valueToSell,
302 | string $coinToBuy,
303 | ?int $height = null,
304 | string $swapFrom = 'optimal'
305 | ): \stdClass {
306 | $params = [
307 | 'coin_to_sell' => $coinToSell,
308 | 'value_to_sell' => $valueToSell,
309 | 'coin_to_buy' => $coinToBuy,
310 | 'swap_from' => $swapFrom
311 | ];
312 |
313 | if ($height) {
314 | $params['height'] = $height;
315 | }
316 |
317 | return $this->get('estimate_coin_sell_all', $params);
318 | }
319 |
320 | /**
321 | * Return estimate of buy coin transaction.
322 | *
323 | * @param string $coinToSell
324 | * @param string $valueToBuy
325 | * @param string $coinToBuy
326 | * @param null|int $height
327 | * @param string $swapFrom
328 | * @return \stdClass
329 | * @throws Exception
330 | * @throws GuzzleException
331 | */
332 | public function estimateCoinBuy(
333 | string $coinToSell,
334 | string $valueToBuy,
335 | string $coinToBuy,
336 | ?int $height = null,
337 | string $swapFrom = 'optimal'
338 | ): \stdClass {
339 | $params = [
340 | 'coin_to_sell' => $coinToSell,
341 | 'value_to_buy' => $valueToBuy,
342 | 'coin_to_buy' => $coinToBuy,
343 | 'swap_from' => $swapFrom
344 |
345 | ];
346 |
347 | if ($height) {
348 | $params['height'] = $height;
349 | }
350 |
351 | return $this->get('estimate_coin_buy', $params);
352 | }
353 |
354 | /**
355 | * Return estimate of transaction.
356 | *
357 | * @param string $tx
358 | * @param int|null $height
359 | * @return \stdClass
360 | * @throws GuzzleException
361 | */
362 | public function estimateTxCommission(string $tx, ?int $height = null): \stdClass
363 | {
364 | return $this->get('estimate_tx_commission/' . $tx, ($height ? ['height' => $height] : null));
365 | }
366 |
367 | /**
368 | * Get transactions by query.
369 | *
370 | * @param string $query
371 | * @param int|null $page
372 | * @param int|null $perPage
373 | * @return \stdClass
374 | * @throws Exception
375 | * @throws GuzzleException
376 | */
377 | public function getTransactions(string $query, ?int $page = null, ?int $perPage = null): \stdClass
378 | {
379 | $params = ['query' => $query];
380 |
381 | if ($page) {
382 | $params['page'] = $page;
383 | }
384 |
385 | if ($perPage) {
386 | $params['per_page'] = $perPage;
387 | }
388 |
389 |
390 | return $this->get('transactions', $params);
391 | }
392 |
393 | /**
394 | * Returns unconfirmed transactions.
395 | *
396 | * @param int|null $limit
397 | * @return \stdClass
398 | * @throws Exception
399 | * @throws GuzzleException
400 | */
401 | public function getUnconfirmedTxs(?int $limit = null): \stdClass
402 | {
403 | return $this->get('unconfirmed_txs', ($limit ? ['limit' => $limit] : null));
404 | }
405 |
406 | /**
407 | * Returns current max gas price.
408 | *
409 | * @param int|null $height
410 | * @return \stdClass
411 | * @throws Exception
412 | * @throws GuzzleException
413 | */
414 | public function getMaxGasPrice(?int $height = null): \stdClass
415 | {
416 | return $this->get('max_gas', ($height ? ['height' => $height] : null));
417 | }
418 |
419 | /**
420 | * Returns current min gas price.
421 | *
422 | * @return \stdClass
423 | * @throws Exception
424 | * @throws GuzzleException
425 | */
426 | public function getMinGasPrice(): \stdClass
427 | {
428 | return $this->get('min_gas_price');
429 | }
430 |
431 | /**
432 | * Returns missed blocks by validator public key.
433 | *
434 | * @param string $pubKey
435 | * @param int|null $height
436 | * @return \stdClass
437 | * @throws Exception
438 | * @throws GuzzleException
439 | */
440 | public function getMissedBlocks(string $pubKey, ?int $height = null): \stdClass
441 | {
442 | return $this->get('missed_blocks/' . $pubKey, ($height ? ['height' => $height] : null));
443 | }
444 |
445 | /**
446 | * Return network genesis.
447 | *
448 | * @return \stdClass
449 | * @throws GuzzleException
450 | */
451 | public function getGenesis(): \stdClass
452 | {
453 | return $this->get('genesis');
454 | }
455 |
456 | /**
457 | * Return node network information.
458 | *
459 | * @return \stdClass
460 | * @throws GuzzleException
461 | */
462 | public function getNetworkInfo(): \stdClass
463 | {
464 | return $this->get('net_info');
465 | }
466 |
467 | /**
468 | * @param int $id
469 | * @param int|null $height
470 | * @return \stdClass
471 | * @throws GuzzleException
472 | */
473 | public function getCoinInfoByID(int $id, ?int $height = null): \stdClass
474 | {
475 | return $this->get('coin_info_by_id/' . $id, ($height ? ['height' => $height] : null));
476 | }
477 |
478 | /**
479 | * @param int|null $height
480 | * @return \stdClass
481 | * @throws GuzzleException
482 | */
483 | public function getHalts(?int $height = null): \stdClass
484 | {
485 | return $this->get('halts', ($height ? ['height' => $height] : null));
486 | }
487 |
488 | /**
489 | * @param string|null $address
490 | * @param string|null $coin
491 | * @return \stdClass
492 | */
493 | public function getFrozen(?string $address = null, ?string $coin = null): \stdClass
494 | {
495 | $params = [];
496 |
497 | if ($address) {
498 | $params['address'] = $address;
499 | }
500 |
501 | if ($coin) {
502 | $params['coin'] = $coin;
503 | }
504 |
505 | return $this->get('frozen', $params);
506 | }
507 |
508 | /**
509 | * @param string $address
510 | * @param string|null $publicKey
511 | * @param int|null $height
512 | * @return \stdClass
513 | * @throws GuzzleException
514 | */
515 | public function getWaitlist(string $address, ?string $publicKey = null, ?int $height = null): \stdClass
516 | {
517 | $params = [];
518 |
519 | if ($height) {
520 | $params['height'] = $height;
521 | }
522 |
523 | if ($publicKey) {
524 | $params['publicKey'] = $publicKey;
525 | }
526 |
527 | return $this->get('waitlist/' . $address, $params);
528 | }
529 |
530 | /**
531 | * @param int|null $height
532 | * @return \stdClass
533 | * @throws GuzzleException
534 | */
535 | public function getPriceCommissions(?int $height = null): \stdClass
536 | {
537 | return $this->get('price_commissions', ($height ? ['height' => $height] : null));
538 | }
539 |
540 | /**
541 | * @param int $height
542 | * @return \stdClass
543 | * @throws GuzzleException
544 | */
545 | public function getPriceVotes(int $height): \stdClass
546 | {
547 | return $this->get('price_votes/' . $height);
548 | }
549 |
550 | /**
551 | * @param string $coin0
552 | * @param string $coin1
553 | * @param int|null $height
554 | * @return \stdClass
555 | * @throws GuzzleException
556 | */
557 | public function getSwapPool(string $coin0, string $coin1, ?int $height = null): \stdClass
558 | {
559 | return $this->get('swap_pool/' . $coin0 . '/' . $coin1, ($height ? ['height' => $height] : null));
560 | }
561 |
562 | /**
563 | * @param string $coin0
564 | * @param string $coin1
565 | * @param string $provider
566 | * @param int|null $height
567 | * @return \stdClass
568 | * @throws GuzzleException
569 | */
570 | public function getSwapPoolProvider(string $coin0, string $coin1, string $provider, ?int $height = null): \stdClass
571 | {
572 | return $this->get('swap_pool/' . $coin0 . '/' . $coin1 . '/' . $provider, ($height ? ['height' => $height] : null));
573 | }
574 |
575 | /**
576 | * @param array $ids
577 | * @param int|null $height
578 | * @return \stdClass
579 | * @throws GuzzleException
580 | */
581 | public function getLimitOrders(array $ids, ?int $height = null): \stdClass
582 | {
583 | $params = ['ids' => $ids];
584 | if ($height) {
585 | $params['height'] = $height;
586 | }
587 |
588 | return $this->get('limit_orders', $params);
589 | }
590 |
591 | /**
592 | * @param int $limitOrderId
593 | * @param int|null $height
594 | * @return \stdClass
595 | * @throws GuzzleException
596 | */
597 | public function getLimitOrder(int $limitOrderId, ?int $height = null): \stdClass
598 | {
599 | return $this->get('limit_order/' . $limitOrderId, ($height ? ['height' => $height] : null));
600 | }
601 |
602 | /**
603 | * @param string $sellCoin
604 | * @param string $buyCoin
605 | * @param int|null $limit
606 | * @param int|null $height
607 | * @return \stdClass
608 | * @throws GuzzleException
609 | */
610 | public function getLimitOrdersByCoins(
611 | string $sellCoin,
612 | string $buyCoin,
613 | int $limit = null,
614 | ?int $height = null
615 | ): \stdClass {
616 | $params = [];
617 | if ($limit) {
618 | $params['limit'] = $limit;
619 | }
620 |
621 | if ($height) {
622 | $params['height'] = $height;
623 | }
624 |
625 | return $this->get('limit_orders/' . $sellCoin . '/' . $buyCoin, $params);
626 | }
627 | }
628 |
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterCheck.php:
--------------------------------------------------------------------------------
1 | rlp = new RLP;
61 |
62 | if(is_array($checkOrAddress)) {
63 | $this->structure = $this->defineProperties($checkOrAddress);
64 | }
65 |
66 | if(is_string($checkOrAddress) && !$passphrase) {
67 | $this->structure = $this->decode($checkOrAddress);
68 | }
69 | else if(is_string($checkOrAddress)) {
70 | $this->minterAddress = $checkOrAddress;
71 | }
72 |
73 | $this->passphrase = $passphrase;
74 | }
75 |
76 | /**
77 | * Get check structure.
78 | *
79 | * @return array
80 | */
81 | public function getBody(): array
82 | {
83 | return $this->structure;
84 | }
85 |
86 | /**
87 | * Get owner address from decoded check.
88 | *
89 | * @return string
90 | */
91 | public function getOwnerAddress(): string
92 | {
93 | return $this->minterAddress;
94 | }
95 |
96 | /**
97 | * Sign check.
98 | *
99 | * @param string $privateKey
100 | * @return string
101 | */
102 | public function sign(string $privateKey): string
103 | {
104 | // create message hash and passphrase by first 4 fields
105 | $msgHash = $this->serialize(array_slice($this->structure, 0, 6));
106 |
107 | $passphrase = hash('sha256', $this->passphrase);
108 |
109 | // create elliptic curve and sign
110 | $signature = ECDSA::sign($msgHash, $passphrase);
111 |
112 | // define lock field
113 | $this->structure['lock'] = hex2bin($this->formatLockFromSignature($signature));
114 |
115 | // create message hash with lock field
116 | $msgHashWithLock = $this->serialize(array_slice($this->structure, 0, 7));
117 |
118 | // create signature
119 | $signature = ECDSA::sign($msgHashWithLock, $privateKey);
120 | $this->structure = array_merge($this->structure, Helper::hex2buffer($signature));
121 |
122 | // rlp encode data and add Minter wallet prefix
123 | return MinterPrefix::CHECK . $this->rlp->encode($this->structure);
124 | }
125 |
126 | /**
127 | * Create proof by address and passphrase.
128 | *
129 | * @return string
130 | * @throws \Exception
131 | */
132 | public function createProof(): string
133 | {
134 | if(!$this->minterAddress) {
135 | throw new \Exception('Minter address is not defined');
136 | }
137 |
138 | // create msg hash of address
139 | $minterAddress = [hex2bin(Helper::removeWalletPrefix($this->minterAddress))];
140 | $addressHash = $this->serialize($minterAddress);
141 |
142 | // get SHA 256 hash of password and create EC signature
143 | $passphrase = hash('sha256', $this->passphrase);
144 | $signature = ECDSA::sign($addressHash, $passphrase);
145 |
146 | // return formatted proof
147 | return $this->formatLockFromSignature($signature);
148 | }
149 |
150 | /**
151 | * Decode check.
152 | *
153 | * @param string $check
154 | * @return array
155 | */
156 | protected function decode(string $check): array
157 | {
158 | // prepare check string and convert to hex array
159 | $check = Helper::removePrefix($check, MinterPrefix::CHECK);
160 | $check = $this->rlp->decode('0x' . $check);
161 |
162 | // prepare decoded data
163 | foreach ($check as $key => $value) {
164 | $field = $this->structure[$key];
165 |
166 | switch ($field) {
167 | case 'nonce':
168 | $data[$field] = Helper::hex2str($value);
169 | break;
170 |
171 | case 'value':
172 | $data[$field] = MinterConverter::convertToBase(Helper::hexDecode($value));
173 | break;
174 |
175 | default:
176 | $data[$field] = (string) $value;
177 | if(in_array($field, ['dueBlock', 'v', 'chainId', 'coin', 'gasCoin'])) {
178 | $data[$field] = hexdec($value);
179 | }
180 | break;
181 | }
182 | }
183 |
184 | // set owner address
185 | list($body, $signature) = array_chunk($data, 7, true);
186 | $this->setOwnerAddress($body, $signature);
187 |
188 | return $data;
189 | }
190 |
191 | /**
192 | * Set check owner address.
193 | *
194 | * @param array $body
195 | * @param array $signature
196 | */
197 | protected function setOwnerAddress(array $body, array $signature): void
198 | {
199 | // encode check to rlp
200 | $lock = array_pop($body);
201 | $check = $this->encode($body);
202 | $check['lock'] = hex2bin($lock);
203 |
204 | // create keccak hash from check
205 | $msg = $this->serialize($check);
206 |
207 | // recover public key
208 | $signature = new Signature([
209 | 'r' => (string) $signature['r'],
210 | 's' => (string) $signature['s'],
211 | 'recoveryParam' => (int) $signature['v']
212 | ]);
213 |
214 | $publicKey = ECDSA::recover($msg, $signature);
215 | $publicKey = MinterPrefix::PUBLIC_KEY . $publicKey;
216 |
217 | $this->minterAddress = MinterWallet::getAddressFromPublicKey($publicKey);
218 | }
219 |
220 | /**
221 | * Merge input fields with structure.
222 | *
223 | * @param array $check
224 | * @return array
225 | * @throws \Exception
226 | */
227 | protected function defineProperties(array $check): array
228 | {
229 | $structure = array_flip($this->structure);
230 |
231 | if(!$this->validateFields($check)) {
232 | throw new \Exception('Invalid fields');
233 | }
234 |
235 | return array_merge($structure, $this->encode($check));
236 | }
237 |
238 | /**
239 | * Encode input fields.
240 | *
241 | * @param array $check
242 | * @return array
243 | */
244 | protected function encode(array $check): array
245 | {
246 | return [
247 | 'nonce' => Helper::hexDecode(
248 | Helper::str2hex($check['nonce'])
249 | ),
250 |
251 | 'chainId' => dechex($check['chainId']),
252 |
253 | 'dueBlock' => $check['dueBlock'],
254 |
255 | 'coin' => dechex($check['coin']),
256 |
257 | 'value' => MinterConverter::convertToPip($check['value']),
258 |
259 | 'gasCoin' => dechex($check['gasCoin'])
260 | ];
261 | }
262 |
263 | /**
264 | * Create message Keccak hash from structure fields limited by number of fields.
265 | *
266 | * @return array
267 | */
268 | protected function serialize($data): string
269 | {
270 | // create msg hash with lock field
271 | $msgHash = $this->rlp->encode($data);
272 |
273 | return Helper::createKeccakHash($msgHash);
274 | }
275 |
276 | /**
277 | * Validate that input fields are correct.
278 | *
279 | * @param array $fields
280 | * @return bool
281 | */
282 | protected function validateFields(array $fields): bool
283 | {
284 | $structure = array_flip($this->structure);
285 |
286 | foreach ($fields as $field => $fieldValue) {
287 | if(!isset($structure[$field])) {
288 | return false;
289 | }
290 |
291 | if($field === 'nonce' && strlen($fieldValue) > 32) {
292 | return false;
293 | }
294 | }
295 |
296 | return true;
297 | }
298 |
299 | /**
300 | * Prepare lock field.
301 | *
302 | * @param array $signature
303 | * @return string
304 | */
305 | protected function formatLockFromSignature(array $signature): string
306 | {
307 | $r = str_pad($signature['r'], 64, '0', STR_PAD_LEFT);
308 | $s = str_pad($signature['s'], 64, '0', STR_PAD_LEFT);
309 | $recovery = hexdec($signature['v']) === ECDSA::V_BITS ? '00' : '01';
310 |
311 | return $r . $s. $recovery;
312 | }
313 | }
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterCoins/MinterAddLimitOrderTx.php:
--------------------------------------------------------------------------------
1 | coinToSell = $coinToSell;
31 | $this->coinToBuy = $coinToBuy;
32 | $this->valueToSell = $valueToSell;
33 | $this->valueToBuy = $valueToBuy;
34 | }
35 |
36 | /**
37 | * Prepare data for signing
38 | *
39 | * @return array
40 | */
41 | function encodeData(): array
42 | {
43 | return [
44 | $this->coinToSell,
45 | MinterConverter::convertToPip($this->valueToSell),
46 | $this->coinToBuy,
47 | MinterConverter::convertToPip($this->valueToBuy)
48 | ];
49 | }
50 |
51 | function decodeData()
52 | {
53 | $this->coinToSell = hexdec($this->coinToSell);
54 | $this->coinToBuy = hexdec($this->coinToBuy);
55 | $this->valueToSell = MinterConverter::convertToBase(Helper::hexDecode($this->valueToSell));
56 | $this->valueToBuy = MinterConverter::convertToBase(Helper::hexDecode($this->valueToBuy));
57 | }
58 | }
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterCoins/MinterAddLiquidityTx.php:
--------------------------------------------------------------------------------
1 | coin0 = $coin0;
33 | $this->coin1 = $coin1;
34 | $this->volume0 = $volume0;
35 | $this->maximumVolume1 = $maximumVolume1;
36 | }
37 |
38 | /**
39 | * Prepare data for signing
40 | *
41 | * @return array
42 | */
43 | function encodeData(): array
44 | {
45 | return [
46 | $this->coin0,
47 | $this->coin1,
48 | MinterConverter::convertToPip($this->volume0),
49 | MinterConverter::convertToPip($this->maximumVolume1)
50 | ];
51 | }
52 |
53 | function decodeData()
54 | {
55 | $this->coin0 = hexdec($this->coin0);
56 | $this->coin1 = hexdec($this->coin1);
57 | $this->volume0 = MinterConverter::convertToBase(Helper::hexDecode($this->volume0));
58 | $this->maximumVolume1 = MinterConverter::convertToBase(Helper::hexDecode($this->maximumVolume1));
59 | }
60 | }
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterCoins/MinterBurnTokenTx.php:
--------------------------------------------------------------------------------
1 | coin = $coin;
28 | $this->value = $value;
29 | }
30 |
31 | /**
32 | * Prepare data for signing
33 | *
34 | * @return array
35 | */
36 | public function encodeData(): array
37 | {
38 | return [
39 | $this->coin,
40 | MinterConverter::convertToPip($this->value)
41 | ];
42 | }
43 |
44 | public function decodeData()
45 | {
46 | $this->coin = hexdec($this->coin);
47 | $this->value = MinterConverter::convertToBase(Helper::hexDecode($this->value));
48 | }
49 | }
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterCoins/MinterBuyCoinTx.php:
--------------------------------------------------------------------------------
1 | coinToBuy = $coinToBuy;
32 | $this->coinToSell = $coinToSell;
33 | $this->valueToBuy = $valueToBuy;
34 | $this->maximumValueToSell = $maximumValueToSell;
35 | }
36 |
37 | public function encodeData(): array
38 | {
39 | return [
40 | $this->coinToBuy,
41 | MinterConverter::convertToPip($this->valueToBuy),
42 | $this->coinToSell,
43 | MinterConverter::convertToPip($this->maximumValueToSell)
44 | ];
45 | }
46 |
47 | public function decodeData()
48 | {
49 | $this->coinToBuy = hexdec($this->coinToBuy);
50 | $this->valueToBuy = MinterConverter::convertToBase(Helper::hexDecode($this->valueToBuy));
51 | $this->coinToSell = hexdec($this->coinToSell);
52 | $this->maximumValueToSell = MinterConverter::convertToBase(Helper::hexDecode($this->maximumValueToSell));
53 | }
54 | }
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterCoins/MinterBuySwapPoolTx.php:
--------------------------------------------------------------------------------
1 | coins = $coins;
31 | $this->valueToBuy = $valueToBuy;
32 | $this->maximumValueToSell = $maximumValueToSell;
33 | }
34 |
35 | public function encodeData(): array
36 | {
37 | return [
38 | $this->coins,
39 | MinterConverter::convertToPip($this->valueToBuy),
40 | MinterConverter::convertToPip($this->maximumValueToSell)
41 | ];
42 | }
43 |
44 | public function decodeData()
45 | {
46 | $this->valueToBuy = MinterConverter::convertToBase(Helper::hexDecode($this->valueToBuy));
47 | $this->maximumValueToSell = MinterConverter::convertToBase(Helper::hexDecode($this->maximumValueToSell));
48 | $this->coins = array_map(function ($value) {
49 | return hexdec($value);
50 | }, $this->coins);
51 | }
52 | }
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterCoins/MinterCoinTx.php:
--------------------------------------------------------------------------------
1 | MinterSendCoinTx::class,
17 | MinterSellCoinTx::TYPE => MinterSellCoinTx::class,
18 | MinterSellAllCoinTx::TYPE => MinterSellAllCoinTx::class,
19 | MinterBuyCoinTx::TYPE => MinterBuyCoinTx::class,
20 | MinterCreateCoinTx::TYPE => MinterCreateCoinTx::class,
21 | MinterDeclareCandidacyTx::TYPE => MinterDeclareCandidacyTx::class,
22 | MinterDelegateTx::TYPE => MinterDelegateTx::class,
23 | MinterUnbondTx::TYPE => MinterUnbondTx::class,
24 | MinterRedeemCheckTx::TYPE => MinterRedeemCheckTx::class,
25 | MinterSetCandidateOnTx::TYPE => MinterSetCandidateOnTx::class,
26 | MinterSetCandidateOffTx::TYPE => MinterSetCandidateOffTx::class,
27 | MinterCreateMultisigTx::TYPE => MinterCreateMultisigTx::class,
28 | MinterMultiSendTx::TYPE => MinterMultiSendTx::class,
29 | MinterEditCandidateTx::TYPE => MinterEditCandidateTx::class,
30 | MinterRecreateCoinTx::TYPE => MinterRecreateCoinTx::class,
31 | MinterEditCoinOwnerTx::TYPE => MinterEditCoinOwnerTx::class,
32 | MinterSetHaltBlockTx::TYPE => MinterSetHaltBlockTx::class,
33 | MinterEditMultisigTx::TYPE => MinterEditMultisigTx::class,
34 | MinterEditCandidatePublicKeyTx::TYPE => MinterEditCandidatePublicKeyTx::class,
35 | MinterAddLiquidityTx::TYPE => MinterAddLiquidityTx::class,
36 | MinterRemoveLiquidityTx::TYPE => MinterRemoveLiquidityTx::class,
37 | MinterSellSwapPoolTx::TYPE => MinterSellSwapPoolTx::class,
38 | MinterBuySwapPoolTx::TYPE => MinterBuySwapPoolTx::class,
39 | MinterSellAllSwapPoolTx::TYPE => MinterSellAllSwapPoolTx::class,
40 | MinterEditCandidateCommissionTx::TYPE => MinterEditCandidateCommissionTx::class,
41 | MinterMintTokenTx::TYPE => MinterMintTokenTx::class,
42 | MinterBurnTokenTx::TYPE => MinterBurnTokenTx::class,
43 | MinterCreateTokenTx::TYPE => MinterCreateTokenTx::class,
44 | MinterRecreateTokenTx::TYPE => MinterRecreateTokenTx::class,
45 | MinterPriceCommissionTx::TYPE => MinterPriceCommissionTx::class,
46 | MinterCreateSwapPoolTx::TYPE => MinterCreateSwapPoolTx::class,
47 | MinterAddLimitOrderTx::TYPE => MinterAddLimitOrderTx::class,
48 | MinterRemoveLimitOrderTx::TYPE => MinterRemoveLimitOrderTx::class,
49 | MinterMoveStakeTx::TYPE => MinterMoveStakeTx::class,
50 | MinterLockStakeTx::TYPE => MinterLockStakeTx::class,
51 | MinterLockTx::TYPE => MinterLockTx::class,
52 | MinterVoteUpdateTx::TYPE => MinterVoteUpdateTx::class,
53 | ];
54 |
55 | /**
56 | * @return int
57 | */
58 | public function getType(): int
59 | {
60 | return static::TYPE;
61 | }
62 |
63 | /**
64 | * @return Buffer
65 | */
66 | public function encode(): Buffer
67 | {
68 | $rlp = new RLP();
69 | return $rlp->encode($this->encodeData());
70 | }
71 |
72 | /**
73 | * Prepare data tx for signing
74 | *
75 | * @return array
76 | */
77 | abstract function encodeData(): array;
78 |
79 | /**
80 | * Prepare output tx data
81 | */
82 | abstract function decodeData();
83 | }
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterCoins/MinterCreateCoinTx.php:
--------------------------------------------------------------------------------
1 | name = $name;
36 | $this->symbol = $symbol;
37 | $this->amount = $amount;
38 | $this->reserve = $reserve;
39 | $this->crr = $crr;
40 | $this->maxSupply = $maxSupply;
41 | }
42 |
43 | /**
44 | * Prepare tx data for signing
45 | *
46 | * @return array
47 | */
48 | public function encodeData(): array
49 | {
50 | return [
51 | $this->name,
52 | MinterConverter::convertCoinName($this->symbol),
53 | MinterConverter::convertToPip($this->amount),
54 | MinterConverter::convertToPip($this->reserve),
55 | $this->crr === 0 ? '' : $this->crr,
56 | MinterConverter::convertToPip($this->maxSupply)
57 | ];
58 | }
59 |
60 | public function decodeData()
61 | {
62 | $this->name = Helper::hex2str($this->name);
63 | $this->symbol = Helper::hex2str($this->symbol);
64 | $this->amount = MinterConverter::convertToBase(Helper::hexDecode($this->amount));
65 | $this->reserve = MinterConverter::convertToBase(Helper::hexDecode($this->reserve));
66 | $this->crr = hexdec($this->crr);
67 | $this->maxSupply = MinterConverter::convertToBase(Helper::hexDecode($this->maxSupply));
68 | }
69 | }
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterCoins/MinterCreateMultisigTx.php:
--------------------------------------------------------------------------------
1 | threshold = $threshold;
29 | $this->weights = $weights;
30 | $this->addresses = $addresses;
31 | }
32 |
33 | /**
34 | * Prepare data for signing
35 | *
36 | * @return array
37 | */
38 | public function encodeData(): array
39 | {
40 | $addresses = [];
41 | foreach ($this->addresses as $address) {
42 | $address = Helper::removeWalletPrefix($address);
43 | $addresses[] = hex2bin($address);
44 | }
45 |
46 | $weights = [];
47 | foreach ($this->weights as $weight) {
48 | $weights[] = $weight === 0 ? '' : $weight;
49 | }
50 |
51 | $threshold = $this->threshold === 0 ? '' : $this->threshold;
52 |
53 | return [
54 | $threshold,
55 | $weights,
56 | $addresses,
57 | ];
58 | }
59 |
60 | public function decodeData()
61 | {
62 | $threshold = (int)Helper::hexDecode($this->threshold);
63 |
64 | $weights = [];
65 | foreach ($this->weights as $weight) {
66 | $weights[] = hexdec($weight);
67 | }
68 |
69 | $addresses = [];
70 | foreach ($this->addresses as $address) {
71 | $addresses[] = Helper::addWalletPrefix($address);
72 | }
73 |
74 | $this->threshold = $threshold;
75 | $this->weights = $weights;
76 | $this->addresses = $addresses;
77 | }
78 | }
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterCoins/MinterCreateSwapPoolTx.php:
--------------------------------------------------------------------------------
1 | coin0 = $coin0;
33 | $this->coin1 = $coin1;
34 | $this->volume0 = $volume0;
35 | $this->volume1 = $volume1;
36 | }
37 |
38 | /**
39 | * Prepare data for signing
40 | *
41 | * @return array
42 | */
43 | function encodeData(): array
44 | {
45 | return [
46 | $this->coin0,
47 | $this->coin1,
48 | MinterConverter::convertToPip($this->volume0),
49 | MinterConverter::convertToPip($this->volume1)
50 | ];
51 | }
52 |
53 | function decodeData()
54 | {
55 | $this->coin0 = hexdec($this->coin0);
56 | $this->coin1 = hexdec($this->coin1);
57 | $this->volume0 = MinterConverter::convertToBase(Helper::hexDecode($this->volume0));
58 | $this->volume1 = MinterConverter::convertToBase(Helper::hexDecode($this->volume1));
59 | }
60 | }
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterCoins/MinterCreateTokenTx.php:
--------------------------------------------------------------------------------
1 | name = $name;
36 | $this->symbol = $symbol;
37 | $this->initialAmount = $initialAmount;
38 | $this->maxSupply = $maxSupply;
39 | $this->mintable = $mintable;
40 | $this->burnable = $burnable;
41 | }
42 |
43 | /**
44 | * Prepare tx data for signing
45 | *
46 | * @return array
47 | */
48 | public function encodeData(): array
49 | {
50 | return [
51 | $this->name,
52 | MinterConverter::convertCoinName($this->symbol),
53 | MinterConverter::convertToPip($this->initialAmount),
54 | MinterConverter::convertToPip($this->maxSupply),
55 | (int) $this->mintable,
56 | (int) $this->burnable
57 | ];
58 | }
59 |
60 | public function decodeData()
61 | {
62 | $this->name = Helper::hex2str($this->name);
63 | $this->symbol = Helper::hex2str($this->symbol);
64 | $this->initialAmount = MinterConverter::convertToBase(Helper::hexDecode($this->initialAmount));
65 | $this->maxSupply = MinterConverter::convertToBase(Helper::hexDecode($this->maxSupply));
66 | $this->mintable = (bool) hexdec($this->mintable);
67 | $this->burnable = (bool) hexdec($this->burnable);
68 | }
69 | }
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterCoins/MinterDeclareCandidacyTx.php:
--------------------------------------------------------------------------------
1 | address = $address;
35 | $this->publicKey = $publicKey;
36 | $this->commission = $commission;
37 | $this->coin = $coin;
38 | $this->stake = $stake;
39 | }
40 |
41 | /**
42 | * Prepare data for signing
43 | *
44 | * @return array
45 | */
46 | public function encodeData(): array
47 | {
48 | return [
49 | hex2bin(Helper::removeWalletPrefix($this->address)),
50 | hex2bin(Helper::removePrefix($this->publicKey, MinterPrefix::PUBLIC_KEY)),
51 | $this->commission === 0 ? '' : $this->commission,
52 | $this->coin,
53 | MinterConverter::convertToPip($this->stake)
54 | ];
55 | }
56 |
57 | public function decodeData()
58 | {
59 | $this->address = Helper::addWalletPrefix($this->address);
60 | $this->publicKey = MinterPrefix::PUBLIC_KEY . $this->publicKey;
61 | $this->commission = (int) Helper::hexDecode($this->commission);
62 | $this->coin = hexdec($this->coin);
63 | $this->stake = MinterConverter::convertToBase(Helper::hexDecode($this->stake));
64 | }
65 | }
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterCoins/MinterDelegateTx.php:
--------------------------------------------------------------------------------
1 | publicKey = $publicKey;
31 | $this->coin = $coin;
32 | $this->stake = $stake;
33 | }
34 |
35 | /**
36 | * Prepare data for signing
37 | *
38 | * @return array
39 | */
40 | public function encodeData(): array
41 | {
42 | return [
43 | hex2bin(Helper::removePrefix($this->publicKey, MinterPrefix::PUBLIC_KEY)),
44 | $this->coin,
45 | MinterConverter::convertToPip($this->stake)
46 | ];
47 | }
48 |
49 | public function decodeData()
50 | {
51 | $this->publicKey = MinterPrefix::PUBLIC_KEY . $this->publicKey;
52 | $this->coin = hexdec($this->coin);
53 | $this->stake = MinterConverter::convertToBase(Helper::hexDecode($this->stake));
54 | }
55 | }
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterCoins/MinterEditCandidateCommissionTx.php:
--------------------------------------------------------------------------------
1 | publicKey = $publicKey;
29 | $this->commission = $commission;
30 | }
31 |
32 | /**
33 | * Prepare data for signing
34 | *
35 | * @return array
36 | */
37 | public function encodeData(): array
38 | {
39 | return [
40 | hex2bin(Helper::removePrefix($this->publicKey, MinterPrefix::PUBLIC_KEY)),
41 | $this->commission === 0 ? '' : $this->commission
42 | ];
43 | }
44 |
45 | public function decodeData()
46 | {
47 | $this->publicKey = MinterPrefix::PUBLIC_KEY . $this->publicKey;
48 | $this->commission = (int) Helper::hexDecode($this->commission);
49 | }
50 | }
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterCoins/MinterEditCandidatePublicKeyTx.php:
--------------------------------------------------------------------------------
1 | publicKey = $publicKey;
28 | $this->newPublicKey = $newPublicKey;
29 | }
30 |
31 | /**
32 | * Prepare data for signing
33 | *
34 | * @return array
35 | */
36 | public function encodeData(): array
37 | {
38 | return [
39 | hex2bin(Helper::removePrefix($this->publicKey, MinterPrefix::PUBLIC_KEY)),
40 | hex2bin(Helper::removePrefix($this->newPublicKey, MinterPrefix::PUBLIC_KEY)),
41 | ];
42 | }
43 |
44 | public function decodeData()
45 | {
46 | $this->publicKey = MinterPrefix::PUBLIC_KEY . $this->publicKey;
47 | $this->newPublicKey = MinterPrefix::PUBLIC_KEY . $this->newPublicKey;
48 | }
49 | }
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterCoins/MinterEditCandidateTx.php:
--------------------------------------------------------------------------------
1 | publicKey = $publicKey;
32 | $this->rewardAddress = $rewardAddress;
33 | $this->ownerAddress = $ownerAddress;
34 | $this->controlAddress = $controlAddress;
35 | }
36 |
37 | /**
38 | * Prepare data for signing
39 | *
40 | * @return array
41 | */
42 | public function encodeData(): array
43 | {
44 | return [
45 | hex2bin(Helper::removePrefix($this->publicKey, MinterPrefix::PUBLIC_KEY)),
46 | hex2bin(Helper::removeWalletPrefix($this->rewardAddress)),
47 | hex2bin(Helper::removeWalletPrefix($this->ownerAddress)),
48 | hex2bin(Helper::removeWalletPrefix($this->controlAddress))
49 | ];
50 | }
51 |
52 | public function decodeData()
53 | {
54 | $this->publicKey = MinterPrefix::PUBLIC_KEY . $this->publicKey;
55 | $this->rewardAddress = Helper::addWalletPrefix($this->rewardAddress);
56 | $this->ownerAddress = Helper::addWalletPrefix($this->ownerAddress);
57 | $this->controlAddress = Helper::addWalletPrefix($this->controlAddress);
58 | }
59 | }
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterCoins/MinterEditCoinOwnerTx.php:
--------------------------------------------------------------------------------
1 | symbol = $symbol;
28 | $this->newOwner = $newOwner;
29 | }
30 |
31 | /**
32 | * Prepare tx data for signing
33 | *
34 | * @return array
35 | */
36 | public function encodeData(): array
37 | {
38 | return [
39 | MinterConverter::convertCoinName($this->symbol),
40 | hex2bin(Helper::removeWalletPrefix($this->newOwner)),
41 | ];
42 | }
43 |
44 | public function decodeData()
45 | {
46 | $this->symbol = Helper::hex2str($this->symbol);
47 | $this->newOwner = Helper::addWalletPrefix($this->newOwner);
48 | }
49 | }
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterCoins/MinterEditMultisigTx.php:
--------------------------------------------------------------------------------
1 | threshold = $threshold;
29 | $this->weights = $weights;
30 | $this->addresses = $addresses;
31 | }
32 |
33 | /**
34 | * Prepare tx data for signing
35 | *
36 | * @return array
37 | */
38 | public function encodeData(): array
39 | {
40 | $addresses = [];
41 | foreach ($this->addresses as $address) {
42 | $address = Helper::removeWalletPrefix($address);
43 | $addresses[] = hex2bin($address);
44 | }
45 |
46 | $weights = [];
47 | foreach ($this->weights as $weight) {
48 | $weights[] = $weight === 0 ? '' : $weight;
49 | }
50 |
51 | $threshold = $this->threshold === 0 ? '' : $this->threshold;
52 |
53 | return [
54 | $threshold,
55 | $weights,
56 | $addresses
57 | ];
58 | }
59 |
60 | public function decodeData()
61 | {
62 | $threshold = hexdec($this->threshold);
63 |
64 | $weights = [];
65 | foreach ($this->weights as $weight) {
66 | $weights[] = hexdec($weight);
67 | }
68 |
69 | $addresses = [];
70 | foreach ($this->addresses as $address) {
71 | $addresses[] = Helper::addWalletPrefix($address);
72 | }
73 |
74 | $this->threshold = $threshold;
75 | $this->weights = $weights;
76 | $this->addresses = $addresses;
77 | }
78 | }
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterCoins/MinterLockStakeTx.php:
--------------------------------------------------------------------------------
1 | dueBlock = $dueBlock;
29 | $this->coin = $coin;
30 | $this->value = $value;
31 | }
32 |
33 | /**
34 | * Prepare data for signing
35 | *
36 | * @return array
37 | */
38 | function encodeData(): array
39 | {
40 | return [
41 | $this->dueBlock,
42 | $this->coin,
43 | MinterConverter::convertToPip($this->value),
44 | ];
45 | }
46 |
47 | function decodeData()
48 | {
49 | $this->dueBlock = hexdec($this->dueBlock);
50 | $this->coin = hexdec($this->coin);
51 | $this->value = MinterConverter::convertToBase(Helper::hexDecode($this->value));
52 | }
53 | }
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterCoins/MinterMintTokenTx.php:
--------------------------------------------------------------------------------
1 | coin = $coin;
28 | $this->value = $value;
29 | }
30 |
31 | /**
32 | * Prepare data for signing
33 | *
34 | * @return array
35 | */
36 | public function encodeData(): array
37 | {
38 | return [
39 | $this->coin,
40 | MinterConverter::convertToPip($this->value)
41 | ];
42 | }
43 |
44 | public function decodeData()
45 | {
46 | $this->coin = hexdec($this->coin);
47 | $this->value = MinterConverter::convertToBase(Helper::hexDecode($this->value));
48 | }
49 | }
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterCoins/MinterMoveStakeTx.php:
--------------------------------------------------------------------------------
1 | fromPubKey = $fromPubKey;
32 | $this->toPubKey = $toPubKey;
33 | $this->coin = $coin;
34 | $this->value = $value;
35 | }
36 |
37 | /**
38 | * Prepare data for signing
39 | *
40 | * @return array
41 | */
42 | function encodeData(): array
43 | {
44 | return [
45 | hex2bin(Helper::removePrefix($this->fromPubKey, MinterPrefix::PUBLIC_KEY)),
46 | hex2bin(Helper::removePrefix($this->toPubKey, MinterPrefix::PUBLIC_KEY)),
47 | $this->coin,
48 | MinterConverter::convertToPip($this->value),
49 | ];
50 | }
51 |
52 | function decodeData()
53 | {
54 | $this->fromPubKey = MinterPrefix::PUBLIC_KEY . $this->fromPubKey;
55 | $this->toPubKey = MinterPrefix::PUBLIC_KEY . $this->toPubKey;
56 | $this->coin = hexdec($this->coin);
57 | $this->value = MinterConverter::convertToBase(Helper::hexDecode($this->value));
58 | }
59 | }
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterCoins/MinterMultiSendTx.php:
--------------------------------------------------------------------------------
1 | list = $list;
24 | }
25 |
26 | /**
27 | * Prepare tx data for signing
28 | *
29 | * @return array
30 | */
31 | public function encodeData(): array
32 | {
33 | $list = ['list' => []];
34 |
35 | foreach ($this->list as $key => $data) {
36 | /** @var $data MinterSendCoinTx */
37 | $list['list'][$key] = $data->encodeData();
38 | }
39 |
40 | return $list;
41 | }
42 |
43 | public function decodeData()
44 | {
45 | foreach ($this->list as $key => $data) {
46 | $send = new MinterSendCoinTx(...$data);
47 | $send->decodeData();
48 |
49 | $this->list[$key] = $send;
50 | }
51 | }
52 | }
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterCoins/MinterPriceCommissionTx.php:
--------------------------------------------------------------------------------
1 | pubKey = $pubKey;
159 | $this->height = $height;
160 | $this->coin = $coin;
161 | $this->payloadByte = $payloadByte;
162 | $this->send = $send;
163 | $this->buyBancor = $buyBancor;
164 | $this->sellBancor = $sellBancor;
165 | $this->sellAllBancor = $sellAllBancor;
166 | $this->buyPoolBase = $buyPoolBase;
167 | $this->buyPoolDelta = $buyPoolDelta;
168 | $this->sellPoolBase = $sellPoolBase;
169 | $this->sellPoolDelta = $sellPoolDelta;
170 | $this->sellAllPoolBase = $sellAllPoolBase;
171 | $this->sellAllPoolDelta = $sellAllPoolDelta;
172 | $this->createTicker3 = $createTicker3;
173 | $this->createTicker4 = $createTicker4;
174 | $this->createTicker5 = $createTicker5;
175 | $this->createTicker6 = $createTicker6;
176 | $this->createTicker7to10 = $createTicker7to10;
177 | $this->createCoin = $createCoin;
178 | $this->createToken = $createToken;
179 | $this->recreateCoin = $recreateCoin;
180 | $this->recreateToken = $recreateToken;
181 | $this->declareCandidacy = $declareCandidacy;
182 | $this->delegate = $delegate;
183 | $this->unbond = $unbond;
184 | $this->redeemCheck = $redeemCheck;
185 | $this->setCandidateOn = $setCandidateOn;
186 | $this->setCandidateOff = $setCandidateOff;
187 | $this->createMultisig = $createMultisig;
188 | $this->multisendBase = $multisendBase;
189 | $this->multisendDelta = $multisendDelta;
190 | $this->editCandidate = $editCandidate;
191 | $this->setHaltBlock = $setHaltBlock;
192 | $this->editTickerOwner = $editTickerOwner;
193 | $this->editMultisig = $editMultisig;
194 | $this->editCandidatePublicKey = $editCandidatePublicKey;
195 | $this->createSwapPool = $createSwapPool;
196 | $this->addLiquidity = $addLiquidity;
197 | $this->removeLiquidity = $removeLiquidity;
198 | $this->editCandidateCommission = $editCandidateCommission;
199 | $this->burnToken = $burnToken;
200 | $this->mintToken = $mintToken;
201 | $this->voteCommission = $voteCommission;
202 | $this->voteUpdate = $voteUpdate;
203 | }
204 |
205 | /**
206 | * Prepare tx data for signing
207 | *
208 | * @return array
209 | */
210 | function encodeData(): array
211 | {
212 | return [
213 | hex2bin(Helper::removePrefix($this->pubKey, MinterPrefix::PUBLIC_KEY)),
214 | $this->height,
215 | $this->coin,
216 | MinterConverter::convertToPip($this->payloadByte),
217 | MinterConverter::convertToPip($this->send),
218 | MinterConverter::convertToPip($this->buyBancor),
219 | MinterConverter::convertToPip($this->sellBancor),
220 | MinterConverter::convertToPip($this->sellAllBancor),
221 | MinterConverter::convertToPip($this->buyPoolBase),
222 | MinterConverter::convertToPip($this->buyPoolDelta),
223 | MinterConverter::convertToPip($this->sellPoolBase),
224 | MinterConverter::convertToPip($this->sellPoolDelta),
225 | MinterConverter::convertToPip($this->sellAllPoolBase),
226 | MinterConverter::convertToPip($this->sellAllPoolDelta),
227 | MinterConverter::convertToPip($this->createTicker3),
228 | MinterConverter::convertToPip($this->createTicker4),
229 | MinterConverter::convertToPip($this->createTicker5),
230 | MinterConverter::convertToPip($this->createTicker6),
231 | MinterConverter::convertToPip($this->createTicker7to10),
232 | MinterConverter::convertToPip($this->createCoin),
233 | MinterConverter::convertToPip($this->createToken),
234 | MinterConverter::convertToPip($this->recreateCoin),
235 | MinterConverter::convertToPip($this->recreateToken),
236 | MinterConverter::convertToPip($this->declareCandidacy),
237 | MinterConverter::convertToPip($this->delegate),
238 | MinterConverter::convertToPip($this->unbond),
239 | MinterConverter::convertToPip($this->redeemCheck),
240 | MinterConverter::convertToPip($this->setCandidateOn),
241 | MinterConverter::convertToPip($this->setCandidateOff),
242 | MinterConverter::convertToPip($this->createMultisig),
243 | MinterConverter::convertToPip($this->multisendBase),
244 | MinterConverter::convertToPip($this->multisendDelta),
245 | MinterConverter::convertToPip($this->editCandidate),
246 | MinterConverter::convertToPip($this->setHaltBlock),
247 | MinterConverter::convertToPip($this->editTickerOwner),
248 | MinterConverter::convertToPip($this->editMultisig),
249 | MinterConverter::convertToPip($this->editCandidatePublicKey),
250 | MinterConverter::convertToPip($this->createSwapPool),
251 | MinterConverter::convertToPip($this->addLiquidity),
252 | MinterConverter::convertToPip($this->removeLiquidity),
253 | MinterConverter::convertToPip($this->editCandidateCommission),
254 | MinterConverter::convertToPip($this->burnToken),
255 | MinterConverter::convertToPip($this->mintToken),
256 | MinterConverter::convertToPip($this->voteCommission),
257 | MinterConverter::convertToPip($this->voteUpdate)
258 | ];
259 | }
260 |
261 |
262 | function decodeData()
263 | {
264 | $this->pubKey = MinterPrefix::PUBLIC_KEY . $this->pubKey;
265 | $this->height = (int)hexdec($this->height);
266 | $this->coin = hexdec($this->coin);
267 | $this->payloadByte = MinterConverter::convertToBase(Helper::hexDecode($this->payloadByte));
268 | $this->send = MinterConverter::convertToBase(Helper::hexDecode($this->send));
269 | $this->buyBancor = MinterConverter::convertToBase(Helper::hexDecode($this->buyBancor));
270 | $this->sellBancor = MinterConverter::convertToBase(Helper::hexDecode($this->sellBancor));
271 | $this->sellAllBancor = MinterConverter::convertToBase(Helper::hexDecode($this->sellAllBancor));
272 | $this->buyPoolBase = MinterConverter::convertToBase(Helper::hexDecode($this->buyPoolBase));
273 | $this->buyPoolDelta = MinterConverter::convertToBase(Helper::hexDecode($this->buyPoolDelta));
274 | $this->sellPoolBase = MinterConverter::convertToBase(Helper::hexDecode($this->sellPoolBase));
275 | $this->sellPoolDelta = MinterConverter::convertToBase(Helper::hexDecode($this->sellPoolDelta));
276 | $this->sellAllPoolBase = MinterConverter::convertToBase(Helper::hexDecode($this->sellAllPoolBase));
277 | $this->sellAllPoolDelta = MinterConverter::convertToBase(Helper::hexDecode($this->sellAllPoolDelta));
278 | $this->createTicker3 = MinterConverter::convertToBase(Helper::hexDecode($this->createTicker3));
279 | $this->createTicker4 = MinterConverter::convertToBase(Helper::hexDecode($this->createTicker4));
280 | $this->createTicker5 = MinterConverter::convertToBase(Helper::hexDecode($this->createTicker5));
281 | $this->createTicker6 = MinterConverter::convertToBase(Helper::hexDecode($this->createTicker6));
282 | $this->createTicker7to10 = MinterConverter::convertToBase(Helper::hexDecode($this->createTicker7to10));
283 | $this->createCoin = MinterConverter::convertToBase(Helper::hexDecode($this->createCoin));
284 | $this->createToken = MinterConverter::convertToBase(Helper::hexDecode($this->createToken));
285 | $this->recreateCoin = MinterConverter::convertToBase(Helper::hexDecode($this->recreateCoin));
286 | $this->recreateToken = MinterConverter::convertToBase(Helper::hexDecode($this->recreateToken));
287 | $this->declareCandidacy = MinterConverter::convertToBase(Helper::hexDecode($this->declareCandidacy));
288 | $this->delegate = MinterConverter::convertToBase(Helper::hexDecode($this->delegate));
289 | $this->unbond = MinterConverter::convertToBase(Helper::hexDecode($this->unbond));
290 | $this->redeemCheck = MinterConverter::convertToBase(Helper::hexDecode($this->redeemCheck));
291 | $this->setCandidateOn = MinterConverter::convertToBase(Helper::hexDecode($this->setCandidateOn));
292 | $this->setCandidateOff = MinterConverter::convertToBase(Helper::hexDecode($this->setCandidateOff));
293 | $this->createMultisig = MinterConverter::convertToBase(Helper::hexDecode($this->createMultisig));
294 | $this->multisendBase = MinterConverter::convertToBase(Helper::hexDecode($this->multisendBase));
295 | $this->multisendDelta = MinterConverter::convertToBase(Helper::hexDecode($this->multisendDelta));
296 | $this->editCandidate = MinterConverter::convertToBase(Helper::hexDecode($this->editCandidate));
297 | $this->setHaltBlock = MinterConverter::convertToBase(Helper::hexDecode($this->setHaltBlock));
298 | $this->editTickerOwner = MinterConverter::convertToBase(Helper::hexDecode($this->editTickerOwner));
299 | $this->editMultisig = MinterConverter::convertToBase(Helper::hexDecode($this->editMultisig));
300 | $this->editCandidatePublicKey = MinterConverter::convertToBase(Helper::hexDecode($this->editCandidatePublicKey));
301 | $this->createSwapPool = MinterConverter::convertToBase(Helper::hexDecode($this->createSwapPool));
302 | $this->addLiquidity = MinterConverter::convertToBase(Helper::hexDecode($this->addLiquidity));
303 | $this->removeLiquidity = MinterConverter::convertToBase(Helper::hexDecode($this->removeLiquidity));
304 | $this->editCandidateCommission = MinterConverter::convertToBase(Helper::hexDecode($this->editCandidateCommission));
305 | $this->burnToken = MinterConverter::convertToBase(Helper::hexDecode($this->burnToken));
306 | $this->mintToken = MinterConverter::convertToBase(Helper::hexDecode($this->mintToken));
307 | $this->voteCommission = MinterConverter::convertToBase(Helper::hexDecode($this->voteCommission));
308 | $this->voteUpdate = MinterConverter::convertToBase(Helper::hexDecode($this->voteUpdate));
309 | }
310 | }
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterCoins/MinterRecreateCoinTx.php:
--------------------------------------------------------------------------------
1 | name = $name;
36 | $this->symbol = $symbol;
37 | $this->amount = $amount;
38 | $this->reserve = $reserve;
39 | $this->crr = $crr;
40 | $this->maxSupply = $maxSupply;
41 | }
42 |
43 | /**
44 | * Prepare tx data for signing
45 | *
46 | * @return array
47 | */
48 | public function encodeData(): array
49 | {
50 | return [
51 | $this->name,
52 | MinterConverter::convertCoinName($this->symbol),
53 | MinterConverter::convertToPip($this->amount),
54 | MinterConverter::convertToPip($this->reserve),
55 | $this->crr === 0 ? '' : $this->crr,
56 | MinterConverter::convertToPip($this->maxSupply)
57 | ];
58 | }
59 |
60 | public function decodeData()
61 | {
62 | $this->name = Helper::hex2str($this->name);
63 | $this->symbol = Helper::hex2str($this->symbol);
64 | $this->amount = MinterConverter::convertToBase(Helper::hexDecode($this->amount));
65 | $this->reserve = MinterConverter::convertToBase(Helper::hexDecode($this->reserve));
66 | $this->crr = hexdec($this->crr);
67 | $this->maxSupply = MinterConverter::convertToBase(Helper::hexDecode($this->maxSupply));
68 | }
69 | }
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterCoins/MinterRecreateTokenTx.php:
--------------------------------------------------------------------------------
1 | name = $name;
36 | $this->symbol = $symbol;
37 | $this->initialAmount = $initialAmount;
38 | $this->maxSupply = $maxSupply;
39 | $this->mintable = $mintable;
40 | $this->burnable = $burnable;
41 | }
42 |
43 | /**
44 | * Prepare tx data for signing
45 | *
46 | * @return array
47 | */
48 | public function encodeData(): array
49 | {
50 | return [
51 | $this->name,
52 | MinterConverter::convertCoinName($this->symbol),
53 | MinterConverter::convertToPip($this->initialAmount),
54 | MinterConverter::convertToPip($this->maxSupply),
55 | (int) $this->mintable,
56 | (int) $this->burnable
57 | ];
58 | }
59 |
60 | public function decodeData()
61 | {
62 | $this->name = Helper::hex2str($this->name);
63 | $this->symbol = Helper::hex2str($this->symbol);
64 | $this->initialAmount = MinterConverter::convertToBase(Helper::hexDecode($this->initialAmount));
65 | $this->maxSupply = MinterConverter::convertToBase(Helper::hexDecode($this->maxSupply));
66 | $this->mintable = (bool) hexdec($this->mintable);
67 | $this->burnable = (bool) hexdec($this->burnable);
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterCoins/MinterRedeemCheckTx.php:
--------------------------------------------------------------------------------
1 | check = $check;
28 | $this->proof = $proof;
29 | }
30 |
31 | /**
32 | * Prepare data for signing
33 | *
34 | * @return array
35 | */
36 | public function encodeData(): array
37 | {
38 | return [
39 | hex2bin(Helper::removePrefix($this->check, MinterPrefix::CHECK)),
40 | hex2bin($this->proof)
41 | ];
42 | }
43 |
44 | public function decodeData()
45 | {
46 | $this->check = MinterPrefix::CHECK . $this->check;
47 | $this->proof = (string) $this->proof;
48 | }
49 | }
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterCoins/MinterRemoveLimitOrderTx.php:
--------------------------------------------------------------------------------
1 | id = $id;
23 | }
24 |
25 | /**
26 | * Prepare data for signing
27 | *
28 | * @return array
29 | */
30 | function encodeData(): array
31 | {
32 | return [
33 | $this->id,
34 | ];
35 | }
36 |
37 | function decodeData()
38 | {
39 | $this->id = hexdec($this->id);
40 | }
41 | }
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterCoins/MinterRemoveLiquidityTx.php:
--------------------------------------------------------------------------------
1 | coin0 = $coin0;
35 | $this->coin1 = $coin1;
36 | $this->liquidity = $liquidity;
37 | $this->minimumVolume0 = $minimumVolume0;
38 | $this->minimumVolume1 = $minimumVolume1;
39 | }
40 |
41 | /**
42 | * Prepare data for signing
43 | *
44 | * @return array
45 | */
46 | function encodeData(): array
47 | {
48 | return [
49 | $this->coin0,
50 | $this->coin1,
51 | MinterConverter::convertToPip($this->liquidity),
52 | MinterConverter::convertToPip($this->minimumVolume0),
53 | MinterConverter::convertToPip($this->minimumVolume1)
54 | ];
55 | }
56 |
57 | function decodeData()
58 | {
59 | $this->coin0 = hexdec($this->coin0);
60 | $this->coin1 = hexdec($this->coin1);
61 | $this->liquidity = MinterConverter::convertToBase(Helper::hexDecode($this->liquidity));
62 | $this->minimumVolume0 = MinterConverter::convertToBase(Helper::hexDecode($this->minimumVolume0));
63 | $this->minimumVolume1 = MinterConverter::convertToBase(Helper::hexDecode($this->minimumVolume1));
64 | }
65 | }
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterCoins/MinterSellAllCoinTx.php:
--------------------------------------------------------------------------------
1 | coinToBuy = $coinToBuy;
30 | $this->coinToSell = $coinToSell;
31 | $this->minimumValueToBuy = $minimumValueToBuy;
32 | }
33 |
34 | /**
35 | * Prepare tx data for signing
36 | *
37 | * @return array
38 | */
39 | public function encodeData(): array
40 | {
41 | return [
42 | $this->coinToSell,
43 | $this->coinToBuy,
44 | MinterConverter::convertToPip($this->minimumValueToBuy)
45 | ];
46 | }
47 |
48 | public function decodeData()
49 | {
50 | $this->coinToSell = hexdec($this->coinToSell);
51 | $this->coinToBuy = hexdec($this->coinToBuy);
52 | $this->minimumValueToBuy = MinterConverter::convertToBase(Helper::hexDecode($this->minimumValueToBuy));
53 | }
54 | }
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterCoins/MinterSellAllSwapPoolTx.php:
--------------------------------------------------------------------------------
1 | coins = $coins;
29 | $this->minimumValueToBuy = $minimumValueToBuy;
30 | }
31 |
32 | /**
33 | * Prepare tx data for signing
34 | *
35 | * @return array
36 | */
37 | public function encodeData(): array
38 | {
39 | return [
40 | $this->coins,
41 | MinterConverter::convertToPip($this->minimumValueToBuy)
42 | ];
43 | }
44 |
45 | public function decodeData()
46 | {
47 | $this->minimumValueToBuy = MinterConverter::convertToBase(Helper::hexDecode($this->minimumValueToBuy));
48 | $this->coins = array_map(function ($value) {
49 | return hexdec($value);
50 | }, $this->coins);
51 | }
52 | }
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterCoins/MinterSellCoinTx.php:
--------------------------------------------------------------------------------
1 | coinToBuy = $coinToBuy;
32 | $this->coinToSell = $coinToSell;
33 | $this->valueToSell = $valueToSell;
34 | $this->minimumValueToBuy = $minimumValueToBuy;
35 | }
36 |
37 | /**
38 | * Prepare tx data for signing
39 | *
40 | * @return array
41 | */
42 | public function encodeData(): array
43 | {
44 | return [
45 | $this->coinToSell,
46 | MinterConverter::convertToPip($this->valueToSell),
47 | $this->coinToBuy,
48 | MinterConverter::convertToPip($this->minimumValueToBuy)
49 | ];
50 | }
51 |
52 | public function decodeData()
53 | {
54 | $this->coinToSell = hexdec($this->coinToSell);
55 | $this->valueToSell = MinterConverter::convertToBase(Helper::hexDecode($this->valueToSell));
56 | $this->coinToBuy = hexdec($this->coinToBuy);
57 | $this->minimumValueToBuy = MinterConverter::convertToBase(Helper::hexDecode($this->minimumValueToBuy));
58 | }
59 | }
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterCoins/MinterSellSwapPoolTx.php:
--------------------------------------------------------------------------------
1 | coins = $coins;
31 | $this->valueToSell = $valueToSell;
32 | $this->minimumValueToBuy = $minimumValueToBuy;
33 | }
34 |
35 | /**
36 | * Prepare tx data for signing
37 | *
38 | * @return array
39 | */
40 | public function encodeData(): array
41 | {
42 | return [
43 | $this->coins,
44 | MinterConverter::convertToPip($this->valueToSell),
45 | MinterConverter::convertToPip($this->minimumValueToBuy)
46 | ];
47 | }
48 |
49 | public function decodeData()
50 | {
51 | $this->valueToSell = MinterConverter::convertToBase(Helper::hexDecode($this->valueToSell));
52 | $this->minimumValueToBuy = MinterConverter::convertToBase(Helper::hexDecode($this->minimumValueToBuy));
53 | $this->coins = array_map(function ($value) {
54 | return hexdec($value);
55 | }, $this->coins);
56 | }
57 | }
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterCoins/MinterSendCoinTx.php:
--------------------------------------------------------------------------------
1 | coin = $coin;
30 | $this->to = $to;
31 | $this->value = $value;
32 | }
33 |
34 | public function encodeData(): array
35 | {
36 | return [
37 | $this->coin,
38 | hex2bin(Helper::removeWalletPrefix($this->to)),
39 | MinterConverter::convertToPip($this->value)
40 | ];
41 | }
42 |
43 | public function decodeData()
44 | {
45 | $this->coin = hexdec($this->coin);
46 | $this->to = Helper::addWalletPrefix($this->to);
47 | $this->value = MinterConverter::convertToBase(Helper::hexDecode($this->value));
48 | }
49 | }
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterCoins/MinterSetCandidateOffTx.php:
--------------------------------------------------------------------------------
1 | publicKey = $publicKey;
26 | }
27 |
28 | /**
29 | * Prepare data for signing
30 | *
31 | * @return array
32 | */
33 | public function encodeData(): array
34 | {
35 | return [
36 | hex2bin(
37 | Helper::removePrefix($this->publicKey, MinterPrefix::PUBLIC_KEY)
38 | ),
39 | ];
40 | }
41 |
42 | public function decodeData()
43 | {
44 | $this->publicKey = MinterPrefix::PUBLIC_KEY . $this->publicKey;
45 | }
46 | }
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterCoins/MinterSetCandidateOnTx.php:
--------------------------------------------------------------------------------
1 | publicKey = $publicKey;
26 | }
27 |
28 | /**
29 | * Prepare data for signing
30 | *
31 | * @return array
32 | */
33 | public function encodeData(): array
34 | {
35 | return [
36 | hex2bin(
37 | Helper::removePrefix($this->publicKey, MinterPrefix::PUBLIC_KEY)
38 | ),
39 | ];
40 | }
41 |
42 | public function decodeData()
43 | {
44 | $this->publicKey = MinterPrefix::PUBLIC_KEY . $this->publicKey;
45 | }
46 | }
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterCoins/MinterSetHaltBlockTx.php:
--------------------------------------------------------------------------------
1 | publicKey = $publicKey;
28 | $this->height = $height;
29 | }
30 |
31 | /**
32 | * Prepare data for signing
33 | *
34 | * @return array
35 | */
36 | public function encodeData(): array
37 | {
38 | return [
39 | hex2bin(Helper::removePrefix($this->publicKey, MinterPrefix::PUBLIC_KEY)),
40 | $this->height,
41 | ];
42 | }
43 |
44 | public function decodeData()
45 | {
46 | $this->publicKey = MinterPrefix::PUBLIC_KEY . $this->publicKey;
47 | $this->height = (int)hexdec($this->height);
48 | }
49 | }
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterCoins/MinterUnbondTx.php:
--------------------------------------------------------------------------------
1 | publicKey = $publicKey;
31 | $this->coin = $coin;
32 | $this->value = $value;
33 | }
34 |
35 | /**
36 | * Prepare data for signing
37 | *
38 | * @return array
39 | */
40 | public function encodeData(): array
41 | {
42 | return [
43 | hex2bin(Helper::removePrefix($this->publicKey, MinterPrefix::PUBLIC_KEY)),
44 | $this->coin,
45 | MinterConverter::convertToPip($this->value)
46 | ];
47 | }
48 |
49 | public function decodeData()
50 | {
51 | $this->publicKey = MinterPrefix::PUBLIC_KEY . $this->publicKey;
52 | $this->coin = hexdec($this->coin);
53 | $this->value = MinterConverter::convertToBase(Helper::hexDecode($this->value));
54 | }
55 | }
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterCoins/MinterVoteUpdateTx.php:
--------------------------------------------------------------------------------
1 | publicKey = $publicKey;
29 | $this->version = $version;
30 | $this->height = $height;
31 | }
32 |
33 | /**
34 | * Prepare data for signing
35 | *
36 | * @return array
37 | */
38 | public function encodeData(): array
39 | {
40 | return [
41 | $this->version,
42 | hex2bin(Helper::removePrefix($this->publicKey, MinterPrefix::PUBLIC_KEY)),
43 | $this->height
44 | ];
45 | }
46 |
47 | public function decodeData()
48 | {
49 | $this->publicKey = MinterPrefix::PUBLIC_KEY . $this->publicKey;
50 | $this->height = hexdec($this->height);
51 | $this->version = Helper::hex2str($this->version);
52 | }
53 | }
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterConverter.php:
--------------------------------------------------------------------------------
1 | data = $txData;
50 | $this->rlp = new RLP();
51 | }
52 |
53 | /**
54 | * @param string $payload
55 | * @return MinterDeepLink
56 | */
57 | public function setPayload(string $payload): MinterDeepLink
58 | {
59 | $this->payload = $payload;
60 | return $this;
61 | }
62 |
63 | /**
64 | * @param string|int $nonce
65 | * @return MinterDeepLink
66 | */
67 | public function setNonce($nonce): MinterDeepLink
68 | {
69 | $this->nonce = $nonce;
70 | return $this;
71 | }
72 |
73 | /**
74 | * @param $gasCoin
75 | * @return MinterDeepLink
76 | */
77 | public function setGasCoin($gasCoin): MinterDeepLink
78 | {
79 | $this->gasCoin = $gasCoin;
80 | return $this;
81 | }
82 |
83 | /**
84 | * @param string|int $gasPrice
85 | * @return MinterDeepLink
86 | */
87 | public function setGasPrice($gasPrice): MinterDeepLink
88 | {
89 | $this->gasPrice = $gasPrice;
90 | return $this;
91 | }
92 |
93 | /**
94 | * @param string $p
95 | * @return MinterDeepLink
96 | */
97 | public function setCheckPassword(string $p): MinterDeepLink
98 | {
99 | $this->checkPassword = $p;
100 | return $this;
101 | }
102 |
103 | /**
104 | * @param string $uri
105 | * @return MinterDeepLink
106 | */
107 | public function setHost(string $uri): MinterDeepLink
108 | {
109 | $this->uri = $uri;
110 | return $this;
111 | }
112 |
113 | /**
114 | * @return string
115 | */
116 | public function getHost(): string
117 | {
118 | return $this->uri ?? self::LINK_BASE_URL;
119 | }
120 |
121 | /**
122 | * @return string
123 | */
124 | public function encode(): string
125 | {
126 | $payload = Helper::str2buffer($this->payload ?? '');
127 | $gasCoin = $this->gasCoin ?? MinterTx::BASE_COIN_ID;
128 | $data = $this->data->encode();
129 | $txType = $this->data->getType();
130 |
131 | $deepLink = [
132 | 'type' => $txType,
133 | 'data' => $data,
134 | 'payload' => $payload,
135 | 'nonce' => $this->nonce,
136 | 'gasPrice' => $this->gasPrice,
137 | 'gasCoin' => $gasCoin
138 | ];
139 |
140 | $data = $this->rlp->encode($deepLink);
141 | $data = hex2bin($data);
142 | $data = Helper::base64urlEncode($data);
143 |
144 | $url = $this->getHost() . '/' . $data;
145 | if ($this->checkPassword) {
146 | $checkPassword = Helper::str2buffer($this->checkPassword);
147 | $checkPassword = Helper::base64urlEncode($checkPassword);
148 | $url .= "?p=" . $checkPassword;
149 | }
150 |
151 | return $url;
152 | }
153 | }
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterPrefix.php:
--------------------------------------------------------------------------------
1 | self::TOTAL_BLOCKS_COUNT) {
47 | return 0;
48 | }
49 |
50 | if($blockNumber === self::TOTAL_BLOCKS_COUNT) {
51 | return self::LAST_REWARD;
52 | }
53 |
54 | $reward = self::formula($blockNumber);
55 | return $reward;
56 | }
57 |
58 | /**
59 | * Calculate reward by formula
60 | *
61 | * @param int $blockNumber
62 | * @return string
63 | */
64 | protected static function formula(int $blockNumber): string
65 | {
66 | $reward = self::FIRST_REWARD - ($blockNumber / 200000);
67 |
68 | return ceil($reward);
69 | }
70 | }
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterSignature.php:
--------------------------------------------------------------------------------
1 | addSingleSignature(...$data);
25 | return;
26 | }
27 |
28 | $this->addMultiSignature(...$data);
29 | }
30 |
31 | /**
32 | * Add single signature
33 | *
34 | * @param string $v
35 | * @param string $r
36 | * @param string $s
37 | */
38 | public function addSingleSignature(string $v, string $r, string $s)
39 | {
40 | $this->signatures[] = new Signature([
41 | "r" => $r,
42 | "s" => $s,
43 | "recoveryParam" => hexdec($v)
44 | ]);
45 | }
46 |
47 | /**
48 | * Handle multi-signature
49 | *
50 | * @param string $sender
51 | * @param array $signatures
52 | */
53 | public function addMultiSignature(string $sender, $signatures)
54 | {
55 | $this->multisigAddress = MinterPrefix::ADDRESS . $sender;
56 | foreach ($signatures as $signature) {
57 | $this->addSingleSignature(...$signature);
58 | }
59 | }
60 |
61 | public function getSignatures(): array
62 | {
63 | return $this->signatures;
64 | }
65 |
66 | public function getMultisigAddress(): string
67 | {
68 | return $this->multisigAddress;
69 | }
70 | }
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterTx.php:
--------------------------------------------------------------------------------
1 | setNonce($nonce);
71 | $this->setData($txData);
72 |
73 | if (!$this->getChainID()) {
74 | $this->setChainID(self::MAINNET_CHAIN_ID);
75 | }
76 |
77 | if (!$this->getGasCoin()) {
78 | $this->setGasCoin(self::BASE_COIN_ID);
79 | }
80 |
81 | if (!$this->getGasPrice()) {
82 | $this->setGasPrice(self::DEFAULT_GAS_PRICE);
83 | }
84 |
85 | parent::__construct();
86 | }
87 |
88 | /**
89 | * Sign tx
90 | *
91 | * @param string $privateKey
92 | * @return string
93 | */
94 | public function sign(string $privateKey): string
95 | {
96 | $this->setSignatureType(self::SIGNATURE_SINGLE_TYPE);
97 | return MinterPrefix::TRANSACTION . $this->signTransaction($privateKey);
98 | }
99 |
100 | /**
101 | * Sign with multi-signature
102 | *
103 | * @param string $multisigAddress
104 | * @param array $privateKeys
105 | * @return string
106 | */
107 | public function signMultisig(string $multisigAddress, array $privateKeys): string
108 | {
109 | $this->setSignatureType(self::SIGNATURE_MULTI_TYPE);
110 | return MinterPrefix::TRANSACTION . $this->signTransactionWithMultisig($multisigAddress, $privateKeys);
111 | }
112 |
113 | /**
114 | * @param string $multisigAddress
115 | * @param array $signatures
116 | * @return string
117 | */
118 | public function signMultisigBySigns(string $multisigAddress, array $signatures): string
119 | {
120 | $this->setSignatureType(self::SIGNATURE_MULTI_TYPE);
121 | return MinterPrefix::TRANSACTION . $this->signTransactionWithSignatures($multisigAddress, $signatures);
122 | }
123 |
124 | /**
125 | * Create transaction signature by private key
126 | *
127 | * @param string $privateKey
128 | * @return string
129 | */
130 | public function createSignature(string $privateKey): string
131 | {
132 | if ($this->getSignatureType() === null) {
133 | $this->setSignatureType(self::SIGNATURE_SINGLE_TYPE);
134 | }
135 |
136 | return $this->createEncodedSignature($privateKey);
137 | }
138 |
139 | /**
140 | * Get fee of transaction in base coin
141 | *
142 | * @return string
143 | */
144 | public function getFee(): string
145 | {
146 | // get transaction data fee
147 | $gas = $this->getData()->getFee();
148 |
149 | if ($this->getGasCoin() !== self::BASE_COIN_ID) {
150 | throw new InvalidArgumentException('Cannot calculate transaction commission with the custom gas coin');
151 | }
152 |
153 | // multiplied gas price
154 | $gasPrice = bcmul($gas, self::FEE_DEFAULT_MULTIPLIER, 0);
155 |
156 | // commission for payload and serviceData bytes
157 | $commission = bcadd(
158 | strlen($this->payload) * bcmul(self::PAYLOAD_COMMISSION, self::FEE_DEFAULT_MULTIPLIER, 0),
159 | strlen($this->serviceData) * bcmul(self::PAYLOAD_COMMISSION, self::FEE_DEFAULT_MULTIPLIER, 0)
160 | );
161 |
162 | $fee = bcadd($gasPrice, $commission, 0);
163 | return MinterConverter::convertToBase($fee);
164 | }
165 |
166 | /**
167 | * Decode transaction
168 | *
169 | * @param string $tx
170 | * @return MinterTx
171 | */
172 | public static function decode(string $tx): MinterTx
173 | {
174 | $data = Helper::hex2rlp($tx);
175 | if (count($data) !== 10) {
176 | throw new InvalidArgumentException('Incorrect transaction raw');
177 | }
178 |
179 | list($nonce, $chainId, $gasPrice, $gasCoin, $type, $data, $payload, $serviceData, $signatureType, $signatureData) = $data;
180 |
181 | /** @var MinterTxInterface $txData */
182 | $txData = MinterCoinTx::TYPE_TO_DATA[hexdec($type)];
183 | $txData = new $txData(...$data);
184 | $txData->decodeData();
185 |
186 | $tx = new MinterTx(hexdec($nonce), $txData);
187 | $tx->setGasPrice(hexdec($gasPrice));
188 | $tx->setGasCoin(hexdec($gasCoin));
189 | $tx->setChainID(hexdec($chainId));
190 | $tx->setSignatureType(hexdec($signatureType));
191 | $tx->setPayload(Helper::hex2str($payload));
192 | $tx->setServiceData(Helper::hex2str($serviceData));
193 |
194 | $signature = new MinterSignature($tx->getSignatureType(), $signatureData);
195 | $tx->setSignatureData($signature);
196 |
197 | return $tx;
198 | }
199 |
200 | /**
201 | * Get sender Minter address
202 | *
203 | * @return string
204 | */
205 | public function getSenderAddress(): string
206 | {
207 | if ($this->getSignatureType() === self::SIGNATURE_SINGLE_TYPE) {
208 | return MinterWallet::getAddressFromPublicKey($this->recoverPublicKey());
209 | }
210 |
211 | return $this->getSignatureData()->getMultisigAddress();
212 | }
213 |
214 | /**
215 | * @param int $nonce
216 | * @return MinterTx
217 | */
218 | public function setNonce(int $nonce): MinterTx
219 | {
220 | $this->nonce = $nonce;
221 | return $this;
222 | }
223 |
224 | /**
225 | * @param int $gasPrice
226 | * @return MinterTx
227 | */
228 | public function setGasPrice(int $gasPrice): MinterTx
229 | {
230 | $this->gasPrice = $gasPrice;
231 | return $this;
232 | }
233 |
234 | /**
235 | * @param int $gasCoin
236 | * @return MinterTx
237 | */
238 | public function setGasCoin(int $gasCoin): MinterTx
239 | {
240 | $this->gasCoin = $gasCoin;
241 | return $this;
242 | }
243 |
244 | /**
245 | * @param mixed $data
246 | * @return MinterTx
247 | */
248 | public function setData($data): MinterTx
249 | {
250 | $this->data = $data;
251 | return $this;
252 | }
253 |
254 | /**
255 | * @param int $signatureType
256 | * @return MinterTx
257 | */
258 | public function setSignatureType(int $signatureType): MinterTx
259 | {
260 | $this->signatureType = $signatureType;
261 | return $this;
262 | }
263 |
264 | /**
265 | * @param MinterSignature $signatureData
266 | * @return MinterTx
267 | */
268 | public function setSignatureData(MinterSignature $signatureData): MinterTx
269 | {
270 | $this->signatureData = $signatureData;
271 | return $this;
272 | }
273 |
274 | /**
275 | * @param int $chainID
276 | * @return MinterTx
277 | */
278 | public function setChainID(int $chainID): MinterTx
279 | {
280 | $this->chainID = $chainID;
281 | return $this;
282 | }
283 |
284 | /**
285 | * @return $this
286 | */
287 | public function setTestnetChainId(): MinterTx
288 | {
289 | $this->chainID = self::TESTNET_CHAIN_ID;
290 | return $this;
291 | }
292 |
293 | /**
294 | * @param mixed $payload
295 | * @return MinterTx
296 | */
297 | public function setPayload($payload): MinterTx
298 | {
299 | $this->payload = $payload;
300 | return $this;
301 | }
302 |
303 | /**
304 | * @param mixed $serviceData
305 | * @return MinterTx
306 | */
307 | public function setServiceData($serviceData): MinterTx
308 | {
309 | $this->serviceData = $serviceData;
310 | return $this;
311 | }
312 |
313 | /**
314 | * @return mixed
315 | */
316 | public function getNonce()
317 | {
318 | return $this->nonce;
319 | }
320 |
321 | /**
322 | * @return mixed
323 | */
324 | public function getChainID()
325 | {
326 | return $this->chainID;
327 | }
328 |
329 |
330 | /**
331 | * @return mixed
332 | */
333 | public function getGasCoin()
334 | {
335 | return $this->gasCoin;
336 | }
337 |
338 | /**
339 | * @return mixed
340 | */
341 | public function getGasPrice()
342 | {
343 | return $this->gasPrice;
344 | }
345 |
346 | /**
347 | * @return mixed
348 | */
349 | public function getSignatureType()
350 | {
351 | return $this->signatureType;
352 | }
353 |
354 | /**
355 | * @return mixed
356 | */
357 | public function getServiceData()
358 | {
359 | return $this->serviceData;
360 | }
361 |
362 | /**
363 | * @return mixed
364 | */
365 | public function getPayload()
366 | {
367 | return $this->payload;
368 | }
369 |
370 | /**
371 | * @return MinterSignature
372 | */
373 | public function getSignatureData(): MinterSignature
374 | {
375 | return $this->signatureData;
376 | }
377 |
378 | /**
379 | * @return MinterSendCoinTx|MinterBuyCoinTx|MinterSellCoinTx|MinterSellAllCoinTx|MinterDelegateTx|MinterUnbondTx|MinterMultiSendTx|MinterCreateMultisigTx|MinterCreateCoinTx|MinterRecreateCoinTx|MinterEditCoinOwnerTx|MinterDeclareCandidacyTx|MinterSetCandidateOnTx|MinterSetCandidateOffTx|MinterEditCandidateTx|MinterRedeemCheckTx|MinterSetHaltBlockTx|MinterSellSwapPoolTx|MinterSellAllSwapPoolTx|MinterBuySwapPoolTx|MinterPriceCommissionTx|MinterCreateTokenTx|MinterRecreateTokenTx|MinterCreateSwapPoolTx|MinterBurnTokenTx|MinterMintTokenTx|MinterAddLiquidityTx|MinterRemoveLiquidityTx|MinterAddLimitOrderTx|MinterRemoveLimitOrderTx|MinterLockTx|MinterLockStakeTx|MinterMoveStakeTx|MinterVoteUpdateTx
380 | */
381 | public function getData(): MinterTxInterface
382 | {
383 | return $this->data;
384 | }
385 | }
386 |
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterTxSigner.php:
--------------------------------------------------------------------------------
1 | rlp = new RLP();
40 | }
41 |
42 | /**
43 | * @param string $privateKey
44 | * @return Buffer
45 | */
46 | public function createEncodedSignature(string $privateKey)
47 | {
48 | $tx = $this->encodeRLP();
49 | $hash = Helper::createKeccakHash($tx);
50 | $signature = $this->createSignatureByHash($hash, $privateKey);
51 |
52 | return $this->rlp->encode($signature);
53 | }
54 |
55 | /**
56 | * @param string $privateKey
57 | * @return string
58 | */
59 | protected function signTransaction(string $privateKey): string
60 | {
61 | $tx = $this->encodeRLP();
62 | $hash = Helper::createKeccakHash($tx);
63 | $signature = $this->createSignatureByHash($hash, $privateKey);
64 |
65 | return $this->encodeRLP($signature);
66 | }
67 |
68 | /**
69 | * @param string $multisigAddress
70 | * @param array $privateKeys
71 | * @return string
72 | */
73 | protected function signTransactionWithMultisig(string $multisigAddress, array $privateKeys): string
74 | {
75 | $tx = $this->encodeRLP();
76 | $hash = Helper::createKeccakHash($tx);
77 |
78 | $signatures = [];
79 | foreach ($privateKeys as $privateKey) {
80 | $signatures[] = $this->createSignatureByHash($hash, $privateKey);
81 | }
82 |
83 | return $this->signMultisig($multisigAddress, $signatures);
84 | }
85 |
86 | /**
87 | * @param string $multisigAddress
88 | * @param array $signatures
89 | * @return string
90 | */
91 | protected function signTransactionWithSignatures(string $multisigAddress, array $signatures): string
92 | {
93 | foreach ($signatures as $key => $signature) {
94 | $signatures[$key] = $this->rlp->decode('0x' . $signature);
95 | }
96 |
97 | return $this->signMultisig($multisigAddress, $signatures);
98 | }
99 |
100 | /**
101 | * Recover sender public key from signature
102 | *
103 | * @return string
104 | */
105 | protected function recoverPublicKey(): string
106 | {
107 | $tx = $this->encodeRLP();
108 | $hash = Helper::createKeccakHash($tx);
109 | $signature = $this->signatureData->getSignatures()[0];
110 |
111 | return MinterPrefix::PUBLIC_KEY . ECDSA::recover($hash, $signature);
112 | }
113 |
114 | /**
115 | * @param string $multisigAddress
116 | * @param array $signatures
117 | * @return string
118 | */
119 | private function signMultisig(string $multisigAddress, array $signatures): string
120 | {
121 | $multisigAddress = Helper::removeWalletPrefix($multisigAddress);
122 | $multisigAddress = hex2bin($multisigAddress);
123 |
124 | return $this->encodeRLP([$multisigAddress, $signatures]);
125 | }
126 |
127 | /**
128 | * @param string $hash
129 | * @param string $privateKey
130 | * @return array|Buffer
131 | */
132 | private function createSignatureByHash(string $hash, string $privateKey)
133 | {
134 | $signature = ECDSA::sign($hash, $privateKey);
135 | $signature = Helper::hex2buffer($signature);
136 | return $signature;
137 | }
138 |
139 | /**
140 | * Encode transaction to RLP
141 | *
142 | * @param array|null $signature
143 | * @return Buffer
144 | */
145 | private function encodeRLP(?array $signature = null): Buffer
146 | {
147 | $tx = [
148 | $this->nonce,
149 | $this->chainID,
150 | $this->gasPrice,
151 | $this->gasCoin,
152 | $this->data->getType(),
153 | $this->data->encode(),
154 | Helper::str2buffer($this->payload ?? ''),
155 | $this->serviceData ?? '',
156 | $this->signatureType
157 | ];
158 |
159 | if ($signature) {
160 | $tx[] = $this->rlp->encode($signature);
161 | }
162 |
163 | return $this->rlp->encode($tx);
164 | }
165 | }
--------------------------------------------------------------------------------
/src/Minter/SDK/MinterWallet.php:
--------------------------------------------------------------------------------
1 | mnemonic = self::generateMnemonic();
40 | $this->privateKey = self::mnemonicToPrivateKey($this->mnemonic);
41 | $this->publicKey = self::privateToPublic($this->privateKey);
42 | $this->address = self::getAddressFromPublicKey($this->publicKey);
43 | }
44 |
45 | /**
46 | * Create Minter wallet by private key
47 | *
48 | * @param string $privateKey
49 | * @return MinterWallet
50 | */
51 | public static function createFromPrivate(string $privateKey): MinterWallet
52 | {
53 | $wallet = new MinterWallet();
54 | $wallet->privateKey = $privateKey;
55 | $wallet->publicKey = self::privateToPublic($wallet->getPrivateKey());
56 | $wallet->address = self::getAddressFromPublicKey($wallet->getPublicKey());
57 |
58 | return $wallet;
59 | }
60 |
61 | /**
62 | * Create Minter wallet by mnemonic phrase
63 | *
64 | * @param string $mnemonic
65 | * @return MinterWallet
66 | */
67 | public static function createFromMnemonic(string $mnemonic): MinterWallet
68 | {
69 | $wallet = new MinterWallet();
70 | $wallet->mnemonic = $mnemonic;
71 | $wallet->privateKey = self::mnemonicToPrivateKey($wallet->getMnemonic());
72 | $wallet->publicKey = self::privateToPublic($wallet->getPrivateKey());
73 | $wallet->address = self::getAddressFromPublicKey($wallet->getPublicKey());
74 |
75 | return $wallet;
76 | }
77 |
78 | /**
79 | * Generate public key
80 | *
81 | * @param string $privateKey
82 | * @return string
83 | */
84 | public static function privateToPublic(string $privateKey): string
85 | {
86 | return MinterPrefix::PUBLIC_KEY . ECDSA::privateToPublic($privateKey);
87 | }
88 |
89 | /**
90 | * Retrieve address from public key
91 | *
92 | * @param string $publicKey
93 | * @return string
94 | */
95 | public static function getAddressFromPublicKey(string $publicKey): string
96 | {
97 | $publicKey = Helper::removePrefix($publicKey, MinterPrefix::PUBLIC_KEY);
98 | $hash = Keccak::hash(hex2bin($publicKey), 256);
99 | return MinterPrefix::ADDRESS . substr($hash, -40);
100 | }
101 |
102 | /**
103 | * Generate mnemonic phrase from entropy.
104 | *
105 | * @return string
106 | */
107 | public static function generateMnemonic(): string
108 | {
109 | return BIP39::entropyToMnemonic(
110 | BIP39::generateEntropy(self::BIP44_ENTROPY_BITS)
111 | );
112 | }
113 |
114 | /**
115 | * Get private key from mnemonic.
116 | *
117 | * @param string $mnemonic
118 | * @return string
119 | */
120 | public static function mnemonicToPrivateKey(string $mnemonic): string
121 | {
122 | $seed = BIP39::mnemonicToSeedHex($mnemonic, '');
123 | return BIP44::fromMasterSeed($seed)->derive(self::BIP44_SEED_ADDRESS_PATH)->privateKey;
124 | }
125 |
126 | /**
127 | * Validate that address is valid Minter address
128 | *
129 | * @param string $address
130 | * @return bool
131 | */
132 | public static function validateAddress(string $address): bool
133 | {
134 | return strlen($address) === 42 && substr($address, 0, 2) === MinterPrefix::ADDRESS && ctype_xdigit(substr($address, -40));
135 | }
136 |
137 | /**
138 | * @return string
139 | */
140 | public function getMnemonic(): string
141 | {
142 | return $this->mnemonic;
143 | }
144 |
145 | /**
146 | * @return string
147 | */
148 | public function getAddress(): string
149 | {
150 | return $this->address;
151 | }
152 |
153 | /**
154 | * @return string
155 | */
156 | public function getPrivateKey(): string
157 | {
158 | return $this->privateKey;
159 | }
160 |
161 | /**
162 | * @return string
163 | */
164 | public function getPublicKey(): string
165 | {
166 | return $this->publicKey;
167 | }
168 | }
--------------------------------------------------------------------------------