From 4e63292cf1d0d96bdfc86881d2dfa1bb714df9d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9A=D0=B0=D0=BC=D0=B8=D0=BB=D1=8C=20=D0=9C=D1=83=D1=85?= =?UTF-8?q?=D0=B0=D0=BC=D0=B5=D1=82=D0=B7=D1=8F=D0=BD=D0=BE=D0=B2?= Date: Fri, 7 Jun 2019 11:13:33 +0300 Subject: [PATCH 1/2] add generateMnemonic, mnemonicToSeed, seedToPrivateKey in MinterWallet; update README --- README.md | 52 +++++++++++++++++++++++++++++++++ src/Minter/SDK/MinterWallet.php | 46 ++++++++++++++++++++++++----- tests/MinterWalletTest.php | 21 +++++++++++++ 3 files changed, 112 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 513d5c9..674c1bb 100644 --- a/README.md +++ b/README.md @@ -722,6 +722,58 @@ $check->getBody(); // check body $check->getOwnerAddress(); // check owner address ``` +### Minter Wallet + +###### Example + +* Create wallet. This method returns generated seed, private key, public key, mnemonic and Minter address. + +```php +use Minter\SDK\MinterWallet; + +$wallet = MinterWallet::create(); +``` + +* Generate mnemonic. + +```php +use Minter\SDK\MinterWallet; + +$mnemonic = MinterWallet::generateMnemonic(); +``` + +* Get seed from mnemonic. + +```php +use Minter\SDK\MinterWallet; + +$seed = MinterWallet::mnemonicToSeed($mnemonic); +``` + +* Get private key from seed. + +```php +use Minter\SDK\MinterWallet; + +$privateKey = MinterWallet::seedToPrivateKey($seed); +``` + +* Get public key from private key. + +```php +use Minter\SDK\MinterWallet; + +$publicKey = MinterWallet::privateToPublic($privateKey); +``` + +* Get Minter address from public key. + +```php +use Minter\SDK\MinterWallet; + +$address = MinterWallet::getAddressFromPublicKey($publicKey); +``` + ## Tests To run unit tests: diff --git a/src/Minter/SDK/MinterWallet.php b/src/Minter/SDK/MinterWallet.php index 3938786..9f9fcf1 100644 --- a/src/Minter/SDK/MinterWallet.php +++ b/src/Minter/SDK/MinterWallet.php @@ -32,11 +32,9 @@ class MinterWallet */ public static function create(): array { - $entropy = BIP39::generateEntropy(self::BIP44_ENTROPY_BITS); - $mnemonic = BIP39::entropyToMnemonic($entropy); - $seed = BIP39::mnemonicToSeedHex($mnemonic, ''); - $privateKey = BIP44::fromMasterSeed($seed)->derive(self::BIP44_SEED_ADDRESS_PATH)->privateKey; - + $mnemonic = self::generateMnemonic(); + $seed = self::mnemonicToSeed($mnemonic); + $privateKey = self::seedToPrivateKey($seed); $publicKey = self::privateToPublic($privateKey); $address = self::getAddressFromPublicKey($publicKey); @@ -48,7 +46,7 @@ public static function create(): array 'private_key' => $privateKey ]; } - + /** * Generate public key * @@ -57,7 +55,7 @@ public static function create(): array */ public static function privateToPublic(string $privateKey): string { - return MinterPrefix::PUBLIC_KEY . ECDSA::privateToPublic($privateKey); + return MinterPrefix::PUBLIC_KEY . ECDSA::privateToPublic($privateKey); } /** @@ -78,6 +76,40 @@ public static function getAddressFromPublicKey(string $publicKey): string return MinterPrefix::ADDRESS . substr($hash, -40); } + /** + * Generate mnemonic phrase from entropy. + * + * @return string + */ + public static function generateMnemonic(): string + { + return BIP39::entropyToMnemonic( + BIP39::generateEntropy(self::BIP44_ENTROPY_BITS) + ); + } + + /** + * Get seed from the mnemonic phrase. + * + * @param string $mnemonic + * @return string + */ + public static function mnemonicToSeed(string $mnemonic): string + { + return BIP39::mnemonicToSeedHex($mnemonic, ''); + } + + /** + * Get private key from seed. + * + * @param string $seed + * @return string + */ + public static function seedToPrivateKey(string $seed): string + { + return BIP44::fromMasterSeed($seed)->derive(self::BIP44_SEED_ADDRESS_PATH)->privateKey; + } + /** * Validate that address is valid Minter address * diff --git a/tests/MinterWalletTest.php b/tests/MinterWalletTest.php index 0efffb0..1007f32 100644 --- a/tests/MinterWalletTest.php +++ b/tests/MinterWalletTest.php @@ -24,6 +24,11 @@ final class MinterWalletTest extends TestCase */ const VALID_ADDRESS = 'Mx17b1240ba6d45258f836b45ae0c4fc1106f5ce59'; + // Data for testing mnemonicToSeed, seedToPrivateKey + const MNEMONIC = 'suffer draft bacon typical start retire air sniff large biology mail diagram'; + const VALID_SEED = '33fa1096997d9b0f47469463710b3a2e91971144265b281dc71f831539a3b8e3413e5969e5ffb4d3c5a37cfa0f964bcc779efe4ae37fceef048175105caad624'; + const VALID_PRIVATE_KEY_FROM_SEED = 'd3520cc797f12b8a81e805ddf5a5bf8b994e347003ea25c9ccaecb5073f3fef1'; + /** * Test converting private key to public key. */ @@ -103,4 +108,20 @@ public function testCreateWallet() MinterWallet::privateToPublic($wallet['private_key']) ); } + + /** + * Test mnemonic to seed. + */ + public function testMnemonicToSeed() + { + $this->assertEquals(self::VALID_SEED, MinterWallet::mnemonicToSeed(self::MNEMONIC)); + } + + /** + * Test seed to private key. + */ + public function testSeedToPrivateKey() + { + $this->assertEquals(self::VALID_PRIVATE_KEY_FROM_SEED, MinterWallet::seedToPrivateKey(self::VALID_SEED)); + } } From db36f436758050dec8cad41c0b091b2a0f2a7154 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9A=D0=B0=D0=BC=D0=B8=D0=BB=D1=8C=20=D0=9C=D1=83=D1=85?= =?UTF-8?q?=D0=B0=D0=BC=D0=B5=D1=82=D0=B7=D1=8F=D0=BD=D0=BE=D0=B2?= Date: Fri, 7 Jun 2019 11:16:16 +0300 Subject: [PATCH 2/2] update README --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 674c1bb..a190eb2 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,7 @@ This is a pure PHP SDK for working with Minter blockchain - [Get hash of transaction](#get-hash-of-transaction) - [Decode Transaction](#decode-transaction) - [Minter Check](#create-minter-check) + - [Minter Wallet](#minter-wallet) * [Tests](#tests) ## Installing