From bb0280dc4eee18485a684dbb80439e1e3d25fd76 Mon Sep 17 00:00:00 2001 From: Cosmin Harangus Date: Thu, 3 Oct 2019 19:58:18 +0300 Subject: [PATCH 1/2] Generate extended public keys from an extended key --- hd-wallet-derive.php | 6 ++++++ src/WalletDerive.php | 47 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/hd-wallet-derive.php b/hd-wallet-derive.php index 6a0f472..d295c5c 100755 --- a/hd-wallet-derive.php +++ b/hd-wallet-derive.php @@ -50,6 +50,12 @@ function main() return 0; } + if (@$params['get-extended']) { + $result = $walletDerive->getExtendedPublicKeys($key); + WalletDeriveReport::printResults($params, $result); + return 0; + } + // Key derived from mnemonic if mnemonic is choosen if( !@$params['key'] && @$params['mnemonic'] && !@$orig_params['path'] && !@$orig_params['preset']) { $path = $walletDerive->getCoinBip44ExtKeyPathPurposeByKeyType($params['coin'], $params['key-type']); diff --git a/src/WalletDerive.php b/src/WalletDerive.php index 43014ea..2bed25c 100644 --- a/src/WalletDerive.php +++ b/src/WalletDerive.php @@ -194,6 +194,53 @@ function serializePrivKey($symbol, $network, $key) { return $hex ? '0x' . $key->getHex() : $key->toWif($network); } + /** + * Get extended public keys from a given key in all available formats + */ + function getExtendedPublicKeys($key) { + $params = $this->get_params(); + $coin = $params['coin']; + list($symbol) = explode('-', $coin); + + $networkCoinFactory = new NetworkCoinFactory(); + $network = $networkCoinFactory->getNetworkCoinInstance($coin); + Bitcoin::setNetwork($network); + + // get initial key type for the coin + $initial_key_type = $this->getKeyTypeFromCoinAndKey($coin, $key); + + // store results here + $extkeys = array(); + + // try to generate xpub address + $key_type = 'x'; + $this->params['addr-type'] = 'legacy'; + // generate the master key for the given type from the initial type + $master = $this->fromExtended($coin, $key, $network, $initial_key_type); + if ( $this->networkSupportsKeyType($network, $key_type, $coin ) && method_exists($master, 'getPublicKey') ) { + $extkeys[] = array( 'xpub' => $this->toExtendedKey($coin, $master->withoutPrivateKey(), $network, $key_type)); + } + + // try to generate ypub address + $key_type = 'y'; + $this->params['addr-type'] = 'p2sh-segwit'; + // regenerate the master key for the given type from the initial type + $master = $this->fromExtended($coin, $key, $network, $initial_key_type); + if ( $this->networkSupportsKeyType($network, $key_type, $coin ) && method_exists($master, 'getPublicKey') ) { + $extkeys[] = array( 'ypub' => $this->toExtendedKey($coin, $master->withoutPrivateKey(), $network, $key_type)); + } + + // try to generate zpub address + $key_type = 'z'; + $this->params['addr-type'] = 'bech32'; + // regenerate the master key for the given type from the initial type + $master = $this->fromExtended($coin, $key, $network, $initial_key_type); + if ( $this->networkSupportsKeyType($network, $key_type, $coin ) && method_exists($master, 'getPublicKey') ) { + $extkeys[] = array( 'zpub' => $this->toExtendedKey($coin, $master->withoutPrivateKey(), $network, $key_type)); + } + + return $extkeys; + } private function address($key, $network) { $addrCreator = new AddressCreator(); From deed0945c788de6b562ee32c65c55a4d28ba8c8e Mon Sep 17 00:00:00 2001 From: Cosmin Harangus Date: Tue, 15 Oct 2019 19:39:48 +0300 Subject: [PATCH 2/2] Fix issues and update cli docs --- hd-wallet-derive.php | 13 +++++++------ src/Utils/Util.php | 4 +++- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/hd-wallet-derive.php b/hd-wallet-derive.php index d295c5c..cf0b2ae 100755 --- a/hd-wallet-derive.php +++ b/hd-wallet-derive.php @@ -50,12 +50,6 @@ function main() return 0; } - if (@$params['get-extended']) { - $result = $walletDerive->getExtendedPublicKeys($key); - WalletDeriveReport::printResults($params, $result); - return 0; - } - // Key derived from mnemonic if mnemonic is choosen if( !@$params['key'] && @$params['mnemonic'] && !@$orig_params['path'] && !@$orig_params['preset']) { $path = $walletDerive->getCoinBip44ExtKeyPathPurposeByKeyType($params['coin'], $params['key-type']); @@ -68,6 +62,13 @@ function main() } } $key = @$params['key'] ?: $walletDerive->mnemonicToKey($params['coin'], $params['mnemonic'], $params['key-type'], $params['mnemonic-pw']); + + if (@$params['gen-extended']) { + $result = $walletDerive->getExtendedPublicKeys($key); + WalletDeriveReport::printResults($params, $result, true); + return 0; + } + $addrs = $walletDerive->derive_keys($key); // Prints result diff --git a/src/Utils/Util.php b/src/Utils/Util.php index f1c95d7..2904c4e 100644 --- a/src/Utils/Util.php +++ b/src/Utils/Util.php @@ -35,7 +35,7 @@ public static function getCliParams() 'list-cols', 'bch-format:', 'alt-extended:', - 'gen-key', 'gen-key-all', + 'gen-key', 'gen-key-all', 'gen-extended', 'gen-words:', 'version', 'help', 'help-coins', 'preset:', 'path-change', 'path-account:', 'help-presets', @@ -95,6 +95,7 @@ public static function processCliParams() $params['gen-key'] = isset($params['gen-key']) || isset($params['gen-words']); $params['gen-key-all'] = isset($params['gen-key-all']); // hidden param, for the truly worthy who read the code. + $params['gen-extended'] = isset($params['gen-extended']); $key = @$params['key']; $mnemonic = @$params['mnemonic']; @@ -284,6 +285,7 @@ public static function printHelp() --includeroot include root key as first element of report. --gen-key generates a new key. + --gen-extended generate the coresponding x, y or z public keys from a provided key --gen-words= num words to generate. implies --gen-key. one of: [$allowed_numwords] default = 24.