public function testUnspentOutputFinder()
 {
     //some addresses with known unspent outputs, and some without any
     $addresses = array('2NG3QEhJc1xzN5qxPdNAZfGaTdGAv3ixMbH', '2NA7zpiq5PcYUx6oraEwz8zPzn6HefSvdLA', '2Mu1xrQAEd8LsiRHNvgXDaU8kQU5WKqzCq7', '2N9ijhGSX3kGbe16RMCQ2hviH8RLAVdaqZg');
     $blockchainDataService = new BlocktrailBitcoinService("MY_APIKEY", "MY_APISECRET", "BTC", true, 'v1');
     $unspenOutputFinder = new UnspentOutputFinder($blockchainDataService);
     //get unspent outputs for an array of addresses
     $result = $unspenOutputFinder->getUTXOs($addresses);
     $this->assertEquals(3, count($result), "expected results for 3 of the 4 given addresses");
     $this->assertArrayHasKey('2NG3QEhJc1xzN5qxPdNAZfGaTdGAv3ixMbH', $result);
     $this->assertArrayHasKey('2NA7zpiq5PcYUx6oraEwz8zPzn6HefSvdLA', $result);
     $this->assertArrayHasKey('2N9ijhGSX3kGbe16RMCQ2hviH8RLAVdaqZg', $result);
     $this->assertEquals(2, count($result['2NA7zpiq5PcYUx6oraEwz8zPzn6HefSvdLA']), "expected address to have 2 unspent outputs");
     $this->assertArrayHasKey('hash', $result['2NA7zpiq5PcYUx6oraEwz8zPzn6HefSvdLA'][0]);
     $this->assertArrayHasKey('index', $result['2NA7zpiq5PcYUx6oraEwz8zPzn6HefSvdLA'][0]);
     $this->assertArrayHasKey('value', $result['2NA7zpiq5PcYUx6oraEwz8zPzn6HefSvdLA'][0]);
     $this->assertArrayHasKey('script_hex', $result['2NA7zpiq5PcYUx6oraEwz8zPzn6HefSvdLA'][0]);
     $this->assertEquals(10000000, $result['2NA7zpiq5PcYUx6oraEwz8zPzn6HefSvdLA'][0]['value']);
     $this->assertEquals(10000000, $result['2NA7zpiq5PcYUx6oraEwz8zPzn6HefSvdLA'][1]['value']);
     $total = $result['2NG3QEhJc1xzN5qxPdNAZfGaTdGAv3ixMbH'][0]['value'] + $result['2N9ijhGSX3kGbe16RMCQ2hviH8RLAVdaqZg'][0]['value'] + $result['2NA7zpiq5PcYUx6oraEwz8zPzn6HefSvdLA'][0]['value'] + $result['2NA7zpiq5PcYUx6oraEwz8zPzn6HefSvdLA'][1]['value'];
     $this->assertEquals(40000000, $total);
 }
 /**
  * discover funds in the wallet
  *
  * @param int $increment    how many addresses to scan at a time
  * @return array
  */
 public function discoverWalletFunds($increment = 200)
 {
     $totalBalance = 0;
     $totalUTXOs = 0;
     $totalAddressesGenerated = 0;
     $addressUTXOs = array();
     //addresses and their utxos, paths and redeem scripts
     //for each blocktrail pub key, do fund discovery on batches of addresses
     foreach ($this->blocktrailPublicKeys as $keyIndex => $blocktrailPubKey) {
         $i = 0;
         do {
             if ($this->debug) {
                 echo "\ngenerating {$increment} addresses using blocktrail key index {$keyIndex}\n";
             }
             $addresses = $this->createBatchAddresses($i, $increment, $keyIndex);
             $totalAddressesGenerated += count($addresses);
             if ($this->debug) {
                 echo "\nstarting fund discovery for {$increment} addresses";
             }
             //get the unspent outputs for this batch of addresses
             $utxos = $this->utxoFinder->getUTXOs(array_keys($addresses));
             //save the address utxos, along with relevant path and redeem script
             foreach ($utxos as $address => $outputs) {
                 $addressUTXOs[$address] = array('path' => $addresses[$address]['path'], 'redeem' => $addresses[$address]['redeem'], 'utxos' => $outputs);
                 $totalUTXOs += count($outputs);
                 //add up the total utxo value for all addresses
                 $totalBalance = array_reduce($outputs, function ($carry, $output) {
                     return $carry += $output['value'];
                 }, $totalBalance);
                 if ($this->debug) {
                     echo "\nfound " . count($outputs) . " unspent outputs in address {$address}";
                 }
             }
             //increment for next batch
             $i += $increment;
         } while (count($utxos) > 0);
     }
     if ($this->debug) {
         echo "\nfinished fund discovery: {$totalBalance} Satoshi (in {$totalUTXOs} outputs) found when searching {$totalAddressesGenerated} addresses";
     }
     $this->sweepData = ['utxos' => $addressUTXOs, 'count' => $totalUTXOs, 'balance' => $totalBalance, 'addressesSearched' => $totalAddressesGenerated];
     return $this->sweepData;
 }