|
|
@ -18,6 +18,8 @@ var BASE_URL = 'http://localhost:3001/copay/api'; |
|
|
|
var WALLET_CRITICAL_DATA = ['xPrivKey', 'm', 'publicKeyRing', 'sharedEncryptingKey']; |
|
|
|
var WALLET_EXTRA_DATA = ['copayerId', 'roPrivKey', 'rwPrivKey']; |
|
|
|
|
|
|
|
var WALLET_AIRGAPPED_TOCOMPLETE = ['publicKeyRing', 'm', 'n', 'sharedEncryptingKey']; |
|
|
|
|
|
|
|
function _encryptMessage(message, encryptingKey) { |
|
|
|
if (!message) return null; |
|
|
|
return WalletUtils.encryptMessage(message, encryptingKey); |
|
|
@ -110,20 +112,30 @@ API.prototype._tryToCompleteFromServer = function(data, cb) { |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
API.prototype._tryToCompleteFromData = function(data, toComplete, cb) { |
|
|
|
var inData = _decryptMessage(toComplete, |
|
|
|
WalletUtils.privateKeyToAESKey(data.roPrivKey)); |
|
|
|
if (!inData) |
|
|
|
return cb('Could not complete wallet'); |
|
|
|
|
|
|
|
API.prototype._tryToComplete = function(opts, data, cb) { |
|
|
|
if (opts.pkr) { |
|
|
|
var pkr = _decryptMessage(opts.pkr,WalletUtils.privateKeyToAESKey(data.roPrivKey)); |
|
|
|
try { |
|
|
|
inData = JSON.parse(inData); |
|
|
|
_.extend(data, _.pick(inData, WALLET_AIRGAPPED_TOCOMPLETE)); |
|
|
|
} catch (ex) { |
|
|
|
return cb(ex); |
|
|
|
} |
|
|
|
|
|
|
|
if (!pkr) |
|
|
|
return cb('Could not complete wallet'); |
|
|
|
this.storage.save(data, function(err) { |
|
|
|
return cb(err, data); |
|
|
|
}); |
|
|
|
}; |
|
|
|
|
|
|
|
data.publicKeyRing = JSON.parse(pkr); |
|
|
|
this.storage.save(data, function(err) { |
|
|
|
return cb(err, data); |
|
|
|
}); |
|
|
|
|
|
|
|
API.prototype._tryToComplete = function(opts, data, cb) { |
|
|
|
if (opts.toComplete) { |
|
|
|
this._tryToCompleteFromData(data, opts.toComplete, cb); |
|
|
|
} else { |
|
|
|
this._tryToCompleteFromServer(data,cb); |
|
|
|
this._tryToCompleteFromServer(data, cb); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
@ -151,13 +163,10 @@ API.prototype._loadAndCheck = function(opts, cb) { |
|
|
|
|
|
|
|
this._load(function(err, data) { |
|
|
|
if (err) return cb(err); |
|
|
|
if (data.n > 1) { |
|
|
|
var pkrComplete = data.publicKeyRing && data.m && data.publicKeyRing.length === data.n; |
|
|
|
|
|
|
|
if (!pkrComplete) { |
|
|
|
return self._tryToComplete(opts, data, cb); |
|
|
|
} |
|
|
|
} |
|
|
|
if (!data.n || (data.n > 1 && data.publicKeyRing.length != data.n)) |
|
|
|
return self._tryToComplete(opts, data, cb); |
|
|
|
|
|
|
|
return cb(null, data); |
|
|
|
}); |
|
|
|
}; |
|
|
@ -542,7 +551,10 @@ API.prototype.import = function(str, cb) { |
|
|
|
API.prototype.parseTxProposals = function(txData, cb) { |
|
|
|
var self = this; |
|
|
|
|
|
|
|
this._loadAndCheck({pkr: txData.pkr},function(err, data) { |
|
|
|
this._loadAndCheck({ |
|
|
|
toComplete: txData.toComplete |
|
|
|
}, function(err, data) { |
|
|
|
if (err) return cb(err); |
|
|
|
|
|
|
|
var txps = txData.txps; |
|
|
|
_processTxps(txps, data.sharedEncryptingKey); |
|
|
@ -645,13 +657,13 @@ API.prototype.getSignatures = function(txp, cb) { |
|
|
|
}); |
|
|
|
}; |
|
|
|
|
|
|
|
API.prototype.getEncryptedPublicKeyRing = function(cb) { |
|
|
|
API.prototype.getEncryptedWalletData = function(cb) { |
|
|
|
var self = this; |
|
|
|
|
|
|
|
this._loadAndCheck({}, function(err, data) { |
|
|
|
if (err) return cb(err); |
|
|
|
var pkr = JSON.stringify(data.publicKeyRing); |
|
|
|
return cb(null, _encryptMessage(pkr, WalletUtils.privateKeyToAESKey(data.roPrivKey))); |
|
|
|
var toComplete = JSON.stringify(_.pick(data, WALLET_AIRGAPPED_TOCOMPLETE)); |
|
|
|
return cb(null, _encryptMessage(toComplete, WalletUtils.privateKeyToAESKey(data.roPrivKey))); |
|
|
|
}); |
|
|
|
}; |
|
|
|
|
|
|
|