public function testBIP32Key()
 {
     $this->assertEquals(new BIP32Key("xpub1", "m"), new BIP32Key(["xpub1", "m"]));
     $this->assertEquals(new BIP32Key("xpub1", "m"), BIP32Key::create("xpub1", "m"));
     $this->assertEquals(new BIP32Key("xpub1", "m"), BIP32Key::create(["xpub1", "m"]));
     $e = null;
     try {
         BIP32Key::create("xpub1");
     } catch (\Exception $e) {
     }
     $this->assertTrue(!!$e, "an exception should be thrown");
     $k = BIP32Key::create("xprv9s21ZrQH143K44ed3A1NBn3udjmm6qHRpX4Da47ZpRdhqxpkhCWwMFWNpFbSkxAtkZ2s2345tyX5GdTuDWQYZ9jZPuTbkkBeHx3h6RmzL8J", "m");
     $this->assertEquals("xprv9s21ZrQH143K44ed3A1NBn3udjmm6qHRpX4Da47ZpRdhqxpkhCWwMFWNpFbSkxAtkZ2s2345tyX5GdTuDWQYZ9jZPuTbkkBeHx3h6RmzL8J", $k->key());
     $this->assertEquals("m", $k->path());
     $this->assertEquals(["xprv9s21ZrQH143K44ed3A1NBn3udjmm6qHRpX4Da47ZpRdhqxpkhCWwMFWNpFbSkxAtkZ2s2345tyX5GdTuDWQYZ9jZPuTbkkBeHx3h6RmzL8J", "m"], $k->tuple());
     $c1 = $k->buildKey("m/1");
     $this->assertEquals("xprv9uyqGTZ6imvYQgfExoMn4ja1cD8DhHqhTxZVDBKSeETMqd87Nx5vexxEnuXYFMFi5ViQFdvw7AQt3RovuTivKdSFmygPBadBmuCVLszfHDc", $c1->key());
     $this->assertEquals("m/1", $c1->path());
     $this->assertEquals(["xprv9uyqGTZ6imvYQgfExoMn4ja1cD8DhHqhTxZVDBKSeETMqd87Nx5vexxEnuXYFMFi5ViQFdvw7AQt3RovuTivKdSFmygPBadBmuCVLszfHDc", "m/1"], $c1->tuple());
     $p = $c1->bip32Path();
     $this->assertTrue($p instanceof BIP32Path);
     $this->assertEquals("m/1", (string) $p);
     $this->assertEquals("039e3650a99c00105dee96b0ceee7ace9ad6f898fc728275937b9f58e831570210", $c1->publicKey());
 }
 /**
  * @param $primaryMnemonic
  * @param $backupMnemonic
  * @param $blocktrailPublicKeys
  */
 public function __construct($primaryMnemonic, $backupMnemonic, $blocktrailPublicKeys)
 {
     /*
      * if DOMPDF is not already loaded we have to do it
      * they require a config file to be loaded, no autoloading :/
      */
     if (!defined('DOMPDF_ENABLE_AUTOLOAD')) {
         // disable DOMPDF's internal autoloader if you are using Composer
         define('DOMPDF_ENABLE_AUTOLOAD', false);
         //try the different possible locations for the config file, depending on if the sdk is included as a dependency or is the main project itself
         @(include_once __DIR__ . '/../../../dompdf/dompdf/dompdf_config.inc.php') || @(include_once __DIR__ . '/../vendor/dompdf/dompdf/dompdf_config.inc.php');
     }
     //set the fonts path
     $this->fontsPath = dirname(__FILE__) . '/../resources/fonts';
     $this->primaryMnemonic = $primaryMnemonic;
     $this->backupMnemonic = $backupMnemonic;
     $this->blocktrailPublicKeys = array_map(function ($key) {
         return BIP32Key::create($key);
         // M/9999' or M/0' or M/1'
     }, $blocktrailPublicKeys);
 }
 /**
  * @param                                $primaryMnemonic
  * @param                                $primaryPassphrase
  * @param                                $backupMnemonic
  * @param array                          $blocktrailPublicKeys
  * @param BlockchainDataServiceInterface $bitcoinClient
  * @param string                         $network
  * @param bool                           $testnet
  * @throws \Exception
  */
 public function __construct($primaryMnemonic, $primaryPassphrase, $backupMnemonic, array $blocktrailPublicKeys, BlockchainDataServiceInterface $bitcoinClient, $network = 'btc', $testnet = false)
 {
     // normalize network and set bitcoinlib to the right magic-bytes
     list($this->network, $this->testnet) = $this->normalizeNetwork($network, $testnet);
     BitcoinLib::setMagicByteDefaults($this->network . ($this->testnet ? '-testnet' : ''));
     //create BIP32 keys for the Blocktrail public keys
     foreach ($blocktrailPublicKeys as $blocktrailKey) {
         $this->blocktrailPublicKeys[$blocktrailKey['keyIndex']] = BIP32Key::create($blocktrailKey['pubkey'], $blocktrailKey['path']);
     }
     //set the unspent output finder, using the given bitcoin data service provider
     $this->bitcoinClient = $bitcoinClient;
     $this->utxoFinder = new UnspentOutputFinder($this->bitcoinClient);
     // cleanup copy paste errors from mnemonics
     $primaryMnemonic = str_replace("  ", " ", str_replace("\r\n", " ", str_replace("\n", " ", trim($primaryMnemonic))));
     $backupMnemonic = str_replace("  ", " ", str_replace("\r\n", " ", str_replace("\n", " ", trim($backupMnemonic))));
     // convert the primary and backup mnemonics to seeds (using BIP39), then create private keys (using BIP32)
     $primarySeed = BIP39::mnemonicToSeedHex($primaryMnemonic, $primaryPassphrase);
     $backupSeed = BIP39::mnemonicToSeedHex($backupMnemonic, "");
     $this->primaryPrivateKey = BIP32Key::create(BIP32::master_key($primarySeed, $this->network, $this->testnet));
     $this->backupPrivateKey = BIP32Key::create(BIP32::master_key($backupSeed, $this->network, $this->testnet));
 }
Exemplo n.º 4
0
 /**
  * upgrade wallet to different blocktrail cosign key
  *
  * @param $keyIndex
  * @return bool
  * @throws \Exception
  */
 public function upgradeKeyIndex($keyIndex)
 {
     if ($this->locked) {
         throw new \Exception("Wallet needs to be unlocked to upgrade key index");
     }
     $walletPath = WalletPath::create($keyIndex);
     // do the upgrade to the new 'key_index'
     $primaryPublicKey = BIP32::extended_private_to_public(BIP32::build_key($this->primaryPrivateKey->tuple(), (string) $walletPath->keyIndexPath()));
     $result = $this->sdk->upgradeKeyIndex($this->identifier, $keyIndex, $primaryPublicKey);
     $this->primaryPublicKeys[$keyIndex] = BIP32Key::create($primaryPublicKey);
     $this->keyIndex = $keyIndex;
     $this->walletPath = $walletPath;
     // update the blocktrail public keys
     foreach ($result['blocktrail_public_keys'] as $keyIndex => $pubKey) {
         if (!isset($this->blocktrailPublicKeys[$keyIndex])) {
             $this->blocktrailPublicKeys[$keyIndex] = BIP32Key::create($pubKey);
         }
     }
     return true;
 }