diff --git a/package.json b/package.json
index 64355d676..9f3964fd9 100644
--- a/package.json
+++ b/package.json
@@ -82,7 +82,7 @@
"ajv": "^5.5.2",
"angular2-moment": "^1.7.1",
"autoprefixer": "^7.2.4",
- "bitcore-wallet-client": "^6.4.0",
+ "bitcore-wallet-client": "^6.5.0",
"buffer-compare": "^1.1.1",
"cordova-android": "6.4.0",
"cordova-clipboard": "^1.1.1",
diff --git a/src/pages/incoming-data-menu/incoming-data-menu.ts b/src/pages/incoming-data-menu/incoming-data-menu.ts
index 3f6d90166..a3507d7e2 100644
--- a/src/pages/incoming-data-menu/incoming-data-menu.ts
+++ b/src/pages/incoming-data-menu/incoming-data-menu.ts
@@ -6,10 +6,11 @@ import { NavParams, ViewController } from 'ionic-angular';
templateUrl: 'incoming-data-menu.html',
})
export class IncomingDataMenuPage {
+ public https: boolean;
public data: string;
public type: string;
- public https: boolean;
+ public coin: string;
constructor(
private viewCtrl: ViewController,
@@ -21,6 +22,7 @@ export class IncomingDataMenuPage {
ionViewDidLoad() {
this.data = this.navParams.data.data;
this.type = this.navParams.data.type;
+ this.coin = this.navParams.data.coin;
if (this.type === 'url') {
if (this.data.indexOf('https://') === 0) {
this.https = true;
@@ -29,6 +31,11 @@ export class IncomingDataMenuPage {
}
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 });
}
}
\ No newline at end of file
diff --git a/src/pages/receive/custom-amount/custom-amount.ts b/src/pages/receive/custom-amount/custom-amount.ts
index 218150c62..10f1edddf 100644
--- a/src/pages/receive/custom-amount/custom-amount.ts
+++ b/src/pages/receive/custom-amount/custom-amount.ts
@@ -2,6 +2,9 @@ import { Component } from '@angular/core';
import { NavParams } from 'ionic-angular';
import { Logger } from '@nsalaun/ng-logger';
+// Native
+import { SocialSharing } from '@ionic-native/social-sharing';
+
//providers
import { ProfileProvider } from '../../../providers/profile/profile';
import { PlatformProvider } from '../../../providers/platform/platform';
@@ -26,14 +29,17 @@ export class CustomAmountPage {
private profileProvider: ProfileProvider,
private platformProvider: PlatformProvider,
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.coin = this.navParams.data.coin;
let walletId = this.navParams.data.walletId;
this.wallet = this.profileProvider.getWallet(walletId);
this.showShareButton = this.platformProvider.isCordova;
+
+ let addr = this.navParams.data.toAddress;
+ this.address = this.walletProvider.getAddressView(this.wallet, addr);
}
ionViewDidLoad() {
@@ -42,16 +48,11 @@ export class CustomAmountPage {
}
private updateQrAddress(): void {
- this.setProtocolHandler();
- this.qrAddress = this.protocolHandler + ":" + this.address + "?amount=" + this.amount;
+ this.qrAddress = this.walletProvider.getProtoAddress(this.wallet, this.address) + "?amount=" + this.amount;
}
- private setProtocolHandler(): void {
- this.protocolHandler = this.walletProvider.getProtocolHandler(this.wallet.coin);
- }
-
- public shareAddress = function () {
- //window.plugins.socialsharing.share(this.qrAddress, null, null, null); TODO
+ public shareAddress(): void {
+ this.socialSharing.share(this.qrAddress);
}
}
diff --git a/src/pages/receive/receive.ts b/src/pages/receive/receive.ts
index 9277bf4f0..f530b113d 100644
--- a/src/pages/receive/receive.ts
+++ b/src/pages/receive/receive.ts
@@ -2,15 +2,15 @@ import { Component } from '@angular/core';
import { Logger } from '@nsalaun/ng-logger';
import { NavController, Events, AlertController } from 'ionic-angular';
-//native
+// Native
import { SocialSharing } from '@ionic-native/social-sharing';
-//pages
+// Pages
import { AmountPage } from '../send/amount/amount';
import { CopayersPage } from './../add/copayers/copayers';
import { BackupGamePage } from '../backup/backup-game/backup-game';
-//providers
+// Providers
import { WalletProvider } from '../../providers/wallet/wallet';
import { ProfileProvider } from '../../providers/profile/profile';
import { PlatformProvider } from '../../providers/platform/platform';
@@ -62,15 +62,10 @@ export class ReceivePage {
private onWalletSelect(wallet: any): any {
this.wallet = wallet;
if (this.wallet) {
- this.setProtocolHandler();
this.setAddress();
}
}
- private setProtocolHandler(): void {
- this.protocolHandler = this.walletProvider.getProtocolHandler(this.wallet.coin);
- }
-
private checkSelectedWallet(wallet: any, wallets: any): any {
if (!wallet) return wallets[0];
let w = _.find(wallets, (w: any) => {
@@ -99,7 +94,7 @@ export class ReceivePage {
this.walletProvider.getAddress(this.wallet, newAddr).then((addr) => {
this.loading = false
- this.address = addr;
+ this.address = this.walletProvider.getAddressView(this.wallet, addr);
this.updateQrAddress();
}).catch((err) => {
this.loading = false;
@@ -108,13 +103,12 @@ export class ReceivePage {
}
private updateQrAddress(): void {
- this.qrAddress = this.protocolHandler + ":" + this.address;
+ this.qrAddress = this.walletProvider.getProtoAddress(this.wallet, this.address);
}
public shareAddress(): void {
- let protocol = 'bitcoin';
- if (this.wallet.coin == 'bch') protocol += 'cash';
- this.socialSharing.share(protocol + ':' + this.address);
+ if (!this.showShareButton) return;
+ this.socialSharing.share(this.qrAddress);
}
public showWallets(): void {
diff --git a/src/pages/scan/scan.ts b/src/pages/scan/scan.ts
index 54adadaff..719a88ef0 100644
--- a/src/pages/scan/scan.ts
+++ b/src/pages/scan/scan.ts
@@ -96,7 +96,7 @@ export class ScanPage {
this.modalIsOpen = false;
switch (data.redirTo) {
case 'AmountPage':
- this.sendPaymentToAddress(data.value);
+ this.sendPaymentToAddress(data.value, data.coin);
break;
case 'AddressBookPage':
this.addToAddressBook(data.value);
@@ -125,9 +125,9 @@ export class ScanPage {
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.push(AmountPage, { toAddress: bitcoinAddress });
+ this.navCtrl.push(AmountPage, { toAddress: bitcoinAddress, coin: coin });
}
private addToAddressBook(bitcoinAddress: string): void {
diff --git a/src/pages/send/confirm/confirm.html b/src/pages/send/confirm/confirm.html
index 105044f37..79bbe6c96 100644
--- a/src/pages/send/confirm/confirm.html
+++ b/src/pages/send/confirm/confirm.html
@@ -55,9 +55,9 @@
-
-
-
{{tx.toAddress}}
+
+
+ {{tx.origToAddress}}
{{tx.name}}
@@ -76,9 +76,9 @@
-
-
-
{{tx.toAddress}}
+
+
+ {{tx.origToAddress}}
{{tx.name}}
@@ -128,4 +128,4 @@
-
+
\ No newline at end of file
diff --git a/src/pages/send/confirm/confirm.ts b/src/pages/send/confirm/confirm.ts
index abf679ea3..bc1c2c9ec 100644
--- a/src/pages/send/confirm/confirm.ts
+++ b/src/pages/send/confirm/confirm.ts
@@ -11,6 +11,7 @@ import { FeeWarningPage } from '../fee-warning/fee-warning';
import { SuccessModalPage } from '../../success/success';
// Providers
+import { BwcProvider } from '../../../providers/bwc/bwc';
import { ConfigProvider } from '../../../providers/config/config';
import { PlatformProvider } from '../../../providers/platform/platform';
import { ProfileProvider } from '../../../providers/profile/profile';
@@ -28,6 +29,8 @@ import { TxFormatProvider } from '../../../providers/tx-format/tx-format';
})
export class ConfirmPage {
+ private bitcoreCash: any;
+
public countDown = null;
public CONFIRM_LIMIT_USD: number;
public FEE_TOO_HIGH_LIMIT_PER: number;
@@ -55,6 +58,7 @@ export class ConfirmPage {
public usingCustomFee: boolean = false;
constructor(
+ private bwcProvider: BwcProvider,
private navCtrl: NavController,
private navParams: NavParams,
private logger: Logger,
@@ -71,6 +75,7 @@ export class ConfirmPage {
private txFormatProvider: TxFormatProvider,
private events: Events
) {
+ this.bitcoreCash = this.bwcProvider.getBitcoreCash();
this.CONFIRM_LIMIT_USD = 20;
this.FEE_TOO_HIGH_LIMIT_PER = 15;
this.config = this.configProvider.get();
@@ -95,8 +100,15 @@ export class ConfirmPage {
coin: this.navParams.data.coin,
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.showAddress = false;
this.walletSelectorTitle = 'Send from'; // TODO gettextCatalog
diff --git a/src/pages/settings/advanced/advanced.html b/src/pages/settings/advanced/advanced.html
index 1f152dc8d..a7119c1f8 100644
--- a/src/pages/settings/advanced/advanced.html
+++ b/src/pages/settings/advanced/advanced.html
@@ -12,7 +12,7 @@
@@ -20,11 +20,23 @@
+
+
+
+
+
+ If enabled, Bitcoin Cash addresses will be shown using Copay style address, and not the new cashaddr format.
+
+
+
@@ -37,7 +49,7 @@
diff --git a/src/pages/settings/advanced/advanced.ts b/src/pages/settings/advanced/advanced.ts
index 2788616c6..3891bdfef 100644
--- a/src/pages/settings/advanced/advanced.ts
+++ b/src/pages/settings/advanced/advanced.ts
@@ -13,6 +13,7 @@ export class AdvancedPage {
public spendUnconfirmed: boolean;
public recentTransactionsEnabled: boolean;
public showNextSteps: boolean;
+ public useLegacyAddress: boolean;
constructor(
private configProvider: ConfigProvider,
@@ -30,6 +31,7 @@ export class AdvancedPage {
this.spendUnconfirmed = config.wallet.spendUnconfirmed;
this.recentTransactionsEnabled = config.recentTransactions.enabled;
this.showNextSteps = config.showNextSteps.enabled;
+ this.useLegacyAddress = config.wallet.useLegacyAddress;
}
public spendUnconfirmedChange(): void {
@@ -50,6 +52,15 @@ export class AdvancedPage {
this.configProvider.set(opts);
}
+ public useLegacyAddressChange(): void {
+ let opts = {
+ wallet: {
+ useLegacyAddress: this.useLegacyAddress
+ }
+ };
+ this.configProvider.set(opts);
+ }
+
public nextStepsChange(): void {
let opts = {
showNextSteps: {
diff --git a/src/pages/tx-details/tx-details.ts b/src/pages/tx-details/tx-details.ts
index 722261c1c..5f1931424 100644
--- a/src/pages/tx-details/tx-details.ts
+++ b/src/pages/tx-details/tx-details.ts
@@ -63,7 +63,11 @@ export class TxDetailsPage {
this.txsUnsubscribedForNotifications = this.config.confirmedTxsNotifications ? !this.config.confirmedTxsNotifications.enabled : true;
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 {
this.blockexplorerUrl = 'insight.bitpay.com';
}
@@ -153,7 +157,7 @@ export class TxDetailsPage {
this.walletProvider.getTx(this.wallet, this.txId).then((tx: any) => {
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);
this.btx.feeFiatStr = v;
this.btx.feeRateStr = (this.btx.fees / (this.btx.amount + this.btx.fees) * 100).toFixed(2) + '%';
diff --git a/src/providers/config/config.ts b/src/providers/config/config.ts
index 0d9d2ccdd..5b8e45eaa 100644
--- a/src/providers/config/config.ts
+++ b/src/providers/config/config.ts
@@ -11,6 +11,7 @@ interface Config {
};
wallet: {
+ useLegacyAddress: boolean,
requiredCopayers: number;
totalCopayers: number;
spendUnconfirmed: boolean;
@@ -101,6 +102,7 @@ const configDefault: Config = {
// wallet default config
wallet: {
+ useLegacyAddress: false,
requiredCopayers: 2,
totalCopayers: 3,
spendUnconfirmed: false,
diff --git a/src/providers/incoming-data/incoming-data.ts b/src/providers/incoming-data/incoming-data.ts
index 42fbef7c3..6bf6e8827 100644
--- a/src/providers/incoming-data/incoming-data.ts
+++ b/src/providers/incoming-data/incoming-data.ts
@@ -80,6 +80,12 @@ export class IncomingDataProvider {
coin = 'bch';
parsed = this.bwcProvider.getBitcoreCash().URI(data);
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;
amount = parsed.amount ? parsed.amount : '';
@@ -156,7 +162,8 @@ export class IncomingDataProvider {
if (this.navCtrl.getActive().name === 'ScanPage') {
this.showMenu({
data: data,
- type: 'bitcoinAddress'
+ type: 'bitcoinAddress',
+ coin: 'btc'
});
} else {
let coin = 'btc';
diff --git a/src/providers/tx-format/tx-format.ts b/src/providers/tx-format/tx-format.ts
index fa9c5d50c..13bd2656c 100644
--- a/src/providers/tx-format/tx-format.ts
+++ b/src/providers/tx-format/tx-format.ts
@@ -10,17 +10,30 @@ import * as _ from "lodash";
@Injectable()
export class TxFormatProvider {
+ private bitcoreCash: any;
+
// TODO: implement configService
public pendingTxProposalsCountForUs: number
constructor(
- private bwc: BwcProvider,
+ private bwcProvider: BwcProvider,
private rate: RateProvider,
private config: ConfigProvider,
private filter: FilterProvider,
private logger: Logger
) {
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 {
@@ -32,7 +45,7 @@ export class TxFormatProvider {
var opts = {
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 {
@@ -78,7 +91,7 @@ export class TxFormatProvider {
return val();
};
- public processTx(coin: string, tx: any): any {
+ public processTx(coin: string, tx: any, useLegacyAddress?: boolean): any {
if (!tx || tx.action == 'invalid')
return tx;
@@ -99,6 +112,11 @@ export class TxFormatProvider {
}, 0);
}
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);
@@ -110,6 +128,10 @@ export class TxFormatProvider {
tx.amountUnitStr = tx.amountStr.split(' ')[1];
}
+ if (tx.addressTo && coin == 'bch' && !useLegacyAddress) {
+ tx.addressTo = this.toCashAddress(tx.addressTo);
+ }
+
return tx;
};
diff --git a/src/providers/wallet/wallet.ts b/src/providers/wallet/wallet.ts
index 6b1c51d82..5f71a603d 100644
--- a/src/providers/wallet/wallet.ts
+++ b/src/providers/wallet/wallet.ts
@@ -1,7 +1,9 @@
import { Injectable } from '@angular/core';
import { Events } from 'ionic-angular';
import { Logger } from '@nsalaun/ng-logger';
+import * as lodash from 'lodash';
+// Providers
import { ConfigProvider } from '../config/config';
import { BwcProvider } from '../bwc/bwc';
import { TxFormatProvider } from '../tx-format/tx-format';
@@ -12,8 +14,6 @@ import { FilterProvider } from '../filter/filter';
import { PopupProvider } from '../popup/popup';
import { OnGoingProcessProvider } from '../on-going-process/on-going-process';
import { TouchIdProvider } from '../touchid/touchid';
-
-import * as lodash from 'lodash';
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 {
return new Promise((resolve, reject) => {
this.persistenceProvider.getLastAddress(wallet.id).then((addr) => {
@@ -1299,7 +1322,7 @@ export class WalletProvider {
return reject(err);
});
});
- };
+ }
public getSendMaxInfo(wallet: any, opts: any): Promise {
return new Promise((resolve, reject) => {
@@ -1309,11 +1332,14 @@ export class WalletProvider {
return resolve(res);
});
});
- };
+ }
public getProtocolHandler(coin: string): string {
- if (coin == 'bch') return 'bitcoincash';
- else return 'bitcoin';
+ if (coin == 'bch') {
+ return 'bitcoincash';
+ } else {
+ return 'bitcoin';
+ }
}
public copyCopayers(wallet: any, newWallet: any): Promise {