OSDN Git Service

update selection
[bytom/Bytom-JS-SDK.git] / src / sdk / keys.js
1 import { createKey ,resetKeyPassword, createPubkey, signMessage, signTransaction} from '../wasm/func';
2 import {getDB} from '../db/db';
3 import {createkey, isValidMnemonic} from '../utils/key/createKey';
4 import {encryptKey, decryptKey} from '../utils/key/keystore';
5 import { restoreFromKeyStore } from '../utils/account';
6 import { camelize } from '../utils/utils';
7 import CryptoJS from 'crypto-js';
8
9
10 function keysSDK() {
11 }
12
13 /**
14  * reset key password
15  * 
16  * @param {String}} rootXPub 
17  * @param {String} oldPassword 
18  * @param {String} newPassword 
19  */
20 keysSDK.prototype.resetKeyPassword = function(rootXPub, oldPassword, newPassword) {
21     let retPromise = new Promise((resolve, reject) => {
22         let data = {rootXPub: rootXPub, oldPassword:oldPassword, newPassword:newPassword};
23         resetKeyPassword(data).then(res => {
24             getDB().then(db => {
25                 let objectStore = db.transaction(['keys'], 'readwrite').objectStore('keys');
26                 let index = objectStore.index('xpub');
27                 let keyRange = IDBKeyRange.only(rootXPub);
28                 let getRequest = index.openCursor(keyRange);
29                 getRequest.onsuccess = function (event) {
30                     const cursor = event.target.result;
31                     if(cursor && cursor.value.xpub === rootXPub) {
32                         const updateData = cursor.value;
33                         updateData.key = res.data;
34                         const request = cursor.update(updateData);
35                         request.onsuccess = function() {
36                             resolve(true);
37                         };
38                         request.onerror = function() {
39                             reject(new Error('db update error'));
40                         };
41                     } else {
42                         reject(new Error('db update error: not found by rootXPub'));
43                     }
44                 };
45                 getRequest.onerror = function () {
46                     reject(new Error('db get error'));
47                 };
48             }).catch(error => {
49                 reject(error);
50             });
51         }).catch(error => {
52             reject(error);
53         });
54     });
55     return retPromise;
56 };
57
58 /**
59  * get key by XPub
60  * 
61  * @param {String} xpub 
62  */
63 keysSDK.prototype.getKeyByXPub = function(xpub) {
64     let retPromise = new Promise((resolve, reject) => {
65         getDB().then(db => {
66             let getRequest = db.transaction(['keys'], 'readonly')
67                 .objectStore('keys')
68                 .index('xpub')
69                 .get(xpub);
70             getRequest.onsuccess = function(e) {
71                 if(e.target.result) {
72                     resolve(e.target.result.key);
73                 } else {
74                     reject(new Error('not found by XPub'));    
75                 }
76             };
77             getRequest.onerror = function() {
78                 reject(new Error('db get error'));
79             };
80         }).catch(error => {
81             reject(error);
82         });
83     });
84     return retPromise;
85 };
86
87 /**
88  * List key
89  *
90  * @returns {Promise}
91  */
92 keysSDK.prototype.list = function() {
93     let retPromise = new Promise((resolve, reject) => {
94         getDB().then(db => {
95             let transaction = db.transaction(['keys'], 'readonly');
96             let objectStore = transaction.objectStore('keys');
97             let oc = objectStore.openCursor();
98             let ret = [];
99             oc.onsuccess = function (event) {
100                 var cursor = event.target.result;
101                 if (cursor) {
102                     ret.push({alias: cursor.value.alias, xpub: cursor.value.xpub});
103                     cursor.continue();
104                 } else {
105                     resolve(ret);
106                 }
107             };
108             oc.onerror = function(e){
109                 reject(e);
110             };
111         }).catch(err => {
112             reject(err);
113         });
114     });
115     return retPromise;
116 };
117
118 /**
119  * Create a new key.
120  *
121  * @param {String} alias - User specified, unique identifier.
122  * @param {String} password - User specified, key password.
123  */
124 keysSDK.prototype.createKey = function(alias, password) {
125     var normalizedAlias = alias.toLowerCase().trim();
126
127     let data = {};
128     data.alias = normalizedAlias;
129     data.password = password;
130     const res = createkey(data);
131
132     res.vault = this.encryptMnemonic(res.mnemonic, password, res.keystore);
133
134     return res;
135 };
136
137 /**
138  * Create a new key.
139  *
140  * @param {String} alias - User specified, unique identifier.
141  * @param {String} password - User specified, key password.
142  */
143 keysSDK.prototype.restoreFromMnemonic = function(alias, password, mnemonic) {
144     var normalizedAlias = alias.toLowerCase().trim();
145
146     let data = {};
147     data.alias = normalizedAlias;
148     data.password = password;
149     data.mnemonic = mnemonic;
150
151     const res = createkey(data);
152
153     res.vault = this.encryptMnemonic(mnemonic, password, res.keystore);
154     return res;
155 };
156
157 /**
158  * Create a new key.
159  *
160  * @param {String} alias - User specified, unique identifier.
161  * @param {String} password - User specified, key password.
162  */
163 keysSDK.prototype.restoreFromKeystore = function( password, keystore) {
164
165     const result = decryptKey(keystore, password);
166     result.xpub = result.xPub.toString('hex');
167     delete result['xPub'];
168
169     return result;
170 };
171
172
173 /**
174  * Create a new key.
175  *
176  * @param {String} alias - User specified, unique identifier.
177  * @param {String} password - User specified, key password.
178  */
179 keysSDK.prototype.encryptMnemonic = function(mnemonic, password, keystore) {
180
181     const result = decryptKey(keystore, password);
182     const xprv = result.xPrv.toString('hex');
183
184     const ciphertext = CryptoJS.AES.encrypt(mnemonic, xprv);
185
186     return ciphertext.toString();
187 };
188
189 /**
190  * Create a new key.
191  *
192  * @param {String} alias - User specified, unique identifier.
193  * @param {String} password - User specified, key password.
194  */
195 keysSDK.prototype.decryptMnemonic = function(ciphertext, password, keystore) {
196
197     const result = decryptKey(keystore, password);
198     const xprv = result.xPrv.toString('hex');
199
200
201     const bytes = CryptoJS.AES.decrypt(ciphertext, xprv);
202     const plaintext = bytes.toString(CryptoJS.enc.Utf8);
203
204     return plaintext;
205 };
206
207
208
209 /**
210  * Create a new key.
211  *
212  * @param {String} keystore - User specified, unique identifier.
213  */
214 keysSDK.prototype.isValidKeystore = function(  keystore ) {
215
216     const walletImage = camelize(JSON.parse(keystore));
217
218     let keys, key;
219     if(walletImage.keyImages && walletImage.keyImages.xkeys ){
220         keys = walletImage.keyImages.xkeys;
221     }
222
223     // match older version of backups keystore files
224     else if(walletImage['accounts-server']){
225         keys = walletImage.keys.map(keyItem => JSON.parse( keyItem.key ) );
226     }else{
227         key  = walletImage;
228     }
229
230     if(keys){
231         if(keys.length>1){
232             throw 'do not support multiple keystore imported.';
233         }
234         else if(keys.length === 1){
235             key = keys[0];
236         }
237     }
238
239     return key;
240 };
241
242 /**
243  * Create a new key.
244  *
245  * @param {String} alias - User specified, unique identifier.
246  * @param {String} password - User specified, key password.
247  */
248 keysSDK.prototype.isValidMnemonic = function(mnemonic) {
249
250     return isValidMnemonic(mnemonic);
251 };
252
253 /**
254  * Create a new key.
255  * 
256  * @param {String} alias - User specified, unique identifier.
257  * @param {String} password - User specified, key password.
258  */
259 keysSDK.prototype.create = function(alias, password) {
260     var normalizedAlias = alias.toLowerCase().trim();
261     let retPromise = new Promise((resolve, reject) => {
262         getDB().then(db => {
263             let getRequest = db.transaction(['keys'], 'readonly')
264                 .objectStore('keys')
265                 .index('alias')
266                 .get(normalizedAlias);
267             getRequest.onsuccess = function (e) {
268                 if (e.target.result) {
269                     reject(new Error('key alias already exists'));
270                     return;
271                 }
272                 let data = {};
273                 data.alias = normalizedAlias;
274                 data.auth = password;
275                 createKey(data).then((res) => {
276                     let jsonData = JSON.parse(res.data);
277                     let dbData = {
278                         key:res.data,
279                         xpub:jsonData.xpub,
280                         alias:alias,
281                     };
282                     let request = db.transaction(['keys'], 'readwrite')
283                         .objectStore('keys')
284                         .add(dbData);
285                     request.onsuccess = function () {
286                         resolve({xpub:jsonData.xpub, alias: alias});
287                     };
288                     request.onerror = function () {
289                         reject(new Error('db insert error'));
290                     };
291                 }).catch(error => {
292                     reject(error);    
293                 });
294             };
295             getRequest.onerror = function () {
296                 reject(new Error('db get error'));
297             };
298         }).catch(error => {
299             reject(error);
300         });
301     });
302     return retPromise;
303 };
304
305
306 /**
307  * Create a new key.
308  *
309  * @param {String} xpub - xpub.
310  */
311 keysSDK.prototype.createPubkey = function(xpub) {
312     let retPromise = new Promise((resolve, reject) => {
313         let data = {};
314         data.xpub = xpub;
315         data.seed = 1;
316         createPubkey(data).then((res) => {
317             let jsonData = JSON.parse(res.data);
318             resolve(jsonData);
319         }).catch(error => {
320             reject(error);
321         });
322     });
323     return retPromise;
324 };
325
326 /**
327  * Sign Message.
328  *
329  * @param {String} message - message.
330  * @param {String} password - password.
331  * @param {Object} address - address.
332  */
333 keysSDK.prototype.signMessage = function(message, password, keystore) {
334     let data = {};
335     data.message = message;
336     data.password = password;
337     data.key = keystore;
338     return signMessage(data).then((res) => {
339         let jsonData = JSON.parse(res.data);
340         return (jsonData);
341     }).catch(error => {
342         throw (error);
343     });
344
345
346 };
347
348 export default keysSDK;