Merge pull request #1933 from matiu/ivan

Tested with @matiaspando
This commit is contained in:
Matias Alejo Garcia 2014-12-02 18:28:31 -03:00
commit 0bac775982
21 changed files with 166 additions and 49 deletions

18
2fa Normal file
View file

@ -0,0 +1,18 @@
- 2-2
1 desktop
1 mobile
- each device creates its own key
- both devices are expected to be logged using the same profile (email / password)
- if using local storage -> all is OK.
- keys will be safe an will never leave the device
- if using insight
both 'copayers' need to have a new and different password for accessing the wallet.
-

12
TODO Normal file
View file

@ -0,0 +1,12 @@
- homeWallet address...e sta ok?
- receive controller .. owned
--
// pkr.cache = opts.cache;
(en send.js)
// $rootScope.pendingTxCount = res.pendingForUs;
-- probar payment intent
// TODO refrescar en 'add'

1
commm Normal file
View file

@ -0,0 +1 @@
7b6bcfbbbb6bf82f8843305f563d2a2491f310fe

View file

@ -62,7 +62,8 @@ angular.module('copayApp.controllers').controller('CreateController',
$scope.error = 'Could not create wallet: ' + err;
}
}
$rootScope.$digest()
$rootScope.$digest();
});
};
});

View file

@ -1,5 +0,0 @@
'use strict';
angular.module('copayApp.controllers').controller('CreateWalletController', function($scope, $rootScope) {
$rootScope.title = 'Create Wallet';
});

View file

@ -25,7 +25,7 @@ angular.module('copayApp.controllers').controller('HomeController', function($sc
$scope.$on("$destroy", function(){
var iden = $rootScope.iden;
if (iden) {
iden.removeListener('newWallets', $scope.done );
iden.removeListener('newWallet', $scope.done );
iden.removeListener('noWallets', $scope.done );
}
});

View file

@ -1,13 +1,16 @@
'use strict';
angular.module('copayApp.controllers').controller('HomeWalletController',
function($scope, $rootScope) {
angular.module('copayApp.controllers').controller('HomeWalletController', function($scope, $rootScope) {
$scope.init = function() {
$rootScope.title = 'Home';
$scope.addr = _.last($rootScope.wallet.getReceiveAddresses());
// This is necesarry, since wallet can change in homeWallet, without running init() again.
$rootScope.$watch('wallet', function() {
$scope.addr = _.last($rootScope.wallet.getReceiveAddresses());
if ($rootScope.wallet && $rootScope.wallet.isComplete()) {
$scope.addr = _.last($rootScope.wallet.getReceiveAddresses());
}
});
}
);
};
});

View file

@ -81,6 +81,8 @@ angular.module('copayApp.controllers').controller('ImportController',
if (err) {
$scope.loading = false;
$scope.error = 'Could not read wallet. Please check your password';
$rootScope.$digest();
return;
}
copay.Compatibility.deleteOldWallet(backupOldWallet);
});

View file

@ -1,7 +1,7 @@
'use strict';
angular.module('copayApp.controllers').controller('JoinController',
function($scope, $rootScope, $timeout, isMobile, notification) {
function($scope, $rootScope, $timeout, isMobile, notification, identityService) {
$rootScope.fromSetup = false;
$scope.loading = false;
$scope.isMobile = isMobile.any();

View file

@ -1,5 +1,5 @@
'use strict';
angular.module('copayApp.controllers').controller('ProfileController', function($scope, $rootScope, $location, $modal, $filter, backupService, identityService) {
angular.module('copayApp.controllers').controller('ProfileController', function($scope, $rootScope, $location, $modal, $filter, $timeout, backupService, identityService) {
$scope.username = $rootScope.iden.getName();
$scope.isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0;
@ -26,11 +26,13 @@ angular.module('copayApp.controllers').controller('ProfileController', function(
});
};
$scope.init = function() {
if ($rootScope.quotaPerItem) {
$scope.perItem = $filter('noFractionNumber')($rootScope.quotaPerItem / 1000, 1);
$scope.nrWallets = parseInt($rootScope.quotaItems) - 1;
}
// no need to add event handlers here. Wallet deletion is handle by callback.
};
$scope.setWallets = function() {
@ -46,8 +48,10 @@ angular.module('copayApp.controllers').controller('ProfileController', function(
w.usage = $filter('noFractionNumber')(bits / max * 100, 0);
}
});
$scope.wallets = wallets;
$timeout(function(){
$scope.$digest();
})
};
$scope.downloadWalletBackup = function(w) {

View file

@ -63,7 +63,19 @@ angular.module('copayApp.controllers').controller('SidebarController', function(
$scope.walletSelection = false;
$scope.setWallets();
});
iden.on('deleteWallet', function() {
iden.on('walletDeleted', function(wid) {
if (wid == $rootScope.wallet.id) {
copay.logger.debug('Deleted focused wallet:', wid);
// new focus
var newWid = $rootScope.iden.getLastFocusedWalletId();
if (newWid && $rootScope.iden.getWalletById(newWid)) {
identityService.setFocusedWallet(newWid);
} else {
copay.logger.debug('No wallets');
identityService.noFocusedWallet(newWid);
}
}
$scope.walletSelection = false;
$scope.setWallets();
});

View file

@ -151,6 +151,7 @@ Identity.prototype.readAndBindWallet = function(walletId, cb) {
var self = this;
self.retrieveWalletFromStorage(walletId, {}, function(error, wallet) {
if (!error) {
self.wallets[wallet.getId()] = wallet;
self.bindWallet(wallet);
}
return cb(error);
@ -386,6 +387,8 @@ Identity.prototype.importWalletFromObj = function(obj, opts, cb) {
log.debug('Updating Indexes for wallet:' + w.getName());
w.updateIndexes(function(err) {
log.debug('Adding wallet to profile:' + w.getName());
self.wallets[w.getId()] = w;
self.updateFocusedTimestamp(w.getId());
self.bindWallet(w);
self.storeWallet(w, cb);
});
@ -471,8 +474,9 @@ Identity.importFromFullJson = function(str, password, opts, cb) {
* @emits newWallet (walletId)
*/
Identity.prototype.bindWallet = function(w) {
preconditions.checkArgument(w && this.wallets[w.getId()]);
var self = this;
self.wallets[w.getId()] = w;
log.debug('Binding wallet:' + w.getName());
w.on('txProposalsUpdated', function() {
@ -569,11 +573,10 @@ Identity.prototype.createWallet = function(opts, cb) {
opts.version = opts.version || this.version;
var self = this;
var w = new walletClass(opts);
self.bindWallet(w);
self.wallets[w.getId()] = w;
self.updateFocusedTimestamp(w.getId());
self.bindWallet(w);
self.storeWallet(w, function(err) {
if (err) return cb(err);
@ -641,7 +644,7 @@ Identity.prototype.deleteWallet = function(walletId, cb) {
this.storage.removeItem(Wallet.getStorageKey(walletId), function(err) {
if (err) return cb(err);
self.emitAndKeepAlive('deletedWallet', walletId);
self.emitAndKeepAlive('walletDeleted', walletId);
self.store(null, cb);
return cb();
});
@ -664,15 +667,16 @@ Identity.prototype.decodeSecret = function(secret) {
* @return {string} walletId
*/
Identity.prototype.getLastFocusedWalletId = function() {
var max = _.max(this.focusedTimestamp);
var aId = _.findKey(this.wallets) || this.walletIds[0];
if (this.walletIds.length == 0) return undefined;
var max = _.max(this.focusedTimestamps);
if (!max)
return aId;
return this.walletIds[0];
return _.findKey(this.focusedTimestamps, function(ts) {
return ts == max;
}) || aId;
}) || this.walletIds[0];
};
Identity.prototype.updateFocusedTimestamp = function(wid) {

View file

@ -125,7 +125,7 @@ Wallet.TX_SIGNED_AND_BROADCASTED = 'txSignedAndBroadcasted';
Wallet.prototype.emitAndKeepAlive = function(args) {
var args = Array.prototype.slice.call(arguments);
log.debug('Wallet:'+ this.getName() + ' Emitting:', args);
log.debug('Wallet:' + this.getName() + ' Emitting:', args);
this.keepAlive();
this.emit.apply(this, arguments);
};
@ -331,14 +331,16 @@ Wallet.prototype._onPublicKeyRing = function(senderId, data) {
return;
}
if (hasChanged) {
if (wasIncomplete) {
this.sendPublicKeyRing();
}
if (this.publicKeyRing.isComplete()) {
this._lockIncomming();
this.emitAndKeepAlive('ready');
} else {
this.emitAndKeepAlive('publicKeyRingUpdated');
}
this.emitAndKeepAlive('publicKeyRingUpdated');
}
};
@ -891,7 +893,7 @@ Wallet.prototype._setupBlockchainHandlers = function() {
self.blockchain.on('tx', function(tx) {
log.debug('Wallet:' + self.id + ' blockchain tx event');
var addresses = self.getAddresses();
if (_.indexOf(addresses,tx.address)>=0) {
if (_.indexOf(addresses, tx.address) >= 0) {
self.emitAndKeepAlive('tx', tx.address, self.addressIsChange(tx.address));
}
});
@ -932,7 +934,7 @@ Wallet.prototype.netStart = function() {
self._setupBlockchainHandlers();
self.netStarted= true;
self.netStarted = true;
if (!this.isShared()) {
self.emitAndKeepAlive('ready');
@ -956,7 +958,7 @@ Wallet.prototype.netStart = function() {
}
log.debug('Wallet:' + self.id + ' Starting network.');
this.network.start(startOpts, function() {
self.emitAndKeepAlive('ready');
self.emitAndKeepAlive(self.isComplete() ? 'ready' : 'waitingCopayers');
});
};
@ -1399,7 +1401,8 @@ Wallet.prototype.getPendingTxProposalsCount = function() {
var txps = this.txProposals.txps;
var maxRejectCount = this.maxRejectCount();
var myId = this.getMyCopayerId();
var pending =0, pendingForUs = 0;
var pending = 0,
pendingForUs = 0;
_.each(txps, function(inTxp, ntxid) {
if (!inTxp.isPending(maxRejectCount))
@ -1407,7 +1410,7 @@ Wallet.prototype.getPendingTxProposalsCount = function() {
pending++;
if (!inTxp.signedBy[myId] && !inTxp.rejectedBy[myId] )
if (!inTxp.signedBy[myId] && !inTxp.rejectedBy[myId])
pendingForUs++
});
@ -1845,9 +1848,8 @@ Wallet.prototype._getPayProRefundOutputs = function(txp) {
var opts = JSON.parse(txp.builder.vanilla.opts);
if (!opts.remainderOut) {
log.warn('no remainder set. Not setting refund in PayPro');
return;
return;
}
console.log('[Wallet.js.1842:builder:]',txp.builder.vanilla.opts); //TODO
var addrStr = opts.remainderOut.address;
var addr = new bitcore.Address(addrStr);
var script = bitcore.Script.createP2SH(addr.payload()).getBuffer();
@ -2032,7 +2034,7 @@ Wallet.prototype.addressIsOwn = function(addrStr) {
/**
* @desc Returns true if a given address is a change address (remainder)
* @param addrStr
* @return {boolean}
* @return {boolean}
*/
Wallet.prototype.addressIsChange = function(addrStr) {
return this.publicKeyRing.addressIsChange(addrStr);
@ -2129,7 +2131,7 @@ Wallet.prototype.getUnspent = function(cb) {
var addresses = this.getAddresses();
log.debug('Wallet ' + this.getName() + ': Getting unspents from ' + addresses.length + ' addresses');
log.debug('Wallet ' + this.getName() + ': Getting unspents from ' + addresses.length + ' addresses');
this.blockchain.getUnspent(addresses, function(err, unspentList) {
if (err) {

View file

@ -126,6 +126,13 @@ angular.module('copayApp.services')
$location.path('/send');
};
root.noFocusedWallet = function() {
$rootScope.wallet = null;
$timeout(function() {
$rootScope.$digest();
})
};
root.setFocusedWallet = function(w, dontUpdateIt) {
if (!_.isObject(w))
w = $rootScope.iden.getWalletById(w);
@ -157,6 +164,11 @@ angular.module('copayApp.services')
notification.error('Error', $filter('translate')('Received corrupt message from ') + peerId);
}
});
w.on('publicKeyRingUpdated', function() {
$rootScope.$digest();
});
w.on('ready', function() {
var isFocused = root.isFocused(wid);
copay.logger.debug('Wallet:' + w.getName() + ' is ready. Focused:', isFocused);
@ -280,13 +292,8 @@ angular.module('copayApp.services')
$rootScope.$digest()
});
iden.on('deletedWallet', function(wid) {
notification.info('Wallet deleted', $filter('translate')('This wallet was deleted'));
if ($rootScope.wallet.id === wid) {
$rootScope.wallet = null;
var lastFocused = iden.getLastFocusedWalletId();
root.setFocusedWallet(lastFocused);
}
iden.on('walletDeleted', function(wid) {
// do nothing. this is handled 'on sync' on controller.
});
iden.on('closed', function() {
@ -307,7 +314,7 @@ angular.module('copayApp.services')
};
root.importWallet = function(encryptedObj, pass, opts, cb) {
copay.Compatibility.importEncryptedWallet($rootScope.iden, encryptedObj, pass, opts);
copay.Compatibility.importEncryptedWallet($rootScope.iden, encryptedObj, pass, opts, cb);
};
root.joinWallet = function(opts, cb) {

37
meeting Normal file
View file

@ -0,0 +1,37 @@
- We have an historical opportunity
- To create the software EVERYONE in the WORLD will use for their finance
- To enhance everyone's life by creating an awesome software
- To colaborate with Bitcoin adoption, by creating a simple and intuite wallet
-
- be obsessive about the UX
- fucking use Copay
- subscribe and read bitcore dev
- Company funds
- Startups
- Middle size companies
- Friends funds
- Own funds
- 1-1 for every day usage
- easy and FAST mobile access
- QR reading
- PayPro
- 2-4 for long term holding
- swipe without need of insight or copay.io
- paper walleting
-
NOT:

19
test-users Normal file
View file

@ -0,0 +1,19 @@
wallet addr: 2N7YdozHPSyDomeov9sU6kL3RdGkZPUaV2v
ematiu+1@gmail.com password: 123
extPubKey: tprv8ZgxMBicQKsPdWNCTqR5zbCTTCLgc4saAQE32LqLWMHmSzFncTdZegFS7CyA8FKQX9kX7FPAJ1scvtkgumYRJ4iAc4pNekm3LzPtikR3C2L
ematiu+2@gmail.com password:2
extPubKey: tprv8ZgxMBicQKsPem5BuuDT6xY9etUC2RohpUoyzoa1MEkkZyAHhszaHPZTmgDheN31hSP1r6bRwpj2JC66r1CPpftwaRrhz9Wz3e9yRVScw9Y
ematiu+3@gmail.com password:3
extPubKey: tprv8ZgxMBicQKsPeQixUQZw1zm2LY6uJqT6oJMStMQHsHkMQDFXwxdomkkFCvMWZbQri3B8mzapiMvREXP85HFKmoUND48yfLEq7AuNCaj41Dw
util/swipeWallet.js n2kMqQ8Si9GndzQ6FrJxcwHMKacK2rCEpK 2 tprv8ZgxMBicQKsPdWNCTqR5zbCTTCLgc4saAQE32LqLWMHmSzFncTdZegFS7CyA8FKQX9kX7FPAJ1scvtkgumYRJ4iAc4pNekm3LzPtikR3C2L tprv8ZgxMBicQKsPem5BuuDT6xY9etUC2RohpUoyzoa1MEkkZyAHhszaHPZTmgDheN31hSP1r6bRwpj2JC66r1CPpftwaRrhz9Wz3e9yRVScw9Y tprv8ZgxMBicQKsPeQixUQZw1zm2LY6uJqT6oJMStMQHsHkMQDFXwxdomkkFCvMWZbQri3B8mzapiMvREXP85HFKmoUND48yfLEq7AuNCaj41Dw
my addr: n2kMqQ8Si9GndzQ6FrJxcwHMKacK2rCEpK

View file

@ -16,7 +16,7 @@ describe('http utils', function() {
send: function() {
var self = this;
setTimeout(function() {
self.response = 'test';
self.response = [1,2,3,4];
self.error ? self.onerror() : self.onload();
}, 10);
},

View file

@ -21,7 +21,7 @@ describe('log utils', function() {
log.warn('hola');
var arg = console.warn.getCall(0).args[0];
arg.should.contain('util.log.js');
//arg.should.contain('util.log.js'); /* Firefox does not include the stack track */
arg.should.contain('hola');
console.warn.restore();
});

View file

@ -116,7 +116,6 @@ var createBundle = function(opts) {
// The following 2 lines fix karma tests
b.require('sjcl');
if (opts.debug) {
//include dev dependencies
b.require('sinon');

View file

@ -1,4 +1,4 @@
<div class="home-wallet" ng-controller="HomeWalletController">
<div class="home-wallet" ng-controller="HomeWalletController" ng-init="init()">
<div class="row hide-for-large-up">
<div class="medium-12 small-12 columns">
<h1 translate>Home</h1>

1
w Normal file
View file

@ -0,0 +1 @@
xprv9s21ZrQH143K3DYCbPDJdFhNDCzChAdsFwz2HFwgtcEufYffAvhZXcJ3XwxjepPJp3FBSHYFnPsxtAzDbSruoRW3rVThyqc2iFKSFw7zhE6