From 6111439ef0c66e14fe25fbd0c0028f92d3333ab4 Mon Sep 17 00:00:00 2001 From: Gabriel Masclef Date: Tue, 26 Sep 2017 17:40:14 -0300 Subject: [PATCH] Feat: tx-formt provider implemented --- src/app/app.module.ts | 4 + src/providers/filter/filter.ts | 52 ++++++ src/providers/rate/rate.ts | 1 + src/providers/tx-format/tx-format.ts | 228 +++++++++++++++++++++++++++ 4 files changed, 285 insertions(+) create mode 100644 src/providers/filter/filter.ts create mode 100644 src/providers/tx-format/tx-format.ts diff --git a/src/app/app.module.ts b/src/app/app.module.ts index ee85dfa4f..5dd93610b 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -53,6 +53,7 @@ import { CustomAmountPage } from '../pages/receive/custom-amount/custom-amount'; import { AppProvider } from '../providers/app/app'; import { BwcProvider } from '../providers/bwc/bwc'; import { ConfigProvider } from '../providers/config/config'; +import { FilterProvider } from '../providers/filter/filter'; import { LanguageProvider } from '../providers/language/language'; import { PersistenceProvider, persistenceProviderFactory } from '../providers/persistence/persistence'; import { PlatformProvider } from '../providers/platform/platform'; @@ -60,6 +61,7 @@ import { PopupProvider } from '../providers/popup/popup'; import { ProfileProvider } from '../providers/profile/profile'; import { RateProvider } from '../providers/rate/rate'; import { ScanProvider } from '../providers/scan/scan'; +import { TxFormatProvider } from '../providers/tx-format/tx-format'; import { WalletProvider } from '../providers/wallet/wallet'; export function createTranslateLoader(http: Http) { @@ -93,6 +95,7 @@ let providers: any = [ BwcProvider, ConfigProvider, Clipboard, + FilterProvider, LanguageProvider, PlatformProvider, ProfileProvider, @@ -104,6 +107,7 @@ let providers: any = [ ScanProvider, SocialSharing, Toast, + TxFormatProvider, WalletProvider, { provide: ErrorHandler, diff --git a/src/providers/filter/filter.ts b/src/providers/filter/filter.ts new file mode 100644 index 000000000..239a8b1a0 --- /dev/null +++ b/src/providers/filter/filter.ts @@ -0,0 +1,52 @@ +import { Injectable } from '@angular/core'; +import { Http } from '@angular/http'; +import 'rxjs/add/operator/map'; +import * as _ from "lodash"; + +@Injectable() +export class FilterProvider { + + public formats: any; + + constructor(public http: Http) { + console.log('Hello FilterProvider Provider'); + this.formats = { + CURRENCY_SYM: "$", + DECIMAL_SEP: ".", + GROUP_SEP: "," + } + } + + formatFiatAmount(amount: number) { + var value: any; + var sep: any; + var group: any; + var intValue: any; + var floatValue: any; + var finalValue: any; + + var fractionSize = 2; + value = _.round(amount, fractionSize).toString(); + sep = value.indexOf(this.formats.DECIMAL_SEP); + group = value.indexOf(this.formats.GROUP_SEP); + + if (amount >= 0) { + if (group > 0) { + if (sep < 0) { + return value; + } + intValue = value.substring(0, sep); + floatValue = parseFloat(value.substring(sep)); + floatValue = floatValue.toFixed(2); + floatValue = floatValue.toString().substring(1); + finalValue = intValue + floatValue; + return finalValue; + } else { + value = parseFloat(value); + return value.toFixed(2); + } + } + return 0; + } + +} diff --git a/src/providers/rate/rate.ts b/src/providers/rate/rate.ts index 8d27ad240..1839c4d16 100644 --- a/src/providers/rate/rate.ts +++ b/src/providers/rate/rate.ts @@ -23,6 +23,7 @@ export class RateProvider { this._ratesBCH = {}; this.SAT_TO_BTC = 1 / 1e8; this.BTC_TO_SAT = 1e8; + this.updateRates(); } updateRates(): Promise { diff --git a/src/providers/tx-format/tx-format.ts b/src/providers/tx-format/tx-format.ts new file mode 100644 index 000000000..6d16fc6a1 --- /dev/null +++ b/src/providers/tx-format/tx-format.ts @@ -0,0 +1,228 @@ +import { Injectable } from '@angular/core'; +import { Http } from '@angular/http'; +import 'rxjs/add/operator/map'; +import { BwcProvider } from '../bwc/bwc'; +import { RateProvider } from '../rate/rate'; +import { ConfigProvider } from '../config/config'; +import { FilterProvider } from '../filter/filter'; +import * as _ from "lodash"; + +@Injectable() +export class TxFormatProvider { + + // TODO: implement configService + public config: any; + public pendingTxProposalsCountForUs: number + + constructor( + public http: Http, + private bwc: BwcProvider, + private rate: RateProvider, + private configProvider: ConfigProvider, + private filter: FilterProvider + ) { + console.log('Hello TxFormatProvider Provider'); + console.log("configProvider", this.configProvider.get()); + } + + formatAmount(satoshis: number, fullPrecision?: boolean) { + this.config = this.configProvider.get(); + var settings = this.config.wallet.settings; + + if (settings.unitCode == 'sat') return satoshis; + + //TODO : now only works for english, specify opts to change thousand separator and decimal separator + var opts = { + fullPrecision: !!fullPrecision + }; + return this.bwc.getUtils().formatAmount(satoshis, settings.unitCode, opts); + } + + formatAmountStr(coin: string, satoshis: number) { + if (isNaN(satoshis)) return; + return this.formatAmount(satoshis) + ' ' + (coin).toUpperCase(); + } + + toFiat(coin: string, satoshis: number, code: string): Promise { + return new Promise ((resolve, reject) => { + if (isNaN(satoshis)) resolve(); + var v1; + v1 = this.rate.toFiat(satoshis, code, coin); + if (!v1) resolve(null); + resolve(v1.toFixed(2)); + }); + } + + formatToUSD(coin: string, satoshis: number) { + return new Promise ((resolve, reject) => { + var v1; + if (isNaN(satoshis)) resolve(); + v1 = this.rate.toFiat(satoshis, 'USD', coin); + if (!v1) resolve(null); + resolve(v1.toFixed(2)); + }); + }; + + formatAlternativeStr(coin: string, satoshis: number) { + return new Promise ((resolve, reject) => { + if (isNaN(satoshis)) resolve(); + this.config = this.configProvider.get(); + var settings = this.config.wallet.settings; + + var v1 = parseFloat((this.rate.toFiat(satoshis, settings.alternativeIsoCode, coin)).toFixed(2)); + var v1FormatFiat = this.filter.formatFiatAmount(v1); + if (!v1FormatFiat) resolve(null); + + resolve(v1FormatFiat + ' ' + settings.alternativeIsoCode); + }); + }; + + processTx(coin: string, tx: any) { + if (!tx || tx.action == 'invalid') + return tx; + + // New transaction output format + if (tx.outputs && tx.outputs.length) { + + var outputsNr = tx.outputs.length; + + if (tx.action != 'received') { + if (outputsNr > 1) { + tx.recipientCount = outputsNr; + tx.hasMultiplesOutputs = true; + } + tx.amount = _.reduce(tx.outputs, function(total: any, o: any) { + o.amountStr = this.formatAmountStr(coin, o.amount); + o.alternativeAmountStr = this.formatAlternativeStr(coin, o.amount); + return total + o.amount; + }, 0); + } + tx.toAddress = tx.outputs[0].toAddress; + } + + tx.amountStr = this.formatAmountStr(coin, tx.amount); + tx.alternativeAmountStr = this.formatAlternativeStr(coin, tx.amount); + tx.feeStr = this.formatAmountStr(coin, tx.fee || tx.fees); + + if (tx.amountStr) { + tx.amountValueStr = tx.amountStr.split(' ')[0]; + tx.amountUnitStr = tx.amountStr.split(' ')[1]; + } + + return tx; + }; + + formatPendingTxps(txps) { + this.pendingTxProposalsCountForUs = 0; + var now = Math.floor(Date.now() / 1000); + + /* To test multiple outputs... + var txp = { + message: 'test multi-output', + fee: 1000, + createdOn: new Date() / 1000, + outputs: [] + }; + function addOutput(n) { + txp.outputs.push({ + amount: 600, + toAddress: '2N8bhEwbKtMvR2jqMRcTCQqzHP6zXGToXcK', + message: 'output #' + (Number(n) + 1) + }); + }; + lodash.times(150, addOutput); + txps.push(txp); + */ + + _.each(txps, function(tx) { + + // no future transactions... + if (tx.createdOn > now) + tx.createdOn = now; + + // TODO: implement profileService.getWallet(tx.walletId) + //tx.wallet = profileService.getWallet(tx.walletId); + tx.wallet = { + coin: "btc", + copayerId: "asdasdasdasd" + } + + + if (!tx.wallet) { + console.log("no wallet at txp?"); + return; + } + + tx = this.processTx(tx.wallet.coin, tx); + + var action: any = _.find(tx.actions, { + copayerId: tx.wallet.copayerId + }); + + if (!action && tx.status == 'pending') { + tx.pendingForUs = true; + } + + if (action && action.type == 'accept') { + tx.statusForUs = 'accepted'; + } else if (action && action.type == 'reject') { + tx.statusForUs = 'rejected'; + } else { + tx.statusForUs = 'pending'; + } + + if (!tx.deleteLockTime) + tx.canBeRemoved = true; + }); + + return txps; + }; + + parseAmount(coin: string, amount: any, currency: string) { + this.config = this.configProvider.get(); + var settings = this.config.wallet.settings; + + var satToBtc = 1 / 100000000; + var unitToSatoshi = settings.unitToSatoshi; + var amountUnitStr; + var amountSat; + var alternativeIsoCode = settings.alternativeIsoCode; + + // If fiat currency + if (currency != 'BCH' && currency != 'BTC' && currency != 'sat') { + amountUnitStr = this.filter.formatFiatAmount(amount) + ' ' + currency; + amountSat = this.rate.fromFiat(amount, currency, coin).toFixed(0); + } else if (currency == 'sat') { + amountSat = amount; + amountUnitStr = this.formatAmountStr(coin, amountSat); + // convert sat to BTC or BCH + amount = (amountSat * satToBtc).toFixed(8); + currency = (coin).toUpperCase(); + } else { + amountSat = parseInt((amount * unitToSatoshi).toFixed(0)); + amountUnitStr = this.formatAmountStr(coin, amountSat); + // convert unit to BTC or BCH + amount = (amountSat * satToBtc).toFixed(8); + currency = (coin).toUpperCase(); + } + + return { + amount: amount, + currency: currency, + alternativeIsoCode: alternativeIsoCode, + amountSat: amountSat, + amountUnitStr: amountUnitStr + }; + }; + + satToUnit(amount: any) { + this.config = this.configProvider.get(); + var settings = this.config.wallet.settings; + + var unitToSatoshi = settings.unitToSatoshi; + var satToUnit = 1 / unitToSatoshi; + var unitDecimals = settings.unitDecimals; + return parseFloat((amount * satToUnit).toFixed(unitDecimals)); + }; + +}