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()); }
/** * create checksum to verify ownership of the master primary key * * @return string[] [address, signature] */ protected function createChecksumVerificationSignature() { $import = BIP32::import($this->primaryPrivateKey->key()); $public = $this->primaryPrivateKey->publicKey(); $address = BitcoinLib::public_key_to_address($public, $import['version']); return [$address, BitcoinLib::signMessage($address, $import)]; }
/** * signs a raw transaction * * @param $rawTransaction * @param $inputs * @return array */ protected function signTransaction($rawTransaction, $inputs) { $wallet = []; $keys = []; $redeemScripts = []; foreach ($inputs as $input) { //create private keys for signing $path = BIP32Path::path($input['path'])->privatePath(); $keys[] = $this->primaryPrivateKey->buildKey($path); $keys[] = $this->backupPrivateKey->buildKey($path->unhardenedPath()); $redeemScripts[] = $input['redeemScript']; } //add the keys and redeem scripts to a wallet to sign the transaction with BIP32::bip32_keys_to_wallet($wallet, array_map(function (BIP32Key $key) { return $key->tuple(); }, $keys)); RawTransaction::redeem_scripts_to_wallet($wallet, $redeemScripts); return RawTransaction::sign($wallet, $rawTransaction, json_encode($inputs)); }
/** * @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); }