CreateKeypair::handle()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 36
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 19
c 1
b 0
f 0
dl 0
loc 36
rs 9.6333
cc 1
nc 1
nop 0
1
<?php
2
3
namespace Vrajroham\LaravelBitpay\Commands;
4
5
use Bitpay\Client\BitpayException;
0 ignored issues
show
Bug introduced by
The type Bitpay\Client\BitpayException was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
use BitPayKeyUtils\KeyHelper\PrivateKey;
7
use GuzzleHttp\Client;
8
use Illuminate\Console\Command;
0 ignored issues
show
Bug introduced by
The type Illuminate\Console\Command was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
9
use Vrajroham\LaravelBitpay\Traits\CreateKeypairTrait;
10
11
class CreateKeypair extends Command
12
{
13
    private $config;
14
    private $privateKey;
15
    private $publicKey;
16
    private $storageEngine;
17
    private $sin;
18
    private $client;
0 ignored issues
show
introduced by
The private property $client is not used, and could be removed.
Loading history...
19
    private $network;
20
    private $adapter;
0 ignored issues
show
introduced by
The private property $adapter is not used, and could be removed.
Loading history...
21
    private $pairingCode;
22
    private $pairingCodeLabel = 'Laravel_BitPay';
23
    private $token;
24
    private $bar;
25
    use CreateKeypairTrait;
26
27
    /**
28
     * The name and signature of the console command.
29
     *
30
     * @var string
31
     */
32
    protected $signature = 'laravel-bitpay:createkeypair';
33
34
    /**
35
     * The console command description.
36
     *
37
     * @var string
38
     */
39
    protected $description = 'Create and persist keypairs. Pair client with BitPay server.';
40
41
    /**
42
     * Create a new command instance.
43
     */
44
    public function __construct()
45
    {
46
        parent::__construct();
47
    }
48
49
    /**
50
     * Execute the console command.
51
     */
52
    public function handle()
53
    {
54
        $this->bar = $this->output->createProgressBar(7);
55
56
        $this->bar->setProgressCharacter('⚡');
57
        $this->bar->setBarCharacter('-');
58
        $this->bar->setEmptyBarCharacter(' ');
59
60
        $this->line('');
61
62
        $this->validateAndLoadConfig();
63
64
        $this->createAndPersistKeypair();
65
66
        $this->pairWithServerAndCreateToken();
67
68
        $this->writeNewEnvironmentFileWith();
69
70
        $this->laravel['config']['laravel-bitpay.token'] = $this->token;
0 ignored issues
show
Bug Best Practice introduced by
The property laravel does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
71
72
        $this->line('');
73
74
        $this->line('<options=bold,underscore>Token</> - <options=bold;fg=green>'.$this->token.'</> //(Token copied to .env for you)');
75
        $this->line('<options=bold,underscore>Pairing code</> - <options=bold;fg=green>'.$this->pairingCode.'</>');
76
77
        $this->line('');
78
79
        $this->line('Please, copy the above pairing code and approve on your BitPay Account at the following link:');
80
81
        $this->line('');
82
83
        $this->line('Open -> <href='.$this->network.'/dashboard/merchant/api-tokens>'.$this->network.'/dashboard/merchant/api-tokens</>');
84
85
        $this->line('');
86
87
        $this->info('Once you have this Pairing Code approved you can start using the Client. ⛳');
88
    }
89
90
    /**
91
     * Create private key and public key. Store keypair in file storgae.
92
     */
93
    public function createAndPersistKeypair()
94
    {
95
        $this->bar->advance();
96
        $this->info(' - Generating private key.');
97
98
        $this->privateKey = new PrivateKey($this->config['private_key']);
99
        $this->privateKey->generate();
100
101
        $this->bar->advance();
102
        $this->info(' - Generating public key.');
103
104
        $this->publicKey = $this->privateKey->getPublicKey();
105
106
        if (in_array('__construct', get_class_methods($this->config['key_storage']))) {
107
            $this->storageEngine = new $this->config['key_storage']($this->config['key_storage_password']);
108
        } else {
109
            $this->storageEngine = new $this->config['key_storage']();
110
        }
111
112
        $this->bar->advance();
113
        $this->info(' - Using <options=bold;fg=red>'.get_class($this->storageEngine).'</> for secure storage.');
114
115
        $this->storageEngine->persist($this->privateKey);
116
117
        $this->bar->advance();
118
        $this->info(' - Keypairs stored securely.');
119
    }
120
121
    /**
122
     * Create token on server using generated keypairs and pair the client with server using pairing code.
123
     *
124
     * @throws \Bitpay\Client\BitpayException
125
     */
126
    public function pairWithServerAndCreateToken()
127
    {
128
        $this->sin = $this->publicKey->getSin()->__toString();
129
130
        $this->bar->advance();
131
        $this->info(' - Created Service Identification Number (SIN Key) for client.');
132
133
        if ('testnet' == $this->config['network']) {
134
            $this->network = 'https://test.bitpay.com';
135
        } elseif ('livenet' == $this->config['network']) {
136
            $this->network = 'https://bitpay.com';
137
        } else {
138
            $this->network = 'https://bitpay.com';
139
        }
140
141
        $bitpayClient = new Client(['base_uri' => $this->network]);
142
143
        $this->bar->advance();
144
        $this->info(' - Connecting Bitpay server 🖥️  and generating token & pairing code.');
145
146
        try {
147
            $this->pairingCodeLabel = config('app.name').'_BitPay_Client';
0 ignored issues
show
Bug introduced by
The function config was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

147
            $this->pairingCodeLabel = /** @scrutinizer ignore-call */ config('app.name').'_BitPay_Client';
Loading history...
148
            $postData = [
149
                'id'     => (string) $this->sin,
150
                'label'  => $this->pairingCodeLabel,
151
                'facade' => 'merchant',
152
            ];
153
            $response = $bitpayClient->post('/tokens', [
154
                'json'    => $postData,
155
                'headers' => [
156
                    'x-accept-version: 2.0.0',
157
                    'Content-Type: application/json',
158
                    // Todo: If added below headers, bitpay responds with error, "This endpoint does not support the `user` facade"
159
                    // 'x-identity' => $this->publicKey->__toString(),
160
                    // 'x-signature' => $this->privateKey->sign($this->network.'/tokens'.json_encode($postData)),
161
                ],
162
            ]);
163
            $response = json_decode($response->getBody()->getContents());
164
        } catch (BitpayException $bitpayException) {
165
            throw $bitpayException;
166
        }
167
168
        $this->bar->finish();
169
        $this->info(' - New token and pairing code received from Bitpay server.');
170
        $this->token = $response->data[0]->token;
171
        $this->pairingCode = $response->data[0]->pairingCode;
172
    }
173
}
174