copay-crown
Version:
A Secure Crown Wallet
248 lines (203 loc) • 7.39 kB
text/typescript
import { Injectable } from '@angular/core';
import { Logger } from '../../providers/logger/logger';
import { BwcProvider } from '../bwc/bwc';
import { ConfigProvider } from '../config/config';
import { FilterProvider } from '../filter/filter';
import { RateProvider } from '../rate/rate';
import * as _ from "lodash";
export class TxFormatProvider {
private bitcoreCash: any;
// TODO: implement configService
public pendingTxProposalsCountForUs: number
constructor(
private bwcProvider: BwcProvider,
private rate: RateProvider,
private configProvider: 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 {
let settings = this.configProvider.get().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.bwcProvider.getUtils().formatAmount(satoshis, settings.unitCode, opts);
}
public formatAmountStr(coin: string, satoshis: number): string {
if (isNaN(satoshis)) return;
return (this.formatAmount(satoshis) + ' ' + coin.toUpperCase());
}
public toFiat(coin: string, satoshis: number, code: string): Promise<any> {
// TODO not a promise
return new Promise((resolve, reject) => {
if (isNaN(satoshis)) return resolve();
var v1;
v1 = this.rate.toFiat(satoshis, code, coin);
if (!v1) return resolve(null);
return resolve(v1.toFixed(2));
});
}
public formatToUSD(coin: string, satoshis: number): Promise<any> {
// TODO not a promise
return new Promise((resolve, reject) => {
let v1: number;
if (isNaN(satoshis)) return resolve();
v1 = this.rate.toFiat(satoshis, 'USD', coin);
if (!v1) return resolve(null);
return resolve(v1.toFixed(2));
});
};
public formatAlternativeStr(coin: string, satoshis: number): string {
if (isNaN(satoshis)) return;
let settings = this.configProvider.get().wallet.settings;
let val = (() => {
var v1 = parseFloat((this.rate.toFiat(satoshis, settings.alternativeIsoCode, coin)).toFixed(2));
v1 = this.filter.formatFiatAmount(v1);
if (!v1) return null;
return v1 + ' ' + settings.alternativeIsoCode;
}).bind(this);
if (!this.rate.isAvailable()) return null;
return val();
};
public processTx(coin: string, tx: any, useLegacyAddress?: boolean): 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, (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;
// 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);
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];
}
if (tx.addressTo && coin == 'bch' && !useLegacyAddress) {
tx.addressTo = this.toCashAddress(tx.addressTo);
}
return tx;
};
public formatPendingTxps(txps): any {
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)
// TODO tx.wallet = profileService.getWallet(tx.walletId);
tx.wallet = {
coin: "btc",
copayerId: "asdasdasdasd"
}
// hardcoded tx.wallet ^
if (!tx.wallet) {
this.logger.debug("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;
};
public parseAmount(coin: string, amount: any, currency: string): any {
let settings = this.configProvider.get().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 = Number(this.rate.fromFiat(amount, currency, coin).toFixed(0));
} else if (currency == 'sat') {
amountSat = Number(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), 10);
amountUnitStr = this.formatAmountStr(coin, amountSat);
// convert unit to BTC or BCH
amount = (amountSat * satToBtc).toFixed(8);
currency = (coin).toUpperCase();
}
return {
amount,
currency,
alternativeIsoCode,
amountSat,
amountUnitStr
};
};
public satToUnit(amount: any): number {
let settings = this.configProvider.get().wallet.settings;
var unitToSatoshi = settings.unitToSatoshi;
var satToUnit = 1 / unitToSatoshi;
var unitDecimals = settings.unitDecimals;
return parseFloat((amount * satToUnit).toFixed(unitDecimals));
};
}