mirror of https://github.com/BTCPrivate/copay.git
Merge pull request #7850 from Gamboster/feat/cashaddrSupport
[V4] Feat: cashAddr support
This commit is contained in:
commit
65e9efdd22
|
@ -82,7 +82,7 @@
|
||||||
"ajv": "^5.5.2",
|
"ajv": "^5.5.2",
|
||||||
"angular2-moment": "^1.7.1",
|
"angular2-moment": "^1.7.1",
|
||||||
"autoprefixer": "^7.2.4",
|
"autoprefixer": "^7.2.4",
|
||||||
"bitcore-wallet-client": "^6.4.0",
|
"bitcore-wallet-client": "^6.5.0",
|
||||||
"buffer-compare": "^1.1.1",
|
"buffer-compare": "^1.1.1",
|
||||||
"cordova-android": "6.4.0",
|
"cordova-android": "6.4.0",
|
||||||
"cordova-clipboard": "^1.1.1",
|
"cordova-clipboard": "^1.1.1",
|
||||||
|
|
|
@ -6,10 +6,11 @@ import { NavParams, ViewController } from 'ionic-angular';
|
||||||
templateUrl: 'incoming-data-menu.html',
|
templateUrl: 'incoming-data-menu.html',
|
||||||
})
|
})
|
||||||
export class IncomingDataMenuPage {
|
export class IncomingDataMenuPage {
|
||||||
|
public https: boolean;
|
||||||
|
|
||||||
public data: string;
|
public data: string;
|
||||||
public type: string;
|
public type: string;
|
||||||
public https: boolean;
|
public coin: string;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private viewCtrl: ViewController,
|
private viewCtrl: ViewController,
|
||||||
|
@ -21,6 +22,7 @@ export class IncomingDataMenuPage {
|
||||||
ionViewDidLoad() {
|
ionViewDidLoad() {
|
||||||
this.data = this.navParams.data.data;
|
this.data = this.navParams.data.data;
|
||||||
this.type = this.navParams.data.type;
|
this.type = this.navParams.data.type;
|
||||||
|
this.coin = this.navParams.data.coin;
|
||||||
if (this.type === 'url') {
|
if (this.type === 'url') {
|
||||||
if (this.data.indexOf('https://') === 0) {
|
if (this.data.indexOf('https://') === 0) {
|
||||||
this.https = true;
|
this.https = true;
|
||||||
|
@ -29,6 +31,11 @@ export class IncomingDataMenuPage {
|
||||||
}
|
}
|
||||||
|
|
||||||
public close(redirTo: string, value: string) {
|
public close(redirTo: string, value: string) {
|
||||||
|
if (redirTo == 'AmountPage') {
|
||||||
|
let coin = this.coin ? this.coin : 'btc';
|
||||||
|
this.viewCtrl.dismiss({ redirTo: redirTo, value: value, coin: coin });
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.viewCtrl.dismiss({ redirTo: redirTo, value: value });
|
this.viewCtrl.dismiss({ redirTo: redirTo, value: value });
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,6 +2,9 @@ import { Component } from '@angular/core';
|
||||||
import { NavParams } from 'ionic-angular';
|
import { NavParams } from 'ionic-angular';
|
||||||
import { Logger } from '@nsalaun/ng-logger';
|
import { Logger } from '@nsalaun/ng-logger';
|
||||||
|
|
||||||
|
// Native
|
||||||
|
import { SocialSharing } from '@ionic-native/social-sharing';
|
||||||
|
|
||||||
//providers
|
//providers
|
||||||
import { ProfileProvider } from '../../../providers/profile/profile';
|
import { ProfileProvider } from '../../../providers/profile/profile';
|
||||||
import { PlatformProvider } from '../../../providers/platform/platform';
|
import { PlatformProvider } from '../../../providers/platform/platform';
|
||||||
|
@ -26,14 +29,17 @@ export class CustomAmountPage {
|
||||||
private profileProvider: ProfileProvider,
|
private profileProvider: ProfileProvider,
|
||||||
private platformProvider: PlatformProvider,
|
private platformProvider: PlatformProvider,
|
||||||
private walletProvider: WalletProvider,
|
private walletProvider: WalletProvider,
|
||||||
private logger: Logger
|
private logger: Logger,
|
||||||
|
private socialSharing: SocialSharing
|
||||||
) {
|
) {
|
||||||
this.address = this.navParams.data.toAddress;
|
|
||||||
this.amount = this.navParams.data.amount;
|
this.amount = this.navParams.data.amount;
|
||||||
this.coin = this.navParams.data.coin;
|
this.coin = this.navParams.data.coin;
|
||||||
let walletId = this.navParams.data.walletId;
|
let walletId = this.navParams.data.walletId;
|
||||||
this.wallet = this.profileProvider.getWallet(walletId);
|
this.wallet = this.profileProvider.getWallet(walletId);
|
||||||
this.showShareButton = this.platformProvider.isCordova;
|
this.showShareButton = this.platformProvider.isCordova;
|
||||||
|
|
||||||
|
let addr = this.navParams.data.toAddress;
|
||||||
|
this.address = this.walletProvider.getAddressView(this.wallet, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
ionViewDidLoad() {
|
ionViewDidLoad() {
|
||||||
|
@ -42,16 +48,11 @@ export class CustomAmountPage {
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateQrAddress(): void {
|
private updateQrAddress(): void {
|
||||||
this.setProtocolHandler();
|
this.qrAddress = this.walletProvider.getProtoAddress(this.wallet, this.address) + "?amount=" + this.amount;
|
||||||
this.qrAddress = this.protocolHandler + ":" + this.address + "?amount=" + this.amount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private setProtocolHandler(): void {
|
public shareAddress(): void {
|
||||||
this.protocolHandler = this.walletProvider.getProtocolHandler(this.wallet.coin);
|
this.socialSharing.share(this.qrAddress);
|
||||||
}
|
|
||||||
|
|
||||||
public shareAddress = function () {
|
|
||||||
//window.plugins.socialsharing.share(this.qrAddress, null, null, null); TODO
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,15 +2,15 @@ import { Component } from '@angular/core';
|
||||||
import { Logger } from '@nsalaun/ng-logger';
|
import { Logger } from '@nsalaun/ng-logger';
|
||||||
import { NavController, Events, AlertController } from 'ionic-angular';
|
import { NavController, Events, AlertController } from 'ionic-angular';
|
||||||
|
|
||||||
//native
|
// Native
|
||||||
import { SocialSharing } from '@ionic-native/social-sharing';
|
import { SocialSharing } from '@ionic-native/social-sharing';
|
||||||
|
|
||||||
//pages
|
// Pages
|
||||||
import { AmountPage } from '../send/amount/amount';
|
import { AmountPage } from '../send/amount/amount';
|
||||||
import { CopayersPage } from './../add/copayers/copayers';
|
import { CopayersPage } from './../add/copayers/copayers';
|
||||||
import { BackupGamePage } from '../backup/backup-game/backup-game';
|
import { BackupGamePage } from '../backup/backup-game/backup-game';
|
||||||
|
|
||||||
//providers
|
// Providers
|
||||||
import { WalletProvider } from '../../providers/wallet/wallet';
|
import { WalletProvider } from '../../providers/wallet/wallet';
|
||||||
import { ProfileProvider } from '../../providers/profile/profile';
|
import { ProfileProvider } from '../../providers/profile/profile';
|
||||||
import { PlatformProvider } from '../../providers/platform/platform';
|
import { PlatformProvider } from '../../providers/platform/platform';
|
||||||
|
@ -62,15 +62,10 @@ export class ReceivePage {
|
||||||
private onWalletSelect(wallet: any): any {
|
private onWalletSelect(wallet: any): any {
|
||||||
this.wallet = wallet;
|
this.wallet = wallet;
|
||||||
if (this.wallet) {
|
if (this.wallet) {
|
||||||
this.setProtocolHandler();
|
|
||||||
this.setAddress();
|
this.setAddress();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private setProtocolHandler(): void {
|
|
||||||
this.protocolHandler = this.walletProvider.getProtocolHandler(this.wallet.coin);
|
|
||||||
}
|
|
||||||
|
|
||||||
private checkSelectedWallet(wallet: any, wallets: any): any {
|
private checkSelectedWallet(wallet: any, wallets: any): any {
|
||||||
if (!wallet) return wallets[0];
|
if (!wallet) return wallets[0];
|
||||||
let w = _.find(wallets, (w: any) => {
|
let w = _.find(wallets, (w: any) => {
|
||||||
|
@ -99,7 +94,7 @@ export class ReceivePage {
|
||||||
|
|
||||||
this.walletProvider.getAddress(this.wallet, newAddr).then((addr) => {
|
this.walletProvider.getAddress(this.wallet, newAddr).then((addr) => {
|
||||||
this.loading = false
|
this.loading = false
|
||||||
this.address = addr;
|
this.address = this.walletProvider.getAddressView(this.wallet, addr);
|
||||||
this.updateQrAddress();
|
this.updateQrAddress();
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
|
@ -108,13 +103,12 @@ export class ReceivePage {
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateQrAddress(): void {
|
private updateQrAddress(): void {
|
||||||
this.qrAddress = this.protocolHandler + ":" + this.address;
|
this.qrAddress = this.walletProvider.getProtoAddress(this.wallet, this.address);
|
||||||
}
|
}
|
||||||
|
|
||||||
public shareAddress(): void {
|
public shareAddress(): void {
|
||||||
let protocol = 'bitcoin';
|
if (!this.showShareButton) return;
|
||||||
if (this.wallet.coin == 'bch') protocol += 'cash';
|
this.socialSharing.share(this.qrAddress);
|
||||||
this.socialSharing.share(protocol + ':' + this.address);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public showWallets(): void {
|
public showWallets(): void {
|
||||||
|
|
|
@ -96,7 +96,7 @@ export class ScanPage {
|
||||||
this.modalIsOpen = false;
|
this.modalIsOpen = false;
|
||||||
switch (data.redirTo) {
|
switch (data.redirTo) {
|
||||||
case 'AmountPage':
|
case 'AmountPage':
|
||||||
this.sendPaymentToAddress(data.value);
|
this.sendPaymentToAddress(data.value, data.coin);
|
||||||
break;
|
break;
|
||||||
case 'AddressBookPage':
|
case 'AddressBookPage':
|
||||||
this.addToAddressBook(data.value);
|
this.addToAddressBook(data.value);
|
||||||
|
@ -125,9 +125,9 @@ export class ScanPage {
|
||||||
this.externalLinkProvider.open(url);
|
this.externalLinkProvider.open(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
private sendPaymentToAddress(bitcoinAddress: string): void {
|
private sendPaymentToAddress(bitcoinAddress: string, coin: string): void {
|
||||||
//this.navCtrl.parent.select(3); TODO go to send and then amount page
|
//this.navCtrl.parent.select(3); TODO go to send and then amount page
|
||||||
this.navCtrl.push(AmountPage, { toAddress: bitcoinAddress });
|
this.navCtrl.push(AmountPage, { toAddress: bitcoinAddress, coin: coin });
|
||||||
}
|
}
|
||||||
|
|
||||||
private addToAddressBook(bitcoinAddress: string): void {
|
private addToAddressBook(bitcoinAddress: string): void {
|
||||||
|
|
|
@ -55,9 +55,9 @@
|
||||||
|
|
||||||
<div class="payment-proposal-to" *ngIf="!tx.recipientType">
|
<div class="payment-proposal-to" *ngIf="!tx.recipientType">
|
||||||
<img class="icon-bitcoin" src="assets/img/icon-bitcoin-small.svg">
|
<img class="icon-bitcoin" src="assets/img/icon-bitcoin-small.svg">
|
||||||
<div *ngIf="!tx.paypro" copy-to-clipboard="{{ tx.toAddress }}">
|
<div *ngIf="!tx.paypro" copy-to-clipboard="{{ tx.origToAddress }}">
|
||||||
<!--TODO: <contact *ngIf="tx.toAddress && !tx.name" address="{{tx.toAddress}}"></contact>-->
|
<!--TODO: <contact *ngIf="tx.origToAddress && !tx.name" address="{{tx.origToAddress}}"></contact>-->
|
||||||
<span *ngIf="!tx.name">{{tx.toAddress}}</span>
|
<span *ngIf="!tx.name">{{tx.origToAddress}}</span>
|
||||||
<span *ngIf="tx.name">{{tx.name}}</span>
|
<span *ngIf="tx.name">{{tx.name}}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -76,9 +76,9 @@
|
||||||
<img *ngIf="tx.network != 'testnet'" [ngStyle]="{'background-color': tx.color}" src="assets/img/icon-wallet.svg" class="icon-wallet"
|
<img *ngIf="tx.network != 'testnet'" [ngStyle]="{'background-color': tx.color}" src="assets/img/icon-wallet.svg" class="icon-wallet"
|
||||||
/>
|
/>
|
||||||
</ion-icon>
|
</ion-icon>
|
||||||
<div copy-to-clipboard="{{ tx.toAddress }}">
|
<div copy-to-clipboard="{{ tx.origToAddress }}">
|
||||||
<!--TODO: <contact ng-if="tx.toAddress && !tx.name" address="{{tx.toAddress}}"></contact>-->
|
<!--TODO: <contact ng-if="tx.origToAddress && !tx.name" address="{{tx.origToAddress}}"></contact>-->
|
||||||
<span *ngIf="!tx.name">{{tx.toAddress}}</span>
|
<span *ngIf="!tx.name">{{tx.origToAddress}}</span>
|
||||||
<span *ngIf="tx.name">{{tx.name}}</span>
|
<span *ngIf="tx.name">{{tx.name}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -128,4 +128,4 @@
|
||||||
|
|
||||||
<ion-footer>
|
<ion-footer>
|
||||||
<button ion-button block class="button-footer" (click)="approve(tx, wallet)" [disabled]="!wallet" translate>Click to send</button>
|
<button ion-button block class="button-footer" (click)="approve(tx, wallet)" [disabled]="!wallet" translate>Click to send</button>
|
||||||
</ion-footer>
|
</ion-footer>
|
|
@ -11,6 +11,7 @@ import { FeeWarningPage } from '../fee-warning/fee-warning';
|
||||||
import { SuccessModalPage } from '../../success/success';
|
import { SuccessModalPage } from '../../success/success';
|
||||||
|
|
||||||
// Providers
|
// Providers
|
||||||
|
import { BwcProvider } from '../../../providers/bwc/bwc';
|
||||||
import { ConfigProvider } from '../../../providers/config/config';
|
import { ConfigProvider } from '../../../providers/config/config';
|
||||||
import { PlatformProvider } from '../../../providers/platform/platform';
|
import { PlatformProvider } from '../../../providers/platform/platform';
|
||||||
import { ProfileProvider } from '../../../providers/profile/profile';
|
import { ProfileProvider } from '../../../providers/profile/profile';
|
||||||
|
@ -28,6 +29,8 @@ import { TxFormatProvider } from '../../../providers/tx-format/tx-format';
|
||||||
})
|
})
|
||||||
export class ConfirmPage {
|
export class ConfirmPage {
|
||||||
|
|
||||||
|
private bitcoreCash: any;
|
||||||
|
|
||||||
public countDown = null;
|
public countDown = null;
|
||||||
public CONFIRM_LIMIT_USD: number;
|
public CONFIRM_LIMIT_USD: number;
|
||||||
public FEE_TOO_HIGH_LIMIT_PER: number;
|
public FEE_TOO_HIGH_LIMIT_PER: number;
|
||||||
|
@ -55,6 +58,7 @@ export class ConfirmPage {
|
||||||
public usingCustomFee: boolean = false;
|
public usingCustomFee: boolean = false;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
private bwcProvider: BwcProvider,
|
||||||
private navCtrl: NavController,
|
private navCtrl: NavController,
|
||||||
private navParams: NavParams,
|
private navParams: NavParams,
|
||||||
private logger: Logger,
|
private logger: Logger,
|
||||||
|
@ -71,6 +75,7 @@ export class ConfirmPage {
|
||||||
private txFormatProvider: TxFormatProvider,
|
private txFormatProvider: TxFormatProvider,
|
||||||
private events: Events
|
private events: Events
|
||||||
) {
|
) {
|
||||||
|
this.bitcoreCash = this.bwcProvider.getBitcoreCash();
|
||||||
this.CONFIRM_LIMIT_USD = 20;
|
this.CONFIRM_LIMIT_USD = 20;
|
||||||
this.FEE_TOO_HIGH_LIMIT_PER = 15;
|
this.FEE_TOO_HIGH_LIMIT_PER = 15;
|
||||||
this.config = this.configProvider.get();
|
this.config = this.configProvider.get();
|
||||||
|
@ -95,8 +100,15 @@ export class ConfirmPage {
|
||||||
coin: this.navParams.data.coin,
|
coin: this.navParams.data.coin,
|
||||||
txp: {},
|
txp: {},
|
||||||
};
|
};
|
||||||
|
this.tx.origToAddress = this.tx.toAddress;
|
||||||
|
|
||||||
|
if (this.tx.coin && this.tx.coin == 'bch') {
|
||||||
|
this.tx.feeLevel = 'normal';
|
||||||
|
|
||||||
|
// Use legacy address
|
||||||
|
this.tx.toAddress = this.bitcoreCash.Address(this.tx.toAddress).toString();
|
||||||
|
}
|
||||||
|
|
||||||
if (this.tx.coin && this.tx.coin == 'bch') this.tx.feeLevel = 'normal';
|
|
||||||
this.tx.feeLevelName = this.feeProvider.feeOpts[this.tx.feeLevel];
|
this.tx.feeLevelName = this.feeProvider.feeOpts[this.tx.feeLevel];
|
||||||
this.showAddress = false;
|
this.showAddress = false;
|
||||||
this.walletSelectorTitle = 'Send from'; // TODO gettextCatalog
|
this.walletSelectorTitle = 'Send from'; // TODO gettextCatalog
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
<ion-card-header>
|
<ion-card-header>
|
||||||
<div class="toggle-header">
|
<div class="toggle-header">
|
||||||
<ion-label>{{'Use Unconfirmed Funds' | translate}}</ion-label>
|
<ion-label>{{'Use Unconfirmed Funds' | translate}}</ion-label>
|
||||||
<ion-toggle [(ngModel)]="spendUnconfirmed" (ionChange)="spendUnconfirmedChange()" checked="true"></ion-toggle>
|
<ion-toggle [(ngModel)]="spendUnconfirmed" (ionChange)="spendUnconfirmedChange()"></ion-toggle>
|
||||||
</div>
|
</div>
|
||||||
</ion-card-header>
|
</ion-card-header>
|
||||||
<ion-item-divider color="light" text-wrap>
|
<ion-item-divider color="light" text-wrap>
|
||||||
|
@ -20,11 +20,23 @@
|
||||||
</ion-item-divider>
|
</ion-item-divider>
|
||||||
</ion-card>
|
</ion-card>
|
||||||
|
|
||||||
|
<ion-card>
|
||||||
|
<ion-card-header>
|
||||||
|
<div class="toggle-header">
|
||||||
|
<ion-label>{{'Use Bitcoin Cash Copay Style Addresses' | translate}}</ion-label>
|
||||||
|
<ion-toggle [(ngModel)]="useLegacyAddress" (ionChange)="useLegacyAddressChange()"></ion-toggle>
|
||||||
|
</div>
|
||||||
|
</ion-card-header>
|
||||||
|
<ion-item-divider color="light" text-wrap>
|
||||||
|
<span translate>If enabled, Bitcoin Cash addresses will be shown using Copay style address, and not the new cashaddr format.</span>
|
||||||
|
</ion-item-divider>
|
||||||
|
</ion-card>
|
||||||
|
|
||||||
<ion-card>
|
<ion-card>
|
||||||
<ion-card-header>
|
<ion-card-header>
|
||||||
<div class="toggle-header">
|
<div class="toggle-header">
|
||||||
<ion-label>{{'Recent Transaction Card' | translate}}</ion-label>
|
<ion-label>{{'Recent Transaction Card' | translate}}</ion-label>
|
||||||
<ion-toggle [(ngModel)]="recentTransactionsEnabled" (ionChange)="recentTransactionsChange()" checked="true"></ion-toggle>
|
<ion-toggle [(ngModel)]="recentTransactionsEnabled" (ionChange)="recentTransactionsChange()"></ion-toggle>
|
||||||
</div>
|
</div>
|
||||||
</ion-card-header>
|
</ion-card-header>
|
||||||
<ion-item-divider color="light" text-wrap>
|
<ion-item-divider color="light" text-wrap>
|
||||||
|
@ -37,7 +49,7 @@
|
||||||
<ion-card-header>
|
<ion-card-header>
|
||||||
<div class="toggle-header">
|
<div class="toggle-header">
|
||||||
<ion-label>{{'Show Next Steps Card' | translate}}</ion-label>
|
<ion-label>{{'Show Next Steps Card' | translate}}</ion-label>
|
||||||
<ion-toggle [(ngModel)]="showNextSteps" (ionChange)="nextStepsChange()" checked="true"></ion-toggle>
|
<ion-toggle [(ngModel)]="showNextSteps" (ionChange)="nextStepsChange()"></ion-toggle>
|
||||||
</div>
|
</div>
|
||||||
</ion-card-header>
|
</ion-card-header>
|
||||||
<ion-item-divider color="light" text-wrap>
|
<ion-item-divider color="light" text-wrap>
|
||||||
|
|
|
@ -13,6 +13,7 @@ export class AdvancedPage {
|
||||||
public spendUnconfirmed: boolean;
|
public spendUnconfirmed: boolean;
|
||||||
public recentTransactionsEnabled: boolean;
|
public recentTransactionsEnabled: boolean;
|
||||||
public showNextSteps: boolean;
|
public showNextSteps: boolean;
|
||||||
|
public useLegacyAddress: boolean;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private configProvider: ConfigProvider,
|
private configProvider: ConfigProvider,
|
||||||
|
@ -30,6 +31,7 @@ export class AdvancedPage {
|
||||||
this.spendUnconfirmed = config.wallet.spendUnconfirmed;
|
this.spendUnconfirmed = config.wallet.spendUnconfirmed;
|
||||||
this.recentTransactionsEnabled = config.recentTransactions.enabled;
|
this.recentTransactionsEnabled = config.recentTransactions.enabled;
|
||||||
this.showNextSteps = config.showNextSteps.enabled;
|
this.showNextSteps = config.showNextSteps.enabled;
|
||||||
|
this.useLegacyAddress = config.wallet.useLegacyAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
public spendUnconfirmedChange(): void {
|
public spendUnconfirmedChange(): void {
|
||||||
|
@ -50,6 +52,15 @@ export class AdvancedPage {
|
||||||
this.configProvider.set(opts);
|
this.configProvider.set(opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public useLegacyAddressChange(): void {
|
||||||
|
let opts = {
|
||||||
|
wallet: {
|
||||||
|
useLegacyAddress: this.useLegacyAddress
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.configProvider.set(opts);
|
||||||
|
}
|
||||||
|
|
||||||
public nextStepsChange(): void {
|
public nextStepsChange(): void {
|
||||||
let opts = {
|
let opts = {
|
||||||
showNextSteps: {
|
showNextSteps: {
|
||||||
|
|
|
@ -63,7 +63,11 @@ export class TxDetailsPage {
|
||||||
this.txsUnsubscribedForNotifications = this.config.confirmedTxsNotifications ? !this.config.confirmedTxsNotifications.enabled : true;
|
this.txsUnsubscribedForNotifications = this.config.confirmedTxsNotifications ? !this.config.confirmedTxsNotifications.enabled : true;
|
||||||
|
|
||||||
if (this.wallet.coin == 'bch') {
|
if (this.wallet.coin == 'bch') {
|
||||||
this.blockexplorerUrl = 'bch-insight.bitpay.com';
|
if (this.walletProvider.useLegacyAddress()) {
|
||||||
|
this.blockexplorerUrl = 'bch-insight.bitpay.com';
|
||||||
|
} else {
|
||||||
|
this.blockexplorerUrl = 'blockdozer.com/insight';
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
this.blockexplorerUrl = 'insight.bitpay.com';
|
this.blockexplorerUrl = 'insight.bitpay.com';
|
||||||
}
|
}
|
||||||
|
@ -153,7 +157,7 @@ export class TxDetailsPage {
|
||||||
this.walletProvider.getTx(this.wallet, this.txId).then((tx: any) => {
|
this.walletProvider.getTx(this.wallet, this.txId).then((tx: any) => {
|
||||||
if (!opts.hideLoading) this.onGoingProcess.set('loadingTxInfo', false);
|
if (!opts.hideLoading) this.onGoingProcess.set('loadingTxInfo', false);
|
||||||
|
|
||||||
this.btx = this.txFormatProvider.processTx(this.wallet.coin, tx);
|
this.btx = this.txFormatProvider.processTx(this.wallet.coin, tx, this.walletProvider.useLegacyAddress());
|
||||||
let v: string = this.txFormatProvider.formatAlternativeStr(this.wallet.coin, tx.fees);
|
let v: string = this.txFormatProvider.formatAlternativeStr(this.wallet.coin, tx.fees);
|
||||||
this.btx.feeFiatStr = v;
|
this.btx.feeFiatStr = v;
|
||||||
this.btx.feeRateStr = (this.btx.fees / (this.btx.amount + this.btx.fees) * 100).toFixed(2) + '%';
|
this.btx.feeRateStr = (this.btx.fees / (this.btx.amount + this.btx.fees) * 100).toFixed(2) + '%';
|
||||||
|
|
|
@ -11,6 +11,7 @@ interface Config {
|
||||||
};
|
};
|
||||||
|
|
||||||
wallet: {
|
wallet: {
|
||||||
|
useLegacyAddress: boolean,
|
||||||
requiredCopayers: number;
|
requiredCopayers: number;
|
||||||
totalCopayers: number;
|
totalCopayers: number;
|
||||||
spendUnconfirmed: boolean;
|
spendUnconfirmed: boolean;
|
||||||
|
@ -101,6 +102,7 @@ const configDefault: Config = {
|
||||||
|
|
||||||
// wallet default config
|
// wallet default config
|
||||||
wallet: {
|
wallet: {
|
||||||
|
useLegacyAddress: false,
|
||||||
requiredCopayers: 2,
|
requiredCopayers: 2,
|
||||||
totalCopayers: 3,
|
totalCopayers: 3,
|
||||||
spendUnconfirmed: false,
|
spendUnconfirmed: false,
|
||||||
|
|
|
@ -80,6 +80,12 @@ export class IncomingDataProvider {
|
||||||
coin = 'bch';
|
coin = 'bch';
|
||||||
parsed = this.bwcProvider.getBitcoreCash().URI(data);
|
parsed = this.bwcProvider.getBitcoreCash().URI(data);
|
||||||
addr = parsed.address ? parsed.address.toString() : '';
|
addr = parsed.address ? parsed.address.toString() : '';
|
||||||
|
|
||||||
|
// keep address in original format
|
||||||
|
if (parsed.address && data.indexOf(addr) < 0) {
|
||||||
|
addr = parsed.address.toCashAddress();
|
||||||
|
};
|
||||||
|
|
||||||
message = parsed.message;
|
message = parsed.message;
|
||||||
amount = parsed.amount ? parsed.amount : '';
|
amount = parsed.amount ? parsed.amount : '';
|
||||||
|
|
||||||
|
@ -156,7 +162,8 @@ export class IncomingDataProvider {
|
||||||
if (this.navCtrl.getActive().name === 'ScanPage') {
|
if (this.navCtrl.getActive().name === 'ScanPage') {
|
||||||
this.showMenu({
|
this.showMenu({
|
||||||
data: data,
|
data: data,
|
||||||
type: 'bitcoinAddress'
|
type: 'bitcoinAddress',
|
||||||
|
coin: 'btc'
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
let coin = 'btc';
|
let coin = 'btc';
|
||||||
|
|
|
@ -10,17 +10,30 @@ import * as _ from "lodash";
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class TxFormatProvider {
|
export class TxFormatProvider {
|
||||||
|
|
||||||
|
private bitcoreCash: any;
|
||||||
|
|
||||||
// TODO: implement configService
|
// TODO: implement configService
|
||||||
public pendingTxProposalsCountForUs: number
|
public pendingTxProposalsCountForUs: number
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private bwc: BwcProvider,
|
private bwcProvider: BwcProvider,
|
||||||
private rate: RateProvider,
|
private rate: RateProvider,
|
||||||
private config: ConfigProvider,
|
private config: ConfigProvider,
|
||||||
private filter: FilterProvider,
|
private filter: FilterProvider,
|
||||||
private logger: Logger
|
private logger: Logger
|
||||||
) {
|
) {
|
||||||
this.logger.info('TxFormatProvider initialized.');
|
this.logger.info('TxFormatProvider initialized.');
|
||||||
|
this.bitcoreCash = this.bwcProvider.getBitcoreCash();
|
||||||
|
}
|
||||||
|
|
||||||
|
public toCashAddress(address: string, withPrefix?: boolean): string {
|
||||||
|
let cashAddr: string = (this.bitcoreCash.Address(address)).toCashAddress();
|
||||||
|
|
||||||
|
if (withPrefix) {
|
||||||
|
return cashAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cashAddr.split(':')[1]; // rm prefix
|
||||||
}
|
}
|
||||||
|
|
||||||
public formatAmount(satoshis: number, fullPrecision?: boolean): number {
|
public formatAmount(satoshis: number, fullPrecision?: boolean): number {
|
||||||
|
@ -32,7 +45,7 @@ export class TxFormatProvider {
|
||||||
var opts = {
|
var opts = {
|
||||||
fullPrecision: !!fullPrecision
|
fullPrecision: !!fullPrecision
|
||||||
};
|
};
|
||||||
return this.bwc.getUtils().formatAmount(satoshis, settings.unitCode, opts);
|
return this.bwcProvider.getUtils().formatAmount(satoshis, settings.unitCode, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
public formatAmountStr(coin: string, satoshis: number): string {
|
public formatAmountStr(coin: string, satoshis: number): string {
|
||||||
|
@ -78,7 +91,7 @@ export class TxFormatProvider {
|
||||||
return val();
|
return val();
|
||||||
};
|
};
|
||||||
|
|
||||||
public processTx(coin: string, tx: any): any {
|
public processTx(coin: string, tx: any, useLegacyAddress?: boolean): any {
|
||||||
if (!tx || tx.action == 'invalid')
|
if (!tx || tx.action == 'invalid')
|
||||||
return tx;
|
return tx;
|
||||||
|
|
||||||
|
@ -99,6 +112,11 @@ export class TxFormatProvider {
|
||||||
}, 0);
|
}, 0);
|
||||||
}
|
}
|
||||||
tx.toAddress = tx.outputs[0].toAddress;
|
tx.toAddress = tx.outputs[0].toAddress;
|
||||||
|
|
||||||
|
// toDo: translate all tx.outputs[x].toAddress ?
|
||||||
|
if (tx.toAddress && coin == 'bch' && !useLegacyAddress) {
|
||||||
|
tx.toAddress = this.toCashAddress(tx.toAddress);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tx.amountStr = this.formatAmountStr(coin, tx.amount);
|
tx.amountStr = this.formatAmountStr(coin, tx.amount);
|
||||||
|
@ -110,6 +128,10 @@ export class TxFormatProvider {
|
||||||
tx.amountUnitStr = tx.amountStr.split(' ')[1];
|
tx.amountUnitStr = tx.amountStr.split(' ')[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tx.addressTo && coin == 'bch' && !useLegacyAddress) {
|
||||||
|
tx.addressTo = this.toCashAddress(tx.addressTo);
|
||||||
|
}
|
||||||
|
|
||||||
return tx;
|
return tx;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { Events } from 'ionic-angular';
|
import { Events } from 'ionic-angular';
|
||||||
import { Logger } from '@nsalaun/ng-logger';
|
import { Logger } from '@nsalaun/ng-logger';
|
||||||
|
import * as lodash from 'lodash';
|
||||||
|
|
||||||
|
// Providers
|
||||||
import { ConfigProvider } from '../config/config';
|
import { ConfigProvider } from '../config/config';
|
||||||
import { BwcProvider } from '../bwc/bwc';
|
import { BwcProvider } from '../bwc/bwc';
|
||||||
import { TxFormatProvider } from '../tx-format/tx-format';
|
import { TxFormatProvider } from '../tx-format/tx-format';
|
||||||
|
@ -12,8 +14,6 @@ import { FilterProvider } from '../filter/filter';
|
||||||
import { PopupProvider } from '../popup/popup';
|
import { PopupProvider } from '../popup/popup';
|
||||||
import { OnGoingProcessProvider } from '../on-going-process/on-going-process';
|
import { OnGoingProcessProvider } from '../on-going-process/on-going-process';
|
||||||
import { TouchIdProvider } from '../touchid/touchid';
|
import { TouchIdProvider } from '../touchid/touchid';
|
||||||
|
|
||||||
import * as lodash from 'lodash';
|
|
||||||
import { FeeProvider } from '../fee/fee';
|
import { FeeProvider } from '../fee/fee';
|
||||||
|
|
||||||
|
|
||||||
|
@ -322,6 +322,29 @@ export class WalletProvider {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public useLegacyAddress(): boolean {
|
||||||
|
let config = this.configProvider.get();
|
||||||
|
let walletSettings = config.wallet;
|
||||||
|
|
||||||
|
return walletSettings.useLegacyAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getAddressView(wallet: any, address: string): string {
|
||||||
|
if (wallet.coin != 'bch' || this.useLegacyAddress()) return address;
|
||||||
|
return this.txFormatProvider.toCashAddress(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getProtoAddress(wallet: any, address: string) {
|
||||||
|
let proto: string = this.getProtocolHandler(wallet);
|
||||||
|
let protoAddr: string = proto + ':' + address;
|
||||||
|
|
||||||
|
if (wallet.coin != 'bch' || this.useLegacyAddress()) {
|
||||||
|
return protoAddr;
|
||||||
|
} else {
|
||||||
|
return protoAddr.toUpperCase();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
public getAddress(wallet: any, forceNew: boolean): Promise<any> {
|
public getAddress(wallet: any, forceNew: boolean): Promise<any> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.persistenceProvider.getLastAddress(wallet.id).then((addr) => {
|
this.persistenceProvider.getLastAddress(wallet.id).then((addr) => {
|
||||||
|
@ -1299,7 +1322,7 @@ export class WalletProvider {
|
||||||
return reject(err);
|
return reject(err);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
public getSendMaxInfo(wallet: any, opts: any): Promise<any> {
|
public getSendMaxInfo(wallet: any, opts: any): Promise<any> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
@ -1309,11 +1332,14 @@ export class WalletProvider {
|
||||||
return resolve(res);
|
return resolve(res);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
public getProtocolHandler(coin: string): string {
|
public getProtocolHandler(coin: string): string {
|
||||||
if (coin == 'bch') return 'bitcoincash';
|
if (coin == 'bch') {
|
||||||
else return 'bitcoin';
|
return 'bitcoincash';
|
||||||
|
} else {
|
||||||
|
return 'bitcoin';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public copyCopayers(wallet: any, newWallet: any): Promise<any> {
|
public copyCopayers(wallet: any, newWallet: any): Promise<any> {
|
||||||
|
|
Loading…
Reference in New Issue