Browse Source

export/import

activeAddress
Ivan Socolsky 10 years ago
parent
commit
d2085c9b9e
  1. 134
      lib/client/api.js
  2. 46
      lib/client/credentials.js
  3. 26
      test/integration/client.js

134
lib/client/api.js

@ -192,11 +192,13 @@ API.prototype.createWallet = function(walletName, copayerName, m, n, network, cb
var self = this;
network = network || 'livenet';
if (!_.contains(['testnet', 'livenet'], network))
return cb('Invalid network');
if (!_.contains(['testnet', 'livenet'], network)) return cb('Invalid network');
if (!self.credentials) {
log.info('Generating new keys');
self.credentials = Credentials.create(network);
} else {
log.info('Using existing keys');
}
$.checkState(network == self.credentials.network);
@ -226,39 +228,6 @@ API.prototype.createWallet = function(walletName, copayerName, m, n, network, cb
});
};
// API.prototype.reCreateWallet = function(walletName, cb) {
// var self = this;
// this._loadAndCheck(function(err, wcd) {
// if (err) return cb(err);
// var walletPrivKey = new Bitcore.PrivateKey();
// var args = {
// name: walletName,
// m: wcd.m,
// n: wcd.n,
// pubKey: walletPrivKey.toPublicKey().toString(),
// network: wcd.network,
// };
// var url = '/v1/wallets/';
// self._doPostRequest(url, args, function(err, body) {
// if (err) return cb(err);
// var walletId = body.walletId;
// var secret = WalletUtils.toSecret(walletId, walletPrivKey, wcd.network);
// var i = 0;
// async.each(wcd.publicKeyRing, function(xpub, next) {
// var copayerName = 'recovered Copayer #' + i;
// self._doJoinWallet(walletId, walletPrivKey, wcd.publicKeyRing[i++], copayerName, next);
// }, function(err) {
// return cb(err);
// });
// });
// });
// };
API.prototype.joinWallet = function(secret, copayerName, cb) {
var self = this;
@ -371,96 +340,19 @@ API.prototype.getBalance = function(cb) {
};
/**
* Export does not try to complete the wallet from the server. Exports the
* wallet as it is now.
*
* @param opts.access =['full', 'readonly', 'readwrite']
* Exports the wallet as it is now.
*/
// API.prototype.export = function(opts, cb) {
// $.checkState(this.credentials);
// $.shouldBeFunction(cb);
// var self = this;
// opts = opts || {};
// var access = opts.access || 'full';
// this._load(function(err, wcd) {
// if (err) return cb(err);
// var v = [];
// var myXPubKey = wcd.xPrivKey ? (new Bitcore.HDPublicKey(wcd.xPrivKey)).toString() : '';
// _.each(WALLET_CRITICAL_DATA, function(k) {
// var d;
// if (access != 'full' && k === 'xPrivKey') {
// v.push(null);
// return;
// }
// // Skips own pub key IF priv key is exported
// if (access == 'full' && k === 'publicKeyRing') {
// d = _.without(wcd[k], myXPubKey);
// } else {
// d = wcd[k];
// }
// v.push(d);
// });
// if (access != 'full') {
// v.push(wcd.copayerId);
// v.push(wcd.roPrivKey);
// if (access == 'readwrite') {
// v.push(wcd.requestPrivKey);
// }
// }
// return cb(null, JSON.stringify(v));
// });
// }
// API.prototype.import = function(str, cb) {
// var self = this;
// this.storage.load(function(err, wcd) {
// if (wcd)
// return cb('Storage already contains a wallet');
// wcd = {};
// var inData = JSON.parse(str);
// var i = 0;
// _.each(WALLET_CRITICAL_DATA.concat(WALLET_EXTRA_DATA), function(k) {
// wcd[k] = inData[i++];
// });
// if (wcd.xPrivKey) {
// var xpriv = new Bitcore.HDPrivateKey(wcd.xPrivKey);
// var xPubKey = new Bitcore.HDPublicKey(xpriv).toString();
// wcd.publicKeyRing.unshift(xPubKey);
// wcd.copayerId = WalletUtils.xPubToCopayerId(xPubKey);
// wcd.roPrivKey = xpriv.derive('m/1/0').privateKey.toWIF();
// wcd.requestPrivKey = xpriv.derive('m/1/1').privateKey.toWIF();
// }
// if (!wcd.publicKeyRing)
// return cb('Invalid source wallet');
API.prototype.export = function() {
$.checkState(this.credentials);
// wcd.network = wcd.publicKeyRing[0].substr(0, 4) == 'tpub' ? 'testnet' : 'livenet';
return this.credentials.exportCompressed();
}
// self.save(wcd, function(err) {
// return cb(err, WalletUtils.accessFromData(wcd));
// });
// });
// };
/**
*
*/
API.prototype.import = function(str) {
this.credentials = new Credentials();
this.credentials.importCompressed(str);
};
/**
*

46
lib/client/credentials.js

@ -21,6 +21,16 @@ var FIELDS = [
'copayerName',
];
var EXPORTABLE_FIELDS = [
'xPrivKey',
'requestPrivKey',
'xPubKey',
'm',
'n',
'publicKeyRing',
'sharedEncryptingKey',
];
function Credentials() {
this.version = '1.0.0';
};
@ -104,6 +114,42 @@ Credentials.prototype.isComplete = function() {
return true;
};
Credentials.prototype.exportCompressed = function() {
var self = this;
var values = _.map(EXPORTABLE_FIELDS, function(field) {
if ((field == 'xPubKey' || field == 'requestPrivKey') && self.canSign()) return;
if (field == 'publicKeyRing') {
return _.without(self.publicKeyRing, self.xPubKey);
}
return self[field];
});
values.unshift(self.version);
return JSON.stringify(values);
};
Credentials.prototype.importCompressed = function(compressed) {
var self = this;
var list;
try {
list = JSON.parse(compressed);
} catch (ex) {
throw new Error('Invalid string');
}
// Remove version
var version = list[0];
list = _.rest(list);
_.each(EXPORTABLE_FIELDS, function(field, i) {
self[field] = list[i];
});
self._expand();
self.network = self.xPubKey.substr(0, 4) == 'tpub' ? 'testnet' : 'livenet';
self.publicKeyRing.push(self.xPubKey);
};
module.exports = Credentials;

26
test/integration/client.js

@ -864,6 +864,32 @@ describe('client API ', function() {
it.skip('should get paginated transaction history', function(done) {});
});
describe('Export & Import', function() {
it('should export & import', function(done) {
helpers.createAndJoinWallet(clients, 1, 1, function() {
clients[0].createAddress(function(err, address) {
should.not.exist(err);
should.exist(address.address);
var exported = clients[0].export();
var importedClient = new Client({
request: helpers.getRequest(app),
});
importedClient.import(exported);
importedClient.getMainAddresses({}, function(err, list) {
should.not.exist(err);
should.exist(list);
list.length.should.equal(1);
list[0].address.should.equal(address.address);
done();
});
});
})
});
});
describe('Air gapped related flows', function() {
it('should create wallet in proxy from airgapped', function(done) {
var airgapped = new AirGapped({

Loading…
Cancel
Save