This repository has been archived on 2022-08-25. You can view files and clone it, but cannot push or open issues or pull requests.
Files
Frontend/src/app/backend.service.ts
Mondei1 b2043e1546 Alerts added
Better status handling
2021-01-01 19:33:07 +01:00

248 lines
6.3 KiB
TypeScript

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Socket } from 'ngx-socket-io';
import { BehaviorSubject } from 'rxjs';
/*
* The following interfaces are copied from the backend.
*
* Checkout src/helper/types.ts and src/models/invoice/invoice.interface.ts
* (in the backend repository) for more information.
*/
export enum CryptoUnits {
BITCOIN = 'BTC',
BITCOINCASH = 'BCH',
ETHEREUM = 'ETH',
LITECOIN = 'LTC',
DOGECOIN = 'DOGE',
MONERO = 'XMR'
}
export interface ICart {
price: number;
name: string;
image: string;
quantity: number;
}
export interface IPaymentMethod {
method: any;
amount: number;
}
export enum PaymentStatus {
TOOLITTLE = -3,
TOOLATE = -2,
CANCELLED = -1,
REQUESTED = 0,
PENDING = 1,
UNCONFIRMED = 2,
DONE = 3,
TOOMUCH = 4
}
export interface IInvoice {
selector: string;
paymentMethods: IPaymentMethod[];
receiveAddress: string;
paidWith?: CryptoUnits;
paid?: number;
transcationHash?: string;
cart?: ICart[];
totalPrice?: number;
currency: string;
dueBy: number;
status?: PaymentStatus;
email?: string;
successUrl: string;
cancelUrl: string;
createdAt?: number;
}
@Injectable({
providedIn: 'root'
})
export class BackendService {
SERVER_URL = 'http://localhost:2009';
// Fill with empty data
invoice: IInvoice = {
selector: '',
paymentMethods: [],
receiveAddress: '',
paid: 0,
currency: 'USD',
dueBy: Date.now(),
successUrl: '',
cancelUrl: ''
};
invoiceUpdate: BehaviorSubject<IInvoice | null>;
// This value is s
confirmations: number;
constructor(
private socket: Socket,
private http: HttpClient
) {
this.confirmations = 0;
this.invoiceUpdate = new BehaviorSubject<IInvoice | null>(null);
this.socket.on('status', (data: any) => {
console.log('Status has been updated to: ', data);
this.invoice.status = data;
this.invoiceUpdate.next(this.invoice);
});
this.socket.on('subscribe', (success: boolean) => {
if (success) { console.log('We\'re getting the progress of this invoice!'); }
else { console.log('Subscribtion failed'); }
});
}
getSocket(): Socket {
return this.socket;
}
subscribeTo(selector: string): void {
this.socket.on('subscribe', (status: boolean) => {
if (status) {
this.updateInvoice();
console.log('Successfully subscribed to this invoice');
}
else { console.log('Failed to subscribe'); }
});
this.socket.on('confirmationUpdate', (update: any) => {
this.confirmations = update.count;
});
this.socket.emit('subscribe', { selector });
}
updateInvoice(): void {
if (this.invoice !== undefined || this.invoice !== null) {
this.setInvoice(this.invoice.selector);
}
}
setInvoice(selector: string): Promise<IInvoice> {
return new Promise(async (resolve, reject) => {
if (selector === undefined || selector === 'undefined' || selector === '') {
reject();
}
this.http.get(this.SERVER_URL + '/invoice/' + selector, {
observe: 'body',
responseType: 'json'
}).toPromise().then((invoice) => {
this.invoice = invoice as IInvoice;
this.invoiceUpdate.next(this.invoice);
resolve(this.invoice);
}).catch(err => {
reject(err);
});
});
}
setPaymentMethod(method: CryptoUnits): Promise<void> {
return new Promise(async (resolve, reject) => {
if (this.invoice === null) { reject('Invoice is not set!'); return; }
this.http.post(`${this.SERVER_URL}/invoice/${this.invoice?.selector}/setmethod`, { method }, {
responseType: 'json'
}).toPromise().then(() => {
this.setInvoice(this.invoice.selector);
}).catch(err => {
reject(err);
});
});
}
getConfirmation(): Promise<number> {
return new Promise(async (resolve, reject) => {
if (this.invoice === null || this.invoice.status !== PaymentStatus.UNCONFIRMED) {
reject('Invoice is not set!');
return;
}
this.http.get(`${this.SERVER_URL}/invoice/${this.invoice.selector}/confirmation`, {
observe: 'body',
responseType: 'json'
}).toPromise().then((res: any) => {
this.confirmations = res.confirmation;
this.invoiceUpdate.next(this.invoice);
resolve(res.confirmation);
}).catch(err => {
reject(err);
});
});
}
/**
* @returns Path to icon
*/
getIcon(unit: CryptoUnits): string {
switch (unit) {
case CryptoUnits.BITCOIN:
return 'assets/Bitcoin.svg';
case CryptoUnits.BITCOINCASH:
return 'assets/BitcoinCash.svg';
case CryptoUnits.DOGECOIN:
return 'assets/Dogecoin.png';
case CryptoUnits.ETHEREUM:
return 'assets/Ethereum.svg';
case CryptoUnits.LITECOIN:
return 'assets/Litecoin.svg';
case CryptoUnits.MONERO:
return 'assets/Monero.svg';
}
}
findCryptoBySymbol(symbol: string): string | null {
for (const coin in CryptoUnits) {
// @ts-ignore: This actually works but I think it's too hacky for TS. Allow me this one, please.
if (CryptoUnits[coin] === symbol.toUpperCase()) {
return coin.charAt(0).toUpperCase() + coin.toLowerCase().slice(1);
}
}
return null;
}
getAmount(): string | undefined {
return this.invoice?.paymentMethods.find(item => {
return item.method === CryptoUnits.BITCOIN;
})?.amount.toFixed(8);
}
getStatus(): string {
switch (this.invoice?.status) {
case PaymentStatus.PENDING:
return 'Pending';
case PaymentStatus.UNCONFIRMED:
return 'Unconfirmed';
case PaymentStatus.DONE:
return 'Paid';
case PaymentStatus.CANCELLED:
return 'Cancelled by user';
case PaymentStatus.TOOLATE:
return 'Expired';
case PaymentStatus.TOOLITTLE:
return 'Paid too little';
case PaymentStatus.TOOMUCH:
return 'Paid too much';
default:
return 'Unknown';
}
}
isInvoiceDone(): boolean {
return this.invoice?.status === PaymentStatus.DONE;
}
isInvoicePending(): boolean {
return this.invoice?.status === PaymentStatus.PENDING;
}
isInvoiceRequested(): boolean {
return this.invoice?.status === PaymentStatus.REQUESTED;
}
}