fix order in receive

This commit is contained in:
Matias Alejo Garcia 2014-11-30 03:23:15 -03:00
commit abaf5b8f13
5 changed files with 109 additions and 69 deletions

View file

@ -1,7 +1,7 @@
'use strict';
angular.module('copayApp.controllers').controller('ImportProfileController',
function($scope, $rootScope, $location, notification, isMobile, pluginManager, identityService) {
function($scope, $rootScope, $location, notification, isMobile, identityService) {
$scope.title = 'Import a backup';
$scope.importStatus = 'Importing wallet - Reading backup...';
$scope.hideAdv = true;
@ -18,6 +18,8 @@ angular.module('copayApp.controllers').controller('ImportProfileController',
var password = $scope.password;
updateStatus('Importing profile - Setting things up...');
identityService.importProfile(str,password, function(err){
})
copay.Identity.importFromEncryptedFullJson(str, password, {
pluginManager: pluginManager,
network: config.network,
@ -55,10 +57,8 @@ angular.module('copayApp.controllers').controller('ImportProfileController',
};
$scope.import = function(form) {
$scope.loading = true;
if (form.$invalid) {
$scope.loading = false;
$scope.error = 'Please enter the required fields';
return;
}
@ -67,11 +67,11 @@ angular.module('copayApp.controllers').controller('ImportProfileController',
var password = form.password.$modelValue;
if (!backupFile && !backupText) {
$scope.loading = false;
$scope.error = 'Please, select your backup file';
return;
}
$scope.loading = true;
if (backupFile) {
reader.readAsBinaryString(backupFile);
} else {

View file

@ -5,16 +5,14 @@ angular.module('copayApp.controllers').controller('ReceiveController',
$rootScope.title = 'Receive';
$scope.loading = false;
$scope.showAll = false;
$scope.isNewAddr = false;
$scope.newAddr = function() {
var w = $rootScope.wallet;
$scope.loading = true;
$scope.isNewAddr = false;
w.generateAddress(null);
$scope.setAddressList();
$timeout(function() {
$scope.loading = false;
$scope.isNewAddr = true;
}, 1);
};
@ -39,55 +37,32 @@ angular.module('copayApp.controllers').controller('ReceiveController',
});
};
$rootScope.$watch('addrInfos', function() {
if ($rootScope.updatingBalance) return;
$scope.addressList();
});
$scope.toggleShowAll = function() {
$scope.showAll = !$scope.showAll;
$scope.addressList();
$scope.setAddressList();
};
$scope.limitAddress = function(elements, isNewAddr) {
if(!isNewAddr){
elements = elements.sort(function(a, b) {
return (+a.isChange - +b.isChange);
});
}
if (elements.length <= 1 || $scope.showAll) {
return elements;
}
// Show last 3 non-change addresses plus those with balance
var addrs = elements.filter(function(e, i) {
return (!e.isChange && i < 3) || (e.balance && e.balance > 0);
});
return addrs;
};
$scope.addressList = function() {
$scope.addresses = [];
$scope.setAddressList = function() {
var w = $rootScope.wallet;
var balance = $rootScope.balanceByAddr;
var addresses = w.getAddresses();
var addresses = w.getAddressesOrderer();
if (addresses) {
$scope.addrLength = addresses.length;
if (!$scope.showAll)
addresses = addresses.slice(0,3);
var list = [];
_.each(addresses, function(address, index){
$scope.addresses.push({
list.push({
'index': index,
'address': address,
'balance': balance ? balance[address] : 0,
'isChange': w.addressIsChange(address),
// TODO
'owned': w.addressIsOwn(address),
});
});
$scope.addresses = $scope.limitAddress($scope.addresses, $scope.isNewAddr);
$scope.addresses = list;
}
};
}

View file

@ -49,8 +49,7 @@ function PublicKeyRing(opts) {
PublicKeyRing.prototype.resetCache = function() {
this.cache = {};
this.cache.addressToPath = {};
this.cache.receiveAddresses = [];
this.cache.changeAddresses = [];
this.cache.pathToAddress = {};
// Non persistent cache
this._isChange = {};
@ -110,14 +109,26 @@ PublicKeyRing.fromObj = function(opts) {
pkr.addCopayer(opts.copayersExtPubKeys[k]);
}
if (opts.cache) {
log.debug('PublicKeyRing: Using address cache');
pkr.cache = opts.cache;
if (opts.cache && opts.cache.addressToPath) {
log.info('PublicKeyRing: Using address cache');
pkr.cache.addressToPath = opts.cache.addressToPath;
pkr.rebuildCache();
}
return pkr;
};
PublicKeyRing.prototype.rebuildCache = function() {
if (!this.cache.addressToPath)
return;
var self = this;
_.each(this.cache.addressToPath, function(path, address) {
self.cache.pathToAddress[path] = address;
});
};
PublicKeyRing.fromUntrustedObj = function(opts) {
return PublicKeyRing.fromObj(PublicKeyRing.trim(opts));
};
@ -140,7 +151,11 @@ PublicKeyRing.prototype.toObj = function() {
return b.extendedPublicKeyString();
}),
nicknameFor: this.nicknameFor,
cache: this.cache,
// We only store addressToPath and derive the reset from it
cache: {
addressToPath: this.cache.addressToPath
},
};
};
@ -314,7 +329,7 @@ PublicKeyRing.prototype.getPubKeys = function(index, isChange, copayerIndex) {
log.warn('Slow pubkey derivation...');
var path = HDPath.Branch(index, isChange, copayerIndex);
var pubKeys = _.map(this.copayersHK, function(hdKey) {
return hdKey.derive(path).eckey.public;
return hdKey.derive(path).eckey.public;
});
return pubKeys;
@ -353,6 +368,8 @@ PublicKeyRing.prototype.getRedeemScript = function(index, isChange, copayerIndex
PublicKeyRing.prototype._getAddress = function(index, isChange, id) {
var copayerIndex = this.getCosigner(id);
var path = HDPath.FullBranch(index, isChange, copayerIndex);
if (this.cache.pathToAddress[path])
return this.cache.pathToAddress[path];
log.info('Generating Address:', index, isChange, copayerIndex);
var script = this.getRedeemScript(index, isChange, copayerIndex);
@ -364,10 +381,7 @@ PublicKeyRing.prototype._getAddress = function(index, isChange, id) {
PublicKeyRing.prototype._cacheAddress = function(address, path, isChange) {
this.cache.addressToPath[address] = path;
if (isChange)
this.cache.changeAddresses.push(address);
else
this.cache.receiveAddresses.push(address);
this.cache.pathToAddress[path] = address;
};
/**
@ -397,7 +411,7 @@ PublicKeyRing.prototype.getHDParams = function(id) {
* @return {HDPath}
*/
PublicKeyRing.prototype.pathForAddress = function(address) {
this._checkAndRebuildCache();
this._checkCache();
var path = this.cache.addressToPath[address];
if (!path) throw new Error('Couldn\'t find path for address ' + address);
return path;
@ -439,20 +453,20 @@ PublicKeyRing.prototype.addressIsOwn = function(address) {
* @return {boolean}
*/
PublicKeyRing.prototype.addressIsChange = function(address) {
this._checkAndRebuildCache();
this._checkCache();
if (!this.cache.addressToPath[address])
var path = this.cache.addressToPath[address];
if (!path)
return null;
var p = HDPath.indexesForPath(path);
//Memoization Only, never stored.
if (_.isUndefined(this._isChange[address])) {
this._isChange[address] = _.indexOf(this.cache.changeAddresses, address) >= 0;
}
this._isChange[address] = p.isChange;
return !!this._isChange[address];
};
/**
* @desc
* Maps a copayer's public key to his index in the keyring
@ -497,11 +511,20 @@ PublicKeyRing.prototype.buildAddressCache = function() {
};
PublicKeyRing.prototype._checkAndRebuildCache = function(opts) {
// If cache exists, it has to be updated
PublicKeyRing.prototype.size = function(opts) {
var self = this;
return _.reduce(this.indexes, function(sum, index) {
return sum + index.receiveIndex + index.changeIndex
}, 0);
};
PublicKeyRing.prototype._checkCache = function(opts) {
if (_.isEmpty(this.cache.addressToPath)) {
this.buildAddressCache();
}
if (_.size(this.cache.addressToPath) !== this.size()) {
this.buildAddressCache();
}
};
@ -513,11 +536,39 @@ PublicKeyRing.prototype._checkAndRebuildCache = function(opts) {
* @returns {AddressInfo[]}
*/
PublicKeyRing.prototype.getAddresses = function() {
this._checkAndRebuildCache();
var ret = this.cache.receiveAddresses.concat(this.cache.changeAddresses);
return ret;
this._checkCache();
return _.keys(this.cache.addressToPath);
};
/**
* getAddressesOrderer
* {@link Wallet#getAddressesOrderer}
*
* @param pubkey
* @return {string[]}
*/
PublicKeyRing.prototype.getAddressesOrderer = function(pubkey) {
this._checkCache();
var info = _.map(this.cache.addressToPath, function(path, addr) {
var p = HDPath.indexesForPath(path);
p.address = addr;
return p;
});
var copayerIndex = this.getCosigner(pubkey);
var l = info.length;
var sortedInfo = _.sortBy(info, function(i) {
var goodness = ( (i.copayerIndex !== copayerIndex) ? 2 * l : 0 ) +( i.isChange ? l : 0 ) + l - i.addressIndex;
return goodness;
});
return _.pluck(sortedInfo, 'address');
};
/**
* @desc
* Gets information about addresses for a copayer
@ -526,9 +577,12 @@ PublicKeyRing.prototype.getAddresses = function() {
* @returns {AddressInfo[]}
*/
PublicKeyRing.prototype.getReceiveAddresses = function() {
this._checkAndRebuildCache();
var ret = this.cache.receiveAddresses;
return ret;
this._checkCache();
var self = this;
return _.filter(this.getAddresses(), function(addr) {
return !self.addressIsChange(addr);
});
};

View file

@ -1961,6 +1961,17 @@ Wallet.prototype.getAddresses = function() {
return this.publicKeyRing.getAddresses();
};
/**
* @desc gets the list of addresses, orderder for the caller:
* 1) himselfs first
* 2) receive address first
* 3) last created first
*/
Wallet.prototype.getAddressesOrderer = function() {
return this.publicKeyRing.getAddressesOrderer(this.publicKey);
};
/**
* @desc Alias for {@link PublicKeyRing#getAddresses}
* @return {Buffer[]}

View file

@ -1,4 +1,4 @@
<div class="addresses" ng-controller="ReceiveController">
<div class="addresses" ng-controller="ReceiveController" ng-init="setAddressList()">
<div class="row">
<div class="large-12 medium-12 small-12 columns">
<h1 class="hide-for-large-up">{{$root.title}}</h1>
@ -8,8 +8,8 @@
</div>
</div>
<div class="row">
<div class="large-12 columns" ng-if="!!(addresses|removeEmpty).length">
<div ng-repeat="addr in addresses|removeEmpty|orderBy:'-index':true">
<div class="large-12 columns" ng-if="addresses.length">
<div ng-repeat="addr in addresses">
<div class="panel">
<div class="row show-for-large-up">
<div class="large-7 medium-9 columns">