mirror of https://github.com/BTCPrivate/copay.git
[V4] Feat: Show wallet total inputs and fix getMinAmount function
This commit is contained in:
parent
4a042b9954
commit
89efc4ec1f
|
@ -7,12 +7,14 @@
|
|||
<ion-content>
|
||||
<page-wallet-item [wallet]="wallet"></page-wallet-item>
|
||||
<div class="comment">
|
||||
<span translate>Each bitcoin wallet can generate billions of addresses from your 12-word backup.
|
||||
A new address is automatically generated and shown each time you receive a payment.
|
||||
</span><a (click)="showInfo = !showInfo" *ngIf="!showInfo" translate>Why?</a>
|
||||
<span translate>Each bitcoin wallet can generate billions of addresses from your 12-word backup. A new address is automatically generated
|
||||
and shown each time you receive a payment.
|
||||
</span>
|
||||
<a (click)="showInfo = !showInfo" *ngIf="!showInfo" translate>Why?</a>
|
||||
|
||||
<div *ngIf="showInfo">
|
||||
<span translate>It's a good idea to avoid reusing addresses - this both protects your privacy and keeps your bitcoins secure against hypothetical attacks by quantum computers.</span>
|
||||
<span translate>It's a good idea to avoid reusing addresses - this both protects your privacy and keeps your bitcoins secure against
|
||||
hypothetical attacks by quantum computers.</span>
|
||||
<a (click)="showInfo = !showInfo" translate>Hide</a>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -41,10 +43,14 @@
|
|||
<div *ngIf="latestUnused && latestUnused[0]">
|
||||
<div *ngIf="gapReached">
|
||||
<h5 translate>Unused addresses limit</h5>
|
||||
<p><span translate>The maximum number of consecutive unused addresses (20) has been reached. When one of your unused addresses receives a payment, a new address will be generated and shown in your Receive tab.</span> 
|
||||
<p>
|
||||
<span translate>The maximum number of consecutive unused addresses (20) has been reached. When one of your unused addresses receives
|
||||
a payment, a new address will be generated and shown in your Receive tab.</span> 
|
||||
<a (click)="readMore()" *ngIf="!showMore" translate>Read more</a>
|
||||
</p>
|
||||
<p *ngIf="showMore"><span translate>The restore process will stop when 20 addresses are generated in a row which contain no funds. To safely generate more addresses, make a payment to one of the unused addresses which has already been generated.</span> 
|
||||
<p *ngIf="showMore">
|
||||
<span translate>The restore process will stop when 20 addresses are generated in a row which contain no funds. To safely generate
|
||||
more addresses, make a payment to one of the unused addresses which has already been generated.</span> 
|
||||
<a (click)="readMore()" translate>Read less</a>
|
||||
</p>
|
||||
</div>
|
||||
|
@ -65,7 +71,7 @@
|
|||
</div>
|
||||
|
||||
<div *ngIf="allUtxosNb">
|
||||
<ion-item-divider>{{'Wallet Inputs' | translate}}</ion-item-divider>
|
||||
<ion-item-divider color="light">{{'Wallet Inputs' | translate}}</ion-item-divider>
|
||||
|
||||
<ion-item>
|
||||
<span translate>Total wallet inputs</span>
|
||||
|
|
|
@ -8,6 +8,7 @@ import { WalletProvider } from '../../../../../providers/wallet/wallet';
|
|||
import { BwcErrorProvider } from '../../../../../providers/bwc-error/bwc-error';
|
||||
import { PopupProvider } from '../../../../../providers/popup/popup';
|
||||
import { OnGoingProcessProvider } from '../../../../../providers/on-going-process/on-going-process';
|
||||
import { TxFormatProvider } from '../../../../../providers/tx-format/tx-format';
|
||||
|
||||
//pages
|
||||
import { AllAddressesPage } from './all-addresses/all-addresses';
|
||||
|
@ -28,6 +29,13 @@ export class WalletAddressesPage {
|
|||
public latestWithBalance: any;
|
||||
public viewAll: boolean;
|
||||
public gapReached: boolean;
|
||||
public lowUtxosNb: number;
|
||||
public allUtxosNb: number;
|
||||
public lowUtxosSum: string;
|
||||
public allUtxosSum: string;
|
||||
public minFee: string;
|
||||
public minFeePer: string;
|
||||
|
||||
private UNUSED_ADDRESS_LIMIT: number;
|
||||
private BALANCE_ADDRESS_LIMIT: number;
|
||||
private withBalance: any;
|
||||
|
@ -43,6 +51,7 @@ export class WalletAddressesPage {
|
|||
private popupProvider: PopupProvider,
|
||||
private onGoingProcessProvider: OnGoingProcessProvider,
|
||||
private modalCtrl: ModalController,
|
||||
private txFormatProvider: TxFormatProvider
|
||||
) {
|
||||
this.UNUSED_ADDRESS_LIMIT = 5;
|
||||
this.BALANCE_ADDRESS_LIMIT = 5;
|
||||
|
@ -79,6 +88,26 @@ export class WalletAddressesPage {
|
|||
this.loading = false;
|
||||
this.popupProvider.ionicAlert(this.bwcErrorProvider.msg(err, 'Could not update wallet')); //TODO gettextcatalog
|
||||
});
|
||||
|
||||
this.walletProvider.getLowUtxos(this.wallet).then((resp) => {
|
||||
|
||||
if (resp && resp.allUtxos && resp.allUtxos.length) {
|
||||
|
||||
let allSum = _.sumBy(resp.allUtxos || 0, 'satoshis');
|
||||
let per = (resp.minFee / allSum) * 100;
|
||||
|
||||
this.lowUtxosNb = resp.lowUtxos.length;
|
||||
this.allUtxosNb = resp.allUtxos.length;
|
||||
this.lowUtxosSum = this.txFormatProvider.formatAmountStr(this.wallet.coin, _.sumBy(resp.lowUtxos || 0, 'satoshis'));
|
||||
this.allUtxosSum = this.txFormatProvider.formatAmountStr(this.wallet.coin, allSum);
|
||||
this.minFee = this.txFormatProvider.formatAmountStr(this.wallet.coin, resp.minFee || 0);
|
||||
this.minFeePer = per.toFixed(2) + '%';
|
||||
|
||||
}
|
||||
}).catch((err) => {
|
||||
this.logger.warn(err);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private processPaths(list: any): void {
|
||||
|
|
|
@ -10,11 +10,13 @@
|
|||
<ion-label stacked translate>Wallet Service URL</ion-label>
|
||||
<ion-input type="text" formControlName="bwsurl" [value]="walletServiceForm.value.bwsurl" required></ion-input>
|
||||
</ion-item>
|
||||
<div translate>
|
||||
{{appName}} depends on Bitcore Wallet Service (BWS) for blockchain information, networking and Copayer synchronization. The
|
||||
default configuration points to https://bws.bitpay.com (BitPay's public BWS instance).
|
||||
<div class="comment">
|
||||
<span translate>{{appName}} depends on Bitcore Wallet Service (BWS) for blockchain information, networking and Copayer synchronization.
|
||||
The default configuration points to https://bws.bitpay.com (BitPay's public BWS instance).</span>
|
||||
<a (click)="resetDefaultUrl()" translate>
|
||||
Use default url
|
||||
</a>
|
||||
</div>
|
||||
<button ion-button (click)="resetDefaultUrl()"><ion-icon name="refresh"></ion-icon></button>
|
||||
<button ion-button block type="submit" [disabled]="!walletServiceForm.valid">Save</button>
|
||||
</form>
|
||||
</ion-content>
|
|
@ -0,0 +1,5 @@
|
|||
page-wallet-service-url {
|
||||
.comment {
|
||||
padding: 20px;
|
||||
}
|
||||
}
|
|
@ -26,7 +26,7 @@
|
|||
<span translate>Clear cache</span>
|
||||
</button>
|
||||
|
||||
<div translate>
|
||||
<div class="comment" translate>
|
||||
The transaction history and every new incoming transaction are cached in the app. This feature clean this up and synchronizes
|
||||
again from the server
|
||||
</div>
|
||||
|
|
|
@ -3,5 +3,8 @@ page-wallet-transaction-history {
|
|||
&.item {
|
||||
color: color($colors, primary) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
.comment {
|
||||
padding: 20px;
|
||||
}
|
||||
}
|
|
@ -24,6 +24,7 @@ export class FeeProvider {
|
|||
updateTs: 0,
|
||||
coin: ''
|
||||
}
|
||||
|
||||
constructor(
|
||||
private configProvider: ConfigProvider,
|
||||
private logger: Logger,
|
||||
|
@ -106,5 +107,4 @@ export class FeeProvider {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -55,8 +55,6 @@ export class ProfileProvider {
|
|||
public setWalletOrder(walletId: string, index: number): void {
|
||||
this.persistenceProvider.setWalletOrder(walletId, index);
|
||||
this.logger.debug('Wallet new order stored');
|
||||
console.log(this.wallet);
|
||||
console.log(walletId);
|
||||
this.wallet[walletId].order = index;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ import { OnGoingProcessProvider } from '../on-going-process/on-going-process';
|
|||
import { TouchIdProvider } from '../touchid/touchid';
|
||||
|
||||
import * as lodash from 'lodash';
|
||||
import { FeeProvider } from '../fee/fee';
|
||||
|
||||
|
||||
/* TODO LIST:
|
||||
|
@ -55,7 +56,8 @@ export class WalletProvider {
|
|||
private popupProvider: PopupProvider,
|
||||
private ongoingProcess: OnGoingProcessProvider,
|
||||
private touchidProvider: TouchIdProvider,
|
||||
private events: Events
|
||||
private events: Events,
|
||||
private feeProvider: FeeProvider
|
||||
) {
|
||||
this.logger.info('WalletService initialized.');
|
||||
}
|
||||
|
@ -426,7 +428,7 @@ export class WalletProvider {
|
|||
});
|
||||
}
|
||||
|
||||
private updateLocalTxHistory(wallet: any, opts: any) {
|
||||
private updateLocalTxHistory(wallet: any, opts: any): Promise<any> {
|
||||
return new Promise((resolve, reject) => {
|
||||
opts = opts ? opts : {};
|
||||
let FIRST_LIMIT = 5;
|
||||
|
@ -436,10 +438,6 @@ export class WalletProvider {
|
|||
this.progressFn[walletId] = opts.progressFn || (() => { });
|
||||
let foundLimitTx = [];
|
||||
|
||||
if (opts.feeLevels) {
|
||||
opts.lowAmount = this.getLowAmount(wallet, opts.feeLevels);
|
||||
};
|
||||
|
||||
let fixTxsUnit = (txs: any): void => {
|
||||
if (!txs || !txs[0] || !txs[0].amountStr) return;
|
||||
|
||||
|
@ -570,7 +568,11 @@ export class WalletProvider {
|
|||
});
|
||||
};
|
||||
|
||||
updateLowAmount(txs);
|
||||
this.getLowAmount(wallet).then((fee) => {
|
||||
opts.lowAmount = fee;
|
||||
updateLowAmount(txs);
|
||||
});
|
||||
|
||||
|
||||
updateNotes().then(() => {
|
||||
|
||||
|
@ -661,21 +663,31 @@ export class WalletProvider {
|
|||
}
|
||||
|
||||
// Approx utxo amount, from which the uxto is economically redeemable
|
||||
public getLowAmount(wallet: any, feeLevels?: any, nbOutputs?: number) {
|
||||
let minFee: number = this.getMinFee(wallet, feeLevels, nbOutputs);
|
||||
return (minFee / this.LOW_AMOUNT_RATIO);
|
||||
public getLowAmount(wallet: any): Promise<any> {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.getMinFee(wallet).then((fee) => {
|
||||
let minFee: number = fee;
|
||||
return resolve(minFee / this.LOW_AMOUNT_RATIO);
|
||||
}).catch((err) => {
|
||||
return reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Approx utxo amount, from which the uxto is economically redeemable
|
||||
private getMinFee(wallet: any, feeLevels: any, nbOutputs?: number): number {
|
||||
let level: any = lodash.find(feeLevels[wallet.network], (o) => {
|
||||
return o.level == 'normal';
|
||||
});
|
||||
let lowLevelRate = parseInt((level.feePerKb / 1000).toFixed(0));
|
||||
|
||||
var size = this.getEstimatedTxSize(wallet, nbOutputs);
|
||||
return size * lowLevelRate;
|
||||
}
|
||||
public getMinFee(wallet: any, nbOutputs?: number): Promise<any> {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.feeProvider.getFeeLevels(wallet.coin).then((data) => {
|
||||
let lowLevelRate = (lodash.find(data.levels[wallet.network], {
|
||||
level: 'normal',
|
||||
}).feePerKb / 1000).toFixed(0);
|
||||
let size = this.getEstimatedTxSize(wallet, nbOutputs);
|
||||
return resolve(size * parseInt(lowLevelRate));
|
||||
}).catch((err) => {
|
||||
return reject(err);
|
||||
});
|
||||
})
|
||||
};
|
||||
|
||||
// These 2 functions were taken from
|
||||
// https://github.com/bitpay/bitcore-wallet-service/blob/master/lib/model/txproposal.js#L243
|
||||
|
@ -1007,30 +1019,33 @@ export class WalletProvider {
|
|||
});
|
||||
}
|
||||
|
||||
public getLowUtxos(wallet: any, levels: any): Promise<any> {
|
||||
public getLowUtxos(wallet: any): Promise<any> {
|
||||
return new Promise((resolve, reject) => {
|
||||
wallet.getUtxos({
|
||||
coin: wallet.coin
|
||||
}, (err, resp) => {
|
||||
if (err || !resp || !resp.length) return reject(err);
|
||||
|
||||
let minFee = this.getMinFee(wallet, levels, resp.length);
|
||||
this.getMinFee(wallet, resp.length).then((fee) => {
|
||||
let minFee = fee;
|
||||
let balance = lodash.sumBy(resp, 'satoshis');
|
||||
|
||||
let balance = lodash.sumBy(resp, 'satoshis');
|
||||
// for 2 outputs
|
||||
this.getLowAmount(wallet).then((fee) => {
|
||||
let lowAmount = fee;
|
||||
let lowUtxos = lodash.filter(resp, (x: any) => {
|
||||
return x.satoshis < lowAmount;
|
||||
});
|
||||
|
||||
// for 2 outputs
|
||||
let lowAmount = this.getLowAmount(wallet, levels);
|
||||
let lowUtxos = lodash.filter(resp, (x: any) => {
|
||||
return x.satoshis < lowAmount;
|
||||
});
|
||||
|
||||
let totalLow = lodash.sumBy(lowUtxos, 'satoshis');
|
||||
return resolve({
|
||||
allUtxos: resp || [],
|
||||
lowUtxos: lowUtxos || [],
|
||||
totalLow: totalLow,
|
||||
warning: minFee / balance > this.TOTAL_LOW_WARNING_RATIO,
|
||||
minFee: minFee,
|
||||
let totalLow = lodash.sumBy(lowUtxos, 'satoshis');
|
||||
return resolve({
|
||||
allUtxos: resp || [],
|
||||
lowUtxos: lowUtxos || [],
|
||||
totalLow: totalLow,
|
||||
warning: minFee / balance > this.TOTAL_LOW_WARNING_RATIO,
|
||||
minFee: minFee,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue