Complex classes like BlocktrailSDK often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use BlocktrailSDK, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 40 | class BlocktrailSDK implements BlocktrailSDKInterface { |
||
| 41 | /** |
||
| 42 | * @var Connection\RestClientInterface |
||
| 43 | */ |
||
| 44 | protected $client; |
||
| 45 | |||
| 46 | /** |
||
| 47 | * @var string currently only supporting; bitcoin |
||
| 48 | */ |
||
| 49 | protected $network; |
||
| 50 | |||
| 51 | /** |
||
| 52 | * @var bool |
||
| 53 | */ |
||
| 54 | protected $testnet; |
||
| 55 | |||
| 56 | /** |
||
| 57 | * @param string $apiKey the API_KEY to use for authentication |
||
| 58 | * @param string $apiSecret the API_SECRET to use for authentication |
||
| 59 | * @param string $network the cryptocurrency 'network' to consume, eg BTC, LTC, etc |
||
| 60 | * @param bool $testnet testnet yes/no |
||
| 61 | * @param string $apiVersion the version of the API to consume |
||
| 62 | * @param null $apiEndpoint overwrite the endpoint used |
||
| 63 | * this will cause the $network, $testnet and $apiVersion to be ignored! |
||
| 64 | */ |
||
| 65 | 117 | public function __construct($apiKey, $apiSecret, $network = 'BTC', $testnet = false, $apiVersion = 'v1', $apiEndpoint = null) { |
|
| 80 | |||
| 81 | /** |
||
| 82 | * normalize network string |
||
| 83 | * |
||
| 84 | * @param $network |
||
| 85 | * @param $testnet |
||
| 86 | * @return array |
||
| 87 | * @throws \Exception |
||
| 88 | */ |
||
| 89 | 117 | protected function normalizeNetwork($network, $testnet) { |
|
| 93 | |||
| 94 | /** |
||
| 95 | * set BitcoinLib to the correct magic-byte defaults for the selected network |
||
| 96 | * |
||
| 97 | * @param $network |
||
| 98 | * @param bool $testnet |
||
| 99 | * @param bool $regtest |
||
| 100 | */ |
||
| 101 | 117 | protected function setBitcoinLibMagicBytes($network, $testnet, $regtest) { |
|
| 102 | |||
| 103 | 117 | if ($network === "bitcoin") { |
|
| 104 | 117 | if ($regtest) { |
|
| 105 | $useNetwork = NetworkFactory::bitcoinRegtest(); |
||
| 106 | 117 | } else if ($testnet) { |
|
| 107 | 29 | $useNetwork = NetworkFactory::bitcoinTestnet(); |
|
| 108 | } else { |
||
| 109 | 117 | $useNetwork = NetworkFactory::bitcoin(); |
|
| 110 | } |
||
| 111 | 4 | } else if ($network === "bitcoincash") { |
|
| 112 | 4 | if ($regtest) { |
|
| 113 | $useNetwork = new BitcoinCashRegtest(); |
||
| 114 | 4 | } else if ($testnet) { |
|
| 115 | 4 | $useNetwork = new BitcoinCashTestnet(); |
|
| 116 | } else { |
||
| 117 | $useNetwork = new BitcoinCash(); |
||
| 118 | } |
||
| 119 | } |
||
| 120 | |||
| 121 | 117 | Bitcoin::setNetwork($useNetwork); |
|
| 122 | 117 | } |
|
| 123 | |||
| 124 | /** |
||
| 125 | * enable CURL debugging output |
||
| 126 | * |
||
| 127 | * @param bool $debug |
||
| 128 | * |
||
| 129 | * @codeCoverageIgnore |
||
| 130 | */ |
||
| 131 | public function setCurlDebugging($debug = true) { |
||
| 134 | |||
| 135 | /** |
||
| 136 | * enable verbose errors |
||
| 137 | * |
||
| 138 | * @param bool $verboseErrors |
||
| 139 | * |
||
| 140 | * @codeCoverageIgnore |
||
| 141 | */ |
||
| 142 | public function setVerboseErrors($verboseErrors = true) { |
||
| 145 | |||
| 146 | /** |
||
| 147 | * set cURL default option on Guzzle client |
||
| 148 | * @param string $key |
||
| 149 | * @param bool $value |
||
| 150 | * |
||
| 151 | * @codeCoverageIgnore |
||
| 152 | */ |
||
| 153 | public function setCurlDefaultOption($key, $value) { |
||
| 156 | |||
| 157 | /** |
||
| 158 | * @return RestClientInterface |
||
| 159 | */ |
||
| 160 | 2 | public function getRestClient() { |
|
| 163 | |||
| 164 | /** |
||
| 165 | * @param RestClientInterface $restClient |
||
| 166 | */ |
||
| 167 | public function setRestClient(RestClientInterface $restClient) { |
||
| 170 | |||
| 171 | /** |
||
| 172 | * get a single address |
||
| 173 | * @param string $address address hash |
||
| 174 | * @return array associative array containing the response |
||
| 175 | */ |
||
| 176 | 1 | public function address($address) { |
|
| 180 | |||
| 181 | /** |
||
| 182 | * get all transactions for an address (paginated) |
||
| 183 | * @param string $address address hash |
||
| 184 | * @param integer $page pagination: page number |
||
| 185 | * @param integer $limit pagination: records per page (max 500) |
||
| 186 | * @param string $sortDir pagination: sort direction (asc|desc) |
||
| 187 | * @return array associative array containing the response |
||
| 188 | */ |
||
| 189 | 1 | public function addressTransactions($address, $page = 1, $limit = 20, $sortDir = 'asc') { |
|
| 198 | |||
| 199 | /** |
||
| 200 | * get all unconfirmed transactions for an address (paginated) |
||
| 201 | * @param string $address address hash |
||
| 202 | * @param integer $page pagination: page number |
||
| 203 | * @param integer $limit pagination: records per page (max 500) |
||
| 204 | * @param string $sortDir pagination: sort direction (asc|desc) |
||
| 205 | * @return array associative array containing the response |
||
| 206 | */ |
||
| 207 | 1 | public function addressUnconfirmedTransactions($address, $page = 1, $limit = 20, $sortDir = 'asc') { |
|
| 216 | |||
| 217 | /** |
||
| 218 | * get all unspent outputs for an address (paginated) |
||
| 219 | * @param string $address address hash |
||
| 220 | * @param integer $page pagination: page number |
||
| 221 | * @param integer $limit pagination: records per page (max 500) |
||
| 222 | * @param string $sortDir pagination: sort direction (asc|desc) |
||
| 223 | * @return array associative array containing the response |
||
| 224 | */ |
||
| 225 | 1 | public function addressUnspentOutputs($address, $page = 1, $limit = 20, $sortDir = 'asc') { |
|
| 234 | |||
| 235 | /** |
||
| 236 | * get all unspent outputs for a batch of addresses (paginated) |
||
| 237 | * |
||
| 238 | * @param string[] $addresses |
||
| 239 | * @param integer $page pagination: page number |
||
| 240 | * @param integer $limit pagination: records per page (max 500) |
||
| 241 | * @param string $sortDir pagination: sort direction (asc|desc) |
||
| 242 | * @return array associative array containing the response |
||
| 243 | * @throws \Exception |
||
| 244 | */ |
||
| 245 | public function batchAddressUnspentOutputs($addresses, $page = 1, $limit = 20, $sortDir = 'asc') { |
||
| 254 | |||
| 255 | /** |
||
| 256 | * verify ownership of an address |
||
| 257 | * @param string $address address hash |
||
| 258 | * @param string $signature a signed message (the address hash) using the private key of the address |
||
| 259 | * @return array associative array containing the response |
||
| 260 | */ |
||
| 261 | 2 | public function verifyAddress($address, $signature) { |
|
| 268 | |||
| 269 | /** |
||
| 270 | * get all blocks (paginated) |
||
| 271 | * @param integer $page pagination: page number |
||
| 272 | * @param integer $limit pagination: records per page |
||
| 273 | * @param string $sortDir pagination: sort direction (asc|desc) |
||
| 274 | * @return array associative array containing the response |
||
| 275 | */ |
||
| 276 | 1 | public function allBlocks($page = 1, $limit = 20, $sortDir = 'asc') { |
|
| 285 | |||
| 286 | /** |
||
| 287 | * get the latest block |
||
| 288 | * @return array associative array containing the response |
||
| 289 | */ |
||
| 290 | 1 | public function blockLatest() { |
|
| 294 | |||
| 295 | /** |
||
| 296 | * get an individual block |
||
| 297 | * @param string|integer $block a block hash or a block height |
||
| 298 | * @return array associative array containing the response |
||
| 299 | */ |
||
| 300 | 1 | public function block($block) { |
|
| 304 | |||
| 305 | /** |
||
| 306 | * get all transaction in a block (paginated) |
||
| 307 | * @param string|integer $block a block hash or a block height |
||
| 308 | * @param integer $page pagination: page number |
||
| 309 | * @param integer $limit pagination: records per page |
||
| 310 | * @param string $sortDir pagination: sort direction (asc|desc) |
||
| 311 | * @return array associative array containing the response |
||
| 312 | */ |
||
| 313 | 1 | public function blockTransactions($block, $page = 1, $limit = 20, $sortDir = 'asc') { |
|
| 322 | |||
| 323 | /** |
||
| 324 | * get a single transaction |
||
| 325 | * @param string $txhash transaction hash |
||
| 326 | * @return array associative array containing the response |
||
| 327 | */ |
||
| 328 | 5 | public function transaction($txhash) { |
|
| 332 | |||
| 333 | /** |
||
| 334 | * get a single transaction |
||
| 335 | * @param string[] $txhashes list of transaction hashes (up to 20) |
||
| 336 | * @return array[] array containing the response |
||
| 337 | */ |
||
| 338 | public function transactions($txhashes) { |
||
| 342 | |||
| 343 | /** |
||
| 344 | * get a paginated list of all webhooks associated with the api user |
||
| 345 | * @param integer $page pagination: page number |
||
| 346 | * @param integer $limit pagination: records per page |
||
| 347 | * @return array associative array containing the response |
||
| 348 | */ |
||
| 349 | 1 | public function allWebhooks($page = 1, $limit = 20) { |
|
| 357 | |||
| 358 | /** |
||
| 359 | * get an existing webhook by it's identifier |
||
| 360 | * @param string $identifier a unique identifier associated with the webhook |
||
| 361 | * @return array associative array containing the response |
||
| 362 | */ |
||
| 363 | 1 | public function getWebhook($identifier) { |
|
| 367 | |||
| 368 | /** |
||
| 369 | * create a new webhook |
||
| 370 | * @param string $url the url to receive the webhook events |
||
| 371 | * @param string $identifier a unique identifier to associate with this webhook |
||
| 372 | * @return array associative array containing the response |
||
| 373 | */ |
||
| 374 | 1 | public function setupWebhook($url, $identifier = null) { |
|
| 382 | |||
| 383 | /** |
||
| 384 | * update an existing webhook |
||
| 385 | * @param string $identifier the unique identifier of the webhook to update |
||
| 386 | * @param string $newUrl the new url to receive the webhook events |
||
| 387 | * @param string $newIdentifier a new unique identifier to associate with this webhook |
||
| 388 | * @return array associative array containing the response |
||
| 389 | */ |
||
| 390 | 1 | public function updateWebhook($identifier, $newUrl = null, $newIdentifier = null) { |
|
| 398 | |||
| 399 | /** |
||
| 400 | * deletes an existing webhook and any event subscriptions associated with it |
||
| 401 | * @param string $identifier the unique identifier of the webhook to delete |
||
| 402 | * @return boolean true on success |
||
| 403 | */ |
||
| 404 | 1 | public function deleteWebhook($identifier) { |
|
| 408 | |||
| 409 | /** |
||
| 410 | * get a paginated list of all the events a webhook is subscribed to |
||
| 411 | * @param string $identifier the unique identifier of the webhook |
||
| 412 | * @param integer $page pagination: page number |
||
| 413 | * @param integer $limit pagination: records per page |
||
| 414 | * @return array associative array containing the response |
||
| 415 | */ |
||
| 416 | 2 | public function getWebhookEvents($identifier, $page = 1, $limit = 20) { |
|
| 424 | |||
| 425 | /** |
||
| 426 | * subscribes a webhook to transaction events of one particular transaction |
||
| 427 | * @param string $identifier the unique identifier of the webhook to be triggered |
||
| 428 | * @param string $transaction the transaction hash |
||
| 429 | * @param integer $confirmations the amount of confirmations to send. |
||
| 430 | * @return array associative array containing the response |
||
| 431 | */ |
||
| 432 | 1 | public function subscribeTransaction($identifier, $transaction, $confirmations = 6) { |
|
| 441 | |||
| 442 | /** |
||
| 443 | * subscribes a webhook to transaction events on a particular address |
||
| 444 | * @param string $identifier the unique identifier of the webhook to be triggered |
||
| 445 | * @param string $address the address hash |
||
| 446 | * @param integer $confirmations the amount of confirmations to send. |
||
| 447 | * @return array associative array containing the response |
||
| 448 | */ |
||
| 449 | 1 | public function subscribeAddressTransactions($identifier, $address, $confirmations = 6) { |
|
| 458 | |||
| 459 | /** |
||
| 460 | * batch subscribes a webhook to multiple transaction events |
||
| 461 | * |
||
| 462 | * @param string $identifier the unique identifier of the webhook |
||
| 463 | * @param array $batchData A 2D array of event data: |
||
| 464 | * [address => $address, confirmations => $confirmations] |
||
| 465 | * where $address is the address to subscibe to |
||
| 466 | * and optionally $confirmations is the amount of confirmations |
||
| 467 | * @return boolean true on success |
||
| 468 | */ |
||
| 469 | 1 | public function batchSubscribeAddressTransactions($identifier, $batchData) { |
|
| 481 | |||
| 482 | /** |
||
| 483 | * subscribes a webhook to a new block event |
||
| 484 | * @param string $identifier the unique identifier of the webhook to be triggered |
||
| 485 | * @return array associative array containing the response |
||
| 486 | */ |
||
| 487 | 1 | public function subscribeNewBlocks($identifier) { |
|
| 494 | |||
| 495 | /** |
||
| 496 | * removes an transaction event subscription from a webhook |
||
| 497 | * @param string $identifier the unique identifier of the webhook associated with the event subscription |
||
| 498 | * @param string $transaction the transaction hash of the event subscription |
||
| 499 | * @return boolean true on success |
||
| 500 | */ |
||
| 501 | 1 | public function unsubscribeTransaction($identifier, $transaction) { |
|
| 505 | |||
| 506 | /** |
||
| 507 | * removes an address transaction event subscription from a webhook |
||
| 508 | * @param string $identifier the unique identifier of the webhook associated with the event subscription |
||
| 509 | * @param string $address the address hash of the event subscription |
||
| 510 | * @return boolean true on success |
||
| 511 | */ |
||
| 512 | 1 | public function unsubscribeAddressTransactions($identifier, $address) { |
|
| 516 | |||
| 517 | /** |
||
| 518 | * removes a block event subscription from a webhook |
||
| 519 | * @param string $identifier the unique identifier of the webhook associated with the event subscription |
||
| 520 | * @return boolean true on success |
||
| 521 | */ |
||
| 522 | 1 | public function unsubscribeNewBlocks($identifier) { |
|
| 526 | |||
| 527 | /** |
||
| 528 | * create a new wallet |
||
| 529 | * - will generate a new primary seed (with password) and backup seed (without password) |
||
| 530 | * - send the primary seed (BIP39 'encrypted') and backup public key to the server |
||
| 531 | * - receive the blocktrail co-signing public key from the server |
||
| 532 | * |
||
| 533 | * Either takes one argument: |
||
| 534 | * @param array $options |
||
| 535 | * |
||
| 536 | * Or takes three arguments (old, deprecated syntax): |
||
| 537 | * (@nonPHP-doc) @param $identifier |
||
| 538 | * (@nonPHP-doc) @param $password |
||
| 539 | * (@nonPHP-doc) @param int $keyIndex override for the blocktrail cosigning key to use |
||
| 540 | * |
||
| 541 | * @return array[WalletInterface, array] list($wallet, $backupInfo) |
||
| 542 | * @throws \Exception |
||
| 543 | */ |
||
| 544 | 7 | public function createNewWallet($options) { |
|
| 588 | |||
| 589 | 1 | protected function createNewWalletV1($options) { |
|
| 709 | |||
| 710 | 5 | public static function randomBits($bits) { |
|
| 713 | |||
| 714 | 5 | public static function randomBytes($bytes) { |
|
| 717 | |||
| 718 | 2 | protected function createNewWalletV2($options) { |
|
| 841 | |||
| 842 | 4 | protected function createNewWalletV3($options) { |
|
| 983 | |||
| 984 | /** |
||
| 985 | * @param array $bip32Key |
||
| 986 | * @throws BlocktrailSDKException |
||
| 987 | */ |
||
| 988 | 10 | private function verifyPublicBIP32Key(array $bip32Key) { |
|
| 998 | |||
| 999 | /** |
||
| 1000 | * @param array $walletData |
||
| 1001 | * @throws BlocktrailSDKException |
||
| 1002 | */ |
||
| 1003 | 10 | private function verifyPublicOnly(array $walletData) { |
|
| 1007 | |||
| 1008 | /** |
||
| 1009 | * create wallet using the API |
||
| 1010 | * |
||
| 1011 | * @param string $identifier the wallet identifier to create |
||
| 1012 | * @param array $primaryPublicKey BIP32 extended public key - [key, path] |
||
| 1013 | * @param array $backupPublicKey BIP32 extended public key - [backup key, path "M"] |
||
| 1014 | * @param string $primaryMnemonic mnemonic to store |
||
| 1015 | * @param string $checksum checksum to store |
||
| 1016 | * @param int $keyIndex account that we expect to use |
||
| 1017 | * @param bool $segwit opt in to segwit |
||
| 1018 | * @return mixed |
||
| 1019 | */ |
||
| 1020 | 1 | public function storeNewWalletV1($identifier, $primaryPublicKey, $backupPublicKey, $primaryMnemonic, $checksum, $keyIndex, $segwit = false) { |
|
| 1034 | |||
| 1035 | /** |
||
| 1036 | * create wallet using the API |
||
| 1037 | * |
||
| 1038 | * @param string $identifier the wallet identifier to create |
||
| 1039 | * @param array $primaryPublicKey BIP32 extended public key - [key, path] |
||
| 1040 | * @param array $backupPublicKey BIP32 extended public key - [backup key, path "M"] |
||
| 1041 | * @param $encryptedPrimarySeed |
||
| 1042 | * @param $encryptedSecret |
||
| 1043 | * @param $recoverySecret |
||
| 1044 | * @param string $checksum checksum to store |
||
| 1045 | * @param int $keyIndex account that we expect to use |
||
| 1046 | * @param bool $segwit opt in to segwit |
||
| 1047 | * @return mixed |
||
| 1048 | * @throws \Exception |
||
| 1049 | */ |
||
| 1050 | 5 | public function storeNewWalletV2($identifier, $primaryPublicKey, $backupPublicKey, $encryptedPrimarySeed, $encryptedSecret, $recoverySecret, $checksum, $keyIndex, $segwit = false) { |
|
| 1067 | |||
| 1068 | /** |
||
| 1069 | * create wallet using the API |
||
| 1070 | * |
||
| 1071 | * @param string $identifier the wallet identifier to create |
||
| 1072 | * @param array $primaryPublicKey BIP32 extended public key - [key, path] |
||
| 1073 | * @param array $backupPublicKey BIP32 extended public key - [backup key, path "M"] |
||
| 1074 | * @param $encryptedPrimarySeed |
||
| 1075 | * @param $encryptedSecret |
||
| 1076 | * @param $recoverySecret |
||
| 1077 | * @param string $checksum checksum to store |
||
| 1078 | * @param int $keyIndex account that we expect to use |
||
| 1079 | * @param bool $segwit opt in to segwit |
||
| 1080 | * @return mixed |
||
| 1081 | * @throws \Exception |
||
| 1082 | */ |
||
| 1083 | 4 | public function storeNewWalletV3($identifier, $primaryPublicKey, $backupPublicKey, $encryptedPrimarySeed, $encryptedSecret, $recoverySecret, $checksum, $keyIndex, $segwit = false) { |
|
| 1102 | |||
| 1103 | /** |
||
| 1104 | * upgrade wallet to use a new account number |
||
| 1105 | * the account number specifies which blocktrail cosigning key is used |
||
| 1106 | * |
||
| 1107 | * @param string $identifier the wallet identifier to be upgraded |
||
| 1108 | * @param int $keyIndex the new account to use |
||
| 1109 | * @param array $primaryPublicKey BIP32 extended public key - [key, path] |
||
| 1110 | * @return mixed |
||
| 1111 | */ |
||
| 1112 | 5 | public function upgradeKeyIndex($identifier, $keyIndex, $primaryPublicKey) { |
|
| 1121 | |||
| 1122 | /** |
||
| 1123 | * @param array $options |
||
| 1124 | * @return AddressReaderBase |
||
| 1125 | */ |
||
| 1126 | 23 | private function makeAddressReader(array $options) { |
|
| 1137 | |||
| 1138 | /** |
||
| 1139 | * initialize a previously created wallet |
||
| 1140 | * |
||
| 1141 | * Takes an options object, or accepts identifier/password for backwards compatiblity. |
||
| 1142 | * |
||
| 1143 | * Some of the options: |
||
| 1144 | * - "readonly/readOnly/read-only" can be to a boolean value, |
||
| 1145 | * so the wallet is loaded in read-only mode (no private key) |
||
| 1146 | * - "check_backup_key" can be set to your own backup key: |
||
| 1147 | * Format: ["M', "xpub..."] |
||
| 1148 | * Setting this will allow the SDK to check the server hasn't |
||
| 1149 | * a different key (one it happens to control) |
||
| 1150 | |||
| 1151 | * Either takes one argument: |
||
| 1152 | * @param array $options |
||
| 1153 | * |
||
| 1154 | * Or takes two arguments (old, deprecated syntax): |
||
| 1155 | * (@nonPHP-doc) @param string $identifier the wallet identifier to be initialized |
||
| 1156 | * (@nonPHP-doc) @param string $password the password to decrypt the mnemonic with |
||
| 1157 | * |
||
| 1158 | * @return WalletInterface |
||
| 1159 | * @throws \Exception |
||
| 1160 | */ |
||
| 1161 | 23 | public function initWallet($options) { |
|
| 1273 | |||
| 1274 | /** |
||
| 1275 | * get the wallet data from the server |
||
| 1276 | * |
||
| 1277 | * @param string $identifier the identifier of the wallet |
||
| 1278 | * @return mixed |
||
| 1279 | */ |
||
| 1280 | 23 | public function getWallet($identifier) { |
|
| 1284 | |||
| 1285 | /** |
||
| 1286 | * update the wallet data on the server |
||
| 1287 | * |
||
| 1288 | * @param string $identifier |
||
| 1289 | * @param $data |
||
| 1290 | * @return mixed |
||
| 1291 | */ |
||
| 1292 | 3 | public function updateWallet($identifier, $data) { |
|
| 1296 | |||
| 1297 | /** |
||
| 1298 | * delete a wallet from the server |
||
| 1299 | * the checksum address and a signature to verify you ownership of the key of that checksum address |
||
| 1300 | * is required to be able to delete a wallet |
||
| 1301 | * |
||
| 1302 | * @param string $identifier the identifier of the wallet |
||
| 1303 | * @param string $checksumAddress the address for your master private key (and the checksum used when creating the wallet) |
||
| 1304 | * @param string $signature a signature of the checksum address as message signed by the private key matching that address |
||
| 1305 | * @param bool $force ignore warnings (such as a non-zero balance) |
||
| 1306 | * @return mixed |
||
| 1307 | */ |
||
| 1308 | 10 | public function deleteWallet($identifier, $checksumAddress, $signature, $force = false) { |
|
| 1315 | |||
| 1316 | /** |
||
| 1317 | * create new backup key; |
||
| 1318 | * 1) a BIP39 mnemonic |
||
| 1319 | * 2) a seed from that mnemonic with a blank password |
||
| 1320 | * 3) a private key from that seed |
||
| 1321 | * |
||
| 1322 | * @return array [mnemonic, seed, key] |
||
| 1323 | */ |
||
| 1324 | 1 | protected function newBackupSeed() { |
|
| 1329 | |||
| 1330 | /** |
||
| 1331 | * create new primary key; |
||
| 1332 | * 1) a BIP39 mnemonic |
||
| 1333 | * 2) a seed from that mnemonic with the password |
||
| 1334 | * 3) a private key from that seed |
||
| 1335 | * |
||
| 1336 | * @param string $passphrase the password to use in the BIP39 creation of the seed |
||
| 1337 | * @return array [mnemonic, seed, key] |
||
| 1338 | * @TODO: require a strong password? |
||
| 1339 | */ |
||
| 1340 | 1 | protected function newPrimarySeed($passphrase) { |
|
| 1345 | |||
| 1346 | /** |
||
| 1347 | * create a new key; |
||
| 1348 | * 1) a BIP39 mnemonic |
||
| 1349 | * 2) a seed from that mnemonic with the password |
||
| 1350 | * 3) a private key from that seed |
||
| 1351 | * |
||
| 1352 | * @param string $passphrase the password to use in the BIP39 creation of the seed |
||
| 1353 | * @param string $forceEntropy forced entropy instead of random entropy for testing purposes |
||
| 1354 | * @return array |
||
| 1355 | */ |
||
| 1356 | 1 | protected function generateNewSeed($passphrase = "", $forceEntropy = null) { |
|
| 1373 | |||
| 1374 | /** |
||
| 1375 | * generate a new mnemonic from some random entropy (512 bit) |
||
| 1376 | * |
||
| 1377 | * @param string $forceEntropy forced entropy instead of random entropy for testing purposes |
||
| 1378 | * @return string |
||
| 1379 | * @throws \Exception |
||
| 1380 | */ |
||
| 1381 | 1 | protected function generateNewMnemonic($forceEntropy = null) { |
|
| 1391 | |||
| 1392 | /** |
||
| 1393 | * get the balance for the wallet |
||
| 1394 | * |
||
| 1395 | * @param string $identifier the identifier of the wallet |
||
| 1396 | * @return array |
||
| 1397 | */ |
||
| 1398 | 9 | public function getWalletBalance($identifier) { |
|
| 1402 | |||
| 1403 | /** |
||
| 1404 | * do HD wallet discovery for the wallet |
||
| 1405 | * |
||
| 1406 | * this can be REALLY slow, so we've set the timeout to 120s ... |
||
| 1407 | * |
||
| 1408 | * @param string $identifier the identifier of the wallet |
||
| 1409 | * @param int $gap the gap setting to use for discovery |
||
| 1410 | * @return mixed |
||
| 1411 | */ |
||
| 1412 | 2 | public function doWalletDiscovery($identifier, $gap = 200) { |
|
| 1416 | |||
| 1417 | /** |
||
| 1418 | * get a new derivation number for specified parent path |
||
| 1419 | * eg; m/44'/1'/0/0 results in m/44'/1'/0/0/0 and next time in m/44'/1'/0/0/1 and next time in m/44'/1'/0/0/2 |
||
| 1420 | * |
||
| 1421 | * returns the path |
||
| 1422 | * |
||
| 1423 | * @param string $identifier the identifier of the wallet |
||
| 1424 | * @param string $path the parent path for which to get a new derivation |
||
| 1425 | * @return string |
||
| 1426 | */ |
||
| 1427 | 1 | public function getNewDerivation($identifier, $path) { |
|
| 1431 | |||
| 1432 | /** |
||
| 1433 | * get a new derivation number for specified parent path |
||
| 1434 | * eg; m/44'/1'/0/0 results in m/44'/1'/0/0/0 and next time in m/44'/1'/0/0/1 and next time in m/44'/1'/0/0/2 |
||
| 1435 | * |
||
| 1436 | * @param string $identifier the identifier of the wallet |
||
| 1437 | * @param string $path the parent path for which to get a new derivation |
||
| 1438 | * @return mixed |
||
| 1439 | */ |
||
| 1440 | 16 | public function _getNewDerivation($identifier, $path) { |
|
| 1444 | |||
| 1445 | /** |
||
| 1446 | * get the path (and redeemScript) to specified address |
||
| 1447 | * |
||
| 1448 | * @param string $identifier |
||
| 1449 | * @param string $address |
||
| 1450 | * @return array |
||
| 1451 | * @throws \Exception |
||
| 1452 | */ |
||
| 1453 | 1 | public function getPathForAddress($identifier, $address) { |
|
| 1457 | |||
| 1458 | /** |
||
| 1459 | * send the transaction using the API |
||
| 1460 | * |
||
| 1461 | * @param string $identifier the identifier of the wallet |
||
| 1462 | * @param string|array $rawTransaction raw hex of the transaction (should be partially signed) |
||
| 1463 | * @param array $paths list of the paths that were used for the UTXO |
||
| 1464 | * @param bool $checkFee let the server verify the fee after signing |
||
| 1465 | * @return string the complete raw transaction |
||
| 1466 | * @throws \Exception |
||
| 1467 | */ |
||
| 1468 | 4 | public function sendTransaction($identifier, $rawTransaction, $paths, $checkFee = false) { |
|
| 1498 | |||
| 1499 | /** |
||
| 1500 | * use the API to get the best inputs to use based on the outputs |
||
| 1501 | * |
||
| 1502 | * the return array has the following format: |
||
| 1503 | * [ |
||
| 1504 | * "utxos" => [ |
||
| 1505 | * [ |
||
| 1506 | * "hash" => "<txHash>", |
||
| 1507 | * "idx" => "<index of the output of that <txHash>", |
||
| 1508 | * "scriptpubkey_hex" => "<scriptPubKey-hex>", |
||
| 1509 | * "value" => 32746327, |
||
| 1510 | * "address" => "1address", |
||
| 1511 | * "path" => "m/44'/1'/0'/0/13", |
||
| 1512 | * "redeem_script" => "<redeemScript-hex>", |
||
| 1513 | * ], |
||
| 1514 | * ], |
||
| 1515 | * "fee" => 10000, |
||
| 1516 | * "change"=> 1010109201, |
||
| 1517 | * ] |
||
| 1518 | * |
||
| 1519 | * @param string $identifier the identifier of the wallet |
||
| 1520 | * @param array $outputs the outputs you want to create - array[address => satoshi-value] |
||
| 1521 | * @param bool $lockUTXO when TRUE the UTXOs selected will be locked for a few seconds |
||
| 1522 | * so you have some time to spend them without race-conditions |
||
| 1523 | * @param bool $allowZeroConf |
||
| 1524 | * @param string $feeStrategy |
||
| 1525 | * @param null|int $forceFee |
||
| 1526 | * @return array |
||
| 1527 | * @throws \Exception |
||
| 1528 | */ |
||
| 1529 | 12 | public function coinSelection($identifier, $outputs, $lockUTXO = false, $allowZeroConf = false, $feeStrategy = Wallet::FEE_STRATEGY_OPTIMAL, $forceFee = null) { |
|
| 1530 | $args = [ |
||
| 1531 | 12 | 'lock' => (int)!!$lockUTXO, |
|
| 1532 | 12 | 'zeroconf' => (int)!!$allowZeroConf, |
|
| 1533 | 12 | 'fee_strategy' => $feeStrategy, |
|
| 1534 | ]; |
||
| 1535 | |||
| 1536 | 12 | if ($forceFee !== null) { |
|
| 1537 | 1 | $args['forcefee'] = (int)$forceFee; |
|
| 1538 | } |
||
| 1539 | |||
| 1540 | 12 | $response = $this->client->post( |
|
| 1541 | 12 | "wallet/{$identifier}/coin-selection", |
|
| 1542 | 12 | $args, |
|
| 1543 | 12 | $outputs, |
|
| 1544 | 12 | RestClient::AUTH_HTTP_SIG |
|
| 1545 | ); |
||
| 1546 | |||
| 1547 | 6 | return self::jsonDecode($response->body(), true); |
|
| 1548 | } |
||
| 1549 | |||
| 1550 | /** |
||
| 1551 | * |
||
| 1552 | * @param string $identifier the identifier of the wallet |
||
| 1553 | * @param bool $allowZeroConf |
||
| 1554 | * @param string $feeStrategy |
||
| 1555 | * @param null|int $forceFee |
||
| 1556 | * @param int $outputCnt |
||
| 1557 | * @return array |
||
| 1558 | * @throws \Exception |
||
| 1559 | */ |
||
| 1560 | public function walletMaxSpendable($identifier, $allowZeroConf = false, $feeStrategy = Wallet::FEE_STRATEGY_OPTIMAL, $forceFee = null, $outputCnt = 1) { |
||
| 1579 | |||
| 1580 | /** |
||
| 1581 | * @return array ['optimal_fee' => 10000, 'low_priority_fee' => 5000] |
||
| 1582 | */ |
||
| 1583 | 3 | public function feePerKB() { |
|
| 1587 | |||
| 1588 | /** |
||
| 1589 | * get the current price index |
||
| 1590 | * |
||
| 1591 | * @return array eg; ['USD' => 287.30] |
||
| 1592 | */ |
||
| 1593 | 1 | public function price() { |
|
| 1597 | |||
| 1598 | /** |
||
| 1599 | * setup webhook for wallet |
||
| 1600 | * |
||
| 1601 | * @param string $identifier the wallet identifier for which to create the webhook |
||
| 1602 | * @param string $webhookIdentifier the webhook identifier to use |
||
| 1603 | * @param string $url the url to receive the webhook events |
||
| 1604 | * @return array |
||
| 1605 | */ |
||
| 1606 | 1 | public function setupWalletWebhook($identifier, $webhookIdentifier, $url) { |
|
| 1610 | |||
| 1611 | /** |
||
| 1612 | * delete webhook for wallet |
||
| 1613 | * |
||
| 1614 | * @param string $identifier the wallet identifier for which to delete the webhook |
||
| 1615 | * @param string $webhookIdentifier the webhook identifier to delete |
||
| 1616 | * @return array |
||
| 1617 | */ |
||
| 1618 | 1 | public function deleteWalletWebhook($identifier, $webhookIdentifier) { |
|
| 1622 | |||
| 1623 | /** |
||
| 1624 | * lock a specific unspent output |
||
| 1625 | * |
||
| 1626 | * @param $identifier |
||
| 1627 | * @param $txHash |
||
| 1628 | * @param $txIdx |
||
| 1629 | * @param int $ttl |
||
| 1630 | * @return bool |
||
| 1631 | */ |
||
| 1632 | public function lockWalletUTXO($identifier, $txHash, $txIdx, $ttl = 3) { |
||
| 1636 | |||
| 1637 | /** |
||
| 1638 | * unlock a specific unspent output |
||
| 1639 | * |
||
| 1640 | * @param $identifier |
||
| 1641 | * @param $txHash |
||
| 1642 | * @param $txIdx |
||
| 1643 | * @return bool |
||
| 1644 | */ |
||
| 1645 | public function unlockWalletUTXO($identifier, $txHash, $txIdx) { |
||
| 1649 | |||
| 1650 | /** |
||
| 1651 | * get all transactions for wallet (paginated) |
||
| 1652 | * |
||
| 1653 | * @param string $identifier the wallet identifier for which to get transactions |
||
| 1654 | * @param integer $page pagination: page number |
||
| 1655 | * @param integer $limit pagination: records per page (max 500) |
||
| 1656 | * @param string $sortDir pagination: sort direction (asc|desc) |
||
| 1657 | * @return array associative array containing the response |
||
| 1658 | */ |
||
| 1659 | 1 | public function walletTransactions($identifier, $page = 1, $limit = 20, $sortDir = 'asc') { |
|
| 1668 | |||
| 1669 | /** |
||
| 1670 | * get all addresses for wallet (paginated) |
||
| 1671 | * |
||
| 1672 | * @param string $identifier the wallet identifier for which to get addresses |
||
| 1673 | * @param integer $page pagination: page number |
||
| 1674 | * @param integer $limit pagination: records per page (max 500) |
||
| 1675 | * @param string $sortDir pagination: sort direction (asc|desc) |
||
| 1676 | * @return array associative array containing the response |
||
| 1677 | */ |
||
| 1678 | 1 | public function walletAddresses($identifier, $page = 1, $limit = 20, $sortDir = 'asc') { |
|
| 1687 | |||
| 1688 | /** |
||
| 1689 | * get all UTXOs for wallet (paginated) |
||
| 1690 | * |
||
| 1691 | * @param string $identifier the wallet identifier for which to get addresses |
||
| 1692 | * @param integer $page pagination: page number |
||
| 1693 | * @param integer $limit pagination: records per page (max 500) |
||
| 1694 | * @param string $sortDir pagination: sort direction (asc|desc) |
||
| 1695 | * @param boolean $zeroconf include zero confirmation transactions |
||
| 1696 | * @return array associative array containing the response |
||
| 1697 | */ |
||
| 1698 | 1 | public function walletUTXOs($identifier, $page = 1, $limit = 20, $sortDir = 'asc', $zeroconf = true) { |
|
| 1708 | |||
| 1709 | /** |
||
| 1710 | * get a paginated list of all wallets associated with the api user |
||
| 1711 | * |
||
| 1712 | * @param integer $page pagination: page number |
||
| 1713 | * @param integer $limit pagination: records per page |
||
| 1714 | * @return array associative array containing the response |
||
| 1715 | */ |
||
| 1716 | 2 | public function allWallets($page = 1, $limit = 20) { |
|
| 1724 | |||
| 1725 | /** |
||
| 1726 | * send raw transaction |
||
| 1727 | * |
||
| 1728 | * @param $txHex |
||
| 1729 | * @return bool |
||
| 1730 | */ |
||
| 1731 | public function sendRawTransaction($txHex) { |
||
| 1735 | |||
| 1736 | /** |
||
| 1737 | * testnet only ;-) |
||
| 1738 | * |
||
| 1739 | * @param $address |
||
| 1740 | * @param int $amount defaults to 0.0001 BTC, max 0.001 BTC |
||
| 1741 | * @return mixed |
||
| 1742 | * @throws \Exception |
||
| 1743 | */ |
||
| 1744 | public function faucetWithdrawal($address, $amount = 10000) { |
||
| 1751 | |||
| 1752 | /** |
||
| 1753 | * Exists for BC. Remove at major bump. |
||
| 1754 | * |
||
| 1755 | * @see faucetWithdrawal |
||
| 1756 | * @deprecated |
||
| 1757 | * @param $address |
||
| 1758 | * @param int $amount defaults to 0.0001 BTC, max 0.001 BTC |
||
| 1759 | * @return mixed |
||
| 1760 | * @throws \Exception |
||
| 1761 | */ |
||
| 1762 | public function faucetWithdrawl($address, $amount = 10000) { |
||
| 1765 | |||
| 1766 | /** |
||
| 1767 | * verify a message signed bitcoin-core style |
||
| 1768 | * |
||
| 1769 | * @param string $message |
||
| 1770 | * @param string $address |
||
| 1771 | * @param string $signature |
||
| 1772 | * @return boolean |
||
| 1773 | */ |
||
| 1774 | 1 | public function verifyMessage($message, $address, $signature) { |
|
| 1791 | |||
| 1792 | /** |
||
| 1793 | * Take a base58 or cashaddress, and return only |
||
| 1794 | * the cash address. |
||
| 1795 | * This function only works on bitcoin cash. |
||
| 1796 | * @param string $input |
||
| 1797 | * @return string |
||
| 1798 | * @throws BlocktrailSDKException |
||
| 1799 | */ |
||
| 1800 | 1 | public function getLegacyBitcoinCashAddress($input) { |
|
| 1817 | |||
| 1818 | /** |
||
| 1819 | * convert a Satoshi value to a BTC value |
||
| 1820 | * |
||
| 1821 | * @param int $satoshi |
||
| 1822 | * @return float |
||
| 1823 | */ |
||
| 1824 | public static function toBTC($satoshi) { |
||
| 1827 | |||
| 1828 | /** |
||
| 1829 | * convert a Satoshi value to a BTC value and return it as a string |
||
| 1830 | |||
| 1831 | * @param int $satoshi |
||
| 1832 | * @return string |
||
| 1833 | */ |
||
| 1834 | public static function toBTCString($satoshi) { |
||
| 1837 | |||
| 1838 | /** |
||
| 1839 | * convert a BTC value to a Satoshi value |
||
| 1840 | * |
||
| 1841 | * @param float $btc |
||
| 1842 | * @return string |
||
| 1843 | */ |
||
| 1844 | 12 | public static function toSatoshiString($btc) { |
|
| 1847 | |||
| 1848 | /** |
||
| 1849 | * convert a BTC value to a Satoshi value |
||
| 1850 | * |
||
| 1851 | * @param float $btc |
||
| 1852 | * @return string |
||
| 1853 | */ |
||
| 1854 | 12 | public static function toSatoshi($btc) { |
|
| 1857 | |||
| 1858 | /** |
||
| 1859 | * json_decode helper that throws exceptions when it fails to decode |
||
| 1860 | * |
||
| 1861 | * @param $json |
||
| 1862 | * @param bool $assoc |
||
| 1863 | * @return mixed |
||
| 1864 | * @throws \Exception |
||
| 1865 | */ |
||
| 1866 | 32 | protected static function jsonDecode($json, $assoc = false) { |
|
| 1879 | |||
| 1880 | /** |
||
| 1881 | * sort public keys for multisig script |
||
| 1882 | * |
||
| 1883 | * @param PublicKeyInterface[] $pubKeys |
||
| 1884 | * @return PublicKeyInterface[] |
||
| 1885 | */ |
||
| 1886 | 18 | public static function sortMultisigKeys(array $pubKeys) { |
|
| 1896 | |||
| 1897 | /** |
||
| 1898 | * read and decode the json payload from a webhook's POST request. |
||
| 1899 | * |
||
| 1900 | * @param bool $returnObject flag to indicate if an object or associative array should be returned |
||
| 1901 | * @return mixed|null |
||
| 1902 | * @throws \Exception |
||
| 1903 | */ |
||
| 1904 | public static function getWebhookPayload($returnObject = false) { |
||
| 1912 | |||
| 1913 | public static function normalizeBIP32KeyArray($keys) { |
||
| 1918 | |||
| 1919 | /** |
||
| 1920 | * @param array|BIP32Key $key |
||
| 1921 | * @return BIP32Key |
||
| 1922 | * @throws \Exception |
||
| 1923 | */ |
||
| 1924 | 26 | public static function normalizeBIP32Key($key) { |
|
| 1942 | } |
||
| 1943 |
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.