|
|
@ -6,6 +6,7 @@ var util = require('util'); |
|
|
|
var async = require('async'); |
|
|
|
var log = require('npmlog'); |
|
|
|
var request = require('request') |
|
|
|
var events = require('events'); |
|
|
|
log.debug = log.verbose; |
|
|
|
|
|
|
|
var Bitcore = require('bitcore') |
|
|
@ -111,6 +112,7 @@ function API(opts) { |
|
|
|
this.request = request || opts.request; |
|
|
|
this.baseUrl = opts.baseUrl || BASE_URL; |
|
|
|
this.basePath = this.baseUrl.replace(/http.?:\/\/[a-zA-Z0-9:-]*\//, '/'); |
|
|
|
this.noPasswdAccess = opts.noPasswdAccess || 'full'; |
|
|
|
if (this.verbose) { |
|
|
|
log.level = 'debug'; |
|
|
|
} else { |
|
|
@ -118,7 +120,7 @@ function API(opts) { |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
util.inherits(API, events.EventEmitter); |
|
|
|
|
|
|
|
API.prototype._tryToCompleteFromServer = function(wcd, cb) { |
|
|
|
|
|
|
@ -143,7 +145,7 @@ API.prototype._tryToCompleteFromServer = function(wcd, cb) { |
|
|
|
|
|
|
|
wcd.publicKeyRing = _.pluck(wallet.copayers, 'xPubKey') |
|
|
|
|
|
|
|
self.storage.save(wcd, function(err) { |
|
|
|
self.save(wcd, function(err) { |
|
|
|
return cb(err, wcd); |
|
|
|
}); |
|
|
|
}); |
|
|
@ -163,7 +165,7 @@ API.prototype._tryToCompleteFromData = function(wcd, toComplete, cb) { |
|
|
|
return cb(ex); |
|
|
|
} |
|
|
|
|
|
|
|
this.storage.save(wcd, function(err) { |
|
|
|
this.save(wcd, function(err) { |
|
|
|
return cb(err, wcd); |
|
|
|
}); |
|
|
|
}; |
|
|
@ -202,8 +204,16 @@ API.prototype._processWcdAfterRead = function(rawData, requiredAccess, cb) { |
|
|
|
// Decrypt it and try again
|
|
|
|
this.emit('needPassword', function(password) { |
|
|
|
if (!password) return cb('No password'); |
|
|
|
rawData = WE.decryptWallet(rawData, password); |
|
|
|
var access = WU.accessFromData(rawData); |
|
|
|
|
|
|
|
try { |
|
|
|
rawData = WU.decryptWallet(rawData, password); |
|
|
|
} catch (e) {}; |
|
|
|
|
|
|
|
if (!rawData) |
|
|
|
return cb('NOTAUTH'); |
|
|
|
|
|
|
|
access = WU.accessFromData(rawData); |
|
|
|
accessLevel = WU.accessNameToLevel(access); |
|
|
|
|
|
|
|
// Is the data available?
|
|
|
|
if (requiredAccessLevel <= accessLevel) |
|
|
@ -213,16 +223,25 @@ API.prototype._processWcdAfterRead = function(rawData, requiredAccess, cb) { |
|
|
|
}); |
|
|
|
}; |
|
|
|
|
|
|
|
API.prototype._processWcdBeforeWrite = function(wcd, accessWithoutEncrytion, cb) { |
|
|
|
|
|
|
|
API.prototype.setNopasswdAccess = function(noPasswdAccess) { |
|
|
|
if (!_.contains(['none', 'readonly', 'readwrite', 'full'], noPasswdAccess)) |
|
|
|
throw new Error('Bad nopasswd access:' + noPasswdAccess); |
|
|
|
|
|
|
|
this.noPasswdAccess = noPasswdAccess; |
|
|
|
}; |
|
|
|
|
|
|
|
API.prototype._processWcdBeforeWrite = function(wcd, cb) { |
|
|
|
var self = this; |
|
|
|
// Is any encrypted?
|
|
|
|
if (encryptedAccess) { |
|
|
|
if (this.noPasswdAccess == 'full') { |
|
|
|
return cb(null, wcd); |
|
|
|
} else { |
|
|
|
this.emit('needPassword', function(password) { |
|
|
|
if (!password) return cb('No password'); |
|
|
|
rawdata = WE.encryptWallet(wcd, accessWithoutEncrytion, password); |
|
|
|
return cb(null, rawdata); |
|
|
|
if (!password) return cb('No password given'); |
|
|
|
var ewcd = WalletUtils.encryptWallet(wcd, self.noPasswdAccess, password); |
|
|
|
return cb(null, ewcd); |
|
|
|
}); |
|
|
|
} else { |
|
|
|
return rawdata; |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
@ -326,6 +345,18 @@ API.prototype._doJoinWallet = function(walletId, walletPrivKey, xPubKey, copayer |
|
|
|
}); |
|
|
|
}; |
|
|
|
|
|
|
|
API.prototype.save = function(inWcd, cb) { |
|
|
|
var self = this; |
|
|
|
|
|
|
|
self._processWcdBeforeWrite(inWcd, function(err, wcd) { |
|
|
|
if (err) return cb(err); |
|
|
|
|
|
|
|
self.storage.save(wcd, function(err) { |
|
|
|
return cb(err, null); |
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
API.prototype.generateKey = function(network, cb) { |
|
|
|
var self = this; |
|
|
|
network = network || 'livenet'; |
|
|
@ -337,7 +368,8 @@ API.prototype.generateKey = function(network, cb) { |
|
|
|
return cb(self.storage.getName() + ' already contains a wallet'); |
|
|
|
|
|
|
|
var wcd = _initWcd(network); |
|
|
|
self.storage.save(wcd, function(err) { |
|
|
|
|
|
|
|
self.save(wcd, function(err) { |
|
|
|
return cb(err, null); |
|
|
|
}); |
|
|
|
}); |
|
|
@ -378,7 +410,7 @@ API.prototype.createWallet = function(walletName, copayerName, m, n, network, cb |
|
|
|
self._doJoinWallet(walletId, walletPrivKey, wcd.publicKeyRing[0], copayerName, |
|
|
|
function(err, wallet) { |
|
|
|
if (err) return cb(err); |
|
|
|
self.storage.save(wcd, function(err) { |
|
|
|
self.save(wcd, function(err) { |
|
|
|
return cb(err, n > 1 ? secret : null); |
|
|
|
}); |
|
|
|
}); |
|
|
@ -439,7 +471,7 @@ API.prototype.joinWallet = function(secret, copayerName, cb) { |
|
|
|
function(err, joinedWallet) { |
|
|
|
if (err) return cb(err); |
|
|
|
_addWalletToWcd(wcd, secretData.walletPrivKey, joinedWallet.m, joinedWallet.n); |
|
|
|
self.storage.save(wcd, cb); |
|
|
|
self.save(wcd, cb); |
|
|
|
}); |
|
|
|
}); |
|
|
|
}; |
|
|
@ -639,7 +671,7 @@ API.prototype.import = function(str, cb) { |
|
|
|
return cb('Invalid source wallet'); |
|
|
|
|
|
|
|
wcd.network = wcd.publicKeyRing[0].substr(0, 4) == 'tpub' ? 'testnet' : 'livenet'; |
|
|
|
self.storage.save(wcd, function(err) { |
|
|
|
self.save(wcd, function(err) { |
|
|
|
return cb(err, WalletUtils.accessFromData(wcd)); |
|
|
|
}); |
|
|
|
}); |
|
|
|