Add strong typing to variables and functions.
This commit is contained in:
parent
d0e0108274
commit
9921488a04
@ -1,10 +1,8 @@
|
||||
// @ts-ignore
|
||||
import * as accountIndex from '@src/assets/js/block-sync/data/AccountRegistry.json';
|
||||
import {environment} from '@src/environments/environment';
|
||||
const Web3 = require('web3');
|
||||
import Web3 from 'web3';
|
||||
|
||||
const web3 = new Web3(environment.web3Provider);
|
||||
const abi = accountIndex.default;
|
||||
const abi: Array<any> = require('@src/assets/js/block-sync/data/AccountRegistry.json');
|
||||
const web3: Web3 = new Web3(environment.web3Provider);
|
||||
|
||||
export class AccountIndex {
|
||||
contractAddress: string;
|
||||
@ -30,14 +28,14 @@ export class AccountIndex {
|
||||
}
|
||||
|
||||
public async last(numberOfAccounts: number): Promise<Array<string>> {
|
||||
const count = await this.totalAccounts();
|
||||
let lowest = count - numberOfAccounts - 1;
|
||||
const count: number = await this.totalAccounts();
|
||||
let lowest: number = count - numberOfAccounts - 1;
|
||||
if (lowest < 0) {
|
||||
lowest = 0;
|
||||
}
|
||||
let accounts = [];
|
||||
const accounts: Array<string> = [];
|
||||
for (let i = count - 1; i > lowest; i--) {
|
||||
const account = await this.contract.methods.accounts(i).call();
|
||||
const account: string = await this.contract.methods.accounts(i).call();
|
||||
accounts.push(account);
|
||||
}
|
||||
return accounts;
|
||||
@ -46,8 +44,7 @@ export class AccountIndex {
|
||||
public async addToAccountRegistry(address: string): Promise<boolean> {
|
||||
if (!await this.haveAccount(address)) {
|
||||
return await this.contract.methods.add(address).send({from: this.signerAddress});
|
||||
} else {
|
||||
return await this.haveAccount(address);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,8 @@
|
||||
// @ts-ignore
|
||||
import * as registryClient from '@src/assets/js/block-sync/data/TokenUniqueSymbolIndex.json';
|
||||
import Web3 from 'web3';
|
||||
import {environment} from '@src/environments/environment';
|
||||
|
||||
const web3 = new Web3(environment.web3Provider);
|
||||
const abi = registryClient.default;
|
||||
const abi: Array<any> = require('@src/assets/js/block-sync/data/TokenUniqueSymbolIndex.json');
|
||||
const web3: Web3 = new Web3(environment.web3Provider);
|
||||
|
||||
export class TokenRegistry {
|
||||
contractAddress: string;
|
||||
@ -30,7 +28,7 @@ export class TokenRegistry {
|
||||
}
|
||||
|
||||
public async addressOf(identifier: string): Promise<string> {
|
||||
const id = '0x' + web3.utils.padRight(new Buffer(identifier).toString('hex'), 64);
|
||||
const id: string = web3.eth.abi.encodeParameter('bytes32', web3.utils.toHex(identifier));
|
||||
return await this.contract.methods.addressOf(id).call();
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
export class ArraySum {
|
||||
static arraySum(arr: any[]): number {
|
||||
function arraySum(arr: Array<number>): number {
|
||||
return arr.reduce((accumulator, current) => accumulator + current, 0);
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
arraySum
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
function copyToClipboard(text: any): boolean {
|
||||
// create our hidden div element
|
||||
const hiddenCopy = document.createElement('div');
|
||||
const hiddenCopy: HTMLDivElement = document.createElement('div');
|
||||
// set the innerHTML of the div
|
||||
hiddenCopy.innerHTML = text;
|
||||
// set the position to be absolute and off the screen
|
||||
@ -21,7 +21,7 @@ function copyToClipboard(text: any): boolean {
|
||||
// append the div to the body
|
||||
document.body.appendChild(hiddenCopy);
|
||||
// create a selection range
|
||||
const copyRange = document.createRange();
|
||||
const copyRange: Range = document.createRange();
|
||||
// set the copy range to be the hidden div
|
||||
copyRange.selectNode(hiddenCopy);
|
||||
// add the copy range
|
||||
|
@ -3,7 +3,7 @@ import {FormControl, FormGroupDirective, NgForm} from '@angular/forms';
|
||||
|
||||
export class CustomErrorStateMatcher implements ErrorStateMatcher{
|
||||
isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
|
||||
const isSubmitted = form && form.submitted;
|
||||
const isSubmitted: boolean = form && form.submitted;
|
||||
return !!(control && control.invalid && (control.dirty || control.touched || isSubmitted));
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ export class CustomValidator {
|
||||
return null;
|
||||
}
|
||||
|
||||
const valid = regex.test(control.value);
|
||||
const valid: boolean = regex.test(control.value);
|
||||
return valid ? null : error;
|
||||
};
|
||||
}
|
||||
|
@ -1,12 +1,11 @@
|
||||
function exportCsv(arrayData: any[], filename: string, delimiter = ','): void {
|
||||
function exportCsv(arrayData: Array<any>, filename: string, delimiter: string = ','): void {
|
||||
if (arrayData === undefined || arrayData.length === 0) {
|
||||
alert('No data to be exported!');
|
||||
return;
|
||||
}
|
||||
const header = Object.keys(arrayData[0]).join(delimiter) + '\n';
|
||||
let csv = header;
|
||||
let csv: string = Object.keys(arrayData[0]).join(delimiter) + '\n';
|
||||
arrayData.forEach(obj => {
|
||||
let row = [];
|
||||
const row: Array<any> = [];
|
||||
for (const key in obj) {
|
||||
if (obj.hasOwnProperty(key)) {
|
||||
row.push(obj[key]);
|
||||
@ -15,10 +14,10 @@ function exportCsv(arrayData: any[], filename: string, delimiter = ','): void {
|
||||
csv += row.join(delimiter) + '\n';
|
||||
});
|
||||
|
||||
const csvData = new Blob([csv], {type: 'text/csv'});
|
||||
const csvUrl = URL.createObjectURL(csvData);
|
||||
const csvData: Blob = new Blob([csv], {type: 'text/csv'});
|
||||
const csvUrl: string = URL.createObjectURL(csvData);
|
||||
|
||||
let downloadLink = document.createElement('a');
|
||||
const downloadLink: HTMLAnchorElement = document.createElement('a');
|
||||
downloadLink.href = csvUrl;
|
||||
downloadLink.target = '_blank';
|
||||
downloadLink.download = filename + '.csv';
|
||||
|
@ -3,10 +3,10 @@ import {LoggingService} from '@app/_services/logging.service';
|
||||
import {HttpErrorResponse} from '@angular/common/http';
|
||||
import {Router} from '@angular/router';
|
||||
|
||||
// A generalized http repsonse error
|
||||
// A generalized http response error
|
||||
export class HttpError extends Error {
|
||||
public status: number
|
||||
constructor(message, status) {
|
||||
public status: number;
|
||||
constructor(message: string, status: number) {
|
||||
super(message);
|
||||
this.status = status;
|
||||
this.name = 'HttpError';
|
||||
@ -15,7 +15,7 @@ export class HttpError extends Error {
|
||||
|
||||
@Injectable()
|
||||
export class GlobalErrorHandler extends ErrorHandler {
|
||||
private sentencesForWarningLogging: string[] = [];
|
||||
private sentencesForWarningLogging: Array<string> = [];
|
||||
|
||||
constructor(
|
||||
private loggingService: LoggingService,
|
||||
@ -26,15 +26,15 @@ export class GlobalErrorHandler extends ErrorHandler {
|
||||
|
||||
handleError(error: Error): void {
|
||||
this.logError(error);
|
||||
const message = error.message ? error.message : error.toString();
|
||||
const message: string = error.message ? error.message : error.toString();
|
||||
|
||||
// if (error.status) {
|
||||
// error = new Error(message);
|
||||
// }
|
||||
|
||||
const errorTraceString = `Error message:\n${message}.\nStack trace: ${error.stack}`;
|
||||
const errorTraceString: string = `Error message:\n${message}.\nStack trace: ${error.stack}`;
|
||||
|
||||
const isWarning = this.isWarning(errorTraceString);
|
||||
const isWarning: boolean = this.isWarning(errorTraceString);
|
||||
if (isWarning) {
|
||||
this.loggingService.sendWarnLevelMessage(errorTraceString, {error});
|
||||
} else {
|
||||
@ -45,7 +45,7 @@ export class GlobalErrorHandler extends ErrorHandler {
|
||||
}
|
||||
|
||||
logError(error: any): void {
|
||||
const route = this.router.url;
|
||||
const route: string = this.router.url;
|
||||
if (error instanceof HttpErrorResponse) {
|
||||
this.loggingService.sendErrorLevelMessage(
|
||||
`There was an HTTP error on route ${route}.\n${error.message}.\nStatus code: ${(error as HttpErrorResponse).status}`,
|
||||
@ -60,12 +60,12 @@ export class GlobalErrorHandler extends ErrorHandler {
|
||||
}
|
||||
|
||||
private isWarning(errorTraceString: string): boolean {
|
||||
let isWarning = true;
|
||||
let isWarning: boolean = true;
|
||||
if (errorTraceString.includes('/src/app/')) {
|
||||
isWarning = false;
|
||||
}
|
||||
|
||||
this.sentencesForWarningLogging.forEach((whiteListSentence) => {
|
||||
this.sentencesForWarningLogging.forEach((whiteListSentence: string) => {
|
||||
if (errorTraceString.includes(whiteListSentence)) {
|
||||
isWarning = true;
|
||||
}
|
||||
|
@ -1,13 +1,13 @@
|
||||
function HttpGetter(): void {}
|
||||
|
||||
HttpGetter.prototype.get = filename => new Promise((whohoo, doh) => {
|
||||
const xhr = new XMLHttpRequest();
|
||||
HttpGetter.prototype.get = filename => new Promise((resolve, reject) => {
|
||||
const xhr: XMLHttpRequest = new XMLHttpRequest();
|
||||
xhr.addEventListener('load', (e) => {
|
||||
if (xhr.status === 200) {
|
||||
whohoo(xhr.responseText);
|
||||
resolve(xhr.responseText);
|
||||
return;
|
||||
}
|
||||
doh('failed with status ' + xhr.status + ': ' + xhr.statusText);
|
||||
reject('failed with status ' + xhr.status + ': ' + xhr.statusText);
|
||||
});
|
||||
xhr.open('GET', filename);
|
||||
xhr.send();
|
||||
|
@ -3,7 +3,41 @@ import {Injectable} from '@angular/core';
|
||||
import {Observable, of, throwError} from 'rxjs';
|
||||
import {delay, dematerialize, materialize, mergeMap} from 'rxjs/operators';
|
||||
|
||||
const actions = [
|
||||
interface Action {
|
||||
id: number;
|
||||
user: string;
|
||||
role: string;
|
||||
action: string;
|
||||
approval: boolean;
|
||||
}
|
||||
|
||||
interface Token {
|
||||
name: string;
|
||||
symbol: string;
|
||||
address: string;
|
||||
supply: string;
|
||||
decimals: string;
|
||||
reserves: {};
|
||||
reserveRatio?: string;
|
||||
owner?: string;
|
||||
}
|
||||
|
||||
interface Category {
|
||||
name: string;
|
||||
products: Array<string>;
|
||||
}
|
||||
|
||||
interface AreaName {
|
||||
name: string;
|
||||
locations: Array<string>;
|
||||
}
|
||||
|
||||
interface AreaType {
|
||||
name: string;
|
||||
area: Array<string>;
|
||||
}
|
||||
|
||||
const actions: Array<Action> = [
|
||||
{ id: 1, user: 'Tom', role: 'enroller', action: 'Disburse RSV 100', approval: false },
|
||||
{ id: 2, user: 'Christine', role: 'admin', action: 'Change user phone number', approval: true },
|
||||
{ id: 3, user: 'Will', role: 'superadmin', action: 'Reclaim RSV 1000', approval: true },
|
||||
@ -12,7 +46,7 @@ const actions = [
|
||||
{ id: 6, user: 'Patience', role: 'enroller', action: 'Change user information', approval: false }
|
||||
];
|
||||
|
||||
const tokens = [
|
||||
const tokens: Array<Token> = [
|
||||
{
|
||||
name: 'Giftable Reserve', symbol: 'GRZ', address: '0xa686005CE37Dce7738436256982C3903f2E4ea8E', supply: '1000000001000000000000000000',
|
||||
decimals: '18', reserves: {}
|
||||
@ -44,7 +78,7 @@ const tokens = [
|
||||
}
|
||||
];
|
||||
|
||||
const categories = [
|
||||
const categories: Array<Category> = [
|
||||
{
|
||||
name: 'system',
|
||||
products: ['system', 'office main', 'office main phone']
|
||||
@ -146,7 +180,7 @@ const categories = [
|
||||
}
|
||||
];
|
||||
|
||||
const areaNames = [
|
||||
const areaNames: Array<AreaName> = [
|
||||
{
|
||||
name: 'Mukuru Nairobi',
|
||||
locations: ['kayaba', 'kayba', 'kambi', 'mukuru', 'masai', 'hazina', 'south', 'tetra', 'tetrapak', 'ruben', 'rueben', 'kingston',
|
||||
@ -211,7 +245,7 @@ const areaNames = [
|
||||
}
|
||||
];
|
||||
|
||||
const areaTypes = [
|
||||
const areaTypes: Array<AreaType> = [
|
||||
{
|
||||
name: 'urban',
|
||||
area: ['urban', 'nairobi', 'mombasa']
|
||||
@ -230,9 +264,9 @@ const areaTypes = [
|
||||
}
|
||||
];
|
||||
|
||||
const accountTypes = ['user', 'cashier', 'vendor', 'tokenagent', 'group'];
|
||||
const transactionTypes = ['transactions', 'conversions', 'disbursements', 'rewards', 'reclamation'];
|
||||
const genders = ['male', 'female', 'other'];
|
||||
const accountTypes: Array<string> = ['user', 'cashier', 'vendor', 'tokenagent', 'group'];
|
||||
const transactionTypes: Array<string> = ['transactions', 'conversions', 'disbursements', 'rewards', 'reclamation'];
|
||||
const genders: Array<string> = ['male', 'female', 'other'];
|
||||
|
||||
@Injectable()
|
||||
export class MockBackendInterceptor implements HttpInterceptor {
|
||||
@ -285,77 +319,77 @@ export class MockBackendInterceptor implements HttpInterceptor {
|
||||
|
||||
// route functions
|
||||
|
||||
function getActions(): Observable<any> {
|
||||
function getActions(): Observable<HttpResponse<any>> {
|
||||
return ok(actions);
|
||||
}
|
||||
|
||||
function getActionById(): Observable<any> {
|
||||
const queriedAction = actions.find(action => action.id === idFromUrl());
|
||||
function getActionById(): Observable<HttpResponse<any>> {
|
||||
const queriedAction: Action = actions.find(action => action.id === idFromUrl());
|
||||
return ok(queriedAction);
|
||||
}
|
||||
|
||||
function approveAction(): Observable<any> {
|
||||
const queriedAction = actions.find(action => action.id === idFromUrl());
|
||||
function approveAction(): Observable<HttpResponse<any>> {
|
||||
const queriedAction: Action = actions.find(action => action.id === idFromUrl());
|
||||
queriedAction.approval = body.approval;
|
||||
const message = `Action approval status set to ${body.approval} successfully!`;
|
||||
const message: string = `Action approval status set to ${body.approval} successfully!`;
|
||||
return ok(message);
|
||||
}
|
||||
|
||||
function getTokens(): Observable<any> {
|
||||
function getTokens(): Observable<HttpResponse<any>> {
|
||||
return ok(tokens);
|
||||
}
|
||||
|
||||
function getTokenBySymbol(): Observable<any> {
|
||||
const queriedToken = tokens.find(token => token.symbol === stringFromUrl());
|
||||
function getTokenBySymbol(): Observable<HttpResponse<any>> {
|
||||
const queriedToken: Token = tokens.find(token => token.symbol === stringFromUrl());
|
||||
return ok(queriedToken);
|
||||
}
|
||||
|
||||
function getCategories(): Observable<any> {
|
||||
const categoryList = categories.map(category => category.name);
|
||||
function getCategories(): Observable<HttpResponse<any>> {
|
||||
const categoryList: Array<string> = categories.map(category => category.name);
|
||||
return ok(categoryList);
|
||||
}
|
||||
|
||||
function getCategoryByProduct(): Observable<any> {
|
||||
const queriedCategory = categories.find(category => category.products.includes(stringFromUrl()));
|
||||
function getCategoryByProduct(): Observable<HttpResponse<any>> {
|
||||
const queriedCategory: Category = categories.find(category => category.products.includes(stringFromUrl()));
|
||||
return ok(queriedCategory.name);
|
||||
}
|
||||
|
||||
function getAreaNames(): Observable<any> {
|
||||
const areaNameList = areaNames.map(areaName => areaName.name);
|
||||
function getAreaNames(): Observable<HttpResponse<any>> {
|
||||
const areaNameList: Array<string> = areaNames.map(areaName => areaName.name);
|
||||
return ok(areaNameList);
|
||||
}
|
||||
|
||||
function getAreaNameByLocation(): Observable<any> {
|
||||
const queriedAreaName = areaNames.find(areaName => areaName.locations.includes(stringFromUrl()));
|
||||
function getAreaNameByLocation(): Observable<HttpResponse<any>> {
|
||||
const queriedAreaName: AreaName = areaNames.find(areaName => areaName.locations.includes(stringFromUrl()));
|
||||
return ok(queriedAreaName.name);
|
||||
}
|
||||
|
||||
function getAreaTypes(): Observable<any> {
|
||||
const areaTypeList = areaTypes.map(areaType => areaType.name);
|
||||
function getAreaTypes(): Observable<HttpResponse<any>> {
|
||||
const areaTypeList: Array<string> = areaTypes.map(areaType => areaType.name);
|
||||
return ok(areaTypeList);
|
||||
}
|
||||
|
||||
function getAreaTypeByArea(): Observable<any> {
|
||||
const queriedAreaType = areaTypes.find(areaType => areaType.area.includes(stringFromUrl()));
|
||||
function getAreaTypeByArea(): Observable<HttpResponse<any>> {
|
||||
const queriedAreaType: AreaType = areaTypes.find(areaType => areaType.area.includes(stringFromUrl()));
|
||||
return ok(queriedAreaType.name);
|
||||
}
|
||||
|
||||
function getAccountTypes(): Observable<any> {
|
||||
function getAccountTypes(): Observable<HttpResponse<any>> {
|
||||
return ok(accountTypes);
|
||||
}
|
||||
|
||||
function getTransactionTypes(): Observable<any> {
|
||||
function getTransactionTypes(): Observable<HttpResponse<any>> {
|
||||
return ok(transactionTypes);
|
||||
}
|
||||
|
||||
function getGenders(): Observable<any> {
|
||||
function getGenders(): Observable<HttpResponse<any>> {
|
||||
return ok(genders);
|
||||
}
|
||||
|
||||
// helper functions
|
||||
|
||||
function ok(body): Observable<any> {
|
||||
return of(new HttpResponse({ status: 200, body }));
|
||||
function ok(responseBody: any): Observable<HttpResponse<any>> {
|
||||
return of(new HttpResponse({ status: 200, body: responseBody }));
|
||||
}
|
||||
|
||||
function error(message): Observable<any> {
|
||||
@ -363,12 +397,12 @@ export class MockBackendInterceptor implements HttpInterceptor {
|
||||
}
|
||||
|
||||
function idFromUrl(): number {
|
||||
const urlParts = url.split('/');
|
||||
const urlParts: Array<string> = url.split('/');
|
||||
return parseInt(urlParts[urlParts.length - 1], 10);
|
||||
}
|
||||
|
||||
function stringFromUrl(): string {
|
||||
const urlParts = url.split('/');
|
||||
const urlParts: Array<string> = url.split('/');
|
||||
return urlParts[urlParts.length - 1];
|
||||
}
|
||||
}
|
||||
|
@ -1,24 +1,23 @@
|
||||
let objCsv = {
|
||||
const objCsv: { size: number, dataFile: any } = {
|
||||
size: 0,
|
||||
dataFile: []
|
||||
};
|
||||
|
||||
function readCsv(input: any): any {
|
||||
function readCsv(input: any): Array<any> | void {
|
||||
if (input.files && input.files[0]) {
|
||||
let reader = new FileReader();
|
||||
const reader: FileReader = new FileReader();
|
||||
reader.readAsBinaryString(input.files[0]);
|
||||
reader.onload = event => {
|
||||
objCsv.size = event.total;
|
||||
// @ts-ignore
|
||||
objCsv.dataFile = event.target.result;
|
||||
return parseData(objCsv.dataFile);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function parseData(data: any): any {
|
||||
let csvData = [];
|
||||
const lineBreak = data.split('\n');
|
||||
function parseData(data: any): Array<any> {
|
||||
const csvData: Array<any> = [];
|
||||
const lineBreak: Array<any> = data.split('\n');
|
||||
lineBreak.forEach(res => {
|
||||
csvData.push(res.split(','));
|
||||
});
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { validatePerson, validateVcard } from 'cic-schemas-data-validator';
|
||||
|
||||
async function personValidation(person: any): Promise<void> {
|
||||
const personValidationErrors = await validatePerson(person);
|
||||
const personValidationErrors: any = await validatePerson(person);
|
||||
|
||||
if (personValidationErrors) {
|
||||
personValidationErrors.map(error => console.error(`${error.message}`));
|
||||
@ -9,7 +9,7 @@ async function personValidation(person: any): Promise<void> {
|
||||
}
|
||||
|
||||
async function vcardValidation(vcard: any): Promise<void> {
|
||||
const vcardValidationErrors = await validateVcard(vcard);
|
||||
const vcardValidationErrors: any = await validateVcard(vcard);
|
||||
|
||||
if (vcardValidationErrors) {
|
||||
vcardValidationErrors.map(error => console.error(`${error.message}`));
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {Injectable, isDevMode} from '@angular/core';
|
||||
import {Injectable} from '@angular/core';
|
||||
import {
|
||||
HttpRequest,
|
||||
HttpHandler,
|
||||
@ -6,7 +6,7 @@ import {
|
||||
HttpInterceptor, HttpErrorResponse
|
||||
} from '@angular/common/http';
|
||||
import {Observable, throwError} from 'rxjs';
|
||||
import {catchError, retry} from 'rxjs/operators';
|
||||
import {catchError} from 'rxjs/operators';
|
||||
import {ErrorDialogService, LoggingService} from '@app/_services';
|
||||
import {Router} from '@angular/router';
|
||||
|
||||
@ -22,7 +22,7 @@ export class ErrorInterceptor implements HttpInterceptor {
|
||||
intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
|
||||
return next.handle(request).pipe(
|
||||
catchError((err: HttpErrorResponse) => {
|
||||
let errorMessage;
|
||||
let errorMessage: string;
|
||||
if (err.error instanceof ErrorEvent) {
|
||||
// A client-side or network error occurred. Handle it accordingly.
|
||||
errorMessage = `An error occurred: ${err.error.message}`;
|
||||
|
@ -13,7 +13,7 @@ export class HttpConfigInterceptor implements HttpInterceptor {
|
||||
constructor() {}
|
||||
|
||||
intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
|
||||
// const token = sessionStorage.getItem(btoa('CICADA_SESSION_TOKEN'));
|
||||
// const token: string = sessionStorage.getItem(btoa('CICADA_SESSION_TOKEN'));
|
||||
|
||||
// if (token) {
|
||||
// request = request.clone({headers: request.headers.set('Authorization', 'Bearer ' + token)});
|
||||
|
@ -20,9 +20,9 @@ export class LoggingInterceptor implements HttpInterceptor {
|
||||
intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
|
||||
return next.handle(request);
|
||||
// this.loggingService.sendInfoLevelMessage(request);
|
||||
// const startTime = Date.now();
|
||||
// const startTime: number = Date.now();
|
||||
// let status: string;
|
||||
|
||||
//
|
||||
// return next.handle(request).pipe(tap(event => {
|
||||
// status = '';
|
||||
// if (event instanceof HttpResponse) {
|
||||
@ -30,8 +30,8 @@ export class LoggingInterceptor implements HttpInterceptor {
|
||||
// }
|
||||
// }, error => status = 'failed'),
|
||||
// finalize(() => {
|
||||
// const elapsedTime = Date.now() - startTime;
|
||||
// const message = `${request.method} request for ${request.urlWithParams} ${status} in ${elapsedTime} ms`;
|
||||
// const elapsedTime: number = Date.now() - startTime;
|
||||
// const message: string = `${request.method} request for ${request.urlWithParams} ${status} in ${elapsedTime} ms`;
|
||||
// this.loggingService.sendInfoLevelMessage(message);
|
||||
// }));
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
export interface AccountDetails {
|
||||
interface AccountDetails {
|
||||
date_registered: number;
|
||||
gender: string;
|
||||
age?: string;
|
||||
type?: string;
|
||||
balance?: number;
|
||||
identities: {
|
||||
evm: {
|
||||
'bloxberg:8996': string[];
|
||||
@ -40,25 +41,25 @@ export interface AccountDetails {
|
||||
};
|
||||
}
|
||||
|
||||
export interface Signature {
|
||||
interface Signature {
|
||||
algo: string;
|
||||
data: string;
|
||||
digest: string;
|
||||
engine: string;
|
||||
}
|
||||
|
||||
export interface Meta {
|
||||
interface Meta {
|
||||
data: AccountDetails;
|
||||
id: string;
|
||||
signature: Signature;
|
||||
}
|
||||
|
||||
export interface MetaResponse {
|
||||
interface MetaResponse {
|
||||
id: string;
|
||||
m: Meta;
|
||||
}
|
||||
|
||||
export const defaultAccount: AccountDetails = {
|
||||
const defaultAccount: AccountDetails = {
|
||||
date_registered: Date.now(),
|
||||
gender: 'other',
|
||||
identities: {
|
||||
@ -94,3 +95,11 @@ export const defaultAccount: AccountDetails = {
|
||||
}],
|
||||
},
|
||||
};
|
||||
|
||||
export {
|
||||
AccountDetails,
|
||||
Signature,
|
||||
Meta,
|
||||
MetaResponse,
|
||||
defaultAccount
|
||||
};
|
||||
|
@ -1,4 +1,5 @@
|
||||
export * from '@app/_models/transaction';
|
||||
export * from '@app/_models/settings';
|
||||
export * from '@app/_models/user';
|
||||
export * from '@app/_models/account';
|
||||
export * from '@app/_models/staff';
|
||||
export * from '@app/_models/token';
|
||||
|
@ -1,4 +1,4 @@
|
||||
export class Settings {
|
||||
class Settings {
|
||||
w3: W3 = {
|
||||
engine: undefined,
|
||||
provider: undefined,
|
||||
@ -12,7 +12,12 @@ export class Settings {
|
||||
}
|
||||
}
|
||||
|
||||
export class W3 {
|
||||
class W3 {
|
||||
engine: any;
|
||||
provider: any;
|
||||
}
|
||||
|
||||
export {
|
||||
Settings,
|
||||
W3
|
||||
};
|
||||
|
@ -1,7 +1,11 @@
|
||||
export interface Staff {
|
||||
interface Staff {
|
||||
comment: string;
|
||||
email: string;
|
||||
name: string;
|
||||
tag: number;
|
||||
userid: string;
|
||||
}
|
||||
|
||||
export {
|
||||
Staff
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
export interface Token {
|
||||
interface Token {
|
||||
name: string;
|
||||
symbol: string;
|
||||
address: string;
|
||||
@ -13,3 +13,7 @@ export interface Token {
|
||||
reserveRatio?: string;
|
||||
owner?: string;
|
||||
}
|
||||
|
||||
export {
|
||||
Token
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
import {User} from '@app/_models/user';
|
||||
import {AccountDetails} from '@app/_models/account';
|
||||
|
||||
export class BlocksBloom {
|
||||
class BlocksBloom {
|
||||
low: number;
|
||||
blockFilter: string;
|
||||
blocktxFilter: string;
|
||||
@ -8,13 +8,13 @@ export class BlocksBloom {
|
||||
filterRounds: number;
|
||||
}
|
||||
|
||||
export class Token {
|
||||
class TxToken {
|
||||
address: string;
|
||||
name: string;
|
||||
symbol: string;
|
||||
}
|
||||
|
||||
export class Tx {
|
||||
class Tx {
|
||||
block: number;
|
||||
success: boolean;
|
||||
timestamp: number;
|
||||
@ -22,22 +22,30 @@ export class Tx {
|
||||
txIndex: number;
|
||||
}
|
||||
|
||||
export class Transaction {
|
||||
class Transaction {
|
||||
from: string;
|
||||
sender: User;
|
||||
sender: AccountDetails;
|
||||
to: string;
|
||||
recipient: User;
|
||||
token: Token;
|
||||
recipient: AccountDetails;
|
||||
token: TxToken;
|
||||
tx: Tx;
|
||||
value: number;
|
||||
}
|
||||
|
||||
export class Conversion {
|
||||
destinationToken: Token;
|
||||
class Conversion {
|
||||
destinationToken: TxToken;
|
||||
fromValue: number;
|
||||
sourceToken: Token;
|
||||
sourceToken: TxToken;
|
||||
toValue: number;
|
||||
trader: string;
|
||||
user: User;
|
||||
user: AccountDetails;
|
||||
tx: Tx;
|
||||
}
|
||||
|
||||
export {
|
||||
BlocksBloom,
|
||||
TxToken,
|
||||
Tx,
|
||||
Transaction,
|
||||
Conversion
|
||||
};
|
||||
|
@ -1,22 +0,0 @@
|
||||
export class User {
|
||||
dateRegistered: number;
|
||||
vcard: {
|
||||
fn: string;
|
||||
version: string;
|
||||
tel: [{
|
||||
meta: {
|
||||
TYP: string;
|
||||
};
|
||||
value: string[];
|
||||
}];
|
||||
};
|
||||
key: {
|
||||
ethereum: string[];
|
||||
};
|
||||
location: {
|
||||
latitude: string;
|
||||
longitude: string;
|
||||
external: {};
|
||||
};
|
||||
selling: string[];
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import { KeyStore } from 'cic-client-meta';
|
||||
// TODO should we put this on the mutalble key store object
|
||||
// TODO should we put this on the mutable key store object
|
||||
import * as openpgp from 'openpgp';
|
||||
const keyring = new openpgp.Keyring();
|
||||
|
||||
@ -76,15 +76,14 @@ class MutablePgpKeyStore implements MutableKeyStore{
|
||||
}
|
||||
|
||||
async isValidKey(key): Promise<boolean> {
|
||||
// There is supposed to be an opengpg.readKey() method but I can't find it?
|
||||
// There is supposed to be an openpgp.readKey() method but I can't find it?
|
||||
const _key = await openpgp.key.readArmored(key);
|
||||
return !_key.err;
|
||||
}
|
||||
|
||||
async isEncryptedPrivateKey(privateKey: any): Promise<boolean> {
|
||||
const imported = await openpgp.key.readArmored(privateKey);
|
||||
for (let i = 0; i < imported.keys.length; i++) {
|
||||
const key = imported.keys[i];
|
||||
for (const key of imported.keys) {
|
||||
if (key.isDecrypted()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1,20 +1,19 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { hobaParseChallengeHeader } from '@src/assets/js/hoba.js';
|
||||
import { signChallenge } from '@src/assets/js/hoba-pgp.js';
|
||||
import { environment } from '@src/environments/environment';
|
||||
import { LoggingService } from '@app/_services/logging.service';
|
||||
import { MutableKeyStore, MutablePgpKeyStore } from '@app/_pgp';
|
||||
import { ErrorDialogService } from '@app/_services/error-dialog.service';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Observable } from 'rxjs';
|
||||
import { HttpError } from '@app/_helpers/global-error-handler';
|
||||
import {Injectable} from '@angular/core';
|
||||
import {hobaParseChallengeHeader} from '@src/assets/js/hoba.js';
|
||||
import {signChallenge} from '@src/assets/js/hoba-pgp.js';
|
||||
import {environment} from '@src/environments/environment';
|
||||
import {LoggingService} from '@app/_services/logging.service';
|
||||
import {MutableKeyStore, MutablePgpKeyStore} from '@app/_pgp';
|
||||
import {ErrorDialogService} from '@app/_services/error-dialog.service';
|
||||
import {HttpClient} from '@angular/common/http';
|
||||
import {HttpError} from '@app/_helpers/global-error-handler';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class AuthService {
|
||||
sessionToken: any;
|
||||
sessionLoginCount = 0;
|
||||
sessionLoginCount: number = 0;
|
||||
mutableKeyStore: MutableKeyStore;
|
||||
|
||||
constructor(
|
||||
@ -22,18 +21,17 @@ export class AuthService {
|
||||
private loggingService: LoggingService,
|
||||
private errorDialogService: ErrorDialogService
|
||||
) {
|
||||
this.mutableKeyStore = new MutablePgpKeyStore()
|
||||
this.mutableKeyStore = new MutablePgpKeyStore();
|
||||
}
|
||||
|
||||
async init(): Promise<void> {
|
||||
this.mutableKeyStore.loadKeyring();
|
||||
await this.mutableKeyStore.loadKeyring();
|
||||
// TODO setting these together should be atomic
|
||||
if (sessionStorage.getItem(btoa('CICADA_SESSION_TOKEN'))) {
|
||||
this.sessionToken = sessionStorage.getItem(btoa('CICADA_SESSION_TOKEN'));
|
||||
}
|
||||
if (localStorage.getItem(btoa('CICADA_PRIVATE_KEY'))) {
|
||||
this.mutableKeyStore.importPrivateKey(localStorage.getItem(btoa('CICADA_PRIVATE_KEY')))
|
||||
// this.privateKey = localStorage.getItem(btoa('CICADA_PRIVATE_KEY'));
|
||||
await this.mutableKeyStore.importPrivateKey(localStorage.getItem(btoa('CICADA_PRIVATE_KEY')));
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,7 +40,7 @@ export class AuthService {
|
||||
}
|
||||
|
||||
getWithToken(): void {
|
||||
const xhr = new XMLHttpRequest();
|
||||
const xhr: XMLHttpRequest = new XMLHttpRequest();
|
||||
xhr.responseType = 'text';
|
||||
xhr.open('GET', environment.cicMetaUrl + window.location.search.substring(1));
|
||||
xhr.setRequestHeader('Authorization', 'Bearer ' + this.sessionToken);
|
||||
@ -59,10 +57,10 @@ export class AuthService {
|
||||
xhr.send();
|
||||
}
|
||||
|
||||
//TODO renmae to send signed challenge and set session. Also seperate these responsibilities
|
||||
sendResponse(hobaResponseEncoded): Promise<boolean> {
|
||||
// TODO rename to send signed challenge and set session. Also separate these responsibilities
|
||||
sendResponse(hobaResponseEncoded: any): Promise<boolean> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const xhr = new XMLHttpRequest();
|
||||
const xhr: XMLHttpRequest = new XMLHttpRequest();
|
||||
xhr.responseType = 'text';
|
||||
xhr.open('GET', environment.cicMetaUrl + window.location.search.substring(1));
|
||||
xhr.setRequestHeader('Authorization', 'HOBA ' + hobaResponseEncoded);
|
||||
@ -80,11 +78,11 @@ export class AuthService {
|
||||
return resolve(true);
|
||||
});
|
||||
xhr.send();
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
getChallenge(): void {
|
||||
const xhr = new XMLHttpRequest();
|
||||
const xhr: XMLHttpRequest = new XMLHttpRequest();
|
||||
xhr.responseType = 'arraybuffer';
|
||||
xhr.open('GET', environment.cicMetaUrl + window.location.search.substring(1));
|
||||
xhr.onload = async (e) => {
|
||||
@ -117,25 +115,26 @@ export class AuthService {
|
||||
}
|
||||
|
||||
|
||||
async loginResponse(o): Promise<any> {
|
||||
return new Promise(async(resolve, reject) => {
|
||||
async loginResponse(o: { challenge: string, realm: any }): Promise<any> {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
const r = await signChallenge(o.challenge,
|
||||
o.realm,
|
||||
environment.cicMetaUrl,
|
||||
this.mutableKeyStore);
|
||||
const sessionTokenResult = await this.sendResponse(r);
|
||||
const sessionTokenResult: boolean = await this.sendResponse(r);
|
||||
} catch (error) {
|
||||
if (error instanceof HttpError) {
|
||||
if (error.status === 403) {
|
||||
this.errorDialogService.openDialog({ message: 'You are not authorized to use this system' })
|
||||
this.errorDialogService.openDialog({ message: 'You are not authorized to use this system' });
|
||||
}
|
||||
if (error.status === 401) {
|
||||
this.errorDialogService.openDialog({ message: 'Unable to authenticate with the service. ' +
|
||||
this.errorDialogService.openDialog({
|
||||
message: 'Unable to authenticate with the service. ' +
|
||||
'Please speak with the staff at Grassroots ' +
|
||||
'Economics for requesting access ' +
|
||||
'staff@grassrootseconomics.net.' })
|
||||
|
||||
'staff@grassrootseconomics.net.'
|
||||
});
|
||||
}
|
||||
}
|
||||
// TODO define this error
|
||||
@ -158,10 +157,10 @@ export class AuthService {
|
||||
throw Error('The private key is invalid');
|
||||
}
|
||||
// TODO leaving this out for now.
|
||||
//const isEncryptedKeyCheck = await this.mutableKeyStore.isEncryptedPrivateKey(privateKeyArmored);
|
||||
//if (!isEncryptedKeyCheck) {
|
||||
// const isEncryptedKeyCheck = await this.mutableKeyStore.isEncryptedPrivateKey(privateKeyArmored);
|
||||
// if (!isEncryptedKeyCheck) {
|
||||
// throw Error('The private key doesn\'t have a password!');
|
||||
//}
|
||||
// }
|
||||
const key = await this.mutableKeyStore.importPrivateKey(privateKeyArmored);
|
||||
localStorage.setItem(btoa('CICADA_PRIVATE_KEY'), privateKeyArmored);
|
||||
} catch (err) {
|
||||
@ -182,21 +181,20 @@ export class AuthService {
|
||||
}
|
||||
|
||||
getTrustedUsers(): any {
|
||||
let trustedUsers = [];
|
||||
const trustedUsers: Array<any> = [];
|
||||
this.mutableKeyStore.getPublicKeys().forEach(key => trustedUsers.push(key.users[0].userId));
|
||||
return trustedUsers;
|
||||
}
|
||||
|
||||
async getPublicKeys(): Promise<any> {
|
||||
const data = await fetch(environment.publicKeysUrl)
|
||||
return await fetch(environment.publicKeysUrl)
|
||||
.then(res => {
|
||||
if (!res.ok) {
|
||||
//TODO does angular recommend an error interface?
|
||||
// TODO does angular recommend an error interface?
|
||||
throw Error(`${res.statusText} - ${res.status}`);
|
||||
}
|
||||
return res.text();
|
||||
})
|
||||
return data;
|
||||
});
|
||||
}
|
||||
|
||||
getPrivateKey(): any {
|
||||
|
@ -20,10 +20,10 @@ export class BlockSyncService {
|
||||
private registryService: RegistryService,
|
||||
) { }
|
||||
|
||||
blockSync(address: string = null, offset: number = 0, limit: number = 100): any {
|
||||
blockSync(address: string = null, offset: number = 0, limit: number = 100): void {
|
||||
this.transactionService.resetTransactionsList();
|
||||
const settings = new Settings(this.scan);
|
||||
const readyStateElements = { network: 2 };
|
||||
const settings: Settings = new Settings(this.scan);
|
||||
const readyStateElements: { network: number } = { network: 2 };
|
||||
settings.w3.provider = environment.web3Provider;
|
||||
settings.w3.engine = this.registryService.getWeb3();
|
||||
settings.registry = this.registryService.getRegistry();
|
||||
@ -46,7 +46,7 @@ export class BlockSyncService {
|
||||
readyStateProcessor(settings: Settings, bit: number, address: string, offset: number, limit: number): void {
|
||||
this.readyState |= bit;
|
||||
if (this.readyStateTarget === this.readyState && this.readyStateTarget) {
|
||||
const wHeadSync = new Worker('./../assets/js/block-sync/head.js');
|
||||
const wHeadSync: Worker = new Worker('./../assets/js/block-sync/head.js');
|
||||
wHeadSync.onmessage = (m) => {
|
||||
settings.txHelper.processReceipt(m.data);
|
||||
};
|
||||
@ -65,7 +65,7 @@ export class BlockSyncService {
|
||||
}
|
||||
}
|
||||
|
||||
newTransferEvent(tx): any {
|
||||
newTransferEvent(tx: any): any {
|
||||
return new CustomEvent('cic_transfer', {
|
||||
detail: {
|
||||
tx,
|
||||
@ -73,7 +73,7 @@ export class BlockSyncService {
|
||||
});
|
||||
}
|
||||
|
||||
newConversionEvent(tx): any {
|
||||
newConversionEvent(tx: any): any {
|
||||
return new CustomEvent('cic_convert', {
|
||||
detail: {
|
||||
tx,
|
||||
@ -81,8 +81,8 @@ export class BlockSyncService {
|
||||
});
|
||||
}
|
||||
|
||||
async scan(settings, lo, hi, bloomBlockBytes, bloomBlocktxBytes, bloomRounds): Promise<void> {
|
||||
const w = new Worker('./../assets/js/block-sync/ondemand.js');
|
||||
async scan(settings: Settings, lo: number, hi: number, bloomBlockBytes: Uint8Array, bloomBlocktxBytes: Uint8Array, bloomRounds: any): Promise<void> {
|
||||
const w: Worker = new Worker('./../assets/js/block-sync/ondemand.js');
|
||||
w.onmessage = (m) => {
|
||||
settings.txHelper.processReceipt(m.data);
|
||||
};
|
||||
@ -99,12 +99,12 @@ export class BlockSyncService {
|
||||
}
|
||||
|
||||
fetcher(settings: Settings, transactionsInfo: any): void {
|
||||
const blockFilterBinstr = window.atob(transactionsInfo.block_filter);
|
||||
const bOne = new Uint8Array(blockFilterBinstr.length);
|
||||
const blockFilterBinstr: string = window.atob(transactionsInfo.block_filter);
|
||||
const bOne: Uint8Array = new Uint8Array(blockFilterBinstr.length);
|
||||
bOne.map((e, i, v) => v[i] = blockFilterBinstr.charCodeAt(i));
|
||||
|
||||
const blocktxFilterBinstr = window.atob(transactionsInfo.blocktx_filter);
|
||||
const bTwo = new Uint8Array(blocktxFilterBinstr.length);
|
||||
const blocktxFilterBinstr: string = window.atob(transactionsInfo.blocktx_filter);
|
||||
const bTwo: Uint8Array = new Uint8Array(blocktxFilterBinstr.length);
|
||||
bTwo.map((e, i, v) => v[i] = blocktxFilterBinstr.charCodeAt(i));
|
||||
|
||||
settings.scanFilter(settings, transactionsInfo.low, transactionsInfo.high, bOne, bTwo, transactionsInfo.filter_rounds);
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import {MatDialog} from '@angular/material/dialog';
|
||||
import {MatDialog, MatDialogRef} from '@angular/material/dialog';
|
||||
import {ErrorDialogComponent} from '@app/shared/error-dialog/error-dialog.component';
|
||||
|
||||
@Injectable({
|
||||
@ -17,7 +17,7 @@ export class ErrorDialogService {
|
||||
return false;
|
||||
}
|
||||
this.isDialogOpen = true;
|
||||
const dialogRef = this.dialog.open(ErrorDialogComponent, {
|
||||
const dialogRef: MatDialogRef<any> = this.dialog.open(ErrorDialogComponent, {
|
||||
width: '300px',
|
||||
data
|
||||
});
|
||||
|
@ -15,31 +15,31 @@ export class LoggingService {
|
||||
}
|
||||
}
|
||||
|
||||
sendTraceLevelMessage(message, source, error): void {
|
||||
sendTraceLevelMessage(message: any, source: any, error: any): void {
|
||||
this.logger.trace(message, source, error);
|
||||
}
|
||||
|
||||
sendDebugLevelMessage(message, source, error): void {
|
||||
sendDebugLevelMessage(message: any, source: any, error: any): void {
|
||||
this.logger.debug(message, source, error);
|
||||
}
|
||||
|
||||
sendInfoLevelMessage(message): void {
|
||||
sendInfoLevelMessage(message: any): void {
|
||||
this.logger.info(message);
|
||||
}
|
||||
|
||||
sendLogLevelMessage(message, source, error): void {
|
||||
sendLogLevelMessage(message: any, source: any, error: any): void {
|
||||
this.logger.log(message, source, error);
|
||||
}
|
||||
|
||||
sendWarnLevelMessage(message, error): void {
|
||||
sendWarnLevelMessage(message: any, error: any): void {
|
||||
this.logger.warn(message, error);
|
||||
}
|
||||
|
||||
sendErrorLevelMessage(message, source, error): void {
|
||||
sendErrorLevelMessage(message: any, source: any, error: any): void {
|
||||
this.logger.error(message, source, error);
|
||||
}
|
||||
|
||||
sendFatalLevelMessage(message, source, error): void {
|
||||
sendFatalLevelMessage(message: any, source: any, error: any): void {
|
||||
this.logger.fatal(message, source, error);
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,16 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import Web3 from 'web3';
|
||||
import {environment} from '@src/environments/environment';
|
||||
import {CICRegistry} from 'cic-client';
|
||||
import {CICRegistry, FileGetter} from 'cic-client';
|
||||
import {HttpGetter} from '@app/_helpers';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class RegistryService {
|
||||
web3 = new Web3(environment.web3Provider);
|
||||
fileGetter = new HttpGetter();
|
||||
registry = new CICRegistry(this.web3, environment.registryAddress, 'CICRegistry', this.fileGetter,
|
||||
web3: Web3 = new Web3(environment.web3Provider);
|
||||
fileGetter: FileGetter = new HttpGetter();
|
||||
registry: CICRegistry = new CICRegistry(this.web3, environment.registryAddress, 'CICRegistry', this.fileGetter,
|
||||
['../../assets/js/block-sync/data']);
|
||||
|
||||
constructor() {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { EventEmitter, Injectable } from '@angular/core';
|
||||
import {environment} from '@src/environments/environment';
|
||||
import {BehaviorSubject, Observable} from 'rxjs';
|
||||
import {CICRegistry} from 'cic-client';
|
||||
@ -12,9 +12,7 @@ import {RegistryService} from '@app/_services/registry.service';
|
||||
export class TokenService {
|
||||
registry: CICRegistry;
|
||||
tokenRegistry: TokenRegistry;
|
||||
tokens: any = '';
|
||||
private tokensList = new BehaviorSubject<any>(this.tokens);
|
||||
tokensSubject = this.tokensList.asObservable();
|
||||
LoadEvent: EventEmitter<number> = new EventEmitter<number>();
|
||||
|
||||
constructor(
|
||||
private httpClient: HttpClient,
|
||||
@ -24,11 +22,12 @@ export class TokenService {
|
||||
this.registry.load();
|
||||
this.registry.onload = async (address: string): Promise<void> => {
|
||||
this.tokenRegistry = new TokenRegistry(await this.registry.getContractAddressByName('TokenRegistry'));
|
||||
this.LoadEvent.next(Date.now());
|
||||
};
|
||||
}
|
||||
|
||||
async getTokens(): Promise<any> {
|
||||
const count = await this.tokenRegistry.totalTokens();
|
||||
async getTokens(): Promise<Array<Promise<string>>> {
|
||||
const count: number = await this.tokenRegistry.totalTokens();
|
||||
return Array.from({length: count}, async (v, i) => await this.tokenRegistry.entry(i));
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@ import {LoggingService} from '@app/_services/logging.service';
|
||||
import {HttpClient} from '@angular/common/http';
|
||||
import {CICRegistry} from 'cic-client';
|
||||
import {RegistryService} from '@app/_services/registry.service';
|
||||
import Web3 from 'web3';
|
||||
const vCard = require('vcard-parser');
|
||||
|
||||
@Injectable({
|
||||
@ -26,7 +27,7 @@ export class TransactionService {
|
||||
private transactionList = new BehaviorSubject<any[]>(this.transactions);
|
||||
transactionsSubject = this.transactionList.asObservable();
|
||||
userInfo: any;
|
||||
web3: any;
|
||||
web3: Web3;
|
||||
registry: CICRegistry;
|
||||
|
||||
constructor(
|
||||
@ -115,7 +116,7 @@ export class TransactionService {
|
||||
const data = fromHex(methodSignature + strip0x(abi));
|
||||
const tx = new Tx(environment.bloxbergChainId);
|
||||
tx.nonce = await this.web3.eth.getTransactionCount(senderAddress);
|
||||
tx.gasPrice = await this.web3.eth.getGasPrice();
|
||||
tx.gasPrice = Number(await this.web3.eth.getGasPrice());
|
||||
tx.gasLimit = 8000000;
|
||||
tx.to = fromHex(strip0x(transferAuthAddress));
|
||||
tx.value = toValue(value);
|
||||
|
@ -25,18 +25,13 @@ export class UserService {
|
||||
signer: Signer;
|
||||
registry: CICRegistry;
|
||||
|
||||
accountsMeta = [];
|
||||
accounts: any = [];
|
||||
private accountsList = new BehaviorSubject<any>(this.accounts);
|
||||
accountsSubject = this.accountsList.asObservable();
|
||||
accounts: Array<AccountDetails> = [];
|
||||
private accountsList: BehaviorSubject<Array<AccountDetails>> = new BehaviorSubject<Array<AccountDetails>>(this.accounts);
|
||||
accountsSubject: Observable<Array<AccountDetails>> = this.accountsList.asObservable();
|
||||
|
||||
actions: any = '';
|
||||
private actionsList = new BehaviorSubject<any>(this.actions);
|
||||
actionsSubject = this.actionsList.asObservable();
|
||||
|
||||
staff: any = '';
|
||||
private staffList = new BehaviorSubject<any>(this.staff);
|
||||
staffSubject = this.staffList.asObservable();
|
||||
actions: Array<any> = [];
|
||||
private actionsList: BehaviorSubject<any> = new BehaviorSubject<any>(this.actions);
|
||||
actionsSubject: Observable<Array<any>> = this.actionsList.asObservable();
|
||||
|
||||
constructor(
|
||||
private httpClient: HttpClient,
|
||||
@ -54,23 +49,23 @@ export class UserService {
|
||||
}
|
||||
|
||||
resetPin(phone: string): Observable<any> {
|
||||
const params = new HttpParams().set('phoneNumber', phone);
|
||||
const params: HttpParams = new HttpParams().set('phoneNumber', phone);
|
||||
return this.httpClient.get(`${environment.cicUssdUrl}/pin`, {params});
|
||||
}
|
||||
|
||||
getAccountStatus(phone: string): any {
|
||||
const params = new HttpParams().set('phoneNumber', phone);
|
||||
getAccountStatus(phone: string): Observable<any> {
|
||||
const params: HttpParams = new HttpParams().set('phoneNumber', phone);
|
||||
return this.httpClient.get(`${environment.cicUssdUrl}/pin`, {params});
|
||||
}
|
||||
|
||||
getLockedAccounts(offset: number, limit: number): any {
|
||||
getLockedAccounts(offset: number, limit: number): Observable<any> {
|
||||
return this.httpClient.get(`${environment.cicUssdUrl}/accounts/locked/${offset}/${limit}`);
|
||||
}
|
||||
|
||||
async changeAccountInfo(address: string, name: string, phoneNumber: string, age: string, type: string, bio: string, gender: string,
|
||||
businessCategory: string, userLocation: string, location: string, locationType: string
|
||||
): Promise<any> {
|
||||
let accountInfo: any = {
|
||||
const accountInfo: any = {
|
||||
vcard: {
|
||||
fn: [{}],
|
||||
n: [{}],
|
||||
@ -91,10 +86,10 @@ export class UserService {
|
||||
accountInfo.location.area_type = locationType;
|
||||
await vcardValidation(accountInfo.vcard);
|
||||
accountInfo.vcard = btoa(vCard.generate(accountInfo.vcard));
|
||||
const accountKey = await User.toKey(address);
|
||||
const accountKey: string = await User.toKey(address);
|
||||
this.getAccountDetailsFromMeta(accountKey).pipe(first()).subscribe(async res => {
|
||||
const syncableAccount: Syncable = Envelope.fromJSON(JSON.stringify(res)).unwrap();
|
||||
let update = [];
|
||||
const update: Array<ArgPair> = [];
|
||||
for (const prop in accountInfo) {
|
||||
update.push(new ArgPair(prop, accountInfo[prop]));
|
||||
}
|
||||
@ -110,8 +105,8 @@ export class UserService {
|
||||
}
|
||||
|
||||
async updateMeta(syncableAccount: Syncable, accountKey: string, headers: HttpHeaders): Promise<any> {
|
||||
const envelope = await this.wrap(syncableAccount , this.signer);
|
||||
const reqBody = envelope.toJSON();
|
||||
const envelope: Envelope = await this.wrap(syncableAccount , this.signer);
|
||||
const reqBody: string = envelope.toJSON();
|
||||
this.httpClient.put(`${environment.cicMetaUrl}/${accountKey}`, reqBody , { headers }).pipe(first()).subscribe(res => {
|
||||
this.loggingService.sendInfoLevelMessage(`Response: ${res}`);
|
||||
});
|
||||
@ -121,7 +116,7 @@ export class UserService {
|
||||
this.httpClient.get(`${environment.cicCacheUrl}/actions`).pipe(first()).subscribe(res => this.actionsList.next(res));
|
||||
}
|
||||
|
||||
getActionById(id: string): any {
|
||||
getActionById(id: string): Observable<any> {
|
||||
return this.httpClient.get(`${environment.cicCacheUrl}/actions/${id}`);
|
||||
}
|
||||
|
||||
@ -138,14 +133,14 @@ export class UserService {
|
||||
}
|
||||
|
||||
wrap(syncable: Syncable, signer: Signer): Promise<Envelope> {
|
||||
return new Promise<Envelope>(async (whohoo, doh) => {
|
||||
return new Promise<Envelope>(async (resolve, reject) => {
|
||||
syncable.setSigner(signer);
|
||||
syncable.onwrap = async (env) => {
|
||||
if (env === undefined) {
|
||||
doh();
|
||||
reject();
|
||||
return;
|
||||
}
|
||||
whohoo(env);
|
||||
resolve(env);
|
||||
};
|
||||
await syncable.sign();
|
||||
});
|
||||
@ -153,9 +148,9 @@ export class UserService {
|
||||
|
||||
async loadAccounts(limit: number = 100, offset: number = 0): Promise<void> {
|
||||
this.resetAccountsList();
|
||||
const accountIndexAddress = await this.registry.getContractAddressByName('AccountRegistry');
|
||||
const accountIndexAddress: string = await this.registry.getContractAddressByName('AccountRegistry');
|
||||
const accountIndexQuery = new AccountIndex(accountIndexAddress);
|
||||
const accountAddresses = await accountIndexQuery.last(await accountIndexQuery.totalAccounts());
|
||||
const accountAddresses: Array<string> = await accountIndexQuery.last(await accountIndexQuery.totalAccounts());
|
||||
this.loggingService.sendInfoLevelMessage(accountAddresses);
|
||||
for (const accountAddress of accountAddresses.slice(offset, offset + limit)) {
|
||||
await this.getAccountByAddress(accountAddress, limit);
|
||||
@ -163,13 +158,12 @@ export class UserService {
|
||||
}
|
||||
|
||||
async getAccountByAddress(accountAddress: string, limit: number = 100): Promise<Observable<AccountDetails>> {
|
||||
let accountSubject = new Subject<any>();
|
||||
let accountSubject: Subject<any> = new Subject<any>();
|
||||
this.getAccountDetailsFromMeta(await User.toKey(add0x(accountAddress))).pipe(first()).subscribe(async res => {
|
||||
const account = Envelope.fromJSON(JSON.stringify(res)).unwrap();
|
||||
this.accountsMeta.push(account);
|
||||
const account: Syncable = Envelope.fromJSON(JSON.stringify(res)).unwrap();
|
||||
const accountInfo = account.m.data;
|
||||
await personValidation(accountInfo);
|
||||
accountInfo.balance = await this.tokenService.getTokenBalance(accountInfo.identities.evm['bloxberg:8996'][0]);
|
||||
accountInfo.balance = await this.tokenService.getTokenBalance(accountInfo.identities.evm[`bloxberg:${environment.bloxbergChainId}`][0]);
|
||||
accountInfo.vcard = vCard.parse(atob(accountInfo.vcard));
|
||||
await vcardValidation(accountInfo.vcard);
|
||||
this.accounts.unshift(accountInfo);
|
||||
@ -183,11 +177,11 @@ export class UserService {
|
||||
}
|
||||
|
||||
async getAccountByPhone(phoneNumber: string, limit: number = 100): Promise<Observable<AccountDetails>> {
|
||||
let accountSubject = new Subject<any>();
|
||||
let accountSubject: Subject<any> = new Subject<any>();
|
||||
this.getAccountDetailsFromMeta(await Phone.toKey(phoneNumber)).pipe(first()).subscribe(async res => {
|
||||
const response = Envelope.fromJSON(JSON.stringify(res)).unwrap();
|
||||
const address = response.m.data;
|
||||
const account = await this.getAccountByAddress(address, limit);
|
||||
const response: Syncable = Envelope.fromJSON(JSON.stringify(res)).unwrap();
|
||||
const address: string = response.m.data;
|
||||
const account: Observable<AccountDetails> = await this.getAccountByAddress(address, limit);
|
||||
account.subscribe(result => {
|
||||
accountSubject.next(result);
|
||||
});
|
||||
|
@ -22,19 +22,18 @@ export class AppComponent {
|
||||
) {
|
||||
(async () => {
|
||||
try {
|
||||
await this.authService.mutableKeyStore.loadKeyring();
|
||||
await this.authService.init();
|
||||
// this.authService.getPublicKeys()
|
||||
// .pipe(catchError(async (error) => {
|
||||
// this.loggingService.sendErrorLevelMessage('Unable to load trusted public keys.', this, {error});
|
||||
// this.errorDialogService.openDialog({message: 'Trusted keys endpoint can\'t be reached. Please try again later.'});
|
||||
// })).subscribe(this.authService.mutableKeyStore.importPublicKey);
|
||||
const publicKeys = await this.authService.getPublicKeys()
|
||||
const publicKeys = await this.authService.getPublicKeys();
|
||||
await this.authService.mutableKeyStore.importPublicKey(publicKeys);
|
||||
} catch(error) {
|
||||
} catch (error) {
|
||||
this.errorDialogService.openDialog({message: 'Trusted keys endpoint can\'t be reached. Please try again later.'});
|
||||
// TODO do something to halt user progress...show a sad cicada page 🦗?
|
||||
}
|
||||
|
||||
})();
|
||||
this.mediaQuery.addListener(this.onResize);
|
||||
this.onResize(this.mediaQuery);
|
||||
|
@ -27,10 +27,10 @@ export class AuthComponent implements OnInit {
|
||||
key: ['', Validators.required],
|
||||
});
|
||||
await this.authService.init();
|
||||
//if (this.authService.privateKey !== undefined) {
|
||||
// if (this.authService.privateKey !== undefined) {
|
||||
// const setKey = await this.authService.setKey(this.authService.privateKey);
|
||||
// }
|
||||
//}
|
||||
// }
|
||||
}
|
||||
|
||||
get keyFormStub(): any { return this.keyForm.controls; }
|
||||
|
@ -9,6 +9,7 @@ import {FormBuilder, FormGroup, Validators} from '@angular/forms';
|
||||
import {copyToClipboard, CustomErrorStateMatcher, exportCsv} from '@app/_helpers';
|
||||
import {MatSnackBar} from '@angular/material/snack-bar';
|
||||
import {add0x, strip0x} from '@src/assets/js/ethtx/dist/hex';
|
||||
import {environment} from '@src/environments/environment';
|
||||
|
||||
@Component({
|
||||
selector: 'app-account-details',
|
||||
@ -139,7 +140,7 @@ export class AccountDetailsComponent implements OnInit {
|
||||
}
|
||||
|
||||
viewAccount(account): void {
|
||||
this.router.navigateByUrl(`/accounts/${strip0x(account.identities.evm['bloxberg:8996'][0])}`);
|
||||
this.router.navigateByUrl(`/accounts/${strip0x(account.identities.evm[`bloxberg:${environment.bloxbergChainId}`][0])}`);
|
||||
}
|
||||
|
||||
get accountInfoFormStub(): any { return this.accountInfoForm.controls; }
|
||||
|
@ -4,6 +4,7 @@ import {CustomErrorStateMatcher} from '@app/_helpers';
|
||||
import {UserService} from '@app/_services';
|
||||
import {Router} from '@angular/router';
|
||||
import {strip0x} from '@src/assets/js/ethtx/dist/hex';
|
||||
import {environment} from '@src/environments/environment';
|
||||
|
||||
@Component({
|
||||
selector: 'app-account-search',
|
||||
@ -60,7 +61,7 @@ export class AccountSearchComponent implements OnInit {
|
||||
(await this.userService.getAccountByPhone(this.phoneSearchFormStub.phoneNumber.value, 100)).subscribe(async res => {
|
||||
console.log(res);
|
||||
if (res !== undefined) {
|
||||
await this.router.navigateByUrl(`/accounts/${strip0x(res.identities.evm['bloxberg:8996'][0])}`);
|
||||
await this.router.navigateByUrl(`/accounts/${strip0x(res.identities.evm[`bloxberg:${environment.bloxbergChainId}`][0])}`);
|
||||
} else {
|
||||
alert('Account not found!');
|
||||
}
|
||||
@ -74,7 +75,7 @@ export class AccountSearchComponent implements OnInit {
|
||||
this.addressSearchLoading = true;
|
||||
(await this.userService.getAccountByAddress(this.addressSearchFormStub.address.value, 100)).subscribe(async res => {
|
||||
if (res !== undefined) {
|
||||
await this.router.navigateByUrl(`/accounts/${strip0x(res.identities.evm['bloxberg:8996'][0])}`);
|
||||
await this.router.navigateByUrl(`/accounts/${strip0x(res.identities.evm[`bloxberg:${environment.bloxbergChainId}`][0])}`);
|
||||
} else {
|
||||
alert('Account not found!');
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import {Router} from '@angular/router';
|
||||
import {exportCsv} from '@app/_helpers';
|
||||
import {strip0x} from '@src/assets/js/ethtx/dist/hex';
|
||||
import {first} from 'rxjs/operators';
|
||||
import {environment} from '@src/environments/environment';
|
||||
|
||||
@Component({
|
||||
selector: 'app-accounts',
|
||||
@ -57,7 +58,7 @@ export class AccountsComponent implements OnInit {
|
||||
}
|
||||
|
||||
async viewAccount(account): Promise<void> {
|
||||
await this.router.navigateByUrl(`/accounts/${strip0x(account.identities.evm['bloxberg:8996'][0])}`);
|
||||
await this.router.navigateByUrl(`/accounts/${strip0x(account.identities.evm[`bloxberg:${environment.bloxbergChainId}`][0])}`);
|
||||
}
|
||||
|
||||
filterAccounts(): void {
|
||||
|
@ -5,6 +5,7 @@ import {LoggingService, TokenService} from '@app/_services';
|
||||
import {MatTableDataSource} from '@angular/material/table';
|
||||
import {Router} from '@angular/router';
|
||||
import {exportCsv} from '@app/_helpers';
|
||||
import {TokenRegistry} from '../../_eth';
|
||||
|
||||
@Component({
|
||||
selector: 'app-tokens',
|
||||
@ -26,13 +27,14 @@ export class TokensComponent implements OnInit {
|
||||
) { }
|
||||
|
||||
async ngOnInit(): Promise<void> {
|
||||
this.tokenService.LoadEvent.subscribe(async () => {
|
||||
this.tokens = await this.tokenService.getTokens();
|
||||
});
|
||||
this.tokens = await this.tokenService.getTokens();
|
||||
this.loggingService.sendInfoLevelMessage(this.tokens);
|
||||
this.tokenService.tokensSubject.subscribe(tokens => {
|
||||
this.dataSource = new MatTableDataSource(tokens);
|
||||
this.dataSource = new MatTableDataSource(this.tokens);
|
||||
this.dataSource.paginator = this.paginator;
|
||||
this.dataSource.sort = this.sort;
|
||||
});
|
||||
}
|
||||
|
||||
doFilter(value: string): void {
|
||||
|
Loading…
Reference in New Issue
Block a user