mirror of https://github.com/BTCPrivate/copay.git
balances working
This commit is contained in:
parent
601fa94fde
commit
9f039d8c34
|
@ -1,20 +1,20 @@
|
|||
|
||||
<span ng-show="index.isShared" class="size-12"><span translate>{{index.m}}-of-{{index.n}}</span></span>
|
||||
<span ng-show="index.isSingleAddress" class="size-12"><span translate>Auditable</span></span>
|
||||
<img style="height:0.6em; margin-right: 1px;" ng-show="index.network != 'livenet'" src="img/icon-testnet-white.svg">
|
||||
<img style="height:0.6em; margin-right: 1px;" ng-show="!index.canSign && !index.isPrivKeyExternal"
|
||||
<span ng-show="wallet.isShared" class="size-12"><span translate>{{wallet.m}}-of-{{wallet.n}}</span></span>
|
||||
<span ng-show="wallet.isSingleAddress" class="size-12"><span translate>Auditable</span></span>
|
||||
<img style="height:0.6em; margin-right: 1px;" ng-show="wallet.network != 'livenet'" src="img/icon-testnet-white.svg">
|
||||
<img style="height:0.6em; margin-right: 1px;" ng-show="!wallet.canSign() && !wallet.isPrivKeyExternal()"
|
||||
src="img/icon-read-only-white.svg">
|
||||
|
||||
<img style="height:0.6em; margin-right: 1px;" ng-show="index.externalSource == 'trezor'"
|
||||
<img style="height:0.6em; margin-right: 1px;" ng-show="wallet.getPrivKeyExternalSourceName() == 'trezor'"
|
||||
src="img/icon-trezor-white.svg">
|
||||
<img style="height:0.6em; margin-right: 1px;" ng-show="index.externalSource == 'ledger'"
|
||||
<img style="height:0.6em; margin-right: 1px;" ng-show="wallet.getPrivKeyExternalSourceName() == 'ledger'"
|
||||
src="img/icon-ledger-white.svg">
|
||||
<span class="size-12 dib" style="height:0.6em; margin-right: 1px;" ng-show="index.account">#{{index.account || 0}} </span>
|
||||
<span class="size-12 dib" style="height:0.6em; margin-right: 1px;" ng-show="wallet.account">#{{wallet.account || 0}} </span>
|
||||
|
||||
<img style="height:0.6em; margin-right: 1px;" ng-show="index.isPrivKeyEncrypted" src="img/icon-lock-white.svg">
|
||||
<img style="height:0.6em; margin-right: 1px;" ng-show="wallet.isPrivKeyEncrypted()" src="img/icon-lock-white.svg">
|
||||
|
||||
<!-- <img style="height:1em" ng-show="index.preferences.email" src="img/icon-email.svg"> -->
|
||||
<img style="height:0.6em; margin-right: 1px;" ng-show="index.usingCustomBWS" src="img/icon-bws-white.svg">
|
||||
<!-- <img style="height:1em" ng-show="wallet.preferences.email" src="img/icon-email.svg"> -->
|
||||
<img style="height:0.6em; margin-right: 1px;" ng-show="wallet.usingCustomBWS" src="img/icon-bws-white.svg">
|
||||
|
||||
<img style="height:0.6em" class="animated flash infinite" ng-show="index.loadingWallet ||
|
||||
<img style="height:0.6em" class="animated flash infinite" ng-show="wallet.loadingWallet ||
|
||||
index.updatingTxHistory" src="img/icon-sync-white.svg">
|
||||
|
|
|
@ -1,19 +1,25 @@
|
|||
|
||||
<ion-view view-title="Home">
|
||||
<ion-content class="padding home" ng-controller="tabHomeController">
|
||||
<a href="#/add"><i class="ion-ios-plus-outline right"></i></a>
|
||||
<h2>Wallets </h2>
|
||||
<a href="#/add">+</a>
|
||||
<div class="list card">
|
||||
<ul class="pr">
|
||||
|
||||
<li ng-show="wallets[0]"
|
||||
ng-repeat="item in wallets track by $index" class="item item-icon-left"
|
||||
menu-toggle href ui-sref="walletHome" on-tap="openWallet(item.id, index.walletId)">
|
||||
menu-toggle href ui-sref="walletDetails({'walletId': item.id})">
|
||||
<i class="icon icon-wallet size-21" ng-style="{'color':item.color}"></i>
|
||||
{{item.name || item.id}}
|
||||
<span class="item-note" ng-show="item.n > 1">
|
||||
{{item.m}}-of-{{item.n}}
|
||||
<span ng-show="item.n > 1">
|
||||
[ {{item.m}}-of-{{item.n}} ]
|
||||
</span>
|
||||
|
||||
<span class="item-note">
|
||||
{{item.availableBalanceStr}}
|
||||
</span>
|
||||
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,230 @@
|
|||
|
||||
<div ng-controller="walletDetailsController">
|
||||
|
||||
|
||||
<div class="onGoingProcess" ng-show="wallet.updating">
|
||||
<div class="onGoingProcess-content" ng-style="{'background-color':wallet.color}">
|
||||
<div class="spinner">
|
||||
<div class="rect1"></div>
|
||||
<div class="rect2"></div>
|
||||
<div class="rect3"></div>
|
||||
<div class="rect4"></div>
|
||||
<div class="rect5"></div>
|
||||
</div>
|
||||
<span translate>Updating Wallet...</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="oh">
|
||||
|
||||
<div id="walletHome" class="walletHome">
|
||||
<ion-content delegate-handle="my-handle" overflow-scroll="true">
|
||||
<div class="oh pr">
|
||||
<div ng-style="{'background-color':wallet.color}" class="amount">
|
||||
<div ng-if="!wallet.notAuthorized && !wallet.updating">
|
||||
|
||||
<div class="size-14 m10b" ng-if="wallet.totalBalanceAlternative">{{wallet.name}}</div>
|
||||
|
||||
<div class="m15t" ng-show="wallet.updateError" ng-click='update()'>
|
||||
<span class="size-12 db m10b">{{wallet.updateError|translate}}</span>
|
||||
<button class="outline white tiny round" translate>Tap to retry</button>
|
||||
</div>
|
||||
|
||||
<div ng-show="wallet.walletScanStatus == 'error'" ng-click='wallet.retryScan()'>
|
||||
<span translate>Scan status finished with error</span>
|
||||
<br><span translate>Tap to retry</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div ng-click='wallet.updateAll({triggerTxUpdate: true})' ng-show="!wallet.updateError && wallet.walletScanStatus != 'error' && !wallet.hideBalance" on-hold="hideToggle()">
|
||||
<strong class="size-36">{{wallet.totalBalanceStr}}</strong>
|
||||
<div class="size-14" ng-if="wallet.totalBalanceAlternative">{{wallet.totalBalanceAlternative}} {{wallet.alternativeIsoCode}}</div>
|
||||
<div class="size-14" ng-if="wallet.pendingAmount">
|
||||
<span translate>Pending Confirmation</span>: {{wallet.pendingAmountStr}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-show="!wallet.updateError && wallet.walletScanStatus != 'error' && wallet.shouldHideBalance" on-hold="wallet.hideToggle()">
|
||||
<strong class="size-24" translate>[Balance Hidden]</strong>
|
||||
<div class="size-14" translate>
|
||||
Tap and hold to show
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-if="wallet.updating">
|
||||
<div class="size-36">
|
||||
<strong>...</strong>
|
||||
</div>
|
||||
</div>
|
||||
</div> <!-- amount -->
|
||||
|
||||
<div class="wallet-info">
|
||||
<span ng-include="'views/includes/walletInfo.html'"></span>
|
||||
</div>
|
||||
</div> <!-- oh -->
|
||||
|
||||
<div class="p60b">
|
||||
<div class="oh pr m20t" ng-show="wallet.incorrectDerivation">
|
||||
<div class="text-center text-warning">
|
||||
<i class="fi-alert"></i>
|
||||
<span translate>
|
||||
WARNING: Key derivation is not working on this device/wallet. Actions cannot be performed on this wallet.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="oh pr m20t" ng-show="wallet.notAuthorized && !wallet.updating">
|
||||
<div class="text-center text-warning">
|
||||
<i class="fi-alert"></i>
|
||||
<span translate>
|
||||
WARNING: Wallet not registered
|
||||
</span>
|
||||
</div>
|
||||
<div class="text-center text-gray m15r m15l" translate>
|
||||
This wallet is not registered at the given Bitcore Wallet Service (BWS). You can recreate it from the local information.
|
||||
</div>
|
||||
<div class="text-center m10t ">
|
||||
<span class="button outline round dark-gray tiny"
|
||||
ng-click="wallet.recreate()">
|
||||
<span translate>Recreate</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="release size-12" ng-show="newRelease" ng-click="$root.openExternalLink('https://github.com/bitpay/copay/releases/latest')">
|
||||
<span>{{newRelease}}</span><i class="icon-arrow-right3 right size-18"></i>
|
||||
</div>
|
||||
|
||||
<div ng-if="wallet.txps[0]">
|
||||
<h4 ng-show="wallet.requiresMultipleSignatures" class="title m0" translate>Payment Proposals</h4>
|
||||
<h4 ng-show="!wallet.requiresMultipleSignatures" class="title m0" translate>Unsent transactions</h4>
|
||||
<div ng-repeat="tx in wallet.txps">
|
||||
<div ng-include="wallet.txTemplateUrl"></div>
|
||||
</div>
|
||||
|
||||
<div class="text-gray text-center size-12 p10t"
|
||||
ng-show="wallet.lockedBalanceSat">
|
||||
<span translate>Total Locked Balance</span>:
|
||||
<b>{{wallet.lockedBalanceStr}} </b>
|
||||
<span> {{wallet.lockedBalanceAlternative}}
|
||||
{{wallet.alternativeIsoCode}} </span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Activity -->
|
||||
|
||||
<h4 class="title" ng-click="wallet.startSearch(); openSearchModal()" ng-show="!wallet.notAuthorized">
|
||||
<span translate>Activity</span>
|
||||
<i class="dib m5l size-16 pointer fi-magnifying-glass"></i>
|
||||
</h4>
|
||||
|
||||
<div class="oh pr m20t text-gray size-12 text-center"
|
||||
ng-show="!wallet.loadingWallet && !wallet.txHistory[0] && !wallet.updatingTxHistory && !wallet.txHistoryError && !wallet.updateError && !wallet.notAuthorized"
|
||||
translate>No transactions yet ZZZZ {{wallet.totalBalanceStr}}
|
||||
</div>
|
||||
|
||||
<div class="oh pr" ng-show="(wallet.txHistory[0] || wallet.txProgress > 5) && !wallet.notAuthorized">
|
||||
|
||||
<div ng-show="wallet.updatingTxHistory && wallet.txProgress > 5">
|
||||
<div class="row p20 text-center">
|
||||
<div class="columns large-12 medium-12 small-12 m10b">
|
||||
<ion-spinner class="spinner-dark" icon="lines"></ion-spinner>
|
||||
</div>
|
||||
<div class="size-12 text-gray m20t">
|
||||
<div translate>{{wallet.txProgress}} transactions downloaded</div>
|
||||
<div translate>Updating transaction history. Please stand by.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-if="wallet.txHistory[0] && wallet.updatingTxHistory && wallet.newTx" class="row collapse last-transactions-content animated fadeInDown">
|
||||
<div class="large-6 medium-6 small-6 columns size-14">
|
||||
<div class="m10r left">
|
||||
<img src="img/icon-new.svg" width="40">
|
||||
</div>
|
||||
<div class="m10t" style="background:#eee; width: 8em; margin-left: 52px; line-height:0.6em">
|
||||
<span> </span>
|
||||
</div>
|
||||
<div style="margin-top:5px; background:#eee; width: 6em; margin-left: 52px; line-height:0.6em">
|
||||
<span> </span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-repeat="btx in wallet.txHistory track by btx.txid"
|
||||
ng-click="openTxModal(btx)"
|
||||
class="row collapse last-transactions-content">
|
||||
<div class="large-6 medium-6 small-6 columns size-14">
|
||||
<div class="m10r left">
|
||||
<img src="img/icon-receive-history.svg" alt="sync" width="40" ng-show="btx.action == 'received'">
|
||||
<img src="img/icon-sent-history.svg" alt="sync" width="40" ng-show="btx.action == 'sent'">
|
||||
<img src="img/icon-moved.svg" alt="sync" width="40" ng-show="btx.action == 'moved'">
|
||||
</div>
|
||||
<div class="m10t">
|
||||
<span ng-show="btx.action == 'received'">
|
||||
<span class="ellipsis">
|
||||
<span ng-if="btx.note.body">{{btx.note.body}}</span>
|
||||
<span ng-if="!btx.note.body" translate> Received</span>
|
||||
</span>
|
||||
</span>
|
||||
<span ng-show="btx.action == 'sent'">
|
||||
<span class="ellipsis">
|
||||
<span ng-if="btx.message">{{btx.message}}</span>
|
||||
<span ng-if="!btx.message && btx.note.body">{{btx.note.body}}</span>
|
||||
<span ng-if="!btx.message && !btx.note.body && wallet.addressbook[btx.addressTo]">{{wallet.addressbook[btx.addressTo]}}</span>
|
||||
<span ng-if="!btx.message && !btx.note.body && !wallet.addressbook[btx.addressTo]" translate> Sent</span>
|
||||
</span>
|
||||
</span>
|
||||
<span ng-show="btx.action == 'moved'">
|
||||
<span class="ellipsis">
|
||||
<span ng-if="btx.note.body">{{btx.note.body}}</span>
|
||||
<span ng-if="!btx.note.body" translate>Moved</span>
|
||||
</span>
|
||||
|
||||
</span>
|
||||
<span class="label tu warning radius" ng-show="btx.action == 'invalid'" translate>Invalid</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="large-5 medium-5 small-5 columns text-right" >
|
||||
<span class="size-16" ng-class="{'text-bold': btx.recent}">
|
||||
<span ng-if="btx.action == 'received'">+</span>
|
||||
<span ng-if="btx.action == 'sent'">-</span>
|
||||
<span class="size-12" ng-if="btx.action == 'invalid'" translate>
|
||||
(possible double spend)
|
||||
</span>
|
||||
<span ng-if="btx.action != 'invalid'">
|
||||
{{btx.amountStr}}
|
||||
</span>
|
||||
</span>
|
||||
<div class="size-12 text-gray">
|
||||
<time ng-if="btx.time">{{btx.time * 1000 | amTimeAgo}}</time>
|
||||
<span translate class="text-warning"
|
||||
ng-show="!btx.time && (!btx.confirmations || btx.confirmations == 0)">
|
||||
Unconfirmed
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="large-1 medium-1 small-1 columns text-right m10t">
|
||||
<i class="icon-arrow-right3 size-18"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row m20t text-center" ng-show="wallet.historyRendering && !wallet.ching">
|
||||
<div class="columns large-12 medium-12 small-12">
|
||||
<ion-spinner class="spinner-stable" icon="lines"></ion-spinner>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ion-infinite-scroll
|
||||
ng-if="historyShowMore"
|
||||
on-infinite="showMore()"
|
||||
distance="1%">
|
||||
</ion-infinite-scroll>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</ion-content>
|
||||
<div class="extra-margin-bottom"></div>
|
||||
</div> <!-- END WalletHome -->
|
||||
</div>
|
||||
</div>
|
|
@ -20,34 +20,13 @@ angular.module('copayApp.controllers').controller('tabHomeController',
|
|||
});
|
||||
|
||||
self.setWallets = function() {
|
||||
if (!profileService.profile) return;
|
||||
|
||||
var config = configService.getSync();
|
||||
config.colorFor = config.colorFor || {};
|
||||
config.aliasFor = config.aliasFor || {};
|
||||
|
||||
// Sanitize empty wallets (fixed in BWC 1.8.1, and auto fixed when wallets completes)
|
||||
var credentials = lodash.filter(profileService.profile.credentials, 'walletName');
|
||||
var ret = lodash.map(credentials, function(c) {
|
||||
return {
|
||||
m: c.m,
|
||||
n: c.n,
|
||||
name: config.aliasFor[c.walletId] || c.walletName,
|
||||
id: c.walletId,
|
||||
color: config.colorFor[c.walletId] || '#4A90E2',
|
||||
};
|
||||
});
|
||||
|
||||
$scope.wallets = lodash.sortBy(ret, 'name');
|
||||
$scope.wallets = profileService.getWallets();
|
||||
};
|
||||
|
||||
self.updateAllClients = function() {
|
||||
lodash.each(profileService.getClients(), function(client) {
|
||||
walletService.updateStatus(client, {}, function(err, status) {
|
||||
if (err)
|
||||
console.log('[tab-home.js.47]', err); //TODO
|
||||
console.log('[tab-home.js.47:console:]',status); //TODO
|
||||
|
||||
|
||||
lodash.each(profileService.getWallets(), function(wallet) {
|
||||
walletService.updateStatus(wallet, {}, function(err, status) {
|
||||
if (err) {} // TODO
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -55,7 +34,4 @@ console.log('[tab-home.js.47:console:]',status); //TODO
|
|||
self.setWallets();
|
||||
self.updateAllClients();
|
||||
$scope.bitpayCardEnabled = true; // TODO
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('copayApp.controllers').controller('walletDetailsController', function($scope, $rootScope, $interval, $timeout, $filter, $log, $ionicModal, $ionicPopover, $stateParams, profileService, lodash, configService, gettext, gettextCatalog, platformInfo, go, walletService ) {
|
||||
|
||||
|
||||
console.log('[walletDetails.js.5]', $stateParams); //TODO
|
||||
var isCordova = platformInfo.isCordova;
|
||||
var isWP = platformInfo.isWP;
|
||||
var isAndroid = platformInfo.isAndroid;
|
||||
var isChromeApp = platformInfo.isChromeApp;
|
||||
|
||||
var self = this;
|
||||
$rootScope.shouldHideMenuBar = false;
|
||||
$rootScope.wpInputFocused = false;
|
||||
var config = configService.getSync();
|
||||
var configWallet = config.wallet;
|
||||
var walletSettings = configWallet.settings;
|
||||
var ret = {};
|
||||
|
||||
// INIT. Global value
|
||||
ret.unitToSatoshi = walletSettings.unitToSatoshi;
|
||||
ret.satToUnit = 1 / ret.unitToSatoshi;
|
||||
ret.unitName = walletSettings.unitName;
|
||||
ret.alternativeIsoCode = walletSettings.alternativeIsoCode;
|
||||
ret.alternativeName = walletSettings.alternativeName;
|
||||
ret.alternativeAmount = 0;
|
||||
ret.unitDecimals = walletSettings.unitDecimals;
|
||||
ret.isCordova = isCordova;
|
||||
ret.addresses = [];
|
||||
ret.isMobile = platformInfo.isMobile;
|
||||
ret.isWindowsPhoneApp = platformInfo.isWP;
|
||||
ret.countDown = null;
|
||||
ret.sendMaxInfo = {};
|
||||
ret.showAlternative = false;
|
||||
|
||||
$scope.openSearchModal = function() {
|
||||
var fc = profileService.focusedClient;
|
||||
$scope.color = fc.backgroundColor;
|
||||
$scope.self = self;
|
||||
|
||||
$ionicModal.fromTemplateUrl('views/modals/search.html', {
|
||||
scope: $scope,
|
||||
focusFirstInput: true
|
||||
}).then(function(modal) {
|
||||
$scope.searchModal = modal;
|
||||
$scope.searchModal.show();
|
||||
});
|
||||
};
|
||||
|
||||
this.openTxModal = function(btx) {
|
||||
var self = this;
|
||||
|
||||
$scope.btx = lodash.cloneDeep(btx);
|
||||
$scope.self = self;
|
||||
|
||||
$ionicModal.fromTemplateUrl('views/modals/tx-details.html', {
|
||||
scope: $scope,
|
||||
hideDelay: 500
|
||||
}).then(function(modal) {
|
||||
$scope.txDetailsModal = modal;
|
||||
$scope.txDetailsModal.show();
|
||||
});
|
||||
};
|
||||
|
||||
$scope.update = function() {
|
||||
console.log('[walletDetails.js.65:update:] TODO'); //TODO
|
||||
// {triggerTxUpdate: true}
|
||||
};
|
||||
|
||||
$scope.hideToggle = function() {
|
||||
console.log('[walletDetails.js.70:hideToogle:] TODO'); //TODO
|
||||
};
|
||||
$scope.wallet = profileService.getWallet($stateParams.walletId);
|
||||
|
||||
console.log('[walletDetails.js.66]',$scope.wallet); //TODO
|
||||
});
|
|
@ -14,7 +14,7 @@ if (window && window.navigator) {
|
|||
|
||||
//Setting up route
|
||||
angular.module('copayApp').config(function(historicLogProvider, $provide, $logProvider, $stateProvider, $urlRouterProvider, $compileProvider) {
|
||||
$urlRouterProvider.otherwise('/');
|
||||
$urlRouterProvider.otherwise('/tabs');
|
||||
|
||||
$logProvider.debugEnabled(true);
|
||||
$provide.decorator('$log', ['$delegate', 'platformInfo',
|
||||
|
@ -93,8 +93,20 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
|
|||
}
|
||||
}
|
||||
})
|
||||
.state('walletDetails', {
|
||||
url: '/details',
|
||||
needProfile: true,
|
||||
views: {
|
||||
'main': {
|
||||
templateUrl: 'views/walletDetails.html',
|
||||
},
|
||||
},
|
||||
params: {
|
||||
walletId: null,
|
||||
},
|
||||
})
|
||||
.state('walletHome', {
|
||||
url: '/',
|
||||
url: '/old',
|
||||
needProfile: true,
|
||||
views: {
|
||||
'main': {
|
||||
|
|
|
@ -3,82 +3,5 @@
|
|||
angular.module('copayApp.services')
|
||||
.factory('addressService', function(storageService, profileService, $log, $timeout, lodash, bwcError, gettextCatalog) {
|
||||
var root = {};
|
||||
|
||||
root.expireAddress = function(walletId, cb) {
|
||||
$log.debug('Cleaning Address ' + walletId);
|
||||
storageService.clearLastAddress(walletId, function(err) {
|
||||
return cb(err);
|
||||
});
|
||||
};
|
||||
|
||||
root.isUsed = function(walletId, byAddress, cb) {
|
||||
storageService.getLastAddress(walletId, function(err, addr) {
|
||||
var used = lodash.find(byAddress, {
|
||||
address: addr
|
||||
});
|
||||
return cb(null, used);
|
||||
});
|
||||
};
|
||||
|
||||
root._createAddress = function(walletId, cb) {
|
||||
var client = profileService.getClient(walletId);
|
||||
|
||||
$log.debug('Creating address for wallet:', walletId);
|
||||
|
||||
client.createAddress({}, function(err, addr) {
|
||||
if (err) {
|
||||
var prefix = gettextCatalog.getString('Could not create address');
|
||||
if (err.error && err.error.match(/locked/gi)) {
|
||||
$log.debug(err.error);
|
||||
return $timeout(function() {
|
||||
root._createAddress(walletId, cb);
|
||||
}, 5000);
|
||||
} else if (err.message && err.message == 'MAIN_ADDRESS_GAP_REACHED') {
|
||||
$log.warn(err.message);
|
||||
prefix = null;
|
||||
client.getMainAddresses({
|
||||
reverse: true,
|
||||
limit: 1
|
||||
}, function(err, addr) {
|
||||
if (err) return cb(err);
|
||||
return cb(null, addr[0].address);
|
||||
});
|
||||
}
|
||||
return bwcError.cb(err, prefix, cb);
|
||||
}
|
||||
return cb(null, addr.address);
|
||||
});
|
||||
};
|
||||
|
||||
root.getAddress = function(walletId, forceNew, cb) {
|
||||
|
||||
var firstStep;
|
||||
if (forceNew) {
|
||||
firstStep = storageService.clearLastAddress;
|
||||
} else {
|
||||
firstStep = function(walletId, cb) {
|
||||
return cb();
|
||||
};
|
||||
}
|
||||
|
||||
firstStep(walletId, function(err) {
|
||||
if (err) return cb(err);
|
||||
|
||||
storageService.getLastAddress(walletId, function(err, addr) {
|
||||
if (err) return cb(err);
|
||||
|
||||
if (addr) return cb(null, addr);
|
||||
|
||||
root._createAddress(walletId, function(err, addr) {
|
||||
if (err) return cb(err);
|
||||
storageService.storeLastAddress(walletId, addr, function() {
|
||||
if (err) return cb(err);
|
||||
return cb(null, addr);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
return root;
|
||||
});
|
||||
|
|
|
@ -17,31 +17,19 @@ angular.module('copayApp.services')
|
|||
|
||||
root.profile = null;
|
||||
root.focusedClient = null;
|
||||
root.walletClients = {};
|
||||
|
||||
root.Utils = bwcService.getUtils();
|
||||
root.formatAmount = function(amount, fullPrecision) {
|
||||
var config = configService.getSync().wallet.settings;
|
||||
if (config.unitCode == 'sat') return amount;
|
||||
|
||||
//TODO : now only works for english, specify opts to change thousand separator and decimal separator
|
||||
var opts = {
|
||||
fullPrecision: !!fullPrecision
|
||||
};
|
||||
return this.Utils.formatAmount(amount, config.unitCode, opts);
|
||||
};
|
||||
root.wallet = {}; // decorated version of client
|
||||
|
||||
root._setFocus = function(walletId, cb) {
|
||||
$log.debug('Set focus:', walletId);
|
||||
|
||||
// Set local object
|
||||
if (walletId)
|
||||
root.focusedClient = root.walletClients[walletId];
|
||||
root.focusedClient = root.wallet[walletId];
|
||||
else
|
||||
root.focusedClient = [];
|
||||
|
||||
if (lodash.isEmpty(root.focusedClient)) {
|
||||
root.focusedClient = root.walletClients[lodash.keys(root.walletClients)[0]];
|
||||
root.focusedClient = root.wallet[lodash.keys(root.wallet)[0]];
|
||||
}
|
||||
|
||||
// Still nothing?
|
||||
|
@ -51,7 +39,7 @@ angular.module('copayApp.services')
|
|||
$rootScope.$emit('Local/NewFocusedWallet');
|
||||
|
||||
// Set update period
|
||||
lodash.each(root.walletClients, function(client, id) {
|
||||
lodash.each(root.wallet, function(client, id) {
|
||||
client.setNotificationsInterval(BACKGROUND_UPDATE_PERIOD);
|
||||
});
|
||||
root.focusedClient.setNotificationsInterval(FOREGROUND_UPDATE_PERIOD);
|
||||
|
@ -66,18 +54,37 @@ angular.module('copayApp.services')
|
|||
});
|
||||
};
|
||||
|
||||
root.setCustomBWSFlag = function(wallet) {
|
||||
var defaults = configService.getDefaults();
|
||||
var config = configService.getSync();
|
||||
|
||||
wallet.usingCustomBWS = config.bwsFor && config.bwsFor[wallet.id] && (config.bwsFor[wallet.id] != defaults.bws.url);
|
||||
};
|
||||
|
||||
// Adds a wallet client to profileService
|
||||
root.bindWalletClient = function(client, opts) {
|
||||
var opts = opts || {};
|
||||
var walletId = client.credentials.walletId;
|
||||
var config = configService.getSync();
|
||||
config.colorFor = config.colorFor || {};
|
||||
config.aliasFor = config.aliasFor || {};
|
||||
|
||||
if ((root.walletClients[walletId] && root.walletClients[walletId].started) || opts.force) {
|
||||
|
||||
if ((root.wallet[walletId] && root.wallet[walletId].started) || opts.force) {
|
||||
return false;
|
||||
}
|
||||
|
||||
root.walletClients[walletId] = client;
|
||||
root.walletClients[walletId].started = true;
|
||||
root.walletClients[walletId].doNotVerifyPayPro = isChromeApp;
|
||||
// INIT WALLET CLIENT VIEWMODEL
|
||||
var c = client;
|
||||
c.id = walletId;
|
||||
c.started = true;
|
||||
c.doNotVerifyPayPro = isChromeApp;
|
||||
c.name = config.aliasFor[walletId] || client.credentials.walletName;
|
||||
c.color = config.colorFor[walletId] || '#4A90E2';
|
||||
c.network = client.credentials.network;
|
||||
root.setCustomBWSFlag(c);
|
||||
|
||||
root.wallet[walletId] = c;
|
||||
|
||||
client.removeAllListeners();
|
||||
client.on('report', function(n) {
|
||||
|
@ -162,7 +169,7 @@ angular.module('copayApp.services')
|
|||
|
||||
// Used when reading wallets from the profile
|
||||
root.bindWallet = function(credentials, cb) {
|
||||
if (!credentials.walletId)
|
||||
if (!credentials.walletId || !credentials.m)
|
||||
return cb('bindWallet should receive credentials JSON');
|
||||
|
||||
|
||||
|
@ -239,7 +246,7 @@ angular.module('copayApp.services')
|
|||
|
||||
root.pushNotificationsInit = function() {
|
||||
var defaults = configService.getDefaults();
|
||||
var push = pushNotificationsService.init(root.walletClients);
|
||||
var push = pushNotificationsService.init(root.wallet);
|
||||
|
||||
push.on('notification', function(data) {
|
||||
if (!data.additionalData.foreground) {
|
||||
|
@ -431,14 +438,15 @@ angular.module('copayApp.services')
|
|||
});
|
||||
};
|
||||
|
||||
root.getClient = function(walletId) {
|
||||
return root.walletClients[walletId];
|
||||
root.getWallet = function(walletId) {
|
||||
return root.wallet[walletId];
|
||||
};
|
||||
|
||||
|
||||
root.deleteWalletClient = function(client, cb) {
|
||||
var walletId = client.credentials.walletId;
|
||||
|
||||
pushNotificationsService.unsubscribe(root.getClient(walletId), function(err) {
|
||||
pushNotificationsService.unsubscribe(root.getWallet(walletId), function(err) {
|
||||
if (err) $log.warn('Unsubscription error: ' + err.message);
|
||||
else $log.debug('Unsubscribed from push notifications service');
|
||||
});
|
||||
|
@ -448,7 +456,7 @@ angular.module('copayApp.services')
|
|||
|
||||
root.profile.deleteWallet(walletId);
|
||||
|
||||
delete root.walletClients[walletId];
|
||||
delete root.wallet[walletId];
|
||||
root.focusedClient = null;
|
||||
|
||||
|
||||
|
@ -529,7 +537,7 @@ angular.module('copayApp.services')
|
|||
storageService.storeProfile(root.profile, function(err) {
|
||||
var config = configService.getSync();
|
||||
if (config.pushNotifications.enabled)
|
||||
pushNotificationsService.enableNotifications(root.walletClients);
|
||||
pushNotificationsService.enableNotifications(root.wallet);
|
||||
return cb(err, walletId);
|
||||
});
|
||||
|
||||
|
@ -705,8 +713,22 @@ angular.module('copayApp.services')
|
|||
storageService.storeProfile(root.profile, cb);
|
||||
};
|
||||
|
||||
root.getClients = function() {
|
||||
return lodash.values(root.walletClients);
|
||||
root.getWallets = function(network, n) {
|
||||
var ret = lodash.values(root.wallet);
|
||||
|
||||
if (network) {
|
||||
ret = lodash.filter(ret, function(x) {
|
||||
return (x.credentials.network == network);
|
||||
});
|
||||
}
|
||||
|
||||
if (n) {
|
||||
ret = lodash.filter(ret, function(w) {
|
||||
return (w.credentials.n == n);
|
||||
});
|
||||
}
|
||||
|
||||
return lodash.sortBy(ret, 'name');
|
||||
};
|
||||
|
||||
root.needsBackup = function(client, cb) {
|
||||
|
@ -732,36 +754,5 @@ angular.module('copayApp.services')
|
|||
});
|
||||
};
|
||||
|
||||
root.getWallets = function(network, n) {
|
||||
if (!root.profile) return [];
|
||||
|
||||
var config = configService.getSync();
|
||||
config.colorFor = config.colorFor || {};
|
||||
config.aliasFor = config.aliasFor || {};
|
||||
var ret = lodash.map(root.profile.credentials, function(c) {
|
||||
return {
|
||||
m: c.m,
|
||||
n: c.n,
|
||||
name: config.aliasFor[c.walletId] || c.walletName,
|
||||
id: c.walletId,
|
||||
network: c.network,
|
||||
color: config.colorFor[c.walletId] || '#4A90E2',
|
||||
copayerId: c.copayerId
|
||||
};
|
||||
});
|
||||
if (network) {
|
||||
ret = lodash.filter(ret, function(w) {
|
||||
return (w.network == network);
|
||||
});
|
||||
}
|
||||
if (n) {
|
||||
ret = lodash.filter(ret, function(w) {
|
||||
return (w.n == n);
|
||||
});
|
||||
}
|
||||
|
||||
return lodash.sortBy(ret, 'name');
|
||||
};
|
||||
|
||||
return root;
|
||||
});
|
||||
|
|
|
@ -1,15 +1,42 @@
|
|||
'use strict';
|
||||
|
||||
// DO NOT INCLUDE STORAGE HERE \/ \/
|
||||
angular.module('copayApp.services').factory('walletService', function($log, $timeout, lodash, trezor, ledger, storageService, configService, uxLanguage) {
|
||||
angular.module('copayApp.services').factory('walletService', function($log, $timeout, lodash, trezor, ledger, storageService, configService, rateService, uxLanguage, bwcService, $filter) {
|
||||
// DO NOT INCLUDE STORAGE HERE ^^
|
||||
//
|
||||
//
|
||||
// `wallet` is a decorated version of client.
|
||||
|
||||
var root = {};
|
||||
|
||||
var _signWithLedger = function(client, txp, cb) {
|
||||
|
||||
// // RECEIVE
|
||||
// // Check address
|
||||
// root.isUsed(wallet.walletId, balance.byAddress, function(err, used) {
|
||||
// if (used) {
|
||||
// $log.debug('Address used. Creating new');
|
||||
// $rootScope.$emit('Local/AddressIsUsed');
|
||||
// }
|
||||
// });
|
||||
//
|
||||
|
||||
root.Utils = bwcService.getUtils();
|
||||
root.formatAmount = function(amount, fullPrecision) {
|
||||
var config = configService.getSync().wallet.settings;
|
||||
if (config.unitCode == 'sat') return amount;
|
||||
|
||||
//TODO : now only works for english, specify opts to change thousand separator and decimal separator
|
||||
var opts = {
|
||||
fullPrecision: !!fullPrecision
|
||||
};
|
||||
return this.Utils.formatAmount(amount, config.unitCode, opts);
|
||||
};
|
||||
|
||||
|
||||
var _signWithLedger = function(wallet, txp, cb) {
|
||||
$log.info('Requesting Ledger Chrome app to sign the transaction');
|
||||
|
||||
ledger.signTx(txp, client.credentials.account, function(result) {
|
||||
ledger.signTx(txp, wallet.credentials.account, function(result) {
|
||||
$log.debug('Ledger response', result);
|
||||
if (!result.success)
|
||||
return cb(result.message || result.error);
|
||||
|
@ -17,27 +44,27 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
txp.signatures = lodash.map(result.signatures, function(s) {
|
||||
return s.substring(0, s.length - 2);
|
||||
});
|
||||
return client.signTxProposal(txp, cb);
|
||||
return wallet.signTxProposal(txp, cb);
|
||||
});
|
||||
};
|
||||
|
||||
var _signWithTrezor = function(client, txp, cb) {
|
||||
var _signWithTrezor = function(wallet, txp, cb) {
|
||||
$log.info('Requesting Trezor to sign the transaction');
|
||||
|
||||
var xPubKeys = lodash.pluck(client.credentials.publicKeyRing, 'xPubKey');
|
||||
trezor.signTx(xPubKeys, txp, client.credentials.account, function(err, result) {
|
||||
var xPubKeys = lodash.pluck(wallet.credentials.publicKeyRing, 'xPubKey');
|
||||
trezor.signTx(xPubKeys, txp, wallet.credentials.account, function(err, result) {
|
||||
if (err) return cb(err);
|
||||
|
||||
$log.debug('Trezor response', result);
|
||||
txp.signatures = result.signatures;
|
||||
return client.signTxProposal(txp, cb);
|
||||
return wallet.signTxProposal(txp, cb);
|
||||
});
|
||||
};
|
||||
|
||||
root.needsBackup = function(client) {
|
||||
if (client.isPrivKeyExternal()) return false;
|
||||
if (!client.credentials.mnemonic) return false;
|
||||
if (client.credentials.network == 'testnet') return false;
|
||||
root.needsBackup = function(wallet) {
|
||||
if (wallet.isPrivKeyExternal()) return false;
|
||||
if (!wallet.credentials.mnemonic) return false;
|
||||
if (wallet.credentials.network == 'testnet') return false;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
@ -58,10 +85,10 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
// trigger from async events (like updates).
|
||||
// Debounce function avoids multiple popups
|
||||
var _handleError = function(err) {
|
||||
$log.warn('Client ERROR: ', err);
|
||||
$log.warn('wallet ERROR: ', err);
|
||||
|
||||
$log.warn('TODO');
|
||||
return ; // TODO!!!
|
||||
return; // TODO!!!
|
||||
if (err instanceof errors.NOT_AUTHORIZED) {
|
||||
self.notAuthorized = true;
|
||||
go.walletHome();
|
||||
|
@ -76,14 +103,83 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
};
|
||||
root.handleError = lodash.debounce(_handleError, 1000);
|
||||
|
||||
// emits
|
||||
// statusUpdated walletId, err ,statusObj
|
||||
//
|
||||
root.updateStatus = function(client, opts, cb, initStatusHash, tries) {
|
||||
|
||||
root.setBalance = function(wallet, balance) {
|
||||
if (!balance) return;
|
||||
|
||||
var config = configService.getSync().wallet.settings;
|
||||
var COIN = 1e8;
|
||||
|
||||
// Address with Balance
|
||||
wallet.balanceByAddress = balance.byAddress;
|
||||
|
||||
// Spend unconfirmed funds
|
||||
if (wallet.spendUnconfirmed) {
|
||||
wallet.totalBalanceSat = balance.totalAmount;
|
||||
wallet.lockedBalanceSat = balance.lockedAmount;
|
||||
wallet.availableBalanceSat = balance.availableAmount;
|
||||
wallet.totalBytesToSendMax = balance.totalBytesToSendMax;
|
||||
wallet.pendingAmount = null;
|
||||
} else {
|
||||
wallet.totalBalanceSat = balance.totalConfirmedAmount;
|
||||
wallet.lockedBalanceSat = balance.lockedConfirmedAmount;
|
||||
wallet.availableBalanceSat = balance.availableConfirmedAmount;
|
||||
wallet.totalBytesToSendMax = balance.totalBytesToSendConfirmedMax;
|
||||
wallet.pendingAmount = balance.totalAmount - balance.totalConfirmedAmount;
|
||||
}
|
||||
|
||||
// Selected unit
|
||||
wallet.unitToSatoshi = config.unitToSatoshi;
|
||||
wallet.satToUnit = 1 / wallet.unitToSatoshi;
|
||||
wallet.unitName = config.unitName;
|
||||
|
||||
//STR
|
||||
wallet.totalBalanceStr = root.formatAmount(wallet.totalBalanceSat) + ' ' + wallet.unitName;
|
||||
wallet.lockedBalanceStr = root.formatAmount(wallet.lockedBalanceSat) + ' ' + wallet.unitName;
|
||||
wallet.availableBalanceStr = root.formatAmount(wallet.availableBalanceSat) + ' ' + wallet.unitName;
|
||||
|
||||
if (wallet.pendingAmount) {
|
||||
wallet.pendingAmountStr = root.formatAmount(wallet.pendingAmount) + ' ' + wallet.unitName;
|
||||
} else {
|
||||
wallet.pendingAmountStr = null;
|
||||
}
|
||||
|
||||
wallet.alternativeName = config.alternativeName;
|
||||
wallet.alternativeIsoCode = config.alternativeIsoCode;
|
||||
|
||||
rateService.whenAvailable(function() {
|
||||
|
||||
var totalBalanceAlternative = rateService.toFiat(wallet.totalBalanceSat, wallet.alternativeIsoCode);
|
||||
var lockedBalanceAlternative = rateService.toFiat(wallet.lockedBalanceSat, wallet.alternativeIsoCode);
|
||||
var alternativeConversionRate = rateService.toFiat(100000000, wallet.alternativeIsoCode);
|
||||
|
||||
wallet.totalBalanceAlternative = $filter('formatFiatAmount')(totalBalanceAlternative);
|
||||
wallet.lockedBalanceAlternative = $filter('formatFiatAmount')(lockedBalanceAlternative);
|
||||
wallet.alternativeConversionRate = $filter('formatFiatAmount')(alternativeConversionRate);
|
||||
|
||||
wallet.alternativeBalanceAvailable = true;
|
||||
wallet.isRateAvailable = true;
|
||||
});
|
||||
};
|
||||
|
||||
root.setStatus = function(wallet, status) {
|
||||
|
||||
wallet.status = status;
|
||||
wallet.statusUpdatedOn = Date.now();
|
||||
wallet.isValid = true;
|
||||
root.setBalance(wallet, status.balance);
|
||||
|
||||
};
|
||||
|
||||
root.updateStatus = function(wallet, opts, cb, initStatusHash, tries) {
|
||||
tries = tries || 0;
|
||||
opts = opts || {};
|
||||
|
||||
var walletId = client.credentials.walletId
|
||||
if (wallet.isValid && ! opts.force)
|
||||
return;
|
||||
|
||||
|
||||
var walletId = wallet.id;
|
||||
|
||||
if (opts.untilItChanges && lodash.isUndefined(initStatusHash)) {
|
||||
initStatusHash = _walletStatusHash();
|
||||
|
@ -94,7 +190,7 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
if (opts.walletStatus)
|
||||
return cb(null, opts.walletStatus);
|
||||
else {
|
||||
return client.getStatus({
|
||||
return wallet.getStatus({
|
||||
twoStep: true
|
||||
}, function(err, ret) {
|
||||
if (err)
|
||||
|
@ -102,7 +198,7 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
// TODO??
|
||||
// self.isSingleAddress = !!ret.wallet.singleAddress;
|
||||
// self.updating = ret.wallet.scanStatus == 'running';
|
||||
return cb(err);
|
||||
return cb(null, ret);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -117,16 +213,16 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
$timeout(function() {
|
||||
|
||||
// if (!opts.quiet)
|
||||
// self.updating = true;
|
||||
// self.updating = true;
|
||||
|
||||
$log.debug('Updating Status:', client.credentials.walletName, tries);
|
||||
$log.debug('Updating Status:', wallet.credentials.walletName, tries);
|
||||
get(function(err, walletStatus) {
|
||||
var currentStatusHash = _walletStatusHash(walletStatus);
|
||||
$log.debug('Status update. hash:' + currentStatusHash + ' Try:' + tries);
|
||||
if (!err && opts.untilItChanges && initStatusHash == currentStatusHash && tries < 7 && walletId == profileService.focusedClient.credentials.walletId) {
|
||||
return $timeout(function() {
|
||||
$log.debug('Retrying update... ' + walletId + ' Try:' + tries)
|
||||
return root.updateStatus(client, {
|
||||
return root.updateStatus(wallet, {
|
||||
walletStatus: null,
|
||||
untilItChanges: true,
|
||||
triggerTxUpdate: opts.triggerTxUpdate,
|
||||
|
@ -138,8 +234,9 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
root.handleError(err);
|
||||
return cb(err);
|
||||
}
|
||||
$log.debug('Got Wallet Status for:' + wallet.credentials.walletName);
|
||||
|
||||
$log.debug('Wallet Status:' + client.credentials.walletName, walletStatus);
|
||||
root.setStatus(wallet, walletStatus);
|
||||
|
||||
// self.setPendingTxps(walletStatus.pendingTxps);
|
||||
//
|
||||
|
@ -160,11 +257,11 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
|
||||
// TODO
|
||||
if (opts.triggerTxUpdate && opts.untilItChanges) {
|
||||
$timeout(function() {
|
||||
root.debounceUpdateHistory();
|
||||
}, 1);
|
||||
$timeout(function() {
|
||||
root.debounceUpdateHistory();
|
||||
}, 1);
|
||||
}
|
||||
return cb(null, walletStatus);
|
||||
return cb();
|
||||
// } else {
|
||||
// self.loadingWallet = false;
|
||||
// }
|
||||
|
@ -192,10 +289,10 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
});
|
||||
};
|
||||
|
||||
var getTxsFromServer = function(client, skip, endingTxid, limit, cb) {
|
||||
var getTxsFromServer = function(wallet, skip, endingTxid, limit, cb) {
|
||||
var res = [];
|
||||
|
||||
client.getTxHistory({
|
||||
wallet.getTxHistory({
|
||||
skip: skip,
|
||||
limit: limit
|
||||
}, function(err, txsFromServer) {
|
||||
|
@ -213,11 +310,11 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
};
|
||||
|
||||
|
||||
var updateLocalTxHistory = function(client, cb) {
|
||||
var updateLocalTxHistory = function(wallet, cb) {
|
||||
var FIRST_LIMIT = 5;
|
||||
var LIMIT = 50;
|
||||
var requestLimit = FIRST_LIMIT;
|
||||
var walletId = client.credentials.walletId;
|
||||
var walletId = wallet.credentials.walletId;
|
||||
var config = configService.getSync().wallet.settings;
|
||||
|
||||
var fixTxsUnit = function(txs) {
|
||||
|
@ -233,8 +330,8 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
$log.debug('Fixing Tx Cache Unit to:' + name)
|
||||
lodash.each(txs, function(tx) {
|
||||
|
||||
tx.amountStr = profileService.formatAmount(tx.amount) + name;
|
||||
tx.feeStr = profileService.formatAmount(tx.fees) + name;
|
||||
tx.amountStr = root.formatAmount(tx.amount) + name;
|
||||
tx.feeStr = root.formatAmount(tx.fees) + name;
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -260,7 +357,7 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
historyUpdateInProgress[walletId] = true;
|
||||
|
||||
function getNewTxs(newTxs, skip, i_cb) {
|
||||
getTxsFromServer(client, skip, endingTxid, requestLimit, function(err, res, shouldContinue) {
|
||||
getTxsFromServer(wallet, skip, endingTxid, requestLimit, function(err, res, shouldContinue) {
|
||||
if (err) return i_cb(err);
|
||||
|
||||
newTxs = newTxs.concat(lodash.compact(res));
|
||||
|
@ -306,7 +403,7 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
if (!endingTs) return cb2();
|
||||
|
||||
$log.debug('Syncing notes from: ' + endingTs);
|
||||
client.getTxNotes({
|
||||
wallet.getTxNotes({
|
||||
minTs: endingTs
|
||||
}, function(err, notes) {
|
||||
if (err) {
|
||||
|
@ -352,10 +449,10 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
};
|
||||
|
||||
|
||||
root.updateHistory = function(client) {
|
||||
var walletId = client.credentials.walletId;
|
||||
root.updateHistory = function(wallet) {
|
||||
var walletId = wallet.credentials.walletId;
|
||||
|
||||
if (!client.isComplete()) return;
|
||||
if (!wallet.isComplete()) return;
|
||||
|
||||
|
||||
$log.debug('Updating Transaction History');
|
||||
|
@ -363,7 +460,7 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
self.updatingTxHistory = true;
|
||||
|
||||
$timeout(function() {
|
||||
updateLocalTxHistory(client, function(err) {
|
||||
updateLocalTxHistory(wallet, function(err) {
|
||||
historyUpdateInProgress[walletId] = self.updatingTxHistory = false;
|
||||
self.loadingWallet = false;
|
||||
self.txProgress = 0;
|
||||
|
@ -382,45 +479,45 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
|
||||
|
||||
|
||||
root.isEncrypted = function(client) {
|
||||
if (lodash.isEmpty(client)) return;
|
||||
var isEncrypted = client.isPrivKeyEncrypted();
|
||||
root.isEncrypted = function(wallet) {
|
||||
if (lodash.isEmpty(wallet)) return;
|
||||
var isEncrypted = wallet.isPrivKeyEncrypted();
|
||||
if (isEncrypted) $log.debug('Wallet is encrypted');
|
||||
return isEncrypted;
|
||||
};
|
||||
|
||||
root.lock = function(client) {
|
||||
root.lock = function(wallet) {
|
||||
try {
|
||||
client.lock();
|
||||
wallet.lock();
|
||||
} catch (e) {
|
||||
$log.warn('Encrypting wallet:', e);
|
||||
};
|
||||
};
|
||||
|
||||
root.unlock = function(client, password) {
|
||||
if (lodash.isEmpty(client))
|
||||
root.unlock = function(wallet, password) {
|
||||
if (lodash.isEmpty(wallet))
|
||||
return 'MISSING_PARAMETER';
|
||||
if (lodash.isEmpty(password))
|
||||
return 'NO_PASSWORD_GIVEN';
|
||||
try {
|
||||
client.unlock(password);
|
||||
wallet.unlock(password);
|
||||
} catch (e) {
|
||||
$log.warn('Decrypting wallet:', e);
|
||||
return 'PASSWORD_INCORRECT';
|
||||
}
|
||||
};
|
||||
|
||||
root.createTx = function(client, txp, cb) {
|
||||
if (lodash.isEmpty(txp) || lodash.isEmpty(client))
|
||||
root.createTx = function(wallet, txp, cb) {
|
||||
if (lodash.isEmpty(txp) || lodash.isEmpty(wallet))
|
||||
return cb('MISSING_PARAMETER');
|
||||
|
||||
if (txp.sendMax) {
|
||||
client.createTxProposal(txp, function(err, createdTxp) {
|
||||
wallet.createTxProposal(txp, function(err, createdTxp) {
|
||||
if (err) return cb(err);
|
||||
else return cb(null, createdTxp);
|
||||
});
|
||||
} else {
|
||||
client.getFeeLevels(client.credentials.network, function(err, levels) {
|
||||
wallet.getFeeLevels(wallet.credentials.network, function(err, levels) {
|
||||
if (err) return cb(err);
|
||||
|
||||
var feeLevelValue = lodash.find(levels, {
|
||||
|
@ -435,7 +532,7 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
$log.debug('Dynamic fee: ' + txp.feeLevel + ' ' + feeLevelValue.feePerKB + ' SAT');
|
||||
|
||||
txp.feePerKb = feeLevelValue.feePerKB;
|
||||
client.createTxProposal(txp, function(err, createdTxp) {
|
||||
wallet.createTxProposal(txp, function(err, createdTxp) {
|
||||
if (err) return cb(err);
|
||||
else {
|
||||
$log.debug('Transaction created');
|
||||
|
@ -446,11 +543,11 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
}
|
||||
};
|
||||
|
||||
root.publishTx = function(client, txp, cb) {
|
||||
if (lodash.isEmpty(txp) || lodash.isEmpty(client))
|
||||
root.publishTx = function(wallet, txp, cb) {
|
||||
if (lodash.isEmpty(txp) || lodash.isEmpty(wallet))
|
||||
return cb('MISSING_PARAMETER');
|
||||
|
||||
client.publishTxProposal({
|
||||
wallet.publishTxProposal({
|
||||
txp: txp
|
||||
}, function(err, publishedTx) {
|
||||
if (err) return cb(err);
|
||||
|
@ -461,25 +558,25 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
});
|
||||
};
|
||||
|
||||
root.signTx = function(client, txp, cb) {
|
||||
if (lodash.isEmpty(txp) || lodash.isEmpty(client))
|
||||
root.signTx = function(wallet, txp, cb) {
|
||||
if (lodash.isEmpty(txp) || lodash.isEmpty(wallet))
|
||||
return cb('MISSING_PARAMETER');
|
||||
|
||||
if (client.isPrivKeyExternal()) {
|
||||
switch (client.getPrivKeyExternalSourceName()) {
|
||||
if (wallet.isPrivKeyExternal()) {
|
||||
switch (wallet.getPrivKeyExternalSourceName()) {
|
||||
case 'ledger':
|
||||
return _signWithLedger(client, txp, cb);
|
||||
return _signWithLedger(wallet, txp, cb);
|
||||
case 'trezor':
|
||||
return _signWithTrezor(client, txp, cb);
|
||||
return _signWithTrezor(wallet, txp, cb);
|
||||
default:
|
||||
var msg = 'Unsupported External Key:' + client.getPrivKeyExternalSourceName();
|
||||
var msg = 'Unsupported External Key:' + wallet.getPrivKeyExternalSourceName();
|
||||
$log.error(msg);
|
||||
return cb(msg);
|
||||
}
|
||||
} else {
|
||||
|
||||
try {
|
||||
client.signTxProposal(txp, function(err, signedTxp) {
|
||||
wallet.signTxProposal(txp, function(err, signedTxp) {
|
||||
$log.debug('Transaction signed');
|
||||
return cb(err, signedTxp);
|
||||
});
|
||||
|
@ -490,14 +587,14 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
}
|
||||
};
|
||||
|
||||
root.broadcastTx = function(client, txp, cb) {
|
||||
if (lodash.isEmpty(txp) || lodash.isEmpty(client))
|
||||
root.broadcastTx = function(wallet, txp, cb) {
|
||||
if (lodash.isEmpty(txp) || lodash.isEmpty(wallet))
|
||||
return cb('MISSING_PARAMETER');
|
||||
|
||||
if (txp.status != 'accepted')
|
||||
return cb('TX_NOT_ACCEPTED');
|
||||
|
||||
client.broadcastTxProposal(txp, function(err, broadcastedTxp, memo) {
|
||||
wallet.broadcastTxProposal(txp, function(err, broadcastedTxp, memo) {
|
||||
if (err)
|
||||
return cb(err);
|
||||
|
||||
|
@ -508,21 +605,21 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
});
|
||||
};
|
||||
|
||||
root.rejectTx = function(client, txp, cb) {
|
||||
if (lodash.isEmpty(txp) || lodash.isEmpty(client))
|
||||
root.rejectTx = function(wallet, txp, cb) {
|
||||
if (lodash.isEmpty(txp) || lodash.isEmpty(wallet))
|
||||
return cb('MISSING_PARAMETER');
|
||||
|
||||
client.rejectTxProposal(txp, null, function(err, rejectedTxp) {
|
||||
wallet.rejectTxProposal(txp, null, function(err, rejectedTxp) {
|
||||
$log.debug('Transaction rejected');
|
||||
return cb(err, rejectedTxp);
|
||||
});
|
||||
};
|
||||
|
||||
root.removeTx = function(client, txp, cb) {
|
||||
if (lodash.isEmpty(txp) || lodash.isEmpty(client))
|
||||
root.removeTx = function(wallet, txp, cb) {
|
||||
if (lodash.isEmpty(txp) || lodash.isEmpty(wallet))
|
||||
return cb('MISSING_PARAMETER');
|
||||
|
||||
client.removeTxProposal(txp, function(err) {
|
||||
wallet.removeTxProposal(txp, function(err) {
|
||||
$log.debug('Transaction removed');
|
||||
return cb(err);
|
||||
});
|
||||
|
@ -535,11 +632,11 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
clients = [clients];
|
||||
|
||||
function updateRemotePreferencesFor(clients, prefs, cb) {
|
||||
var client = clients.shift();
|
||||
if (!client) return cb();
|
||||
$log.debug('Saving remote preferences', client.credentials.walletName, prefs);
|
||||
var wallet = clients.shift();
|
||||
if (!wallet) return cb();
|
||||
$log.debug('Saving remote preferences', wallet.credentials.walletName, prefs);
|
||||
|
||||
client.savePreferences(prefs, function(err) {
|
||||
wallet.savePreferences(prefs, function(err) {
|
||||
// we ignore errors here
|
||||
if (err) $log.warn(err);
|
||||
|
||||
|
@ -603,9 +700,9 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
});
|
||||
};
|
||||
|
||||
root.recreate = function(client, cb) {
|
||||
root.recreate = function(wallet, cb) {
|
||||
ongoingProcess.set('recreating', true);
|
||||
client.recreateWallet(function(err) {
|
||||
wallet.recreateWallet(function(err) {
|
||||
self.notAuthorized = false;
|
||||
ongoingProcess.set('recreating', false);
|
||||
|
||||
|
@ -615,20 +712,20 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
return;
|
||||
}
|
||||
|
||||
profileService.bindWalletClient(client, {
|
||||
profileService.bindWalletClient(wallet, {
|
||||
force: true
|
||||
});
|
||||
self.startScan(client);
|
||||
self.startScan(wallet);
|
||||
});
|
||||
};
|
||||
|
||||
root.startScan = function(client) {
|
||||
$log.debug('Scanning wallet ' + client.credentials.walletId);
|
||||
if (!client.isComplete()) return;
|
||||
root.startScan = function(wallet) {
|
||||
$log.debug('Scanning wallet ' + wallet.credentials.walletId);
|
||||
if (!wallet.isComplete()) return;
|
||||
|
||||
// self.updating = true;
|
||||
// self.updating = true;
|
||||
|
||||
client.startScan({
|
||||
wallet.startScan({
|
||||
includeCopayerBranches: true,
|
||||
}, function(err) {
|
||||
|
||||
|
@ -642,6 +739,80 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
};
|
||||
|
||||
|
||||
root.expireAddress = function(wallet, cb) {
|
||||
$log.debug('Cleaning Address ' + wallet.id);
|
||||
storageService.clearLastAddress(wallet.id, function(err) {
|
||||
return cb(err);
|
||||
});
|
||||
};
|
||||
|
||||
root.isUsed = function(wallet, byAddress, cb) {
|
||||
storageService.getLastAddress(wallet.id, function(err, addr) {
|
||||
var used = lodash.find(byAddress, {
|
||||
address: addr
|
||||
});
|
||||
return cb(null, used);
|
||||
});
|
||||
};
|
||||
|
||||
root._createAddress = function(wallet, cb) {
|
||||
$log.debug('Creating address for wallet:', wallet.id);
|
||||
|
||||
wallet.createAddress({}, function(err, addr) {
|
||||
if (err) {
|
||||
var prefix = gettextCatalog.getString('Could not create address');
|
||||
if (err.error && err.error.match(/locked/gi)) {
|
||||
$log.debug(err.error);
|
||||
return $timeout(function() {
|
||||
root._createAddress(walletId, cb);
|
||||
}, 5000);
|
||||
} else if (err.message && err.message == 'MAIN_ADDRESS_GAP_REACHED') {
|
||||
$log.warn(err.message);
|
||||
prefix = null;
|
||||
wallet.getMainAddresses({
|
||||
reverse: true,
|
||||
limit: 1
|
||||
}, function(err, addr) {
|
||||
if (err) return cb(err);
|
||||
return cb(null, addr[0].address);
|
||||
});
|
||||
}
|
||||
return bwcError.cb(err, prefix, cb);
|
||||
}
|
||||
return cb(null, addr.address);
|
||||
});
|
||||
};
|
||||
|
||||
root.getAddress = function(wallet, forceNew, cb) {
|
||||
|
||||
var firstStep;
|
||||
if (forceNew) {
|
||||
firstStep = storageService.clearLastAddress;
|
||||
} else {
|
||||
firstStep = function(walletId, cb) {
|
||||
return cb();
|
||||
};
|
||||
}
|
||||
|
||||
firstStep(wallet.id, function(err) {
|
||||
if (err) return cb(err);
|
||||
|
||||
storageService.getLastAddress(wallet.id, function(err, addr) {
|
||||
if (err) return cb(err);
|
||||
|
||||
if (addr) return cb(null, addr);
|
||||
|
||||
root._createAddress(wallet, function(err, addr) {
|
||||
if (err) return cb(err);
|
||||
storageService.storeLastAddress(wallet.id, addr, function() {
|
||||
if (err) return cb(err);
|
||||
return cb(null, addr);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
return root;
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue