Completed
Pull Request — master (#127)
by thomas
58:41 queued 39:41
created

InsightUnspentOutputFinder   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 90
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 84.62%

Importance

Changes 0
Metric Value
dl 0
loc 90
ccs 33
cts 39
cp 0.8462
rs 10
c 0
b 0
f 0
wmc 10
lcom 1
cbo 4

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A getUTXOs() 0 17 4
B getUnspentOutputs() 0 47 5
1
<?php
2
3
namespace Blocktrail\SDK\Services;
4
5
use Blocktrail\SDK\BlocktrailSDK;
6
use Blocktrail\SDK\UnspentOutputFinder;
7
8
class InsightUnspentOutputFinder extends UnspentOutputFinder {
9
10
    protected $testnet;
11
12
    protected $retryLimit;
13
    protected $sleepTime;
14
15
    /**
16
     * @param bool $testnet
17
     */
18 2
    public function __construct($testnet = false) {
19 2
        $this->testnet = $testnet;
20
21 2
        $this->retryLimit = 5;
22 2
        $this->sleepTime = 20;
23 2
    }
24
25 2
    public function getUTXOs(array $addresses) {
26 2
        $results = array();
27
28 2
        foreach (array_chunk($addresses, 500) as $addresses) {
29 2
            if ($this->debug) {
30
                echo "\nchecking " . count($addresses) . " addresses ...";
31
            }
32
            //get the utxos for this address
33 2
            $utxos = $this->getUnspentOutputs($addresses);
34
35 2
            if (count($utxos) > 0) {
36 2
                $results = array_merge($results, $utxos);
37
            }
38
        }
39
40 2
        return $results;
41
    }
42
43
    /**
44
     * gets unspent outputs for a batch of addresses, returning and array of outputs with hash, index, value, and script pub hex
45
     *
46
     * @param string[] $addresses
47
     * @return array        2d array of unspent outputs as ['hash' => $hash, 'index' => $index, 'value' => $value, 'address' => $address, 'script_hex' => $scriptHex]
48
     * @throws \Exception
49
     */
50 1
    protected function getUnspentOutputs($addresses) {
51
        //get unspent outputs for the address - required data: hash, index, value, and script hex
52 1
        $utxos = [];
53 1
        $retries = 0;
54
55
        do {
56 1
            $more = true;
57
58
            try {
59 1
                $client = new \GuzzleHttp\Client();
60 1
                $response = $client->post(
61 1
                    'https://' . ($this->testnet ? 'test-' : '') . 'insight.bitpay.com/api/addrs/utxo',
62
                    [
63 1
                        'json' => ['addrs' => implode(",", $addresses)],
64 1
                        'timeout' => 30,
65
                    ]
66
                );
67
68 1
                $json = json_decode($response->getBody(), true);
69
70 1
                $utxos = $json;
71
72 1
                $more = false;
73
            } catch (\Exception $e) {
74
                //if rate limit hit, sleep for a short while and try again
75
                if ($retries < $this->retryLimit) {
76
                    $retries++;
77
                    sleep($this->sleepTime);
78
                } else {
79
                    throw $e;
80
                }
81
            }
82 1
        } while ($more);
83
84
        //reduce the returned data into the values we're interested in
85 1
        $result = array_map(function ($utxo) {
86
            return array(
87 1
                'hash'       => $utxo['txid'],
88 1
                'index'      => $utxo['vout'],
89 1
                'value'      => BlocktrailSDK::toSatoshi($utxo['amount']),
90 1
                'address'    => $utxo['address'],
91 1
                'script_hex' => $utxo['scriptPubKey'],
92
            );
93 1
        }, $utxos);
94
95
        return $result;
96
    }
97
}
98