Completed
Push — master ( a8a46d...6b0176 )
by thomas
23:45
created

WifPrivateKeySerializer   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 64
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Test Coverage

Coverage 95.65%

Importance

Changes 0
Metric Value
dl 0
loc 64
ccs 22
cts 23
cp 0.9565
rs 10
c 0
b 0
f 0
wmc 8
lcom 1
cbo 8

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A serialize() 0 11 2
B parse() 0 22 5
1
<?php
2
3
declare(strict_types=1);
4
5
namespace BitWasp\Bitcoin\Serializer\Key\PrivateKey;
6
7
use BitWasp\Bitcoin\Base58;
8
use BitWasp\Bitcoin\Bitcoin;
9
use BitWasp\Bitcoin\Crypto\EcAdapter\Adapter\EcAdapterInterface;
10
use BitWasp\Bitcoin\Crypto\EcAdapter\Key\PrivateKeyInterface;
11
use BitWasp\Bitcoin\Crypto\EcAdapter\Serializer\Key\PrivateKeySerializerInterface;
12
use BitWasp\Bitcoin\Exceptions\Base58ChecksumFailure;
13
use BitWasp\Bitcoin\Exceptions\InvalidPrivateKey;
14
use BitWasp\Bitcoin\Network\NetworkInterface;
15
use BitWasp\Buffertools\Buffer;
16
17
class WifPrivateKeySerializer
18
{
19
    /**
20
     * @var PrivateKeySerializerInterface
21
     */
22
    private $keySerializer;
23
24
    /**
25
     * @param PrivateKeySerializerInterface $serializer
26
     */
27 151
    public function __construct(PrivateKeySerializerInterface $serializer)
28
    {
29 151
        $this->keySerializer = $serializer;
30 151
    }
31
32
    /**
33
     * @param NetworkInterface $network
34
     * @param PrivateKeyInterface $privateKey
35
     * @return string
36
     * @throws \Exception
37
     */
38 11
    public function serialize(NetworkInterface $network, PrivateKeyInterface $privateKey): string
39
    {
40 11
        $prefix = pack("H*", $network->getPrivByte());
41 11
        if ($privateKey->isCompressed()) {
42 9
            $ending = "\x01";
43
        } else {
44 4
            $ending = "";
45
        }
46
47 11
        return Base58::encodeCheck(new Buffer("{$prefix}{$this->keySerializer->serialize($privateKey)->getBinary()}{$ending}"));
48
    }
49
50
    /**
51
     * @param string $wif
52
     * @param NetworkInterface|null $network
53
     * @return PrivateKeyInterface
54
     * @throws Base58ChecksumFailure
55
     * @throws InvalidPrivateKey
56
     * @throws \Exception
57
     */
58 10
    public function parse(string $wif, NetworkInterface $network = null): PrivateKeyInterface
59
    {
60 10
        $network = $network ?: Bitcoin::getNetwork();
61 10
        $data = Base58::decodeCheck($wif);
62 8
        if ($data->slice(0, 1)->getHex() !== $network->getPrivByte()) {
63
            throw new \RuntimeException('WIF prefix does not match networks');
64
        }
65
66 8
        $payload = $data->slice(1);
67 8
        $size = $payload->getSize();
68
69 8
        if (33 === $size) {
70 6
            $compressed = true;
71 6
            $payload = $payload->slice(0, 32);
72 4
        } else if (32 === $size) {
73 4
            $compressed = false;
74
        } else {
75 2
            throw new InvalidPrivateKey("Private key should be always be 32 or 33 bytes (depending on if it's compressed)");
76
        }
77
78 8
        return $this->keySerializer->parse($payload, $compressed);
79
    }
80
}
81