Skip to content

Commit 004edaf

Browse files
author
Antonio Buedo
committed
- First commit
1 parent 5f38f19 commit 004edaf

24 files changed

+2511
-0
lines changed

.gitignore

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/bin/**
2+
/build/cache/
3+
/build/docs/
4+
/build/dist/
5+
/build/logs/
6+
/docs/_build/
7+
/node_modules/
8+
/vendor/
9+
/.settings/
10+
.project
11+
.buildpath
12+
composer.lock
13+
composer.phar
14+
.DS_Store
15+
build/.DS_Store
16+
docs/.DS_Store
17+
examples/.DS_Store

composer.json

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"name": "bitpay/key-utils",
3+
"description": "BitPay Utils pack for cryptography",
4+
"type": "library",
5+
"license": "MIT",
6+
"authors": [
7+
{
8+
"name": "Antonio Buedo",
9+
"email": "[email protected]"
10+
}
11+
],
12+
"autoload": {
13+
"psr-4": {
14+
"": "src/"
15+
}
16+
},
17+
"require": {
18+
"ext-bcmath": "*",
19+
"ext-openssl": "*",
20+
"ext-curl": "*",
21+
"ext-json": "*",
22+
"ext-iconv": "*",
23+
"ext-gmp": "*"
24+
}
25+
}

examples.php

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
<?php
2+
3+
use BitPayKeyUtils\KeyHelper\PrivateKey;
4+
use BitPayKeyUtils\Storage\EncryptedFilesystemStorage;
5+
6+
require __DIR__ . '/vendor/autoload.php';
7+
8+
/**
9+
* Generate new private key for every new merchant.
10+
* Make sure you provide an easy recognizable name for each private key/Merchant
11+
*
12+
* WARNING: It is EXTREMELY IMPORTANT to place this key files in a very SECURE location
13+
**/
14+
$privateKey = new PrivateKey(__DIR__ . '/secure/SecurePathPlusYourClientName.key');
15+
$storageEngine = new EncryptedFilesystemStorage('YourMasterPassword');
16+
17+
try {
18+
// Use the EncryptedFilesystemStorage to load the Merchant's encrypted private key with the Master Password.
19+
$privateKey = $storageEngine->load(__DIR__ . '/secure/SecurePathPlusYourClientName.key');
20+
} catch (Exception $ex) {
21+
// Check if the loaded keys is a valid key
22+
if (!$privateKey->isValid()) {
23+
$privateKey->generate();
24+
}
25+
26+
// Encrypt and store it securely.
27+
// This Master password could be one for all keys or a different one for each merchant
28+
$storageEngine->persist($privateKey);
29+
}
30+
31+
/**
32+
* Generate the public key from the private key every time (no need to store the public key).
33+
**/
34+
try {
35+
$publicKey = $privateKey->getPublicKey();
36+
} catch (Exception $ex) {
37+
echo $ex->getMessage();
38+
}
39+
40+
/**
41+
* Derive the SIN from the public key.
42+
**/
43+
$sin = $publicKey->getSin()->__toString();
44+
45+
/**
46+
* Use the SIN to request a pairing code and token.
47+
* The pairing code has to be approved in the BitPay Dashboard
48+
* THIS is just a cUrl example, which explains how to use the key pair for signing requests
49+
**/
50+
$resourceUrl = 'https://test.bitpay.com/tokens';
51+
52+
$facade = 'merchant';
53+
54+
$postData = json_encode([
55+
'id' => $sin,
56+
'facade' => $facade
57+
]);
58+
59+
$curlCli = curl_init($resourceUrl);
60+
61+
curl_setopt($curlCli, CURLOPT_HTTPHEADER, [
62+
'x-accept-version: 2.0.0',
63+
'Content-Type: application/json',
64+
'x-identity' => $publicKey->__toString(),
65+
'x-signature' => $privateKey->sign($resourceUrl . $postData),
66+
]);
67+
68+
curl_setopt($curlCli, CURLOPT_CUSTOMREQUEST, 'POST');
69+
curl_setopt($curlCli, CURLOPT_POSTFIELDS, stripslashes($postData));
70+
curl_setopt($curlCli, CURLOPT_RETURNTRANSFER, true);
71+
72+
$result = curl_exec($curlCli);
73+
$resultData = json_decode($result, TRUE);
74+
curl_close($curlCli);
75+
76+
if (array_key_exists('error', $resultData)) {
77+
echo $resultData['error'];
78+
exit;
79+
}
80+
81+
/**
82+
* Example of a pairing Code returned from the BitPay API
83+
* which needs to be APPROVED on the BitPay Dashboard before being able to use it.
84+
**/
85+
echo $resultData['data'][0]['pairingCode'];
86+
87+
/** End of request **/

src/BitPayKeyUtils/KeyHelper/Key.php

+111
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
<?php
2+
3+
namespace BitPayKeyUtils\KeyHelper;
4+
5+
use BitPayKeyUtils\Util\Point;
6+
7+
/**
8+
* Abstract object that is used for Public, Private, and SIN keys
9+
*
10+
* @package Bitcore
11+
*/
12+
abstract class Key extends Point implements KeyInterface
13+
{
14+
/**
15+
* @var string
16+
*/
17+
protected $hex;
18+
19+
/**
20+
* @var string
21+
*/
22+
protected $dec;
23+
24+
/**
25+
* @var string
26+
*/
27+
protected $id;
28+
29+
/**
30+
* @param string $id
31+
*/
32+
public function __construct($id = null)
33+
{
34+
$this->id = $id;
35+
}
36+
37+
/**
38+
* Returns a new instance of self.
39+
*
40+
* @param string $id
41+
* @return KeyInterface
42+
*/
43+
public static function create($id = null)
44+
{
45+
$class = get_called_class();
46+
47+
return new $class($id);
48+
}
49+
50+
/**
51+
* @return string
52+
*/
53+
public function getId()
54+
{
55+
return $this->id;
56+
}
57+
58+
/**
59+
* @return string
60+
*/
61+
public function getHex()
62+
{
63+
return $this->hex;
64+
}
65+
66+
/**
67+
* @return string
68+
*/
69+
public function getDec()
70+
{
71+
return $this->dec;
72+
}
73+
74+
/**
75+
* @inheritdoc
76+
*/
77+
public function serialize()
78+
{
79+
return serialize(
80+
array(
81+
$this->id,
82+
$this->x,
83+
$this->y,
84+
$this->hex,
85+
$this->dec,
86+
)
87+
);
88+
}
89+
90+
/**
91+
* @inheritdoc
92+
*/
93+
public function unserialize($data)
94+
{
95+
list(
96+
$this->id,
97+
$this->x,
98+
$this->y,
99+
$this->hex,
100+
$this->dec
101+
) = unserialize($data);
102+
}
103+
104+
/**
105+
* @return boolean
106+
*/
107+
public function isGenerated()
108+
{
109+
return (!empty($this->hex));
110+
}
111+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace BitPayKeyUtils\KeyHelper;
4+
5+
use Serializable;
6+
7+
/**
8+
* @package Bitcore
9+
*/
10+
interface KeyInterface extends Serializable
11+
{
12+
/**
13+
* Generates a new key
14+
*/
15+
public function generate();
16+
17+
/**
18+
* @return boolean
19+
*/
20+
public function isValid();
21+
}

0 commit comments

Comments
 (0)