UNPKG

copay-crown

Version:

A Secure Crown Wallet

307 lines (277 loc) 9.97 kB
import { Component } from '@angular/core'; import { Events, ModalController, NavController, NavParams } from 'ionic-angular'; import * as _ from 'lodash'; import { Logger } from '../../../../providers/logger/logger'; // providers import { CoinbaseProvider } from '../../../../providers/coinbase/coinbase'; 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 { TxFormatProvider } from '../../../../providers/tx-format/tx-format'; import { WalletProvider } from '../../../../providers/wallet/wallet'; // pages import { FinishModalPage } from '../../../finish/finish'; import { CoinbasePage } from '../coinbase'; @Component({ selector: 'page-buy-coinbase', templateUrl: 'buy-coinbase.html', }) export class BuyCoinbasePage { private amount: string; private currency: string; private coin: string; private wallets: any; public paymentMethods: any[]; public selectedPaymentMethodId: any; public buyPrice: string; public buyRequestInfo: any; public amountUnitStr: string; public accessToken: string; public accountId: string; public wallet: any; public network: string; public isFiat: boolean; constructor( private coinbaseProvider: CoinbaseProvider, private logger: Logger, private popupProvider: PopupProvider, private navCtrl: NavController, private events: Events, private externalLinkProvider: ExternalLinkProvider, private onGoingProcessProvider: OnGoingProcessProvider, private navParams: NavParams, private walletProvider: WalletProvider, private txFormatProvider: TxFormatProvider, private profileProvider: ProfileProvider, private modalCtrl: ModalController ) { this.coin = 'btc'; this.isFiat = this.navParams.data.currency != 'BTC' ? true : false; this.amount = this.navParams.data.amount; this.currency = this.navParams.data.currency; this.network = this.coinbaseProvider.getNetwork(); } ionViewDidLoad() { this.logger.info('ionViewDidLoad BuyCoinbasePage'); } ionViewWillEnter() { this.wallets = this.profileProvider.getWallets({ onlyComplete: true, network: this.network, coin: this.coin }); if (_.isEmpty(this.wallets)) { this.showErrorAndBack('No wallets available'); return; } this.onWalletSelect(this.wallets[0]); // Default first wallet } private showErrorAndBack(err: any): void { this.logger.error(err); err = err.errors ? err.errors[0].message : err; this.popupProvider.ionicAlert('Error', err).then(() => { this.navCtrl.pop(); }); } private showError(err: any): void { this.logger.error(err); err = err.errors ? err.errors[0].message : err; this.popupProvider.ionicAlert('Error', err); } private processPaymentInfo(): void { this.onGoingProcessProvider.set('connectingCoinbase'); this.coinbaseProvider.init((err: any, res: any) => { if (err) { this.onGoingProcessProvider.clear(); this.showErrorAndBack(err); return; } let accessToken = res.accessToken; this.coinbaseProvider.buyPrice(accessToken, this.coinbaseProvider.getAvailableCurrency(), (err: any, b: any) => { this.buyPrice = b.data || null; }); this.paymentMethods = []; this.selectedPaymentMethodId = null; this.coinbaseProvider.getPaymentMethods(accessToken, (err: any, p: any) => { if (err) { this.onGoingProcessProvider.clear(); this.showErrorAndBack(err); return; } let hasPrimary; let pm; for (let i = 0; i < p.data.length; i++) { pm = p.data[i]; if (pm.allow_buy) { this.paymentMethods.push(pm); } if (pm.allow_buy && pm.primary_buy) { hasPrimary = true; this.selectedPaymentMethodId = pm.id; } } if (_.isEmpty(this.paymentMethods)) { this.onGoingProcessProvider.clear(); let url = 'https://support.coinbase.com/customer/portal/articles/1148716-payment-methods-for-us-customers'; let msg = 'No payment method available to buy'; let okText = 'More info'; let cancelText = 'Go Back'; this.popupProvider.ionicConfirm(null, msg, okText, cancelText).then((res) => { if (res) this.externalLinkProvider.open(url); this.navCtrl.remove(3, 1); this.navCtrl.pop(); }); return; } if (!hasPrimary) this.selectedPaymentMethodId = this.paymentMethods[0].id; this.buyRequest(); }); }); } public buyRequest(): void { this.coinbaseProvider.init((err, res) => { if (err) { this.onGoingProcessProvider.clear(); this.showErrorAndBack(err); return; } let accessToken = res.accessToken; let accountId = res.accountId; let dataSrc = { amount: this.amount, currency: this.currency, payment_method: this.selectedPaymentMethodId, quote: true }; this.coinbaseProvider.buyRequest(accessToken, accountId, dataSrc, (err: any, data: any) => { this.onGoingProcessProvider.clear(); if (err) { this.showErrorAndBack(err); return; } this.buyRequestInfo = data.data; }); }); } public buyConfirm() { let message = 'Buy bitcoin for ' + this.amountUnitStr; let okText = 'Confirm'; let cancelText = 'Cancel'; this.popupProvider.ionicConfirm(null, message, okText, cancelText).then((ok: boolean) => { if (!ok) return; this.onGoingProcessProvider.set('buyingBitcoin'); this.coinbaseProvider.init((err: any, res: any) => { if (err) { this.onGoingProcessProvider.clear(); this.showError(err); return; } let accessToken = res.accessToken; let accountId = res.accountId; let dataSrc = { amount: this.amount, currency: this.currency, payment_method: this.selectedPaymentMethodId, commit: true }; this.coinbaseProvider.buyRequest(accessToken, accountId, dataSrc, (err: any, b: any) => { if (err) { this.onGoingProcessProvider.clear(); this.showError(err); return; } setTimeout(() => { let tx = b.data ? b.data.transaction : null; if (tx && tx.id) { this.processBuyTx(tx); } else { this._processBuyOrder(b); } }, 8000); }); }); }); }; private processBuyTx(tx: any): void { if (!tx) { this.onGoingProcessProvider.clear(); this.showError('Transaction not found'); return; } this.coinbaseProvider.getTransaction(this.accessToken, this.accountId, tx.id, (err: any, updatedTx: any) => { if (err) { this.onGoingProcessProvider.clear(); this.showError(err); return; } this.walletProvider.getAddress(this.wallet, false).then((walletAddr: string) => { updatedTx.data['toAddr'] = walletAddr; updatedTx.data['status'] = 'pending'; // Forcing "pending" status to process later this.logger.debug('Saving transaction to process later...'); this.coinbaseProvider.savePendingTransaction(updatedTx.data, {}, (err: any) => { this.onGoingProcessProvider.clear(); if (err) this.logger.debug(err); this.openFinishModal(); }); }).catch((err) => { this.onGoingProcessProvider.clear(); this.showError(err); }); }); } private _processBuyOrder(b: any): void { this.coinbaseProvider.getBuyOrder(this.accessToken, this.accountId, b.data.id, (err: any, buyResp: any) => { if (err) { this.onGoingProcessProvider.clear(); this.showError(err); return; } let tx = buyResp.data ? buyResp.data.transaction : null; if (tx && tx.id) { this.processBuyTx(tx); } else { setTimeout(() => { this._processBuyOrder(b); }, 5000); } }); } public showWallets(): void { let id = this.wallet ? this.wallet.credentials.walletId : null; this.events.publish('showWalletsSelectorEvent', this.wallets, id, 'Receive in'); this.events.subscribe('selectWalletEvent', (wallet: any) => { if (!_.isEmpty(wallet)) this.onWalletSelect(wallet); this.events.unsubscribe('selectWalletEvent'); }); } public onWalletSelect(wallet: any) { this.wallet = wallet; let parsedAmount = this.txFormatProvider.parseAmount(this.coin, this.amount, this.currency); // Buy always in BTC this.amount = (parsedAmount.amountSat / 100000000).toFixed(8); this.currency = 'BTC'; this.amountUnitStr = parsedAmount.amountUnitStr; this.onGoingProcessProvider.set('calculatingFee'); this.coinbaseProvider.checkEnoughFundsForFee(this.amount, (err: any) => { this.onGoingProcessProvider.clear(); if (err) { this.showErrorAndBack(err); return; } this.processPaymentInfo(); }); } private openFinishModal(): void { let finishText = 'Bought'; let finishComment = 'Bitcoin purchase completed. Coinbase has queued the transfer to your selected wallet'; let modal = this.modalCtrl.create(FinishModalPage, { finishText, finishComment }, { showBackdrop: true, enableBackdropDismiss: false }); modal.present(); modal.onDidDismiss(() => { this.navCtrl.remove(3, 1); this.navCtrl.pop(); this.navCtrl.push(CoinbasePage, { coin: 'btc' }); }); } }