Completed
Pull Request — master (#89)
by thomas
20:32
created

WalletV1::unlock()   D

Complexity

Conditions 15
Paths 144

Size

Total Lines 50
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 21
CRAP Score 17.4683

Importance

Changes 0
Metric Value
cc 15
eloc 27
nc 144
nop 2
dl 0
loc 50
ccs 21
cts 27
cp 0.7778
crap 17.4683
rs 4.9977
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Blocktrail\SDK;
4
5
use BitWasp\Bitcoin\Key\Deterministic\HierarchicalKey;
6
use BitWasp\Bitcoin\Key\Deterministic\HierarchicalKeyFactory;
7
use BitWasp\Bitcoin\Mnemonic\Bip39\Bip39SeedGenerator;
8
use Blocktrail\SDK\Bitcoin\BIP32Key;
9
use Blocktrail\SDK\Exceptions\NotImplementedException;
10
11
class WalletV1 extends Wallet {
12
13
    /**
14
     * BIP39 Mnemonic for the master primary private key
15
     *
16
     * @var string
17
     */
18
    protected $primaryMnemonic;
19
20
    /**
21
     * @param BlocktrailSDKInterface        $sdk                        SDK instance used to do requests
22
     * @param string                        $identifier                 identifier of the wallet
23
     * @param string                        $primaryMnemonic
24
     * @param BIP32Key[]                    $primaryPublicKeys
25
     * @param BIP32Key                      $backupPublicKey            should be BIP32 master public key M/
26
     * @param BIP32Key[]                    $blocktrailPublicKeys
27
     * @param int                           $keyIndex
28
     * @param string                        $checksum
29
     */
30 13
    public function __construct(BlocktrailSDKInterface $sdk, $identifier, $primaryMnemonic, array $primaryPublicKeys, $backupPublicKey, array $blocktrailPublicKeys, $keyIndex, $segwit, $checksum) {
31 13
        $this->primaryMnemonic = $primaryMnemonic;
32
33 13
        parent::__construct($sdk, $identifier, $primaryPublicKeys, $backupPublicKey, $blocktrailPublicKeys, $keyIndex, $segwit, $checksum);
34 13
    }
35
36
    /**
37
     * unlock wallet so it can be used for payments
38
     *
39
     * @param          $options ['primary_private_key' => key] OR ['passphrase' => pass]
40
     * @param callable $fn
41
     * @return bool
42
     * @throws \Exception
43
     */
44 13
    public function unlock($options, callable $fn = null) {
45
        // explode the wallet data
46 13
        $password = isset($options['passphrase']) ? $options['passphrase'] : (isset($options['password']) ? $options['password'] : null);
47 13
        $primaryMnemonic = $this->primaryMnemonic;
48 13
        $primaryPrivateKey = isset($options['primary_private_key']) ? $options['primary_private_key'] : null;
49
50 13
        if ($primaryMnemonic && $primaryPrivateKey) {
51
            throw new \InvalidArgumentException("Can't specify Primary Mnemonic and Primary PrivateKey");
52
        }
53
54 13
        if (!$primaryMnemonic && !$primaryPrivateKey) {
55
            throw new \InvalidArgumentException("Can't init wallet without Primary Mnemonic or Primary PrivateKey");
56
        }
57
58 13
        if ($primaryMnemonic && !$password) {
59
            throw new \InvalidArgumentException("Can't init wallet with Primary Mnemonic without a passphrase");
60
        }
61
62 13
        if ($primaryPrivateKey) {
63 1
            if (!($primaryPrivateKey instanceof HierarchicalKey)) {
64 1
                $primaryPrivateKey = HierarchicalKeyFactory::fromExtended($primaryPrivateKey);
65
            }
66
        } else {
67
            // convert the mnemonic to a seed using BIP39 standard
68 12
            $primarySeed = (new Bip39SeedGenerator())->getSeed($primaryMnemonic, $password);
69
            // create BIP32 private key from the seed
70 12
            $primaryPrivateKey = HierarchicalKeyFactory::fromEntropy($primarySeed);
71
        }
72
73 13
        $network = $this->networkParams->getNetwork();
0 ignored issues
show
Bug introduced by
The method getNetwork() does not seem to exist on object<BitWasp\Bitcoin\Network\NetworkInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
74 13
        $this->primaryPrivateKey = BIP32Key::create($network, $primaryPrivateKey, "m");
75
76
        // create checksum (address) of the primary privatekey to compare to the stored checksum
77 13
        $checksum = $this->primaryPrivateKey->key()->getPublicKey()->getAddress()->getAddress($network);
78 13
        if ($checksum != $this->checksum) {
79 1
            throw new \Exception("Checksum [{$checksum}] does not match [{$this->checksum}], most likely due to incorrect password");
80
        }
81
82 13
        $this->locked = false;
83
84
        // if the response suggests we should upgrade to a different blocktrail cosigning key then we should
85 13
        if (isset($data['upgrade_key_index'])) {
0 ignored issues
show
Bug introduced by
The variable $data seems to never exist, and therefore isset should always return false. Did you maybe rename this variable?

This check looks for calls to isset(...) or empty() on variables that are yet undefined. These calls will always produce the same result and can be removed.

This is most likely caused by the renaming of a variable or the removal of a function/method parameter.

Loading history...
86
            $this->upgradeKeyIndex($data['upgrade_key_index']);
87
        }
88
89 13
        if ($fn) {
90
            $fn($this);
91
            $this->lock();
92
        }
93 13
    }
94
95
    /**
96
     * lock the wallet (unsets primary private key)
97
     *
98
     * @return void
99
     */
100 1
    public function lock() {
101 1
        $this->primaryPrivateKey = null;
102 1
        $this->locked = true;
103 1
    }
104
105
    /**
106
     * change password that is used to store data encrypted on server
107
     *
108
     * @param $newPassword
109
     * @return array backupInfo
110
     * @throws NotImplementedException
111
     */
112
    public function passwordChange($newPassword) {
113
        throw new NotImplementedException();
114
    }
115
}
116