|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
namespace Blocktrail\SDK; |
|
4
|
|
|
|
|
5
|
|
|
use BitWasp\Bitcoin\Key\Deterministic\HierarchicalKeyFactory; |
|
6
|
|
|
use Blocktrail\SDK\Bitcoin\BIP32Key; |
|
7
|
|
|
use Endroid\QrCode\QrCode; |
|
8
|
|
|
|
|
9
|
|
|
/** |
|
10
|
|
|
* Class BackupGenerator |
|
11
|
|
|
*/ |
|
12
|
|
|
class BackupGenerator { |
|
13
|
|
|
|
|
14
|
|
|
const QR_CODE_SIZE = 195; |
|
15
|
|
|
|
|
16
|
|
|
/** |
|
17
|
|
|
* path to fonts used for pdf generation |
|
18
|
|
|
* |
|
19
|
|
|
* @var string |
|
20
|
|
|
*/ |
|
21
|
|
|
protected $fontsPath; |
|
22
|
|
|
|
|
23
|
|
|
/** |
|
24
|
|
|
* array of data and QR codes for the blocktrail public keys |
|
25
|
|
|
* |
|
26
|
|
|
* @var null |
|
27
|
|
|
*/ |
|
28
|
|
|
protected $blocktrailPubKeyQRs = []; |
|
29
|
|
|
|
|
30
|
|
|
protected $identifier; |
|
31
|
|
|
|
|
32
|
|
|
protected $backupInfo; |
|
33
|
|
|
|
|
34
|
|
|
protected $extra; |
|
35
|
|
|
|
|
36
|
|
|
protected $options = [ |
|
37
|
|
|
'page1' => true, |
|
38
|
|
|
'page2' => true, |
|
39
|
|
|
'page3' => true, |
|
40
|
|
|
]; |
|
41
|
|
|
|
|
42
|
|
|
/** |
|
43
|
|
|
* @param string $identifier |
|
44
|
|
|
* @param array $backupInfo |
|
45
|
|
|
* @param array $extra |
|
46
|
|
|
* @param null $options |
|
47
|
|
|
*/ |
|
48
|
|
|
public function __construct($identifier, $backupInfo, $extra = null, $options = null) { |
|
49
|
|
|
/* |
|
50
|
|
|
* if DOMPDF is not already loaded we have to do it |
|
51
|
|
|
* they require a config file to be loaded, no autoloading :/ |
|
52
|
|
|
*/ |
|
53
|
|
|
if (!defined('DOMPDF_ENABLE_AUTOLOAD')) { |
|
54
|
|
|
// disable DOMPDF's internal autoloader if you are using Composer |
|
55
|
|
|
define('DOMPDF_ENABLE_AUTOLOAD', false); |
|
56
|
|
|
|
|
57
|
|
|
//try the different possible locations for the config file, depending on if the sdk is included as a dependency or is the main project itself |
|
58
|
|
|
(@include_once __DIR__ . '/../../../dompdf/dompdf/dompdf_config.inc.php') || @include_once __DIR__ . '/../vendor/dompdf/dompdf/dompdf_config.inc.php'; |
|
59
|
|
|
} |
|
60
|
|
|
|
|
61
|
|
|
//set the fonts path |
|
62
|
|
|
$this->fontsPath = dirname(__FILE__) . '/../resources/fonts'; |
|
63
|
|
|
|
|
64
|
|
|
$this->identifier = $identifier; |
|
65
|
|
|
$this->backupInfo = $backupInfo; |
|
66
|
|
|
$this->extra = $extra ?: []; |
|
67
|
|
|
$this->options = array_merge($this->options, $options ?: []); |
|
68
|
|
|
} |
|
69
|
|
|
|
|
70
|
|
|
/** |
|
71
|
|
|
* process the blocktrail public keys and create qr codes for each one |
|
72
|
|
|
*/ |
|
73
|
|
|
protected function processBlocktrailPubKeys() { |
|
74
|
|
|
if (!isset($this->backupInfo['blocktrail_public_keys'])) { |
|
75
|
|
|
return; |
|
76
|
|
|
} |
|
77
|
|
|
|
|
78
|
|
|
//create QR codes for each blocktrail pub key |
|
79
|
|
|
foreach ($this->backupInfo['blocktrail_public_keys'] as $keyIndex => $key) { |
|
80
|
|
|
$key = $key instanceof BIP32Key ? $key : BIP32Key::create(HierarchicalKeyFactory::fromExtended($key[0]), $key[1]); |
|
81
|
|
|
|
|
82
|
|
|
$qrCode = new QrCode(); |
|
83
|
|
|
$qrCode |
|
84
|
|
|
->setText($key->key()->toExtendedKey()) |
|
85
|
|
|
->setSize(self::QR_CODE_SIZE-20) |
|
86
|
|
|
->setPadding(10) |
|
87
|
|
|
->setErrorCorrection('high') |
|
88
|
|
|
->setForegroundColor(array('r' => 0, 'g' => 0, 'b' => 0, 'a' => 0)) |
|
89
|
|
|
->setBackgroundColor(array('r' => 255, 'g' => 255, 'b' => 255, 'a' => 0)) |
|
90
|
|
|
->setLabel("KeyIndex: ".$keyIndex." Path: ".$key->path()) |
|
91
|
|
|
->setLabelFontSize(10) |
|
92
|
|
|
; |
|
93
|
|
|
$this->blocktrailPubKeyQRs[] = array( |
|
94
|
|
|
'keyIndex' => $keyIndex, |
|
95
|
|
|
'path' => $key->path(), |
|
96
|
|
|
'qr' => $qrCode->getDataUri(), |
|
97
|
|
|
'qrImg' => $qrCode->getImage(), |
|
98
|
|
|
); |
|
99
|
|
|
} |
|
100
|
|
|
} |
|
101
|
|
|
|
|
102
|
|
|
/** |
|
103
|
|
|
* generate html document of backup details |
|
104
|
|
|
* |
|
105
|
|
|
* @return string |
|
106
|
|
|
*/ |
|
107
|
|
|
public function generateHTML() { |
|
108
|
|
|
//create blocktrail pub key QR codes if not already done |
|
109
|
|
|
if (!$this->blocktrailPubKeyQRs) { |
|
110
|
|
|
$this->processBlocktrailPubKeys(); |
|
111
|
|
|
} |
|
112
|
|
|
$pubKeysHtml = ""; |
|
113
|
|
|
foreach ($this->blocktrailPubKeyQRs as $pubKey) { |
|
|
|
|
|
|
114
|
|
|
$pubKeysHtml .= "<img src='{$pubKey['qr']}' />"; |
|
115
|
|
|
} |
|
116
|
|
|
$totalPubKeys = count($this->blocktrailPubKeyQRs); |
|
117
|
|
|
|
|
118
|
|
|
$backupInfo = $this->prepareBackupInfo(); |
|
119
|
|
|
$extraInfo = $this->prepareExtraInfo(); |
|
120
|
|
|
|
|
121
|
|
|
$passwordEncryptedSecret = null; |
|
122
|
|
|
if (isset($this->backupInfo['encrypted_secret'])) { |
|
123
|
|
|
$passwordEncryptedSecret = $this->backupInfo['encrypted_secret']; |
|
124
|
|
|
} |
|
125
|
|
|
|
|
126
|
|
|
$html = self::renderTemplate(__DIR__ . "/../resources/templates/recovery_sheet.html.php", [ |
|
127
|
|
|
'identifier' => $this->identifier, |
|
128
|
|
|
'totalPubKeys' => $totalPubKeys, |
|
129
|
|
|
'pubKeysHtml' => $pubKeysHtml, |
|
130
|
|
|
'backupInfo' => $backupInfo, |
|
131
|
|
|
'extraInfo' => $extraInfo, |
|
132
|
|
|
'passwordEncryptedSecret' => $passwordEncryptedSecret, |
|
133
|
|
|
'options' => $this->options, |
|
134
|
|
|
]); |
|
135
|
|
|
|
|
136
|
|
|
return $html; |
|
137
|
|
|
} |
|
138
|
|
|
|
|
139
|
|
|
protected function prepareBackupInfo() { |
|
140
|
|
|
$backupInfo = []; |
|
141
|
|
|
|
|
142
|
|
|
if (isset($this->backupInfo['primary_mnemonic'])) { |
|
143
|
|
|
$backupInfo[] = [ |
|
144
|
|
|
'title' => 'Primary Mnemonic', |
|
145
|
|
|
'mnemonic' => $this->backupInfo['primary_mnemonic'], |
|
146
|
|
|
]; |
|
147
|
|
|
} |
|
148
|
|
|
if (isset($this->backupInfo['backup_mnemonic'])) { |
|
149
|
|
|
$backupInfo[] = [ |
|
150
|
|
|
'title' => 'Primary Mnemonic', |
|
151
|
|
|
'mnemonic' => $this->backupInfo['backup_mnemonic'], |
|
152
|
|
|
]; |
|
153
|
|
|
} |
|
154
|
|
|
if (isset($this->backupInfo['encrypted_primary_seed'])) { |
|
155
|
|
|
$backupInfo[] = [ |
|
156
|
|
|
'title' => 'Encrypted Primary Seed', |
|
157
|
|
|
'mnemonic' => $this->backupInfo['encrypted_primary_seed'], |
|
158
|
|
|
]; |
|
159
|
|
|
} |
|
160
|
|
|
if (isset($this->backupInfo['backup_seed'])) { |
|
161
|
|
|
$backupInfo[] = [ |
|
162
|
|
|
'title' => 'Backup Seed', |
|
163
|
|
|
'mnemonic' => $this->backupInfo['backup_seed'], |
|
164
|
|
|
]; |
|
165
|
|
|
} |
|
166
|
|
|
if (isset($this->backupInfo['recovery_encrypted_secret'])) { |
|
167
|
|
|
$backupInfo[] = [ |
|
168
|
|
|
'title' => 'Encrypted Recovery Secret', |
|
169
|
|
|
'mnemonic' => $this->backupInfo['recovery_encrypted_secret'], |
|
170
|
|
|
]; |
|
171
|
|
|
} |
|
172
|
|
|
|
|
173
|
|
|
return $backupInfo; |
|
174
|
|
|
} |
|
175
|
|
|
|
|
176
|
|
|
protected function prepareExtraInfo() { |
|
177
|
|
|
$extraInfo = []; |
|
178
|
|
|
|
|
179
|
|
|
foreach ($this->extra as $k => $v) { |
|
180
|
|
|
if (is_array($v)) { |
|
181
|
|
|
$extraInfo[] = $v; |
|
182
|
|
|
} else { |
|
183
|
|
|
$extraInfo[] = ['title' => $k, 'value' => $v]; |
|
184
|
|
|
} |
|
185
|
|
|
} |
|
186
|
|
|
|
|
187
|
|
|
return $extraInfo; |
|
188
|
|
|
} |
|
189
|
|
|
|
|
190
|
|
|
public static function renderTemplate($file, $vars) { |
|
191
|
|
|
if (is_array($vars) && !empty($vars)) { |
|
192
|
|
|
extract($vars); |
|
193
|
|
|
} |
|
194
|
|
|
|
|
195
|
|
|
ob_start(); |
|
196
|
|
|
|
|
197
|
|
|
include $file; |
|
198
|
|
|
|
|
199
|
|
|
return ob_get_clean(); |
|
200
|
|
|
} |
|
201
|
|
|
|
|
202
|
|
|
/** |
|
203
|
|
|
* generate PDF document of backup details |
|
204
|
|
|
* @return string pdf data, ready to be saved to file or streamed to browser |
|
205
|
|
|
*/ |
|
206
|
|
|
public function generatePDF() { |
|
207
|
|
|
$dompdf = new \DOMPDF(); |
|
208
|
|
|
$html = $this->generateHTML(); |
|
209
|
|
|
$dompdf->load_html($html); |
|
210
|
|
|
|
|
211
|
|
|
$dompdf->render(); |
|
212
|
|
|
$pdfStream = $dompdf->output(); |
|
213
|
|
|
return $pdfStream; |
|
214
|
|
|
} |
|
215
|
|
|
|
|
216
|
|
|
/** |
|
217
|
|
|
* generate text document of backup details (not implemented yet) |
|
218
|
|
|
* |
|
219
|
|
|
*/ |
|
220
|
|
|
public function generateTxt() { |
|
221
|
|
|
//... |
|
222
|
|
|
} |
|
223
|
|
|
} |
|
224
|
|
|
|