send view and addressbook Provider

This commit is contained in:
Gabriel Bazán 2017-11-03 16:33:16 -03:00
parent 13809939b2
commit d497baf662
5 changed files with 327 additions and 19 deletions

View File

@ -64,6 +64,8 @@ import { ConfirmPage } from '../pages/send/confirm/confirm';
import { CustomAmountPage } from '../pages/receive/custom-amount/custom-amount';
/* Providers */
import { AddressBookProvider } from '../providers/address-book/address-book';
import { AppProvider } from '../providers/app/app';
import { BwcProvider } from '../providers/bwc/bwc';
import { BwcErrorProvider } from '../providers/bwc-error/bwc-error';
@ -124,6 +126,7 @@ let pages: any = [
];
let providers: any = [
AddressBookProvider,
AndroidFingerprintAuth,
AppProvider,
BwcProvider,

View File

@ -9,13 +9,35 @@
<ion-content padding>
<ion-list>
<ion-label>Recipient</ion-label>
<ion-item>
<ion-item *ngIf="hasWallets">
<ion-icon name="logo-bitcoin" item-left></ion-icon>
<ion-input type="text" placeholder="Search or enter bitcoin address" [(ngModel)]="search" (ngModelChange)="findContact(search)"></ion-input>
<ion-icon class="scanner-icon" name="md-qr-scanner" item-right (click)="openScanner()"></ion-icon>
</ion-item>
</ion-list>
</ion-content>
<div *ngIf="contactsList">
<ion-list>
<ion-label>Contacts</ion-label>
<ion-item *ngFor="let item of contactsList" (click)="goToAmount(item)">
{{item.name}}
</ion-item>
</ion-list>
</div>
<div *ngIf="walletList">
<ion-list>
<ion-label>Transfer to Wallet</ion-label>
<ion-item *ngFor="let item of walletList" (click)="goToAmount(item)">
{{item.name}}
</ion-item>
</ion-list>
</div>
<ion-card *ngIf="!hasWallets">
<ion-card-header>
<span translate>To get started, you'll need to create a bitcoin wallet and get some bitcoin.</span>
</ion-card-header>
<ion-card-content>
<button ion-button (click)="createWallet()" translate>Create bitcoin wallet</button>
</ion-card-content>
</ion-card>
</ion-content>

View File

@ -1,33 +1,181 @@
import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import * as _ from 'lodash';
import { Logger } from '@nsalaun/ng-logger';
//providers
import { ProfileProvider } from '../../providers/profile/profile';
import { WalletProvider } from '../../providers/wallet/wallet';
import { AddressBookProvider } from '../../providers/address-book/address-book';
import { BwcProvider } from '../../providers/bwc/bwc';
import { IncomingDataProvider } from '../../providers/incoming-data/incoming-data';
import { PopupProvider } from '../../providers/popup/popup';
//pages
import { AmountPage } from './amount/amount';
import { CreateWalletPage } from '../add/create-wallet/create-wallet';
import * as _ from 'lodash';
@Component({
selector: 'page-send',
templateUrl: 'send.html',
})
export class SendPage {
public search: string;
public search: string = '';
public wallets: any;
public walletList: any;
public contactsList: any;
public hasWallets: boolean;
public hasContacts: boolean;
public contactsShowMore: boolean;
public searchFocus: boolean;
private CONTACTS_SHOW_LIMIT: number = 10;
private currentContactsPage: number = 0;
constructor(
private navCtrl: NavController,
private profileProvider: ProfileProvider,
private walletProvider: WalletProvider,
private addressBookProvider: AddressBookProvider,
private logger: Logger,
private bwcProvider: BwcProvider,
private incomingDataProvider: IncomingDataProvider,
private popupProvider: PopupProvider
) {
constructor(public navCtrl: NavController) {
}
ionViewDidLoad() {
this.search = '';
console.log('ionViewDidLoad SendPage');
}
openScanner() {
ionViewDidEnter() {
this.wallets = this.profileProvider.getWallets({
onlyComplete: true
});
this.hasWallets = !(_.isEmpty(this.wallets));
console.log(this.hasWallets);
this.updateWalletsList();
this.updateContactsList();
}
private updateWalletsList(): void {
if (!this.hasWallets) return;
this.walletList = [];
_.each(this.wallets, (v: any) => {
this.walletList.push({
color: v.color,
name: v.name,
recipientType: 'wallet',
coin: v.coin,
network: v.network,
getAddress: (): Promise<any> => {
return new Promise((resolve, reject) => {
this.walletProvider.getAddress(v, false).then((addr) => {
return resolve(addr);
}).catch((err) => {
return reject(err);
});
});
}
});
});
}
private updateContactsList() {
this.addressBookProvider.list().then((ab: any) => {
this.hasContacts = _.isEmpty(ab) ? false : true;
if (!this.hasContacts) return;
this.contactsList = [];
_.each(ab, (v: any, k: string) => {
this.contactsList.push({
name: _.isObject(v) ? v.name : v,
address: k,
email: _.isObject(v) ? v.email : null,
recipientType: 'contact',
coin: this.getCoin(k),
getAddress: (): Promise<any> => {
return new Promise((resolve, reject) => {
return resolve(k);
});
}
});
});
let contacts = this.contactsList.slice(0, (this.currentContactsPage + 1) * this.CONTACTS_SHOW_LIMIT);
this.contactsShowMore = this.contactsList.length > contacts.length;
return;
});
}
private getCoin(address: string): string {
let cashAddress = this.bwcProvider.getBitcoreCash().Address.isValid(address, 'livenet');
if (cashAddress) {
return 'bch';
}
return 'btc';
}
public openScanner(): void {
this.navCtrl.parent.select(2);
}
findContact(search: string) {
// TODO: Improve this function
console.log("Send search string", search);
if (search.length === 34) {
this.navCtrl.push(AmountPage, {address: search, sending: true});
public showMore(): void {
this.currentContactsPage++;
this.updateWalletsList();
}
public searchInFocus(): void {
this.searchFocus = true;
}
public searchBlurred(): void {
if (this.search == null || this.search.length == 0) {
this.searchFocus = false;
}
}
findContact(search: string): void {
if (this.incomingDataProvider.redir(search)) return;
if (!search || search.length < 2) {
this.updateContactsList();
return;
}
let result = _.filter(this.contactsList, (item: any) => {
let val = item.name;
return _.includes(val.toLowerCase(), search.toLowerCase());
});
this.contactsList = result;
}
public goToAmount(item: any): void {
item.getAddress().then((addr: string) => {
if (!addr) {
//Error is already formated
this.popupProvider.ionicAlert('Error - no address');
return;
}
this.logger.debug('Got toAddress:' + addr + ' | ' + item.name);
this.navCtrl.push(AmountPage, {
recipientType: item.recipientType,
toAddress: addr,
toName: item.name,
toEmail: item.email,
toColor: item.color,
coin: item.coin
});
return;
}).catch((err: any) => {
this.logger.warn(err);
});
};
public createWallet(): void {
this.navCtrl.push(CreateWalletPage, {});
};
// TODO check if wallets have balance
}

View File

@ -0,0 +1,133 @@
import { Injectable } from '@angular/core';
import { BwcProvider } from '../bwc/bwc';
import { Logger } from '@nsalaun/ng-logger';
import { PersistenceProvider } from '../../providers/persistence/persistence';
import * as _ from 'lodash';
@Injectable()
export class AddressBookProvider {
constructor(
private bwcProvider: BwcProvider,
private logger: Logger,
private persistenceProvider: PersistenceProvider,
) {
console.log('Hello AddressBookProvider Provider');
}
private getNetwork(address: string): string {
let network;
try {
network = (this.bwcProvider.getBitcore().Address(address)).network.name;
} catch (e) {
this.logger.warn('No valid bitcoin address. Trying bitcoin cash...');
network = (this.bwcProvider.getBitcoreCash().Address(address)).network.name;
}
return network;
};
private get(addr: string): Promise<any> {
return new Promise((resolve, reject) => {
this.persistenceProvider.getAddressbook('testnet').then((ab: any) => {
if (ab) ab = JSON.parse(ab);
if (ab && ab[addr]) return resolve(ab[addr]);
this.persistenceProvider.getAddressbook('livenet').then((ab: any) => {
if (ab) ab = JSON.parse(ab);
if (ab && ab[addr]) return resolve(ab[addr]);
return resolve();
}).catch((err: any) => {
return reject();
});
}).catch((err: any) => {
return reject();
});
})
};
public list(): Promise<any> {
return new Promise((resolve, reject) => {
this.persistenceProvider.getAddressbook('testnet').then((ab: any) => {
if (ab) ab = JSON.parse(ab);
ab = ab || {};
this.persistenceProvider.getAddressbook('livenet').then((ab2: any) => {
if (ab2) ab2 = JSON.parse(ab2);
ab2 = ab2 || {};
return resolve(_.defaults(ab2, ab));
}).catch((err: any) => {
return reject(err);
});
}).catch((err: any) => {
return reject('Could not get the Addressbook');
});
});
};
public add(entry: any): Promise<any> {
return new Promise((resolve, reject) => {
var network = this.getNetwork(entry.address);
if (_.isEmpty(network)) return reject('Not valid bitcoin address');
this.persistenceProvider.getAddressbook(network).then((ab: any) => {
if (ab) ab = JSON.parse(ab);
ab = ab || {};
if (_.isArray(ab)) ab = {}; // No array
if (ab[entry.address]) return reject('Entry already exist');
ab[entry.address] = entry;
this.persistenceProvider.setAddressbook(network, JSON.stringify(ab)).then((ab: any) => {
this.list().then((ab: any) => {
return resolve(ab);
}).catch((err: any) => {
return reject(err);
});
}).catch((err: any) => {
return reject('Error adding new entry');
});
}).catch((err: any) => {
return reject(err);
});
});
};
public remove(addr: any): Promise<any> {
return new Promise((resolve, reject) => {
var network = this.getNetwork(addr);
if (_.isEmpty(network)) return reject('Not valid bitcoin address');
this.persistenceProvider.getAddressbook(network).then((ab: any) => {
if (ab) ab = JSON.parse(ab);
ab = ab || {};
if (_.isEmpty(ab)) return reject('Addressbook is empty');
if (!ab[addr]) return reject('Entry does not exist');
delete ab[addr];
this.persistenceProvider.setAddressbook(network, JSON.stringify(ab)).then(() => {
this.list().then((ab: any) => {
return resolve(ab);
}).catch((err: any) => {
return reject(err);
});
}).catch(() => {
return reject('Error deleting entry');
});
}).catch((err: any) => {
return reject(err);
});
});
};
public removeAll(): Promise<any> {
return new Promise((resolve, reject) => {
this.persistenceProvider.removeAddressbook('livenet').then(() => {
this.persistenceProvider.removeAddressbook('testnet').then(() => {
return resolve();
});
}).catch(() => {
return reject('Error deleting addressbook');
}).catch(() => {
return reject('Error deleting addressbook');
});
});
};
}

View File

@ -1,5 +1,5 @@
import { Injectable } from '@angular/core';
import { Events, NavController } from 'ionic-angular';
import { Injectable, Injector, ViewChild } from '@angular/core';
import { Events, NavController, App } from 'ionic-angular';
import { Logger } from '@nsalaun/ng-logger';
//providers
@ -18,10 +18,10 @@ import { ImportWalletPage } from '../../pages/add/import-wallet/import-wallet';
@Injectable()
export class IncomingDataProvider {
private navCtrl: NavController;
constructor(
private app: App,
private events: Events,
private navCtrl: NavController,
private bwcProvider: BwcProvider,
private payproProvider: PayproProvider,
private scanProvider: ScanProvider,
@ -29,6 +29,8 @@ export class IncomingDataProvider {
private logger: Logger,
private appProvider: AppProvider
) {
//TODO Injecting NavController in constructor of service fails with no provider error
this.navCtrl = app.getActiveNav();
console.log('Hello IncomingDataProvider Provider');
}