OSDN Git Service

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