copay-crown
Version:
A Secure Crown Wallet
194 lines (170 loc) • 6.25 kB
text/typescript
import { Component } from "@angular/core";
import { TranslateService } from '@ngx-translate/core';
import { NavController } from 'ionic-angular';
import * as lodash from 'lodash';
import { Logger } from "../../../providers/logger/logger";
// Providers
import { BwcErrorProvider } from "../../../providers/bwc-error/bwc-error";
import { BwcProvider } from "../../../providers/bwc/bwc";
import { ExternalLinkProvider } from "../../../providers/external-link/external-link";
import { OnGoingProcessProvider } from "../../../providers/on-going-process/on-going-process";
import { PopupProvider } from "../../../providers/popup/popup";
import { ProfileProvider } from '../../../providers/profile/profile';
import { PushNotificationsProvider } from "../../../providers/push-notifications/push-notifications";
import { TxFormatProvider } from "../../../providers/tx-format/tx-format";
import { WalletProvider } from "../../../providers/wallet/wallet";
export class BitcoinCashPage {
private walletsBTC: any[];
private walletsBCH: any[];
private errors: any;
public availableWallets: any[];
public nonEligibleWallets: any[];
public error: any;
constructor(
private navCtrl: NavController,
private walletProvider: WalletProvider,
private profileProvider: ProfileProvider,
private txFormatProvider: TxFormatProvider,
private onGoingProcessProvider: OnGoingProcessProvider,
private popupProvider: PopupProvider,
private pushNotificationsProvider: PushNotificationsProvider,
private externalLinkProvider: ExternalLinkProvider,
private bwcErrorProvider: BwcErrorProvider,
private bwcProvider: BwcProvider,
private logger: Logger,
private translate: TranslateService
) {
this.walletsBTC = this.profileProvider.getWallets({
coin: 'btc',
onlyComplete: true,
network: 'livenet'
});
this.walletsBCH = [];
this.availableWallets = [];
this.nonEligibleWallets = [];
this.errors = this.bwcProvider.getErrors();
}
ionViewWillEnter() {
// Filter out already duplicated wallets
this.walletsBCH = this.profileProvider.getWallets({
coin: 'bch',
network: 'livenet'
});
let xPubKeyIndex = lodash.keyBy(this.walletsBCH, "credentials.xPubKey");
this.walletsBTC = lodash.filter(this.walletsBTC, w => {
return !xPubKeyIndex[w.credentials.xPubKey];
});
lodash.each(this.walletsBTC, (w) => {
if (w.credentials.derivationStrategy != 'BIP44') {
w.excludeReason = this.translate.instant('Non BIP44 wallet');
this.nonEligibleWallets.push(w);
} else if (!w.canSign()) {
w.excludeReason = this.translate.instant('Read only wallet');
this.nonEligibleWallets.push(w);
} else if (w.needsBackup) {
w.excludeReason = this.translate.instant('Backup needed');
this.nonEligibleWallets.push(w);
} else {
this.availableWallets.push(w);
}
});
this.availableWallets = this.availableWallets;
this.nonEligibleWallets = this.nonEligibleWallets;
lodash.each(this.availableWallets, (wallet) => {
this.walletProvider.getBalance(wallet, { coin: 'bch' }).then((balance) => {
wallet.bchBalance = this.txFormatProvider.formatAmountStr('bch', balance.availableAmount);
}).catch((err) => {
this.logger.error(err);
});
});
}
public openRecoveryToolLink(): void {
let url = 'https://bitpay.github.io/copay-recovery/';
let optIn = true;
let title = this.translate.instant('Open the recovery tool');
let okText = this.translate.instant('Open');
let cancelText = this.translate.instant('Go Back');
this.externalLinkProvider.open(url, optIn, title, null, okText, cancelText);
}
public duplicate(wallet: any) {
this.logger.debug('Duplicating wallet for BCH: ' + wallet.id + ': ' + wallet.name);
let opts: any = {
name: wallet.name + '[BCH]',
m: wallet.m,
n: wallet.n,
myName: wallet.credentials.copayerName,
networkName: wallet.network,
coin: 'bch',
walletPrivKey: wallet.credentials.walletPrivKey,
compliantDerivation: wallet.credentials.compliantDerivation,
};
let setErr = (err) => {
this.bwcErrorProvider.cb(err, 'Could not duplicate').then((errorMsg) => {
this.logger.warn(errorMsg);
this.popupProvider.ionicAlert(errorMsg, null, 'OK');
return;
});
}
let importOrCreate = () => {
return new Promise((resolve, reject) => {
this.walletProvider.getStatus(wallet, {}).then((status: any) => {
opts.singleAddress = status.wallet.singleAddress;
// first try to import
this.profileProvider.importExtendedPrivateKey(opts.extendedPrivateKey, opts).then((newWallet) => {
return resolve({ newWallet });
}).catch((err) => {
if (!(err instanceof this.errors.NOT_AUTHORIZED)) {
return reject(err);
}
// create and store a wallet
this.profileProvider.createWallet(opts).then((newWallet) => {
return resolve({ newWallet, isNew: true });
});
});
}).catch((err) => {
return reject(err);
});
});
};
// Multisig wallets? add Copayers
function addCopayers(newWallet, isNew, cb) {
if (!isNew) return cb();
if (wallet.n == 1) return cb();
this.logger.info('Adding copayers for BCH wallet config:' + wallet.m + '-' + wallet.n);
this.walletProvider.copyCopayers(wallet, newWallet, (err) => {
if (err) {
return setErr(err);
}
return cb();
});
};
this.walletProvider.getKeys(wallet).then((keys) => {
opts.extendedPrivateKey = keys.xPrivKey;
this.onGoingProcessProvider.set('duplicatingWallet');
importOrCreate().then((result: any) => {
let newWallet = result.newWallet;
let isNew = result.isNew;
this.walletProvider.updateRemotePreferences(newWallet);
this.pushNotificationsProvider.updateSubscription(newWallet);
addCopayers(newWallet, isNew, (err) => {
this.onGoingProcessProvider.clear();
if (err) return setErr(err);
if (isNew)
this.walletProvider.startScan(newWallet);
this.navCtrl.popToRoot({ animate: false }).then(() => {
this.navCtrl.parent.select(0);
});
});
}).catch((err) => {
this.onGoingProcessProvider.clear();
setErr(err);
});
}).catch((err) => {
setErr(err);
});
}
}