Completed
Push — master ( 460d12...eabe8c )
by thomas
24:52
created

HierarchicalKeyFactory::multisig()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 2
dl 0
loc 4
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace BitWasp\Bitcoin\Key\Factory;
6
7
use BitWasp\Bitcoin\Bitcoin;
8
use BitWasp\Bitcoin\Crypto\EcAdapter\Adapter\EcAdapterInterface;
9
use BitWasp\Bitcoin\Crypto\EcAdapter\EcSerializer;
10
use BitWasp\Bitcoin\Crypto\EcAdapter\Serializer\Key\PublicKeySerializerInterface;
11
use BitWasp\Bitcoin\Crypto\Hash;
12
use BitWasp\Bitcoin\Crypto\Random\Random;
13
use BitWasp\Bitcoin\Key\Deterministic\HierarchicalKey;
14
use BitWasp\Bitcoin\Key\Deterministic\MultisigHD;
15
use BitWasp\Bitcoin\Key\KeyToScript\Factory\P2pkhScriptDataFactory;
16
use BitWasp\Bitcoin\Key\KeyToScript\ScriptDataFactory;
17
use BitWasp\Bitcoin\Network\NetworkInterface;
18
use BitWasp\Bitcoin\Serializer\Key\HierarchicalKey\Base58ExtendedKeySerializer;
19
use BitWasp\Bitcoin\Serializer\Key\HierarchicalKey\ExtendedKeySerializer;
20
use BitWasp\Buffertools\Buffer;
21
use BitWasp\Buffertools\BufferInterface;
22
23
class HierarchicalKeyFactory
24
{
25
    /**
26
     * @var EcAdapterInterface
27
     */
28
    private $adapter;
29
30
    /**
31
     * @var Base58ExtendedKeySerializer
32
     */
33
    private $serializer;
34
35
    /**
36
     * @var PrivateKeyFactory
37
     */
38
    private $privFactory;
39
40
    /**
41
     * HierarchicalKeyFactory constructor.
42
     * @param EcAdapterInterface|null $ecAdapter
43
     * @param Base58ExtendedKeySerializer|null $serializer
44
     * @throws \Exception
45
     */
46 77
    public function __construct(EcAdapterInterface $ecAdapter = null, Base58ExtendedKeySerializer $serializer = null)
47
    {
48 77
        $this->adapter = $ecAdapter ?: Bitcoin::getEcAdapter();
49 77
        $this->privFactory = PrivateKeyFactory::compressed($this->adapter);
50 77
        $this->serializer = $serializer ?: new Base58ExtendedKeySerializer(
51 75
            new ExtendedKeySerializer($this->adapter)
52
        );
53 77
    }
54
55
    /**
56
     * @param Random $random
57
     * @param ScriptDataFactory|null $scriptDataFactory
58
     * @return HierarchicalKey
59
     * @throws \BitWasp\Bitcoin\Exceptions\RandomBytesFailure
60
     * @throws \Exception
61
     */
62 8
    public function generateMasterKey(Random $random, ScriptDataFactory $scriptDataFactory = null): HierarchicalKey
63
    {
64 8
        return $this->fromEntropy(
65 8
            $random->bytes(64),
66 8
            $scriptDataFactory
67
        );
68
    }
69
70
    /**
71
     * @param BufferInterface $entropy
72
     * @param ScriptDataFactory|null $scriptFactory
73
     * @return HierarchicalKey
74
     * @throws \Exception
75
     */
76 37
    public function fromEntropy(BufferInterface $entropy, ScriptDataFactory $scriptFactory = null): HierarchicalKey
77
    {
78 37
        $seed = Hash::hmac('sha512', $entropy, new Buffer('Bitcoin seed'));
79 37
        $privSecret = $seed->slice(0, 32);
80 37
        $chainCode = $seed->slice(32, 32);
81 37
        $scriptFactory = $scriptFactory ?: new P2pkhScriptDataFactory(EcSerializer::getSerializer(PublicKeySerializerInterface::class, true, $this->adapter));
82 37
        return new HierarchicalKey($this->adapter, $scriptFactory, 0, 0, 0, $chainCode, $this->privFactory->fromBuffer($privSecret));
83
    }
84
85
    /**
86
     * @param string $extendedKey
87
     * @param NetworkInterface|null $network
88
     * @return HierarchicalKey
89
     * @throws \BitWasp\Bitcoin\Exceptions\Base58ChecksumFailure
90
     * @throws \BitWasp\Buffertools\Exceptions\ParserOutOfRange
91
     */
92 40
    public function fromExtended(string $extendedKey, NetworkInterface $network = null): HierarchicalKey
93
    {
94 40
        return $this->serializer->parse($network ?: Bitcoin::getNetwork(), $extendedKey);
95
    }
96
97
    /**
98
     * @param ScriptDataFactory $scriptFactory
99
     * @param HierarchicalKey ...$keys
100
     * @return MultisigHD
101
     */
102 4
    public function multisig(ScriptDataFactory $scriptFactory, HierarchicalKey ...$keys): MultisigHD
103
    {
104 4
        return new MultisigHD($scriptFactory, ...$keys);
105
    }
106
}
107