fix order in receive
This commit is contained in:
parent
1eebaa4e94
commit
abaf5b8f13
5 changed files with 109 additions and 69 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
angular.module('copayApp.controllers').controller('ImportProfileController',
|
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.title = 'Import a backup';
|
||||||
$scope.importStatus = 'Importing wallet - Reading backup...';
|
$scope.importStatus = 'Importing wallet - Reading backup...';
|
||||||
$scope.hideAdv = true;
|
$scope.hideAdv = true;
|
||||||
|
|
@ -18,6 +18,8 @@ angular.module('copayApp.controllers').controller('ImportProfileController',
|
||||||
var password = $scope.password;
|
var password = $scope.password;
|
||||||
updateStatus('Importing profile - Setting things up...');
|
updateStatus('Importing profile - Setting things up...');
|
||||||
|
|
||||||
|
identityService.importProfile(str,password, function(err){
|
||||||
|
})
|
||||||
copay.Identity.importFromEncryptedFullJson(str, password, {
|
copay.Identity.importFromEncryptedFullJson(str, password, {
|
||||||
pluginManager: pluginManager,
|
pluginManager: pluginManager,
|
||||||
network: config.network,
|
network: config.network,
|
||||||
|
|
@ -55,10 +57,8 @@ angular.module('copayApp.controllers').controller('ImportProfileController',
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.import = function(form) {
|
$scope.import = function(form) {
|
||||||
$scope.loading = true;
|
|
||||||
|
|
||||||
if (form.$invalid) {
|
if (form.$invalid) {
|
||||||
$scope.loading = false;
|
|
||||||
$scope.error = 'Please enter the required fields';
|
$scope.error = 'Please enter the required fields';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -67,11 +67,11 @@ angular.module('copayApp.controllers').controller('ImportProfileController',
|
||||||
var password = form.password.$modelValue;
|
var password = form.password.$modelValue;
|
||||||
|
|
||||||
if (!backupFile && !backupText) {
|
if (!backupFile && !backupText) {
|
||||||
$scope.loading = false;
|
|
||||||
$scope.error = 'Please, select your backup file';
|
$scope.error = 'Please, select your backup file';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$scope.loading = true;
|
||||||
if (backupFile) {
|
if (backupFile) {
|
||||||
reader.readAsBinaryString(backupFile);
|
reader.readAsBinaryString(backupFile);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -5,16 +5,14 @@ angular.module('copayApp.controllers').controller('ReceiveController',
|
||||||
$rootScope.title = 'Receive';
|
$rootScope.title = 'Receive';
|
||||||
$scope.loading = false;
|
$scope.loading = false;
|
||||||
$scope.showAll = false;
|
$scope.showAll = false;
|
||||||
$scope.isNewAddr = false;
|
|
||||||
|
|
||||||
$scope.newAddr = function() {
|
$scope.newAddr = function() {
|
||||||
var w = $rootScope.wallet;
|
var w = $rootScope.wallet;
|
||||||
$scope.loading = true;
|
$scope.loading = true;
|
||||||
$scope.isNewAddr = false;
|
|
||||||
w.generateAddress(null);
|
w.generateAddress(null);
|
||||||
|
$scope.setAddressList();
|
||||||
$timeout(function() {
|
$timeout(function() {
|
||||||
$scope.loading = false;
|
$scope.loading = false;
|
||||||
$scope.isNewAddr = true;
|
|
||||||
}, 1);
|
}, 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.toggleShowAll = function() {
|
||||||
$scope.showAll = !$scope.showAll;
|
$scope.showAll = !$scope.showAll;
|
||||||
$scope.addressList();
|
$scope.setAddressList();
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.limitAddress = function(elements, isNewAddr) {
|
$scope.setAddressList = function() {
|
||||||
|
|
||||||
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 = [];
|
|
||||||
var w = $rootScope.wallet;
|
var w = $rootScope.wallet;
|
||||||
var balance = $rootScope.balanceByAddr;
|
var balance = $rootScope.balanceByAddr;
|
||||||
|
|
||||||
var addresses = w.getAddresses();
|
var addresses = w.getAddressesOrderer();
|
||||||
if (addresses) {
|
if (addresses) {
|
||||||
$scope.addrLength = addresses.length;
|
$scope.addrLength = addresses.length;
|
||||||
|
|
||||||
|
if (!$scope.showAll)
|
||||||
|
addresses = addresses.slice(0,3);
|
||||||
|
|
||||||
|
var list = [];
|
||||||
_.each(addresses, function(address, index){
|
_.each(addresses, function(address, index){
|
||||||
$scope.addresses.push({
|
list.push({
|
||||||
'index': index,
|
'index': index,
|
||||||
'address': address,
|
'address': address,
|
||||||
'balance': balance ? balance[address] : 0,
|
'balance': balance ? balance[address] : 0,
|
||||||
'isChange': w.addressIsChange(address),
|
'isChange': w.addressIsChange(address),
|
||||||
// TODO
|
|
||||||
'owned': w.addressIsOwn(address),
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
$scope.addresses = $scope.limitAddress($scope.addresses, $scope.isNewAddr);
|
$scope.addresses = list;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,8 +49,7 @@ function PublicKeyRing(opts) {
|
||||||
PublicKeyRing.prototype.resetCache = function() {
|
PublicKeyRing.prototype.resetCache = function() {
|
||||||
this.cache = {};
|
this.cache = {};
|
||||||
this.cache.addressToPath = {};
|
this.cache.addressToPath = {};
|
||||||
this.cache.receiveAddresses = [];
|
this.cache.pathToAddress = {};
|
||||||
this.cache.changeAddresses = [];
|
|
||||||
|
|
||||||
// Non persistent cache
|
// Non persistent cache
|
||||||
this._isChange = {};
|
this._isChange = {};
|
||||||
|
|
@ -110,14 +109,26 @@ PublicKeyRing.fromObj = function(opts) {
|
||||||
pkr.addCopayer(opts.copayersExtPubKeys[k]);
|
pkr.addCopayer(opts.copayersExtPubKeys[k]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opts.cache) {
|
if (opts.cache && opts.cache.addressToPath) {
|
||||||
log.debug('PublicKeyRing: Using address cache');
|
log.info('PublicKeyRing: Using address cache');
|
||||||
pkr.cache = opts.cache;
|
pkr.cache.addressToPath = opts.cache.addressToPath;
|
||||||
|
pkr.rebuildCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
return pkr;
|
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) {
|
PublicKeyRing.fromUntrustedObj = function(opts) {
|
||||||
return PublicKeyRing.fromObj(PublicKeyRing.trim(opts));
|
return PublicKeyRing.fromObj(PublicKeyRing.trim(opts));
|
||||||
};
|
};
|
||||||
|
|
@ -140,7 +151,11 @@ PublicKeyRing.prototype.toObj = function() {
|
||||||
return b.extendedPublicKeyString();
|
return b.extendedPublicKeyString();
|
||||||
}),
|
}),
|
||||||
nicknameFor: this.nicknameFor,
|
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...');
|
log.warn('Slow pubkey derivation...');
|
||||||
var path = HDPath.Branch(index, isChange, copayerIndex);
|
var path = HDPath.Branch(index, isChange, copayerIndex);
|
||||||
var pubKeys = _.map(this.copayersHK, function(hdKey) {
|
var pubKeys = _.map(this.copayersHK, function(hdKey) {
|
||||||
return hdKey.derive(path).eckey.public;
|
return hdKey.derive(path).eckey.public;
|
||||||
});
|
});
|
||||||
|
|
||||||
return pubKeys;
|
return pubKeys;
|
||||||
|
|
@ -353,6 +368,8 @@ PublicKeyRing.prototype.getRedeemScript = function(index, isChange, copayerIndex
|
||||||
PublicKeyRing.prototype._getAddress = function(index, isChange, id) {
|
PublicKeyRing.prototype._getAddress = function(index, isChange, id) {
|
||||||
var copayerIndex = this.getCosigner(id);
|
var copayerIndex = this.getCosigner(id);
|
||||||
var path = HDPath.FullBranch(index, isChange, copayerIndex);
|
var path = HDPath.FullBranch(index, isChange, copayerIndex);
|
||||||
|
if (this.cache.pathToAddress[path])
|
||||||
|
return this.cache.pathToAddress[path];
|
||||||
|
|
||||||
log.info('Generating Address:', index, isChange, copayerIndex);
|
log.info('Generating Address:', index, isChange, copayerIndex);
|
||||||
var script = this.getRedeemScript(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) {
|
PublicKeyRing.prototype._cacheAddress = function(address, path, isChange) {
|
||||||
this.cache.addressToPath[address] = path;
|
this.cache.addressToPath[address] = path;
|
||||||
if (isChange)
|
this.cache.pathToAddress[path] = address;
|
||||||
this.cache.changeAddresses.push(address);
|
|
||||||
else
|
|
||||||
this.cache.receiveAddresses.push(address);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -397,7 +411,7 @@ PublicKeyRing.prototype.getHDParams = function(id) {
|
||||||
* @return {HDPath}
|
* @return {HDPath}
|
||||||
*/
|
*/
|
||||||
PublicKeyRing.prototype.pathForAddress = function(address) {
|
PublicKeyRing.prototype.pathForAddress = function(address) {
|
||||||
this._checkAndRebuildCache();
|
this._checkCache();
|
||||||
var path = this.cache.addressToPath[address];
|
var path = this.cache.addressToPath[address];
|
||||||
if (!path) throw new Error('Couldn\'t find path for address ' + address);
|
if (!path) throw new Error('Couldn\'t find path for address ' + address);
|
||||||
return path;
|
return path;
|
||||||
|
|
@ -439,20 +453,20 @@ PublicKeyRing.prototype.addressIsOwn = function(address) {
|
||||||
* @return {boolean}
|
* @return {boolean}
|
||||||
*/
|
*/
|
||||||
PublicKeyRing.prototype.addressIsChange = function(address) {
|
PublicKeyRing.prototype.addressIsChange = function(address) {
|
||||||
this._checkAndRebuildCache();
|
this._checkCache();
|
||||||
|
|
||||||
if (!this.cache.addressToPath[address])
|
var path = this.cache.addressToPath[address];
|
||||||
|
if (!path)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
var p = HDPath.indexesForPath(path);
|
||||||
|
|
||||||
//Memoization Only, never stored.
|
//Memoization Only, never stored.
|
||||||
if (_.isUndefined(this._isChange[address])) {
|
this._isChange[address] = p.isChange;
|
||||||
this._isChange[address] = _.indexOf(this.cache.changeAddresses, address) >= 0;
|
|
||||||
}
|
|
||||||
return !!this._isChange[address];
|
return !!this._isChange[address];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @desc
|
* @desc
|
||||||
* Maps a copayer's public key to his index in the keyring
|
* 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) {
|
PublicKeyRing.prototype.size = function(opts) {
|
||||||
// If cache exists, it has to be updated
|
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)) {
|
if (_.isEmpty(this.cache.addressToPath)) {
|
||||||
this.buildAddressCache();
|
this.buildAddressCache();
|
||||||
}
|
}
|
||||||
|
if (_.size(this.cache.addressToPath) !== this.size()) {
|
||||||
|
this.buildAddressCache();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -513,11 +536,39 @@ PublicKeyRing.prototype._checkAndRebuildCache = function(opts) {
|
||||||
* @returns {AddressInfo[]}
|
* @returns {AddressInfo[]}
|
||||||
*/
|
*/
|
||||||
PublicKeyRing.prototype.getAddresses = function() {
|
PublicKeyRing.prototype.getAddresses = function() {
|
||||||
this._checkAndRebuildCache();
|
this._checkCache();
|
||||||
var ret = this.cache.receiveAddresses.concat(this.cache.changeAddresses);
|
return _.keys(this.cache.addressToPath);
|
||||||
return ret;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
* @desc
|
||||||
* Gets information about addresses for a copayer
|
* Gets information about addresses for a copayer
|
||||||
|
|
@ -526,9 +577,12 @@ PublicKeyRing.prototype.getAddresses = function() {
|
||||||
* @returns {AddressInfo[]}
|
* @returns {AddressInfo[]}
|
||||||
*/
|
*/
|
||||||
PublicKeyRing.prototype.getReceiveAddresses = function() {
|
PublicKeyRing.prototype.getReceiveAddresses = function() {
|
||||||
this._checkAndRebuildCache();
|
this._checkCache();
|
||||||
var ret = this.cache.receiveAddresses;
|
|
||||||
return ret;
|
var self = this;
|
||||||
|
return _.filter(this.getAddresses(), function(addr) {
|
||||||
|
return !self.addressIsChange(addr);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1961,6 +1961,17 @@ Wallet.prototype.getAddresses = function() {
|
||||||
return this.publicKeyRing.getAddresses();
|
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}
|
* @desc Alias for {@link PublicKeyRing#getAddresses}
|
||||||
* @return {Buffer[]}
|
* @return {Buffer[]}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
<div class="addresses" ng-controller="ReceiveController">
|
<div class="addresses" ng-controller="ReceiveController" ng-init="setAddressList()">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="large-12 medium-12 small-12 columns">
|
<div class="large-12 medium-12 small-12 columns">
|
||||||
<h1 class="hide-for-large-up">{{$root.title}}</h1>
|
<h1 class="hide-for-large-up">{{$root.title}}</h1>
|
||||||
|
|
@ -8,8 +8,8 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="large-12 columns" ng-if="!!(addresses|removeEmpty).length">
|
<div class="large-12 columns" ng-if="addresses.length">
|
||||||
<div ng-repeat="addr in addresses|removeEmpty|orderBy:'-index':true">
|
<div ng-repeat="addr in addresses">
|
||||||
<div class="panel">
|
<div class="panel">
|
||||||
<div class="row show-for-large-up">
|
<div class="row show-for-large-up">
|
||||||
<div class="large-7 medium-9 columns">
|
<div class="large-7 medium-9 columns">
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue