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