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

WalletV1::lock()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 0
dl 0
loc 4
ccs 4
cts 4
cp 1
crap 1
rs 10
c 0
b 0
f 0
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