Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 43
0.00% covered (danger)
0.00%
0 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
Blockchain_Info_Api
0.00% covered (danger)
0.00%
0 / 43
0.00% covered (danger)
0.00%
0 / 5
72
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 get_received_by_address
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 get_address_balance
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
2
 get_transactions_received
0.00% covered (danger)
0.00%
0 / 26
0.00% covered (danger)
0.00%
0 / 1
12
 get_blockchain_height
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3/**
4 * "Please limit your queries to a maximum of 1 every 10 seconds"
5 *
6 * @see https://www.blockchain.com/api/blockchain_api
7 * @see https://www.blockchain.com/api/q
8 *
9 * @package    brianhenryie/bh-wp-bitcoin-gateway
10 */
11
12namespace BrianHenryIE\WP_Bitcoin_Gateway\API\Blockchain;
13
14use BrianHenryIE\WP_Bitcoin_Gateway\Art4\Requests\Psr\HttpClient;
15use BrianHenryIE\WP_Bitcoin_Gateway\API\Blockchain_API_Interface;
16use BrianHenryIE\WP_Bitcoin_Gateway\API\Model\Address_Balance;
17use BrianHenryIE\WP_Bitcoin_Gateway\API\Model\Transaction_Interface;
18use BrianHenryIE\WP_Bitcoin_Gateway\BlockchainInfo\BlockchainInfoApi;
19use BrianHenryIE\WP_Bitcoin_Gateway\BlockchainInfo\Model\TransactionOut;
20use DateTimeImmutable;
21use DateTimeZone;
22use Psr\Log\LoggerAwareInterface;
23use Psr\Log\LoggerAwareTrait;
24use Psr\Log\LoggerInterface;
25
26class Blockchain_Info_Api implements Blockchain_API_Interface, LoggerAwareInterface {
27    use LoggerAwareTrait;
28
29    protected BlockchainInfoApi $api;
30
31    /**
32     * Constructor
33     *
34     * @param LoggerInterface $logger A PSR logger.
35     */
36    public function __construct( LoggerInterface $logger ) {
37        $this->logger = $logger;
38
39        // Define Requests options
40        $options = array();
41
42        $client = new HttpClient( $options );
43
44        $this->api = new BlockchainInfoApi( $client, $client, $logger );
45    }
46
47    /**
48     *
49     * @see Blockchain_API_Interface::get_received_by_address()
50     *
51     * @param string $btc_address
52     * @param bool   $confirmed
53     *
54     * @return string
55     * @throws \Exception
56     */
57    public function get_received_by_address( string $btc_address, bool $confirmed ): string {
58        $minimum_confirmations = $confirmed ? 1 : 0;
59
60        return $this->api->getReceivedByAddress( $btc_address, $minimum_confirmations );
61    }
62
63    public function get_address_balance( string $btc_address, int $number_of_confirmations ): Address_Balance {
64
65        $result                            = array();
66        $result['number_of_confirmations'] = $number_of_confirmations;
67        $result['unconfirmed_balance']     = $this->api->getAddressBalance( $btc_address, 0 );
68        $result['confirmed_balance']       = $this->api->getAddressBalance( $btc_address, $number_of_confirmations );
69
70        return new class( $result ) implements Address_Balance {
71
72            protected array $result;
73
74            public function __construct( $result ) {
75                $this->result = $result;
76            }
77
78            public function get_confirmed_balance(): string {
79                return $this->result['confirmed_balance'];
80            }
81
82            public function get_unconfirmed_balance(): string {
83                return $this->result['unconfirmed_balance'];
84            }
85
86            public function get_number_of_confirmations(): int {
87                return $this->result['number_of_confirmations'];
88            }
89        };
90    }
91
92    /**
93     * @param string $btc_address
94     *
95     * @return array<string, Transaction_Interface>
96     * @throws \Exception
97     */
98    public function get_transactions_received( string $btc_address ): array {
99        $raw_address = $this->api->getRawAddr( $btc_address );
100
101        $blockchain_transactions = $raw_address->getTxs();
102
103        /**
104         * @param array $blockchain_transaction
105         *
106         * @throws \Exception
107         */
108        $blockchain_mapper = function ( \BrianHenryIE\WP_Bitcoin_Gateway\BlockchainInfo\Model\Transaction $blockchain_transaction ): Transaction_Interface {
109
110            return new class($blockchain_transaction) implements Transaction_Interface {
111                private \BrianHenryIE\WP_Bitcoin_Gateway\BlockchainInfo\Model\Transaction $transaction;
112
113                public function __construct( \BrianHenryIE\WP_Bitcoin_Gateway\BlockchainInfo\Model\Transaction $transaction ) {
114                    $this->transaction = $transaction;
115                }
116
117                public function get_txid(): string {
118                    return $this->transaction->getHash();
119                }
120
121                public function get_time(): \DateTimeInterface {
122                    return new DateTimeImmutable( '@' . $this->transaction->getTime(), new DateTimeZone( 'UTC' ) );
123                }
124
125                public function get_value( string $to_address ): float {
126
127                    $value_including_fee = array_reduce(
128                        $this->transaction->getOut(),
129                        function ( $carry, TransactionOut $out ) use ( $to_address ) {
130
131                            if ( $out->getAddr() === $to_address ) {
132                                return $carry + $out->getValue();
133                            }
134                            return $carry;
135                        },
136                        0
137                    );
138
139                    return $value_including_fee / 100000000;
140                }
141
142                public function get_block_height(): int {
143                    return $this->transaction->getBlockHeight();
144                }
145            };
146        };
147
148        $transactions = array_map( $blockchain_mapper, $blockchain_transactions );
149
150        // Return the array keyed by id.
151        $keyed_transactions = array();
152        foreach ( $transactions as $transaction ) {
153            $txid                        = (string) $transaction->get_txid();
154            $keyed_transactions[ $txid ] = $transaction;
155        }
156
157        return $keyed_transactions;
158    }
159
160    /**
161     * @throws \Exception
162     */
163    public function get_blockchain_height(): int {
164
165        return $this->api->getBlockCount();
166    }
167}