@sygna/bridge-util 2.0.0 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/dependabot.yml +7 -0
- package/README.md +58 -43
- package/package.json +1 -1
- package/src/api/index.js +2 -1
package/README.md
CHANGED
|
@@ -16,15 +16,56 @@ Dealing with encrypting, decrypting, signing and verifying in Sygna Bridge.
|
|
|
16
16
|
|
|
17
17
|
During the communication of VASPs, there are some private information that must be encrypted. We use ECIES(Elliptic Curve Integrated Encryption Scheme) to securely encrypt these private data so that they can only be accessed by the recipient.
|
|
18
18
|
|
|
19
|
+
We're using [IVMS101 (interVASP Messaging Standard)](https://intervasp.org/) as our private information format.
|
|
20
|
+
|
|
21
|
+
We also provide [IVMS101 Typescript Utility](https://github.com/CoolBitX-Technology/sygna-bridge-ivms-utils/tree/master/typescript) to construct data payload.
|
|
22
|
+
|
|
19
23
|
```javascript
|
|
20
24
|
const sensitive_data = {
|
|
21
|
-
originator: {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
"originator": {
|
|
26
|
+
"originator_persons": [
|
|
27
|
+
{
|
|
28
|
+
"natural_person": {
|
|
29
|
+
"name": {
|
|
30
|
+
"name_identifiers": [
|
|
31
|
+
{
|
|
32
|
+
"primary_identifier": "Wu Xinli",
|
|
33
|
+
"name_identifier_type": "LEGL"
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
},
|
|
37
|
+
"national_identification": {
|
|
38
|
+
"national_identifier": "446005",
|
|
39
|
+
"national_identifier_type": "RAID",
|
|
40
|
+
"registration_authority": "RA000553"
|
|
41
|
+
},
|
|
42
|
+
"country_of_residence": "TZ"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
],
|
|
46
|
+
"account_numbers": [
|
|
47
|
+
"r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV"
|
|
48
|
+
]
|
|
27
49
|
},
|
|
50
|
+
"beneficiary": {
|
|
51
|
+
"beneficiary_persons": [
|
|
52
|
+
{
|
|
53
|
+
"legal_person": {
|
|
54
|
+
"name": {
|
|
55
|
+
"name_identifiers": [
|
|
56
|
+
{
|
|
57
|
+
"legal_person_name": "ABC Limited",
|
|
58
|
+
"legal_person_name_identifier_type": "LEGL"
|
|
59
|
+
}
|
|
60
|
+
]
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
],
|
|
65
|
+
"account_numbers": [
|
|
66
|
+
"rAPERVgXZavGgiGv6xBgtiZurirW2yAmY"
|
|
67
|
+
]
|
|
68
|
+
}
|
|
28
69
|
};
|
|
29
70
|
|
|
30
71
|
const private_info = sygnaBridgeUtil.crypto.encryptPrivateObj(
|
|
@@ -39,9 +80,9 @@ const decrypted_priv_info = sygnaBridge.crypto.decryptPrivateObj(
|
|
|
39
80
|
|
|
40
81
|
### Sign and Verify
|
|
41
82
|
|
|
42
|
-
In Sygna Bridge, we use secp256k1 ECDSA over sha256 of utf-8 json string to create signature on every API call. Since you need to provide the identical utf-8 string during
|
|
83
|
+
In Sygna Bridge, we use secp256k1 ECDSA over sha256 of utf-8 json string to create signature on every API call. Since you need to provide the identical utf-8 string during verification, the order of key-value pair you put into the object is important.
|
|
43
84
|
|
|
44
|
-
The following example is the snippet of originator's signing process of `
|
|
85
|
+
The following example is the snippet of originator's signing process of `permissionRequest` API call. If you put the key `transaction` before `private_info` in the object, the verification will fail in the central server.
|
|
45
86
|
|
|
46
87
|
```javascript
|
|
47
88
|
let transaction = {
|
|
@@ -49,7 +90,7 @@ let transaction = {
|
|
|
49
90
|
vasp_code: 'VASPUSNY1',
|
|
50
91
|
"addrs": [
|
|
51
92
|
{
|
|
52
|
-
"address": "
|
|
93
|
+
"address": "r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV",
|
|
53
94
|
"addr_extra_info": []
|
|
54
95
|
}
|
|
55
96
|
]
|
|
@@ -58,7 +99,7 @@ let transaction = {
|
|
|
58
99
|
vasp_code: 'VASPUSNY1',
|
|
59
100
|
"addrs": [
|
|
60
101
|
{
|
|
61
|
-
"address": "
|
|
102
|
+
"address": "rAPERVgXZavGgiGv6xBgtiZurirW2yAmY",
|
|
62
103
|
"addr_extra_info": []
|
|
63
104
|
}
|
|
64
105
|
]
|
|
@@ -125,42 +166,16 @@ The full logic of originator would be like the following:
|
|
|
125
166
|
```javascript
|
|
126
167
|
// originator.js
|
|
127
168
|
|
|
128
|
-
const privateSenderInfo = {
|
|
129
|
-
originator: { name: 'Antoine Griezmann', date_of_birth: '1991-03-21' },
|
|
130
|
-
beneficiary: { name: 'Leo Messi' },
|
|
131
|
-
};
|
|
132
169
|
const recipientPublicKey = await sbAPI.getVASPPublicKey('10298');
|
|
133
170
|
const private_info = sygnaBridge.crypto.encryptPrivateObj(
|
|
134
|
-
|
|
171
|
+
// sensitive_data from example above
|
|
172
|
+
sensitive_data,
|
|
135
173
|
recipientPublicKey,
|
|
136
174
|
);
|
|
137
175
|
|
|
138
|
-
const transaction = {
|
|
139
|
-
originator_vasp:{
|
|
140
|
-
vasp_code: 'VASPUSNY1',
|
|
141
|
-
"addrs": [
|
|
142
|
-
{
|
|
143
|
-
"address": "3KvJ1uHPShhEAWyqsBEzhfXyeh1TXKAd7D",
|
|
144
|
-
"addr_extra_info": []
|
|
145
|
-
}
|
|
146
|
-
]
|
|
147
|
-
},
|
|
148
|
-
beneficiary_vasp:{
|
|
149
|
-
vasp_code: 'VASPUSNY1',
|
|
150
|
-
"addrs": [
|
|
151
|
-
{
|
|
152
|
-
"address": "3F4ReDwiMLu8LrAiXwwD2DhH8U9xMrUzUf",
|
|
153
|
-
"addr_extra_info": []
|
|
154
|
-
}
|
|
155
|
-
]
|
|
156
|
-
},
|
|
157
|
-
currency_id: 'sygna:0x80000000',
|
|
158
|
-
amount: "0.973",
|
|
159
|
-
};;
|
|
160
|
-
const data_dt = '2019-07-29T07:29:80Z';
|
|
161
|
-
|
|
162
176
|
const signPermissionRequestData = {
|
|
163
177
|
private_info,
|
|
178
|
+
// from example above
|
|
164
179
|
transaction,
|
|
165
180
|
data_dt,
|
|
166
181
|
};
|
|
@@ -188,7 +203,7 @@ const { transfer_id } = await sbAPI.postPermissionRequest(
|
|
|
188
203
|
postPermissionRequestData,
|
|
189
204
|
);
|
|
190
205
|
|
|
191
|
-
//
|
|
206
|
+
// Broadcast your transaction to blockchain after got and api response at your api server.
|
|
192
207
|
const txid = '1a0c9bef489a136f7e05671f7f7fada2b9d96ac9f44598e1bcaa4779ac564dcd';
|
|
193
208
|
|
|
194
209
|
// Inform Sygna Bridge that a specific transfer is successfully broadcasted to the blockchain.
|
|
@@ -202,7 +217,7 @@ let result = await sygnaAPI.postTransactionId(sendTxIdObj);
|
|
|
202
217
|
|
|
203
218
|
### For Beneficiary
|
|
204
219
|
|
|
205
|
-
There is only one api for Beneficiary VASP to call, which is `postPermission`. After the beneficiary server confirm
|
|
220
|
+
There is only one api for Beneficiary VASP to call, which is `postPermission`. After the beneficiary server confirm their legitimacy of a transfer request, they will sign `{ transfer_id, permission_status }` using `signPermission()` function, and send the result with signature to Sygna Bridge Central Server.
|
|
206
221
|
|
|
207
222
|
```javascript
|
|
208
223
|
const permission_status = 'ACCEPTED'; // or "REJECTED"
|
|
@@ -214,7 +229,7 @@ const permissionObj = sygnaBridgeUtil.crypto.signPermission(
|
|
|
214
229
|
signPermissionData,
|
|
215
230
|
beneficiary_privKey,
|
|
216
231
|
);
|
|
217
|
-
const
|
|
232
|
+
const finalResult = await sygnaAPI.postPermission(permissionObj);
|
|
218
233
|
```
|
|
219
234
|
|
|
220
|
-
|
|
235
|
+
For more complete example, please refer to [Example](example/index.js) file.
|
package/package.json
CHANGED
package/src/api/index.js
CHANGED
|
@@ -101,6 +101,7 @@ class API {
|
|
|
101
101
|
const headers = {
|
|
102
102
|
'Content-Type': 'application/json',
|
|
103
103
|
'x-api-key': this.api_key,
|
|
104
|
+
'User-Agent': 'util-js/2.0.2"'
|
|
104
105
|
};
|
|
105
106
|
const response = await fetch(url, {
|
|
106
107
|
method: 'POST',
|
|
@@ -115,7 +116,7 @@ class API {
|
|
|
115
116
|
* @param {string} url
|
|
116
117
|
*/
|
|
117
118
|
async getSB(url) {
|
|
118
|
-
const headers = { 'x-api-key': this.api_key };
|
|
119
|
+
const headers = { 'x-api-key': this.api_key, 'User-Agent': 'util-js/2.0.2"' };
|
|
119
120
|
const response = await fetch(url, { headers: headers });
|
|
120
121
|
return await response.json();
|
|
121
122
|
}
|