diff --git a/.scrutinizer.yml b/.scrutinizer.yml index 0dd6705..7a55891 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -1,3 +1,11 @@ +build: + nodes: + php-scrutinizer-run: + project_setup: + override: true + tests: + override: [php-scrutinizer-run] + filter: excluded_paths: [examples*, vendor/*, build/*, tests/*] diff --git a/composer.json b/composer.json index 4139529..858052e 100644 --- a/composer.json +++ b/composer.json @@ -33,7 +33,8 @@ "ext-dom": "*", "ext-curl": "*", - "bitwasp/bitcoin": "v0.0.34.1", + "bitwasp/bitcoin": "^v0.0.35.0", + "btccom/bitwasp-bitcoin-bch-addon": "v0.0.2", "btccom/justencrypt": "v0.2.0", "btccom/cashaddress": "v0.0.3", "mdanter/ecc": "v0.4.*", @@ -46,7 +47,8 @@ "dompdf/dompdf" : "0.6.*", "endroid/qrcode": "1.5.*", "blocktrail/cryptojs-aes-php": "0.1.*", - "spomky-labs/php-aes-gcm": "v1.2.0" + "spomky-labs/php-aes-gcm": "v1.2.0", + "symfony/http-foundation": "^2.7|^3.0|^4.0" }, "require-dev": { "phpunit/phpunit": "5.*", diff --git a/examples/wallet_cpfp.php b/examples/wallet_cpfp.php index 6fe24b8..ec68d7c 100644 --- a/examples/wallet_cpfp.php +++ b/examples/wallet_cpfp.php @@ -1,12 +1,9 @@ getNewAddress(); +$addrReader = $wallet->getAddressReader(); // setup txbuilder -$txBuilder = new TransactionBuilder(); +$txBuilder = new TransactionBuilder($addrReader); // set change address to our address $txBuilder->setChangeAddress($myAddress); @@ -90,8 +88,8 @@ // add UTXOs to txbuilder foreach ($utxos as $utxo) { $scriptPubKey = ScriptFactory::fromHex($utxo['scriptpubkey_hex']); - $address = AddressFactory::fromString($utxo['address']); - $path = $wallet->getPathForAddress($address->getAddress()); + $address = $addrReader->fromString($utxo['address']); + $path = $wallet->getPathForAddress($address->getAddress())['path']; $scripts = $wallet->getWalletScriptByPath($path); $redeemScript = $scripts->getRedeemScript(); $witnessScript = null; diff --git a/src/Address/AddressReaderBase.php b/src/Address/AddressReaderBase.php deleted file mode 100644 index a5f003d..0000000 --- a/src/Address/AddressReaderBase.php +++ /dev/null @@ -1,46 +0,0 @@ -slice(0, 1)->getHex(); - - if ($prefixByte === $network->getP2shByte()) { - return new ScriptHashAddress($data->slice(1)); - } else if ($prefixByte === $network->getAddressByte()) { - return new PayToPubKeyHashAddress($data->slice(1)); - } - } catch (\Exception $e) { - } - return null; - } - - /** - * @param $strAddress - * @param NetworkInterface|null $network - * @return AddressInterface - */ - abstract public function fromString($strAddress, NetworkInterface $network = null); - - /** - * @param ScriptInterface $script - * @return AddressInterface - */ - abstract public function fromOutputScript(ScriptInterface $script); -} diff --git a/src/Address/Base32AddressInterface.php b/src/Address/Base32AddressInterface.php deleted file mode 100644 index 6528255..0000000 --- a/src/Address/Base32AddressInterface.php +++ /dev/null @@ -1,15 +0,0 @@ -isWitness($wp)) { - /** @var WitnessProgram $wp */ - return new SegwitAddress($wp); - } - - $decode = (new OutputClassifier())->decode($outputScript); - switch ($decode->getType()) { - case ScriptType::P2PKH: - /** @var BufferInterface $solution */ - return new PayToPubKeyHashAddress($decode->getSolution()); - case ScriptType::P2SH: - /** @var BufferInterface $solution */ - return new ScriptHashAddress($decode->getSolution()); - default: - throw new \RuntimeException('Script type is not associated with an address'); - } - } - - /** - * @param string $strAddress - * @param NetworkInterface|null $network - * @return Base58AddressInterface|SegwitAddress|null - * @throws BlocktrailSDKException - */ - public function fromString($strAddress, NetworkInterface $network = null) { - $network = $network ?: Bitcoin::getNetwork(); - - if (($base58Address = $this->readBase58($strAddress, $network))) { - return $base58Address; - } - - if (($bech32Address = $this->readSegwitAddress($strAddress, $network))) { - return $bech32Address; - } - - throw new BlocktrailSDKException("Address not recognized"); - } -} diff --git a/src/Address/BitcoinCashAddressReader.php b/src/Address/BitcoinCashAddressReader.php deleted file mode 100644 index 06c1bbf..0000000 --- a/src/Address/BitcoinCashAddressReader.php +++ /dev/null @@ -1,123 +0,0 @@ -useNewCashAddress = (bool) $useNewCashAddress; - } - - /** - * @param string $strAddress - * @param BitcoinCashNetworkInterface $network - * @return CashAddress|null - */ - protected function readCashAddress($strAddress, BitcoinCashNetworkInterface $network) { - try { - list ($prefix, $scriptType, $hash) = \CashAddr\CashAddress::decode($strAddress); - if ($prefix !== $network->getCashAddressPrefix()) { - return null; - } - if (!($scriptType === ScriptType::P2PKH || $scriptType === ScriptType::P2SH)) { - return null; - } - - return new CashAddress($scriptType, new Buffer($hash, 20)); - } catch (\Exception $e) { - // continue on - } - - try { - list ($prefix, $scriptType, $hash) = \CashAddr\CashAddress::decode( - sprintf("%s:%s", $network->getCashAddressPrefix(), $strAddress) - ); - - if ($prefix !== $network->getCashAddressPrefix()) { - return null; - } - if (!($scriptType === ScriptType::P2PKH || $scriptType === ScriptType::P2SH)) { - return null; - } - - return new CashAddress($scriptType, new Buffer($hash, 20)); - } catch (\Exception $e) { - // continue on - } - - return null; - } - - /** - * @param string $strAddress - * @param NetworkInterface|null $network - * @return Base58AddressInterface|CashAddress - * @throws BlocktrailSDKException - */ - public function fromString($strAddress, NetworkInterface $network = null) { - $network = $network ?: Bitcoin::getNetwork(); - - if (($base58Address = $this->readBase58($strAddress, $network))) { - return $base58Address; - } - - if ($this->useNewCashAddress && $network instanceof BitcoinCashNetworkInterface) { - if (($base32Address = $this->readCashAddress($strAddress, $network))) { - return $base32Address; - } - } - - throw new BlocktrailSDKException("Address not recognized"); - } - - /** - * @param ScriptInterface $script - * @return Base58AddressInterface|CashAddress - */ - public function fromOutputScript(ScriptInterface $script) { - $decode = (new OutputClassifier())->decode($script); - - switch ($decode->getType()) { - case ScriptType::P2PKH: - /** @var BufferInterface $solution */ - if ($this->useNewCashAddress) { - return new CashAddress(ScriptType::P2PKH, $decode->getSolution()); - } else { - return new PayToPubKeyHashAddress($decode->getSolution()); - } - break; - case ScriptType::P2SH: - /** @var BufferInterface $solution */ - if ($this->useNewCashAddress) { - return new CashAddress(ScriptType::P2SH, $decode->getSolution()); - } else { - return new ScriptHashAddress($decode->getSolution()); - } - break; - default: - throw new \RuntimeException('Script type is not associated with an address'); - } - } -} diff --git a/src/Address/CashAddress.php b/src/Address/CashAddress.php deleted file mode 100644 index 1875f0a..0000000 --- a/src/Address/CashAddress.php +++ /dev/null @@ -1,103 +0,0 @@ -type = $type; - - parent::__construct($hash); - } - - /** - * @param BitcoinCashNetworkInterface $network - * @return string - */ - public function getPrefix(BitcoinCashNetworkInterface $network) { - return $network->getCashAddressPrefix(); - } - - /** - * @return string - */ - public function getType() { - return $this->type; - } - - /** - * @param NetworkInterface|null $network - * @return string - * @throws BlocktrailSDKException - * @throws \CashAddr\Exception\Base32Exception - * @throws \CashAddr\Exception\CashAddressException - */ - public function getAddress(NetworkInterface $network = null) { - if (null === $network) { - $network = Bitcoin::getNetwork(); - } - - if (!($network instanceof BitcoinCashNetworkInterface)) { - throw new BlocktrailSDKException("Invalid network - must implement BitcoinCashNetworkInterface"); - } - - return \CashAddr\CashAddress::encode( - $network->getCashAddressPrefix(), - $this->type, - $this->hash->getBinary() - ); - } - - /** - * @return PayToPubKeyHashAddress|ScriptHashAddress - */ - public function getLegacyAddress() { - if ($this->type === ScriptType::P2PKH) { - return new PayToPubKeyHashAddress($this->hash); - } else { - return new ScriptHashAddress($this->hash); - } - } - - /** - * @return \BitWasp\Bitcoin\Script\ScriptInterface - */ - public function getScriptPubKey() { - if ($this->type === ScriptType::P2PKH) { - return ScriptFactory::scriptPubKey()->p2pkh($this->hash); - } else { - return ScriptFactory::scriptPubKey()->p2sh($this->hash); - } - } -} diff --git a/src/Backend/BtccomConverter.php b/src/Backend/BtccomConverter.php index c8cfcc3..2234b80 100644 --- a/src/Backend/BtccomConverter.php +++ b/src/Backend/BtccomConverter.php @@ -2,15 +2,27 @@ namespace Blocktrail\SDK\Backend; -use BitWasp\Bitcoin\Address\AddressFactory; +use BitWasp\Bitcoin\Address\BaseAddressCreator; +use BitWasp\Bitcoin\Address\PayToPubKeyHashAddress; +use BitWasp\Bitcoin\Address\ScriptHashAddress; use BitWasp\Bitcoin\Script\Classifier\OutputClassifier; use BitWasp\Bitcoin\Script\ScriptType; -use BitWasp\Bitcoin\Transaction\Transaction; use BitWasp\Bitcoin\Transaction\TransactionInput; use Blocktrail\SDK\BlocktrailSDK; use Blocktrail\SDK\Connection\Exceptions\EndpointSpecificError; +use Btccom\BitcoinCash\Address\CashAddress; class BtccomConverter implements ConverterInterface { + + /** + * @var BaseAddressCreator + */ + private $addrReader; + + public function __construct(BaseAddressCreator $addrReader) { + $this->addrReader = $addrReader; + } + public function paginationParams($params) { if (!$params) { return $params; @@ -183,7 +195,7 @@ public function convertAddressUnspentOutputs($res, $address) { $data = BlocktrailSDK::jsonDecode($res, true); $this->handleErros($data); - $spk = AddressFactory::fromString($address)->getScriptPubKey(); + $spk = $this->addrReader->fromString($address)->getScriptPubKey(); $type = (new OutputClassifier())->classify($spk); $scriptAsm = $spk->getScriptParser()->getHumanReadable(); $scriptHex = $spk->getHex(); @@ -211,7 +223,7 @@ public function convertBatchAddressesUnspentOutputs($res) { continue; } - $spk = AddressFactory::fromString($row['address'])->getScriptPubKey(); + $spk = $this->addrReader->fromString($row['address'])->getScriptPubKey(); $type = (new OutputClassifier())->classify($spk); $scriptAsm = $spk->getScriptParser()->getHumanReadable(); $scriptHex = $spk->getHex(); @@ -406,11 +418,19 @@ protected static function utcTimestampToISODateStr($time) { return (new \DateTime("@{$time}"))->format(\DATE_ISO8601); } - protected static function getBase58AddressHash160($addr) { + private function getBase58AddressHash160($addr) { try { - return \strtoupper(AddressFactory::fromString($addr)->getHash()->getHex()); + $obj = $this->addrReader->fromString($addr); + if ($obj instanceof PayToPubKeyHashAddress || $obj instanceof ScriptHashAddress) { + return \strtoupper($obj->getHash()->getHex()); + } + if ($obj instanceof CashAddress && ($obj->getType() == ScriptType::P2PKH || $obj->getType() == ScriptType::P2SH)) { + return \strtoupper($obj->getHash()->getHex()); + } } catch (\Exception $e) { - return null; + // allow fallthrough, don't know this address type } + + return null; } } diff --git a/src/Bitcoin/BIP32Key.php b/src/Bitcoin/BIP32Key.php index 1cb7ba3..f32408d 100644 --- a/src/Bitcoin/BIP32Key.php +++ b/src/Bitcoin/BIP32Key.php @@ -2,7 +2,6 @@ namespace Blocktrail\SDK\Bitcoin; -use BitWasp\Bitcoin\Crypto\EcAdapter\Impl\PhpEcc\Key\PublicKey; use BitWasp\Bitcoin\Crypto\EcAdapter\Key\PublicKeyInterface; use BitWasp\Bitcoin\Key\Deterministic\HierarchicalKey; @@ -148,7 +147,7 @@ public function buildKey($path) { } if ($toPublic) { - $key = $key->toPublic(); + $key = $key->withoutPrivateKey(); } $this->derivations[$originalPath] = BIP32Key::create($key, $originalPath); diff --git a/src/BlocktrailSDK.php b/src/BlocktrailSDK.php index ee37527..97e4a09 100644 --- a/src/BlocktrailSDK.php +++ b/src/BlocktrailSDK.php @@ -2,6 +2,11 @@ namespace Blocktrail\SDK; +use Btccom\BitcoinCash\Address\AddressCreator as BitcoinCashAddressCreator; +use Btccom\BitcoinCash\Address\CashAddress; +use Btccom\BitcoinCash\Network\NetworkFactory as BitcoinCashNetworkFactory; +use BitWasp\Bitcoin\Address\AddressCreator as BitcoinAddressCreator; +use BitWasp\Bitcoin\Address\BaseAddressCreator; use BitWasp\Bitcoin\Address\PayToPubKeyHashAddress; use BitWasp\Bitcoin\Bitcoin; use BitWasp\Bitcoin\Crypto\EcAdapter\EcSerializer; @@ -14,25 +19,17 @@ use BitWasp\Bitcoin\MessageSigner\SignedMessage; use BitWasp\Bitcoin\Mnemonic\Bip39\Bip39SeedGenerator; use BitWasp\Bitcoin\Mnemonic\MnemonicFactory; -use BitWasp\Bitcoin\Network\NetworkFactory; +use BitWasp\Bitcoin\Network\NetworkFactory as BitcoinNetworkFactory; use BitWasp\Bitcoin\Transaction\TransactionFactory; use BitWasp\Buffertools\Buffer; use BitWasp\Buffertools\BufferInterface; use Blocktrail\CryptoJSAES\CryptoJSAES; -use Blocktrail\SDK\Address\AddressReaderBase; -use Blocktrail\SDK\Address\BitcoinAddressReader; -use Blocktrail\SDK\Address\BitcoinCashAddressReader; -use Blocktrail\SDK\Address\CashAddress; -use Blocktrail\SDK\Backend\BlocktrailConverter; use Blocktrail\SDK\Backend\BtccomConverter; use Blocktrail\SDK\Backend\ConverterInterface; use Blocktrail\SDK\Bitcoin\BIP32Key; use Blocktrail\SDK\Connection\RestClient; use Blocktrail\SDK\Exceptions\BlocktrailSDKException; -use Blocktrail\SDK\Network\BitcoinCash; use Blocktrail\SDK\Connection\RestClientInterface; -use Blocktrail\SDK\Network\BitcoinCashRegtest; -use Blocktrail\SDK\Network\BitcoinCashTestnet; use Btccom\JustEncrypt\Encryption; use Btccom\JustEncrypt\EncryptionMnemonic; use Btccom\JustEncrypt\KeyDerivation; @@ -98,9 +95,18 @@ public function __construct($apiKey, $apiSecret, $network = 'BTC', $testnet = fa $btccomEndpoint = \str_replace("chain", "tchain", $btccomEndpoint); } - $this->blocktrailClient = new RestClient($apiEndpoint, $apiVersion, $apiKey, $apiSecret); + if ($throttle = \getenv('BLOCKTRAIL_SDK_THROTTLE_BTCCOM')) { + $throttle = (float)$throttle; + } else { + $throttle = 0.33; + } + $this->dataClient = new RestClient($btccomEndpoint, $apiVersion, $apiKey, $apiSecret); - $this->converter = new BtccomConverter(); + $this->dataClient->setThrottle($throttle); + $this->blocktrailClient = new RestClient($apiEndpoint, $apiVersion, $apiKey, $apiSecret); + $this->converter = new BtccomConverter($this->makeAddressReader([ + 'use_cashaddr' => true, + ])); } /** @@ -127,19 +133,19 @@ protected function setBitcoinLibMagicBytes($network, $testnet, $regtest) { if ($network === "bitcoin") { if ($regtest) { - $useNetwork = NetworkFactory::bitcoinRegtest(); + $useNetwork = BitcoinNetworkFactory::bitcoinRegtest(); } else if ($testnet) { - $useNetwork = NetworkFactory::bitcoinTestnet(); + $useNetwork = BitcoinNetworkFactory::bitcoinTestnet(); } else { - $useNetwork = NetworkFactory::bitcoin(); + $useNetwork = BitcoinNetworkFactory::bitcoin(); } } else if ($network === "bitcoincash") { if ($regtest) { - $useNetwork = new BitcoinCashRegtest(); + $useNetwork = BitcoinCashNetworkFactory::bitcoinCashRegtest(); } else if ($testnet) { - $useNetwork = new BitcoinCashTestnet(); + $useNetwork = BitcoinCashNetworkFactory::bitcoinCashTestnet(); } else { - $useNetwork = new BitcoinCash(); + $useNetwork = BitcoinCashNetworkFactory::bitcoinCash(); } } @@ -720,11 +726,12 @@ protected function createNewWalletV1($options) { } } else { $backupPrivateKey = HierarchicalKeyFactory::fromEntropy((new Bip39SeedGenerator())->getSeed($backupMnemonic, "")); - $backupPublicKey = BIP32Key::create($backupPrivateKey->toPublic(), "M"); + $backupPublicKey = BIP32Key::create($backupPrivateKey->withoutPrivateKey(), "M"); } + $btcAddrCreator = new BitcoinAddressCreator(); // create a checksum of our private key which we'll later use to verify we used the right password - $checksum = $primaryPrivateKey->getPublicKey()->getAddress()->getAddress(); + $checksum = $primaryPrivateKey->getAddress($btcAddrCreator)->getAddress(); $addressReader = $this->makeAddressReader($options); // send the public keys to the server to store them @@ -842,7 +849,8 @@ protected function createNewWalletV2($options) { } // create a checksum of our private key which we'll later use to verify we used the right password - $checksum = $options['primary_private_key']->publicKey()->getAddress()->getAddress(); + $btcAddrCreator = new BitcoinAddressCreator(); + $checksum = $options['primary_private_key']->key()->getAddress($btcAddrCreator)->getAddress(); $addressReader = $this->makeAddressReader($options); // send the public keys and encrypted data to server @@ -981,7 +989,8 @@ protected function createNewWalletV3($options) { } // create a checksum of our private key which we'll later use to verify we used the right password - $checksum = $options['primary_private_key']->publicKey()->getAddress()->getAddress(); + $btcAddrCreator = new BitcoinAddressCreator(); + $checksum = $options['primary_private_key']->key()->getAddress($btcAddrCreator)->getAddress(); $addressReader = $this->makeAddressReader($options); // send the public keys and encrypted data to server @@ -1235,7 +1244,7 @@ public function upgradeKeyIndex($identifier, $keyIndex, $primaryPublicKey) { /** * @param array $options - * @return AddressReaderBase + * @return BaseAddressCreator */ private function makeAddressReader(array $options) { if ($this->network == "bitcoincash") { @@ -1243,9 +1252,9 @@ private function makeAddressReader(array $options) { if (array_key_exists("use_cashaddress", $options) && $options['use_cashaddress']) { $useCashAddress = true; } - return new BitcoinCashAddressReader($useCashAddress); + return new BitcoinCashAddressCreator($useCashAddress); } else { - return new BitcoinAddressReader(); + return new BitcoinAddressCreator(); } } @@ -1877,7 +1886,8 @@ public function faucetWithdrawl($address, $amount = 10000) { */ public function verifyMessage($message, $address, $signature) { $adapter = Bitcoin::getEcAdapter(); - $addr = \BitWasp\Bitcoin\Address\AddressFactory::fromString($address); + $btcAddrCreator = new BitcoinAddressCreator(); + $addr = $btcAddrCreator->fromString($address); if (!$addr instanceof PayToPubKeyHashAddress) { throw new \InvalidArgumentException('Can only verify a message with a pay-to-pubkey-hash address'); } diff --git a/src/Connection/RestClient.php b/src/Connection/RestClient.php index f27c37a..9338702 100644 --- a/src/Connection/RestClient.php +++ b/src/Connection/RestClient.php @@ -37,16 +37,14 @@ class RestClient extends BaseRestClient * @param $apiVersion * @param $apiKey * @param $apiSecret + * @param Throttler|null $throttler */ public function __construct($apiEndpoint, $apiVersion, $apiKey, $apiSecret) { parent::__construct($apiEndpoint, $apiVersion, $apiKey, $apiSecret); $this->guzzle = $this->createGuzzleClient(); - if ($throttle = \getenv('BLOCKTRAIL_SDK_THROTTLE_BTCCOM')) { - $throttle = (float)$throttle; - } else { - $throttle = 0.33; - } + } + public function setThrottle($throttle) { $this->throttler = Throttler::getInstance($this->apiEndpoint, $throttle); } @@ -141,7 +139,9 @@ public function setProxy($proxy) { */ public function request($method, $endpointUrl, $queryString = null, $body = null, $auth = null, $contentMD5Mode = null, $timeout = null) { $request = $this->buildRequest($method, $endpointUrl, $queryString, $body, $auth, $contentMD5Mode, $timeout); - $this->throttler->waitForThrottle(); + if ($this->throttler) { + $this->throttler->waitForThrottle(); + } $response = $this->guzzle->send($request, ['auth' => $auth, 'timeout' => $timeout]); return $this->responseHandler($response); diff --git a/src/Network/AbstractBitcoinCash.php b/src/Network/AbstractBitcoinCash.php deleted file mode 100644 index edb8f68..0000000 --- a/src/Network/AbstractBitcoinCash.php +++ /dev/null @@ -1,41 +0,0 @@ -getAddressByte(), - $base->getP2shByte(), - $base->getPrivByte(), - $base->isTestnet() - ); - - $this->setHDPrivByte($base->getHDPrivByte()); - $this->setHDPubByte($base->getHDPubByte()); - $this->setNetMagicBytes($base->getNetMagicBytes()); - $this->cashAddressPrefix = $cashAddressPrefix; - } - - /** - * @return string - */ - public function getCashAddressPrefix() { - return $this->cashAddressPrefix; - } -} diff --git a/src/Network/BitcoinCash.php b/src/Network/BitcoinCash.php deleted file mode 100644 index bc8543d..0000000 --- a/src/Network/BitcoinCash.php +++ /dev/null @@ -1,16 +0,0 @@ -reader = $reader; } /** * @param array $output + * @param NetworkInterface NetworkInterface * @return array * @throws BlocktrailSDKException */ - protected function readArrayFormat(array $output, Network $network) { + protected function readArrayFormat(array $output, NetworkInterface $network) { if (array_key_exists("scriptPubKey", $output) && array_key_exists("value", $output)) { return [ "scriptPubKey" => $output['scriptPubKey'], diff --git a/src/Throttler.php b/src/Throttler.php index 9623f62..51126f8 100644 --- a/src/Throttler.php +++ b/src/Throttler.php @@ -3,6 +3,10 @@ namespace Blocktrail\SDK; class Throttler { + /** + * @var Throttler[] + */ + private static $instances = []; /** * @var float|null @@ -29,16 +33,14 @@ public function waitForThrottle() { $diff = $this->interval - (\microtime(true) - $this->lastTime); if ($diff > 0) { - usleep((int)ceil($diff * 1000 * 1000)); + usleep((int)ceil($diff * 1e6)); } $this->lastTime = \microtime(true); } - private static $instances = []; - public static function getInstance($key, $interval) { - if (!isset(self::$instances[$key])) { + if (!array_key_exists($key, self::$instances)) { self::$instances[$key] = new Throttler($interval); } diff --git a/src/TransactionBuilder.php b/src/TransactionBuilder.php index 5c00824..aaee656 100644 --- a/src/TransactionBuilder.php +++ b/src/TransactionBuilder.php @@ -6,7 +6,7 @@ use BitWasp\Bitcoin\Script\ScriptFactory; use BitWasp\Bitcoin\Script\ScriptInterface; use BitWasp\Buffertools\Buffer; -use Blocktrail\SDK\Address\AddressReaderBase; +use BitWasp\Bitcoin\Address\BaseAddressCreator; use Blocktrail\SDK\Exceptions\BlocktrailSDKException; /** @@ -38,7 +38,7 @@ class TransactionBuilder { private $feeStrategy = Wallet::FEE_STRATEGY_OPTIMAL; /** - * @var AddressReaderBase + * @var BaseAddressCreator */ private $addressReader; @@ -49,9 +49,9 @@ class TransactionBuilder { /** * TransactionBuilder constructor. - * @param AddressReaderBase $addressReader + * @param BaseAddressCreator $addressReader */ - public function __construct(AddressReaderBase $addressReader) { + public function __construct(BaseAddressCreator $addressReader) { $this->addressReader = $addressReader; $this->outputNormalizer = new OutputsNormalizer($this->addressReader); } diff --git a/src/Wallet.php b/src/Wallet.php index 1b50521..f872cbf 100644 --- a/src/Wallet.php +++ b/src/Wallet.php @@ -2,6 +2,11 @@ namespace Blocktrail\SDK; +use Btccom\BitcoinCash\Address\CashAddress; +use Btccom\BitcoinCash\Transaction\SignatureHash\SigHash as BchSigHash; +use Btccom\BitcoinCash\Transaction\Factory\Checker\CheckerCreator as BchCheckerCreator; +use BitWasp\Bitcoin\Address\AddressCreator as BitcoinAddressCreator; +use BitWasp\Bitcoin\Address\BaseAddressCreator; use BitWasp\Bitcoin\Address\Base58AddressInterface; use BitWasp\Bitcoin\Address\PayToPubKeyHashAddress; use BitWasp\Bitcoin\Address\ScriptHashAddress; @@ -21,8 +26,6 @@ use BitWasp\Bitcoin\Transaction\Transaction; use BitWasp\Bitcoin\Transaction\TransactionInterface; use BitWasp\Buffertools\Buffer; -use Blocktrail\SDK\Address\AddressReaderBase; -use Blocktrail\SDK\Address\CashAddress; use Blocktrail\SDK\Bitcoin\BIP32Key; use Blocktrail\SDK\Bitcoin\BIP32Path; use Blocktrail\SDK\Exceptions\BlocktrailSDKException; @@ -155,7 +158,7 @@ abstract class Wallet implements WalletInterface { protected $changeIndex; /** - * @var AddressReaderBase + * @var BaseAddressCreator */ protected $addressReader; @@ -175,10 +178,11 @@ abstract class Wallet implements WalletInterface { * @param string $network * @param bool $testnet * @param bool $segwit + * @param BaseAddressCreator $addressReader * @param string $checksum * @throws BlocktrailSDKException */ - public function __construct(BlocktrailSDKInterface $sdk, $identifier, array $primaryPublicKeys, $backupPublicKey, array $blocktrailPublicKeys, $keyIndex, $network, $testnet, $segwit, AddressReaderBase $addressReader, $checksum) { + public function __construct(BlocktrailSDKInterface $sdk, $identifier, array $primaryPublicKeys, $backupPublicKey, array $blocktrailPublicKeys, $keyIndex, $network, $testnet, $segwit, BaseAddressCreator $addressReader, $checksum) { $this->sdk = $sdk; $this->identifier = $identifier; @@ -214,7 +218,7 @@ public function __construct(BlocktrailSDKInterface $sdk, $identifier, array $pri } /** - * @return AddressReaderBase + * @return BaseAddressCreator */ public function getAddressReader() { return $this->addressReader; @@ -741,7 +745,7 @@ public function buildTx(TransactionBuilder $txBuilder) { if (SignInfo::MODE_SIGN === $utxo->signMode) { if (!$utxo->path) { - $utxo->path = $this->getPathForAddress($utxo->address->getAddress()); + $utxo->path = $this->getPathForAddress($utxo->address->getAddress())['path']; } if (!$utxo->redeemScript || !$utxo->witnessScript) { @@ -1063,7 +1067,8 @@ protected function determineChange($utxos, $outputs, $fee) { * @throws \Exception */ protected function signTransaction(Transaction $tx, array $signInfo) { - $signer = new Signer($tx, Bitcoin::getEcAdapter()); + $ecAdapter = Bitcoin::getEcAdapter(); + $signer = new Signer($tx, $ecAdapter); assert(Util::all(function ($signInfo) { return $signInfo instanceof SignInfo; @@ -1071,8 +1076,8 @@ protected function signTransaction(Transaction $tx, array $signInfo) { $sigHash = SigHash::ALL; if ($this->network === "bitcoincash") { - $sigHash |= SigHash::BITCOINCASH; - $signer->redeemBitcoinCash(true); + $sigHash |= BchSigHash::BITCOINCASH; + $signer->setCheckerCreator(BchCheckerCreator::fromEcAdapter($ecAdapter)); } foreach ($signInfo as $idx => $info) { @@ -1192,9 +1197,7 @@ public function deleteWallet($force = false) { */ protected function createChecksumVerificationSignature() { $privKey = $this->primaryPrivateKey->key(); - - $pubKey = $this->primaryPrivateKey->publicKey(); - $address = $pubKey->getAddress()->getAddress(); + $address = $this->primaryPrivateKey->key()->getAddress(new BitcoinAddressCreator())->getAddress(); $signer = new MessageSigner(Bitcoin::getEcAdapter()); $signed = $signer->sign($address, $privKey->getPrivateKey()); diff --git a/src/WalletInterface.php b/src/WalletInterface.php index 33cb239..5566370 100644 --- a/src/WalletInterface.php +++ b/src/WalletInterface.php @@ -2,7 +2,7 @@ namespace Blocktrail\SDK; -use Blocktrail\SDK\Address\AddressReaderBase; +use BitWasp\Bitcoin\Address\BaseAddressCreator; use Blocktrail\SDK\Bitcoin\BIP32Key; use Blocktrail\SDK\Bitcoin\BIP32Path; use Blocktrail\SDK\Exceptions\BlocktrailSDKException; @@ -33,7 +33,7 @@ public function getIdentifier(); public function getBackupKey(); /** - * @return AddressReaderBase + * @return BaseAddressCreator */ public function getAddressReader(); @@ -200,7 +200,7 @@ public function sendTx(TransactionBuilder $txBuilder, $apiCheckFee = true); * @param null|int $forceFee * @return array */ - public function coinSelection($outputs, $lockUTXO = true, $allowZeroConf = false, $forceFee = null); + public function coinSelection($outputs, $lockUTXO = true, $allowZeroConf = false, $feeStrategy = self::FEE_STRATEGY_OPTIMAL, $forceFee = null); /** * @return int diff --git a/src/WalletSweeper.php b/src/WalletSweeper.php index f2d3f4c..5bbe5bf 100644 --- a/src/WalletSweeper.php +++ b/src/WalletSweeper.php @@ -2,10 +2,16 @@ namespace Blocktrail\SDK; -use BitWasp\Bitcoin\Address\AddressFactory; +use Btccom\BitcoinCash\Address\CashAddress; +use Btccom\BitcoinCash\Address\AddressCreator as BitcoinCashAddressCreator; +use Btccom\BitcoinCash\Network\NetworkFactory as BitcoinCashNetworkFactory; +use Btccom\BitcoinCash\Transaction\Factory\Checker\CheckerCreator as BchCheckerCreator; +use Btccom\BitcoinCash\Transaction\SignatureHash\SigHash as BchSigHash; +use BitWasp\Bitcoin\Address\AddressCreator as BitcoinAddressCreator; +use BitWasp\Bitcoin\Address\BaseAddressCreator; use BitWasp\Bitcoin\Bitcoin; use BitWasp\Bitcoin\Key\Deterministic\HierarchicalKeyFactory; -use BitWasp\Bitcoin\Network\NetworkFactory; +use BitWasp\Bitcoin\Network\NetworkFactory as BitcoinNetworkFactory; use BitWasp\Bitcoin\Script\P2shScript; use BitWasp\Bitcoin\Script\ScriptFactory; use BitWasp\Bitcoin\Script\WitnessScript; @@ -18,15 +24,9 @@ use BitWasp\Bitcoin\Transaction\TransactionOutput; use BitWasp\Buffertools\Buffer; use BitWasp\Buffertools\BufferInterface; -use Blocktrail\SDK\Address\AddressReaderBase; -use Blocktrail\SDK\Address\BitcoinAddressReader; -use Blocktrail\SDK\Address\BitcoinCashAddressReader; -use Blocktrail\SDK\Address\CashAddress; use Blocktrail\SDK\Bitcoin\BIP32Key; use Blocktrail\SDK\Bitcoin\BIP32Path; use Blocktrail\SDK\Exceptions\BlocktrailSDKException; -use Blocktrail\SDK\Network\BitcoinCash; -use Blocktrail\SDK\Network\BitcoinCashRegtest; abstract class WalletSweeper { @@ -73,7 +73,7 @@ abstract class WalletSweeper { protected $sweepData; /** - * @var AddressReaderBase + * @var BaseAddressCreator */ protected $addressReader; @@ -114,7 +114,7 @@ public function __construct(BufferInterface $primarySeed, BufferInterface $backu /** * @param array $options - * @return AddressReaderBase + * @return BaseAddressCreator */ private function makeAddressReader(array $options) { if ($this->network == "bitcoincash") { @@ -122,9 +122,9 @@ private function makeAddressReader(array $options) { if (array_key_exists("use_cashaddress", $options) && $options['use_cashaddress']) { $useCashAddress = true; } - return new BitcoinCashAddressReader($useCashAddress); + return new BitcoinCashAddressCreator($useCashAddress); } else { - return new BitcoinAddressReader(); + return new BitcoinAddressCreator(); } } @@ -138,19 +138,19 @@ protected function setBitcoinLibMagicBytes($network, $testnet, $regtest) { assert($network == "bitcoin" || $network == "bitcoincash"); if ($network === "bitcoin") { if ($regtest) { - $useNetwork = NetworkFactory::bitcoinRegtest(); + $useNetwork = BitcoinNetworkFactory::bitcoinRegtest(); } else if ($testnet) { - $useNetwork = NetworkFactory::bitcoinTestnet(); + $useNetwork = BitcoinNetworkFactory::bitcoinTestnet(); } else { - $useNetwork = NetworkFactory::bitcoin(); + $useNetwork = BitcoinNetworkFactory::bitcoin(); } } else if ($network === "bitcoincash") { if ($regtest) { - $useNetwork = new BitcoinCashRegtest(); + $useNetwork = BitcoinCashNetworkFactory::bitcoinRegtest(); } else if ($testnet) { - $useNetwork = new BitcoinCashTestnet(); + $useNetwork = BitcoinCashNetworkFactory::bitcoinTestnet(); } else { - $useNetwork = new BitcoinCash(); + $useNetwork = BitcoinCashNetworkFactory::bitcoin(); } } @@ -379,7 +379,7 @@ protected function createTransaction($destinationAddress) { $utxo['hash'], $utxo['index'], $utxo['value'], - AddressFactory::fromString($address), + $this->addressReader->fromString($address), ScriptFactory::fromHex($utxo['script_hex']), $data['path'], $data['redeem'], @@ -429,12 +429,13 @@ protected function createTransaction($destinationAddress) { * @throws \Exception */ protected function signTransaction(TransactionInterface $tx, array $signInfo) { - $signer = new Signer($tx, Bitcoin::getEcAdapter()); + $ecAdapter = Bitcoin::getEcAdapter(); + $signer = new Signer($tx, $ecAdapter); $sigHash = SigHash::ALL; if ($this->network === "bitcoincash") { - $sigHash |= SigHash::BITCOINCASH; - $signer->redeemBitcoinCash(true); + $sigHash |= BchSigHash::BITCOINCASH; + $signer->setCheckerCreator(BchCheckerCreator::fromEcAdapter($ecAdapter)); } assert(Util::all(function ($signInfo) { diff --git a/src/WalletV1.php b/src/WalletV1.php index 3a9a2b8..abd08b8 100644 --- a/src/WalletV1.php +++ b/src/WalletV1.php @@ -2,10 +2,11 @@ namespace Blocktrail\SDK; +use BitWasp\Bitcoin\Address\AddressCreator as BitcoinAddressCreator; +use BitWasp\Bitcoin\Address\BaseAddressCreator; use BitWasp\Bitcoin\Key\Deterministic\HierarchicalKey; use BitWasp\Bitcoin\Key\Deterministic\HierarchicalKeyFactory; use BitWasp\Bitcoin\Mnemonic\Bip39\Bip39SeedGenerator; -use Blocktrail\SDK\Address\AddressReaderBase; use Blocktrail\SDK\Bitcoin\BIP32Key; use Blocktrail\SDK\Exceptions\BlocktrailSDKException; use Blocktrail\SDK\Exceptions\NotImplementedException; @@ -30,11 +31,11 @@ class WalletV1 extends Wallet { * @param string $network * @param bool $testnet * @param bool $segwit - * @param AddressReaderBase $addressReader + * @param BaseAddressCreator $addressReader * @param string $checksum * @throws BlocktrailSDKException */ - public function __construct(BlocktrailSDKInterface $sdk, $identifier, $primaryMnemonic, array $primaryPublicKeys, $backupPublicKey, array $blocktrailPublicKeys, $keyIndex, $network, $testnet, $segwit, AddressReaderBase $addressReader, $checksum) { + public function __construct(BlocktrailSDKInterface $sdk, $identifier, $primaryMnemonic, array $primaryPublicKeys, $backupPublicKey, array $blocktrailPublicKeys, $keyIndex, $network, $testnet, $segwit, BaseAddressCreator $addressReader, $checksum) { $this->primaryMnemonic = $primaryMnemonic; parent::__construct($sdk, $identifier, $primaryPublicKeys, $backupPublicKey, $blocktrailPublicKeys, $keyIndex, $network, $testnet, $segwit, $addressReader, $checksum); @@ -79,8 +80,9 @@ public function unlock($options, callable $fn = null) { $this->primaryPrivateKey = BIP32Key::create($primaryPrivateKey, "m"); + $btcAddrCreator = new BitcoinAddressCreator(); // create checksum (address) of the primary privatekey to compare to the stored checksum - $checksum = $this->primaryPrivateKey->key()->getPublicKey()->getAddress()->getAddress(); + $checksum = $this->primaryPrivateKey->key()->getAddress($btcAddrCreator)->getAddress(); if ($checksum != $this->checksum) { throw new \Exception("Checksum [{$checksum}] does not match [{$this->checksum}], most likely due to incorrect password"); } diff --git a/src/WalletV2.php b/src/WalletV2.php index 47d044b..d3666c2 100644 --- a/src/WalletV2.php +++ b/src/WalletV2.php @@ -2,12 +2,13 @@ namespace Blocktrail\SDK; +use BitWasp\Bitcoin\Address\AddressCreator as BitcoinAddressCreator; +use BitWasp\Bitcoin\Address\BaseAddressCreator; use BitWasp\Bitcoin\Key\Deterministic\HierarchicalKey; use BitWasp\Bitcoin\Key\Deterministic\HierarchicalKeyFactory; use BitWasp\Bitcoin\Mnemonic\MnemonicFactory; use BitWasp\Buffertools\Buffer; use Blocktrail\CryptoJSAES\CryptoJSAES; -use Blocktrail\SDK\Address\AddressReaderBase; use Blocktrail\SDK\Bitcoin\BIP32Key; use Blocktrail\SDK\Exceptions\BlocktrailSDKException; use Blocktrail\SDK\Exceptions\WalletDecryptException; @@ -35,10 +36,10 @@ class WalletV2 extends Wallet { * @param bool $testnet * @param bool $segwit * @param string $checksum - * @param AddressReaderBase $addressReader + * @param BaseAddressCreator $addressReader * @throws BlocktrailSDKException */ - public function __construct(BlocktrailSDKInterface $sdk, $identifier, $encryptedPrimarySeed, $encryptedSecret, $primaryPublicKeys, $backupPublicKey, $blocktrailPublicKeys, $keyIndex, $network, $testnet, $segwit, AddressReaderBase $addressReader, $checksum) { + public function __construct(BlocktrailSDKInterface $sdk, $identifier, $encryptedPrimarySeed, $encryptedSecret, $primaryPublicKeys, $backupPublicKey, $blocktrailPublicKeys, $keyIndex, $network, $testnet, $segwit, BaseAddressCreator $addressReader, $checksum) { $this->encryptedPrimarySeed = $encryptedPrimarySeed; $this->encryptedSecret = $encryptedSecret; @@ -95,7 +96,7 @@ public function unlock($options, callable $fn = null) { $this->primaryPrivateKey = $primaryPrivateKey instanceof BIP32Key ? $primaryPrivateKey : BIP32Key::create($primaryPrivateKey, "m"); // create checksum (address) of the primary privatekey to compare to the stored checksum - $checksum = $this->primaryPrivateKey->publicKey()->getAddress()->getAddress(); + $checksum = $this->primaryPrivateKey->key()->getAddress(new BitcoinAddressCreator())->getAddress(); if ($checksum != $this->checksum) { throw new \Exception("Checksum [{$checksum}] does not match [{$this->checksum}], most likely due to incorrect password"); } diff --git a/src/WalletV2Sweeper.php b/src/WalletV2Sweeper.php index 7245864..7a238d5 100644 --- a/src/WalletV2Sweeper.php +++ b/src/WalletV2Sweeper.php @@ -5,8 +5,6 @@ use BitWasp\Bitcoin\Mnemonic\MnemonicFactory; use BitWasp\Buffertools\Buffer; use Blocktrail\CryptoJSAES\CryptoJSAES; - - use Blocktrail\SDK\Exceptions\BlocktrailSDKException; class WalletV2Sweeper extends WalletSweeper { diff --git a/src/WalletV3.php b/src/WalletV3.php index 5620097..93b5db3 100644 --- a/src/WalletV3.php +++ b/src/WalletV3.php @@ -2,13 +2,13 @@ namespace Blocktrail\SDK; +use BitWasp\Bitcoin\Address\AddressCreator as BitcoinAddressCreator; +use BitWasp\Bitcoin\Address\BaseAddressCreator; use BitWasp\Bitcoin\Key\Deterministic\HierarchicalKeyFactory; use BitWasp\Buffertools\Buffer; use BitWasp\Buffertools\BufferInterface; -use Blocktrail\SDK\Address\AddressReaderBase; use Blocktrail\SDK\Bitcoin\BIP32Key; use Blocktrail\SDK\Exceptions\BlocktrailSDKException; -use Blocktrail\SDK\Exceptions\WalletDecryptException; use Btccom\JustEncrypt\Encryption; use Btccom\JustEncrypt\EncryptionMnemonic; @@ -47,11 +47,11 @@ class WalletV3 extends Wallet * @param string $network * @param bool $testnet * @param bool $segwit - * @param AddressReaderBase $addressReader + * @param BaseAddressCreator $addressReader * @param string $checksum * @throws BlocktrailSDKException */ - public function __construct(BlocktrailSDKInterface $sdk, $identifier, $encryptedPrimarySeed, $encryptedSecret, $primaryPublicKeys, $backupPublicKey, $blocktrailPublicKeys, $keyIndex, $network, $testnet, $segwit, AddressReaderBase $addressReader, $checksum) { + public function __construct(BlocktrailSDKInterface $sdk, $identifier, $encryptedPrimarySeed, $encryptedSecret, $primaryPublicKeys, $backupPublicKey, $blocktrailPublicKeys, $keyIndex, $network, $testnet, $segwit, BaseAddressCreator $addressReader, $checksum) { if ($encryptedPrimarySeed !== null && !($encryptedPrimarySeed instanceof Buffer)) { throw new \InvalidArgumentException('Encrypted Primary Seed must be a Buffer or null'); } @@ -112,7 +112,7 @@ public function unlock($options, callable $fn = null) { $this->primaryPrivateKey = BIP32Key::create(HierarchicalKeyFactory::fromEntropy($this->primarySeed), "m"); // create checksum (address) of the primary privatekey to compare to the stored checksum - $checksum = $this->primaryPrivateKey->publicKey()->getAddress()->getAddress(); + $checksum = $this->primaryPrivateKey->key()->getAddress(new BitcoinAddressCreator())->getAddress(); if ($checksum != $this->checksum) { throw new \Exception("Checksum [{$checksum}] does not match [{$this->checksum}], most likely due to incorrect password"); } diff --git a/tests/Network/BitcoinCashTest.php b/tests/Network/BitcoinCashTest.php index 3c97215..3fee74f 100644 --- a/tests/Network/BitcoinCashTest.php +++ b/tests/Network/BitcoinCashTest.php @@ -4,67 +4,14 @@ use BitWasp\Bitcoin\Network\NetworkFactory; use BitWasp\Buffertools\Buffer; -use Blocktrail\SDK\Address\CashAddress; +use Btccom\BitcoinCash\Address\CashAddress; +use Btccom\BitcoinCash\Network\NetworkFactory as BchNetworkFactory; + use Blocktrail\SDK\Network\BitcoinCash; use Blocktrail\SDK\Network\BitcoinCashTestnet; class BitcoinCashTest extends \PHPUnit_Framework_TestCase { - public function testnetProvider() - { - return [ - [true, "bchtest",], - [false, "bitcoincash",], - ]; - } - - /** - * @param bool $testnet - * @dataProvider testnetProvider - */ - public function testBitcoinCash($testnet, $cashAddrPrefix) - { - if ($testnet) { - $network = new BitcoinCashTestnet(); - } else { - $network = new BitcoinCash(); - } - - $this->assertEquals($testnet, $network->isTestnet()); - $this->assertEquals($cashAddrPrefix, $network->getCashAddressPrefix()); - - if ($testnet) { - $cmp = NetworkFactory::bitcoinTestnet(); - } else { - $cmp = NetworkFactory::bitcoin(); - } - - $this->assertEquals($cmp->getAddressByte(), $network->getAddressByte()); - $this->assertEquals($cmp->getP2shByte(), $network->getP2shByte()); - $this->assertEquals($cmp->getPrivByte(), $network->getPrivByte()); - $this->assertEquals($cmp->isTestnet(), $network->isTestnet()); - $this->assertEquals($cmp->getNetMagicBytes(), $network->getNetMagicBytes()); - $this->assertEquals($cmp->getHDPrivByte(), $network->getHDPrivByte()); - $this->assertEquals($cmp->getHDPubByte(), $network->getHDPubByte()); - } - - /** - * @param $testnet - * @throws \Exception - * @dataProvider testnetProvider - * @expectedException \Exception - * @expectedExceptionMessage No bech32 prefix for segwit addresses set - */ - public function testNoBech32($testnet) - { - if ($testnet) { - $network = new BitcoinCashTestnet(); - } else { - $network = new BitcoinCash(); - } - - $network->getSegwitBech32Prefix(); - } public function getCashAddressFixture() { @@ -89,9 +36,9 @@ public function getCashAddressFixture() public function testCashAddress($testnet, $type, $hashHex, $expected) { if ($testnet) { - $network = new BitcoinCashTestnet(); + $network = BchNetworkFactory::bitcoinCashTestnet(); } else { - $network = new BitcoinCash(); + $network = BchNetworkFactory::bitcoinCash(); } $hash = Buffer::hex($hashHex); diff --git a/tests/OutputsNormalizerTest.php b/tests/OutputsNormalizerTest.php index b4f20c6..78e07df 100644 --- a/tests/OutputsNormalizerTest.php +++ b/tests/OutputsNormalizerTest.php @@ -3,8 +3,10 @@ namespace Blocktrail\SDK\Tests; use BitWasp\Bitcoin\Network\NetworkFactory; -use Blocktrail\SDK\Address\BitcoinAddressReader; -use Blocktrail\SDK\Address\BitcoinCashAddressReader; +use BitWasp\Bitcoin\Network\NetworkFactory as BitcoinNetworkFactory; +use Btccom\BitcoinCash\Network\NetworkFactory as BitcoinCashNetworkFactory; +use BitWasp\Bitcoin\Address\AddressCreator as BitcoinAddressCreator; +use Btccom\BitcoinCash\Address\AddressCreator as BitcoinCashAddressCreator; use Blocktrail\SDK\Blocktrail; use Blocktrail\SDK\Exceptions\BlocktrailSDKException; use Blocktrail\SDK\Network\BitcoinCash; @@ -17,18 +19,18 @@ private function loadAddressReader($network, $testnet) { switch ($network) { case "BTC": if ($testnet) { - return [NetworkFactory::bitcoinTestnet(), new BitcoinAddressReader()]; + return [BitcoinNetworkFactory::bitcoinTestnet(), new BitcoinAddressCreator()]; } - return [NetworkFactory::bitcoin(), new BitcoinAddressReader()]; + return [BitcoinNetworkFactory::bitcoin(), new BitcoinAddressCreator()]; break; case "BCC": if ($testnet) { - $network = new BitcoinCashTestnet(); + $network = BitcoinCashNetworkFactory::bitcoinCashTestnet(); } else { - $network = new BitcoinCash(); + $network = BitcoinCashNetworkFactory::bitcoinCash(); } - return [$network, new BitcoinCashAddressReader(true)]; + return [$network, new BitcoinCashAddressCreator(true)]; break; default: throw new \RuntimeException("Unknown network"); diff --git a/tests/Wallet/BitcoinCashAddressTest.php b/tests/Wallet/BitcoinCashAddressTest.php index 745f0a6..3ac2c49 100644 --- a/tests/Wallet/BitcoinCashAddressTest.php +++ b/tests/Wallet/BitcoinCashAddressTest.php @@ -4,32 +4,31 @@ use BitWasp\Bitcoin\Address\ScriptHashAddress; -use Blocktrail\SDK\Address\BitcoinCashAddressReader; -use Blocktrail\SDK\Address\CashAddress; +use Btccom\BitcoinCash\Address\AddressCreator as BitcoinCashAddressCreator; +use Btccom\BitcoinCash\Network\Networks\BitcoinCash; +use Btccom\BitcoinCash\Network\Networks\BitcoinCashTestnet; +use Btccom\BitcoinCash\Address\CashAddress; use Blocktrail\SDK\BlocktrailSDK; -use Blocktrail\SDK\Network\BitcoinCashRegtest; +use Btccom\BitcoinCash\Network\Networks\BitcoinCashRegtest; use Blocktrail\SDK\Exceptions\BlocktrailSDKException; -use Blocktrail\SDK\Network\BitcoinCash; use Blocktrail\SDK\Wallet; use Mockery\Mock; class BitcoinCashAddressTest extends WalletTestBase { /** - * @expectedException \Blocktrail\SDK\Exceptions\BlocktrailSDKException + * @expectedException \BitWasp\Bitcoin\Exceptions\UnrecognizedAddressException * @expectedExceptionMessage Address not recognized */ public function testShortCashAddress() { - $bch = new BitcoinCash(); $tbch = new BitcoinCashRegtest(); $address = "bchtest:ppm2qsznhks23z7629mms6s4cwef74vcwvhanqgjxu"; $short = "ppm2qsznhks23z7629mms6s4cwef74vcwvhanqgjxu"; - $reader = new BitcoinCashAddressReader(true); - $this->assertEquals($address, $reader->fromString($address, $bch)->getAddress($bch)); - $this->assertEquals($address, $reader->fromString($short, $bch)->getAddress($bch)); + $reader = new BitcoinCashAddressCreator(true); + $this->assertEquals($address, $reader->fromString($address, $tbch)->getAddress($tbch)); + $this->assertEquals($address, $reader->fromString($short, $tbch)->getAddress($tbch)); - $this->setExpectedException(BlocktrailSDKException::class, "Address not recognized"); $reader->fromString($short, $tbch); } @@ -42,7 +41,7 @@ public function testInitializeWithDefaultFormat() { list($legacyAddressWallet, $client) = $this->initWallet($client); $legacyAddress = "2MxYE3e7R2e1NBLDicBMXMy9FRUygeTyEGa"; - $this->assertInstanceOf(BitcoinCashAddressReader::class, $legacyAddressWallet->getAddressReader()); + $this->assertInstanceOf(BitcoinCashAddressCreator::class, $legacyAddressWallet->getAddressReader()); $this->assertInstanceOf(ScriptHashAddress::class, $legacyAddressWallet->getAddressReader()->fromString($legacyAddress, $tbcc)); $cashAddress = "bchreg:pqaql0az73r2lrtk43l3w3scuazgvarqdyufw37rsn"; @@ -52,7 +51,7 @@ public function testInitializeWithDefaultFormat() { 'use_cashaddress' => true, ]); - $this->assertInstanceOf(BitcoinCashAddressReader::class, $newAddressWallet->getAddressReader()); + $this->assertInstanceOf(BitcoinCashAddressCreator::class, $newAddressWallet->getAddressReader()); $this->assertInstanceOf(CashAddress::class, $newAddressWallet->getAddressReader()->fromString($cashAddress, $tbcc)); $convertedLegacy = $client->getLegacyBitcoinCashAddress($cashAddress); diff --git a/tests/Wallet/BuildTxTest.php b/tests/Wallet/BuildTxTest.php index c0720e5..d5e3881 100644 --- a/tests/Wallet/BuildTxTest.php +++ b/tests/Wallet/BuildTxTest.php @@ -2,7 +2,7 @@ namespace Blocktrail\SDK\Tests\Wallet; -use BitWasp\Bitcoin\Address\AddressFactory; +use BitWasp\Bitcoin\Address\AddressCreator; use BitWasp\Bitcoin\Transaction\Transaction; use BitWasp\Bitcoin\Transaction\TransactionInput; use BitWasp\Bitcoin\Transaction\TransactionOutput; @@ -70,11 +70,12 @@ public function testSegwitBuildTx() { $this->assertEquals($outValue, $outputTotal); $this->assertEquals($expectfee, $fee); + $btcAddrCreator = new AddressCreator(); // assert the input(s) $this->assertEquals(1, count($tx->getInputs())); $this->assertEquals($txid, $tx->getInput(0)->getOutPoint()->getTxId()->getHex()); $this->assertEquals(0, $tx->getInput(0)->getOutPoint()->getVout()); - $this->assertEquals($address, AddressFactory::fromOutputScript($signInfo[0]->output->getScript())->getAddress()); + $this->assertEquals($address, $btcAddrCreator->fromOutputScript($signInfo[0]->output->getScript())->getAddress()); $this->assertEquals($scriptPubKey, $signInfo[0]->output->getScript()->getHex()); $this->assertEquals($value, $signInfo[0]->output->getValue()); $this->assertEquals($path, $signInfo[0]->path); @@ -89,7 +90,7 @@ public function testSegwitBuildTx() { // assert the output(s) $this->assertEquals(1, count($tx->getOutputs())); - $this->assertEquals("2N6DJMnoS3xaxpCSDRMULgneCghA1dKJBmT", AddressFactory::fromOutputScript($tx->getOutput(0)->getScript())->getAddress()); + $this->assertEquals("2N6DJMnoS3xaxpCSDRMULgneCghA1dKJBmT", $btcAddrCreator->fromOutputScript($tx->getOutput(0)->getScript())->getAddress()); $this->assertEquals($outValue, $tx->getOutput(0)->getValue()); } @@ -172,7 +173,8 @@ public function testBuildTx1() { // assert the output(s) $this->assertEquals(1, count($tx->getOutputs())); - $this->assertEquals("2N7C5Jn1LasbEK9mvHetBYXaDnQACXkarJe", AddressFactory::fromOutputScript($tx->getOutput(0)->getScript())->getAddress()); + $btcAddrCreator = new AddressCreator(); + $this->assertEquals("2N7C5Jn1LasbEK9mvHetBYXaDnQACXkarJe", $btcAddrCreator->fromOutputScript($tx->getOutput(0)->getScript())->getAddress()); $this->assertEquals(100000, $tx->getOutput(0)->getValue()); @@ -273,7 +275,8 @@ public function testBuildTx3() { $this->assertEquals(BlocktrailSDK::toSatoshi(0.9999), $outputTotal); $this->assertEquals(BlocktrailSDK::toSatoshi(0.0001), $fee); $this->assertEquals(14, count($tx->getOutputs())); - $this->assertEquals("2N6DJMnoS3xaxpCSDRMULgneCghA1dKJBmT", AddressFactory::fromOutputScript($tx->getOutput(13)->getScript())->getAddress()); + $btcAddrCreator = new AddressCreator(); + $this->assertEquals("2N6DJMnoS3xaxpCSDRMULgneCghA1dKJBmT", $btcAddrCreator->fromOutputScript($tx->getOutput(13)->getScript())->getAddress()); $this->assertEquals(99860000, $tx->getOutput(13)->getValue()); } @@ -346,11 +349,12 @@ public function testBuildTx4() { $fee = $inputTotal - $outputTotal; // assert the output(s) + $btcAddrCreator = new AddressCreator(); $this->assertEquals(BlocktrailSDK::toSatoshi(1), $inputTotal); $this->assertEquals(BlocktrailSDK::toSatoshi(0.9999), $outputTotal); $this->assertEquals(BlocktrailSDK::toSatoshi(0.0001), $fee); $this->assertEquals(20, count($tx->getOutputs())); - $this->assertEquals("2N6DJMnoS3xaxpCSDRMULgneCghA1dKJBmT", AddressFactory::fromOutputScript($tx->getOutput(19)->getScript())->getAddress()); + $this->assertEquals("2N6DJMnoS3xaxpCSDRMULgneCghA1dKJBmT", $btcAddrCreator->fromOutputScript($tx->getOutput(19)->getScript())->getAddress()); $this->assertEquals(BlocktrailSDK::toSatoshi(0.9980), $tx->getOutput(19)->getValue()); } @@ -427,12 +431,13 @@ public function testBuildTx5() { $fee = $inputTotal - $outputTotal; // assert the output(s) + $btcAddrCreator = new AddressCreator(); $this->assertEquals(BlocktrailSDK::toSatoshi(1), $inputTotal); $this->assertEquals(BlocktrailSDK::toSatoshi(0.9998), $outputTotal); $this->assertEquals(BlocktrailSDK::toSatoshi(0.0002), $fee); $this->assertEquals(22, count($tx->getOutputs())); $change = $tx->getOutput(21); - $this->assertEquals("2N6DJMnoS3xaxpCSDRMULgneCghA1dKJBmT", AddressFactory::fromOutputScript($change->getScript())->getAddress()); + $this->assertEquals("2N6DJMnoS3xaxpCSDRMULgneCghA1dKJBmT", $btcAddrCreator->fromOutputScript($change->getScript())->getAddress()); $this->assertEquals(BlocktrailSDK::toSatoshi(0.9977), $change->getValue()); } @@ -676,7 +681,8 @@ public function testBuildTx8() { $this->assertEquals(BlocktrailSDK::toSatoshi(0.0019), $outputTotal); $this->assertEquals(BlocktrailSDK::toSatoshi(0.0001), $fee); - $this->assertEquals("2NAUFsSps9S2mEnhaWZoaufwyuCaVPUv8op", AddressFactory::fromOutputScript($tx->getOutput(0)->getScript())->getAddress()); - $this->assertEquals("2NAUFsSps9S2mEnhaWZoaufwyuCaVPUv8op", AddressFactory::fromOutputScript($tx->getOutput(1)->getScript())->getAddress()); + $btcAddrCreator = new AddressCreator(); + $this->assertEquals("2NAUFsSps9S2mEnhaWZoaufwyuCaVPUv8op", $btcAddrCreator->fromOutputScript($tx->getOutput(0)->getScript())->getAddress()); + $this->assertEquals("2NAUFsSps9S2mEnhaWZoaufwyuCaVPUv8op", $btcAddrCreator->fromOutputScript($tx->getOutput(1)->getScript())->getAddress()); } } diff --git a/tests/Wallet/CreateWalletTest.php b/tests/Wallet/CreateWalletTest.php index c53d605..d33c15f 100644 --- a/tests/Wallet/CreateWalletTest.php +++ b/tests/Wallet/CreateWalletTest.php @@ -5,7 +5,7 @@ use BitWasp\Bitcoin\Mnemonic\MnemonicFactory; use BitWasp\Buffertools\Buffer; use Blocktrail\CryptoJSAES\CryptoJSAES; -use Blocktrail\SDK\Address\BitcoinAddressReader; +use BitWasp\Bitcoin\Address\AddressCreator as BitcoinAddressCreator; use Blocktrail\SDK\Wallet; use Blocktrail\SDK\WalletV3; use Btccom\JustEncrypt\Encryption; @@ -407,7 +407,7 @@ public function testCreateWalletV1PasswordChangeNotPossible(Wallet $wallet) { public function testV3EncryptedPrimarySeedNullOrBuffer() { $sdk = $this->mockSDK(); - $reader = new BitcoinAddressReader(); + $reader = new BitcoinAddressCreator(); $this->expectException(\InvalidArgumentException::class); $this->expectExceptionMessage("Encrypted Primary Seed must be a Buffer or null"); @@ -415,7 +415,7 @@ public function testV3EncryptedPrimarySeedNullOrBuffer() { } public function testV3EncryptedSecretNullOrBuffer() { $sdk = $this->mockSDK(); - $reader = new BitcoinAddressReader(); + $reader = new BitcoinAddressCreator(); $this->expectException(\InvalidArgumentException::class); $this->expectExceptionMessage("Encrypted Secret must be a Buffer or null"); diff --git a/tests/Wallet/WalletTestBase.php b/tests/Wallet/WalletTestBase.php index 3f2fe2c..9da27c2 100644 --- a/tests/Wallet/WalletTestBase.php +++ b/tests/Wallet/WalletTestBase.php @@ -2,12 +2,12 @@ namespace Blocktrail\SDK\Tests\Wallet; +use Btccom\BitcoinCash\Address\CashAddress; use BitWasp\Bitcoin\Address\PayToPubKeyHashAddress; use BitWasp\Bitcoin\Address\ScriptHashAddress; use BitWasp\Bitcoin\Script\Classifier\OutputClassifier; use BitWasp\Bitcoin\Script\ScriptInterface; use BitWasp\Bitcoin\Script\ScriptType; -use Blocktrail\SDK\Address\CashAddress; use Blocktrail\SDK\BlocktrailSDK; use Blocktrail\SDK\Tests\MockBlocktrailSDK; use Blocktrail\SDK\Wallet; diff --git a/tests/WalletSweeper/WalletV1SweeperTest.php b/tests/WalletSweeper/WalletV1SweeperTest.php index a132ad5..571110a 100644 --- a/tests/WalletSweeper/WalletV1SweeperTest.php +++ b/tests/WalletSweeper/WalletV1SweeperTest.php @@ -8,14 +8,11 @@ use BitWasp\Bitcoin\Script\ScriptFactory; use BitWasp\Bitcoin\Transaction\TransactionFactory; use BitWasp\Buffertools\Buffer; -use Blocktrail\SDK\Address\BitcoinAddressReader; -use Blocktrail\SDK\Bitcoin\BIP32Path; -use Blocktrail\SDK\Tests\Wallet\CreateWalletTest; +use BitWasp\Bitcoin\Address\AddressCreator as BitcoinAddressCreator; use Blocktrail\SDK\Tests\Wallet\WalletTestBase; use Blocktrail\SDK\UnspentOutputFinder; use Blocktrail\SDK\Wallet; use Blocktrail\SDK\WalletV1Sweeper; -use Btccom\JustEncrypt\KeyDerivation; class WalletV1SweeperTest extends WalletTestBase { @@ -92,7 +89,7 @@ public function testSweep() $sweeper->discoverWalletFunds($batchSize); $tx = $sweeper->sweepWallet("mjpqMuKZA9gYnxXFNdkGLQEMKxokhESvMG", $batchSize); - $addrReader = new BitcoinAddressReader(); + $addrReader = new BitcoinAddressCreator(); $script = $addrReader->fromString("mjpqMuKZA9gYnxXFNdkGLQEMKxokhESvMG")->getScriptPubKey(); $decoded = TransactionFactory::fromHex($tx); diff --git a/tests/WalletSweeper/WalletV2SweeperTest.php b/tests/WalletSweeper/WalletV2SweeperTest.php index 30c93c1..640017a 100644 --- a/tests/WalletSweeper/WalletV2SweeperTest.php +++ b/tests/WalletSweeper/WalletV2SweeperTest.php @@ -7,7 +7,7 @@ use BitWasp\Bitcoin\Script\ScriptFactory; use BitWasp\Bitcoin\Transaction\TransactionFactory; use BitWasp\Buffertools\Buffer; -use Blocktrail\SDK\Address\BitcoinAddressReader; +use BitWasp\Bitcoin\Address\AddressCreator as BitcoinAddressCreator; use Blocktrail\SDK\Tests\Wallet\CreateWalletTest; use Blocktrail\SDK\Tests\Wallet\WalletTestBase; use Blocktrail\SDK\UnspentOutputFinder; @@ -98,7 +98,7 @@ public function testSweep() $sweeper->discoverWalletFunds($batchSize); $tx = $sweeper->sweepWallet("mjpqMuKZA9gYnxXFNdkGLQEMKxokhESvMG", $batchSize); - $addrReader = new BitcoinAddressReader(); + $addrReader = new BitcoinAddressCreator(); $script = $addrReader->fromString("mjpqMuKZA9gYnxXFNdkGLQEMKxokhESvMG")->getScriptPubKey(); $decoded = TransactionFactory::fromHex($tx); diff --git a/tests/WalletSweeper/WalletV3SweeperTest.php b/tests/WalletSweeper/WalletV3SweeperTest.php index 09c2d32..4208ded 100644 --- a/tests/WalletSweeper/WalletV3SweeperTest.php +++ b/tests/WalletSweeper/WalletV3SweeperTest.php @@ -7,12 +7,11 @@ use BitWasp\Bitcoin\Script\ScriptFactory; use BitWasp\Bitcoin\Transaction\TransactionFactory; use BitWasp\Buffertools\Buffer; -use Blocktrail\SDK\Address\BitcoinAddressReader; +use BitWasp\Bitcoin\Address\AddressCreator as BitcoinAddressCreator; use Blocktrail\SDK\Tests\Wallet\CreateWalletTest; use Blocktrail\SDK\Tests\Wallet\WalletTestBase; use Blocktrail\SDK\UnspentOutputFinder; use Blocktrail\SDK\Wallet; -use Blocktrail\SDK\WalletV2Sweeper; use Blocktrail\SDK\WalletV3Sweeper; use Btccom\JustEncrypt\KeyDerivation; @@ -99,7 +98,7 @@ public function testSweep() $sweeper->discoverWalletFunds($batchSize); $tx = $sweeper->sweepWallet("mjpqMuKZA9gYnxXFNdkGLQEMKxokhESvMG", $batchSize); - $addrReader = new BitcoinAddressReader(); + $addrReader = new BitcoinAddressCreator(); $script = $addrReader->fromString("mjpqMuKZA9gYnxXFNdkGLQEMKxokhESvMG")->getScriptPubKey(); $decoded = TransactionFactory::fromHex($tx);