File

src/app/_services/user.service.ts

Index

Properties
Methods

Constructor

constructor(httpClient: HttpClient, loggingService: LoggingService, tokenService: TokenService, registryService: RegistryService, authService: AuthService)
Parameters :
Name Type Optional
httpClient HttpClient No
loggingService LoggingService No
tokenService TokenService No
registryService RegistryService No
authService AuthService No

Methods

approveAction
approveAction(id: string)
Parameters :
Name Type Optional
id string No
Returns : Observable<any>
Async changeAccountInfo
changeAccountInfo(address: string, name: string, phoneNumber: string, age: string, type: string, bio: string, gender: string, businessCategory: string, userLocation: string, location: string, locationType: string)
Parameters :
Name Type Optional
address string No
name string No
phoneNumber string No
age string No
type string No
bio string No
gender string No
businessCategory string No
userLocation string No
location string No
locationType string No
Returns : Promise<any>
Async getAccountByAddress
getAccountByAddress(accountAddress: string, limit: number)
Parameters :
Name Type Optional Default value
accountAddress string No
limit number No 100
Async getAccountByPhone
getAccountByPhone(phoneNumber: string, limit: number)
Parameters :
Name Type Optional Default value
phoneNumber string No
limit number No 100
getAccountDetailsFromMeta
getAccountDetailsFromMeta(userKey: string)
Parameters :
Name Type Optional
userKey string No
Returns : Observable<any>
getAccountStatus
getAccountStatus(phone: string)
Parameters :
Name Type Optional
phone string No
Returns : Observable<any>
getAccountTypes
getAccountTypes()
Returns : Observable<any>
getActionById
getActionById(id: string)
Parameters :
Name Type Optional
id string No
Returns : Observable<any>
getActions
getActions()
Returns : void
getCategories
getCategories()
Returns : Observable<any>
getCategoryByProduct
getCategoryByProduct(product: string)
Parameters :
Name Type Optional
product string No
Returns : Observable<any>
getGenders
getGenders()
Returns : Observable<any>
getLockedAccounts
getLockedAccounts(offset: number, limit: number)
Parameters :
Name Type Optional
offset number No
limit number No
Returns : Observable<any>
getTransactionTypes
getTransactionTypes()
Returns : Observable<any>
Async loadAccounts
loadAccounts(limit: number, offset: number)
Parameters :
Name Type Optional Default value
limit number No 100
offset number No 0
Returns : Promise<void>
resetAccountsList
resetAccountsList()
Returns : void
resetPin
resetPin(phone: string)
Parameters :
Name Type Optional
phone string No
Returns : Observable<any>
revokeAction
revokeAction(id: string)
Parameters :
Name Type Optional
id string No
Returns : Observable<any>
searchAccountByName
searchAccountByName(name: string)
Parameters :
Name Type Optional
name string No
Returns : any
Async updateMeta
updateMeta(syncableAccount: Syncable, accountKey: string, headers: HttpHeaders)
Parameters :
Name Type Optional
syncableAccount Syncable No
accountKey string No
headers HttpHeaders No
Returns : Promise<any>
wrap
wrap(syncable: Syncable, signer: Signer)
Parameters :
Name Type Optional
syncable Syncable No
signer Signer No
Returns : Promise<Envelope>

Properties

accounts
Type : Array<AccountDetails>
Default value : []
Private accountsList
Type : BehaviorSubject<Array<AccountDetails>>
Default value : new BehaviorSubject<Array<AccountDetails>>(this.accounts)
accountsSubject
Type : Observable<Array<AccountDetails>>
Default value : this.accountsList.asObservable()
actions
Type : Array<any>
Default value : []
Private actionsList
Type : BehaviorSubject<any>
Default value : new BehaviorSubject<any>(this.actions)
actionsSubject
Type : Observable<Array<any>>
Default value : this.actionsList.asObservable()
headers
Type : HttpHeaders
Default value : new HttpHeaders({'x-cic-automerge': 'client'})
keystore
Type : MutableKeyStore
registry
Type : CICRegistry
signer
Type : Signer
import {Injectable} from '@angular/core';
import {BehaviorSubject, Observable, Subject} from 'rxjs';
import {HttpClient, HttpHeaders, HttpParams} from '@angular/common/http';
import {environment} from '@src/environments/environment';
import {first} from 'rxjs/operators';
import {ArgPair, Envelope, Phone, Syncable, User} from 'cic-client-meta';
import {AccountDetails} from '@app/_models';
import {LoggingService} from '@app/_services/logging.service';
import {TokenService} from '@app/_services/token.service';
import {AccountIndex} from '@app/_eth';
import {MutableKeyStore, PGPSigner, Signer} from '@app/_pgp';
import {RegistryService} from '@app/_services/registry.service';
import {CICRegistry} from 'cic-client';
import {AuthService} from '@app/_services/auth.service';
import {personValidation, vcardValidation} from '@app/_helpers';
import {add0x} from '@src/assets/js/ethtx/dist/hex';
const vCard = require('vcard-parser');

@Injectable({
  providedIn: 'root'
})
export class UserService {
  headers: HttpHeaders = new HttpHeaders({'x-cic-automerge': 'client'});
  keystore: MutableKeyStore;
  signer: Signer;
  registry: CICRegistry;

  accounts: Array<AccountDetails> = [];
  private accountsList: BehaviorSubject<Array<AccountDetails>> = new BehaviorSubject<Array<AccountDetails>>(this.accounts);
  accountsSubject: Observable<Array<AccountDetails>> = this.accountsList.asObservable();

  actions: Array<any> = [];
  private actionsList: BehaviorSubject<any> = new BehaviorSubject<any>(this.actions);
  actionsSubject: Observable<Array<any>> = this.actionsList.asObservable();

  constructor(
    private httpClient: HttpClient,
    private loggingService: LoggingService,
    private tokenService: TokenService,
    private registryService: RegistryService,
    private authService: AuthService,
  ) {
    this.authService.init().then(() => {
      this.keystore = authService.mutableKeyStore;
      this.signer = new PGPSigner(this.keystore);
    });
    this.registry = registryService.getRegistry();
    this.registry.load();
  }

  resetPin(phone: string): Observable<any> {
    const params: HttpParams = new HttpParams().set('phoneNumber', phone);
    return this.httpClient.get(`${environment.cicUssdUrl}/pin`, {params});
  }

  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): 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> {
    const accountInfo: any = {
      vcard: {
        fn: [{}],
        n: [{}],
        tel: [{}]
      },
      location: {}
    };
    accountInfo.vcard.fn[0].value = name;
    accountInfo.vcard.n[0].value = name.split(' ');
    accountInfo.vcard.tel[0].value = phoneNumber;
    accountInfo.products = [bio];
    accountInfo.gender = gender;
    accountInfo.age = age;
    accountInfo.type = type;
    accountInfo.category = businessCategory;
    accountInfo.location.area = location;
    accountInfo.location.area_name = userLocation;
    accountInfo.location.area_type = locationType;
    await vcardValidation(accountInfo.vcard);
    accountInfo.vcard = btoa(vCard.generate(accountInfo.vcard));
    const accountKey: string = await User.toKey(address);
    this.getAccountDetailsFromMeta(accountKey).pipe(first()).subscribe(async res => {
      const syncableAccount: Syncable = Envelope.fromJSON(JSON.stringify(res)).unwrap();
      const update: Array<ArgPair> = [];
      for (const prop in accountInfo) {
        update.push(new ArgPair(prop, accountInfo[prop]));
      }
      syncableAccount.update(update, 'client-branch');
      await personValidation(syncableAccount.m.data);
      await this.updateMeta(syncableAccount, accountKey, this.headers);
    }, async error => {
      this.loggingService.sendErrorLevelMessage('Can\'t find account info in meta service', this, {error});
      const syncableAccount: Syncable = new Syncable(accountKey, accountInfo);
      await this.updateMeta(syncableAccount, accountKey, this.headers);
    });
    return accountKey;
  }

  async updateMeta(syncableAccount: Syncable, accountKey: string, headers: HttpHeaders): Promise<any> {
    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}`);
    });
  }

  getActions(): void {
    this.httpClient.get(`${environment.cicCacheUrl}/actions`).pipe(first()).subscribe(res => this.actionsList.next(res));
  }

  getActionById(id: string): Observable<any> {
    return this.httpClient.get(`${environment.cicCacheUrl}/actions/${id}`);
  }

  approveAction(id: string): Observable<any> {
    return this.httpClient.post(`${environment.cicCacheUrl}/actions/${id}`, { approval: true });
  }

  revokeAction(id: string): Observable<any> {
    return this.httpClient.post(`${environment.cicCacheUrl}/actions/${id}`, { approval: false });
  }

  getAccountDetailsFromMeta(userKey: string): Observable<any> {
    return this.httpClient.get(`${environment.cicMetaUrl}/${userKey}`, { headers: this.headers });
  }

  wrap(syncable: Syncable, signer: Signer): Promise<Envelope> {
    return new Promise<Envelope>(async (resolve, reject) => {
      syncable.setSigner(signer);
      syncable.onwrap = async (env) => {
        if (env === undefined) {
          reject();
          return;
        }
        resolve(env);
      };
      await syncable.sign();
    });
  }

  async loadAccounts(limit: number = 100, offset: number = 0): Promise<void> {
    this.resetAccountsList();
    const accountIndexAddress: string = await this.registry.getContractAddressByName('AccountRegistry');
    const accountIndexQuery = new AccountIndex(accountIndexAddress);
    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);
    }
  }

  async getAccountByAddress(accountAddress: string, limit: number = 100): Promise<Observable<AccountDetails>> {
    let accountSubject: Subject<any> = new Subject<any>();
    this.getAccountDetailsFromMeta(await User.toKey(add0x(accountAddress))).pipe(first()).subscribe(async res => {
      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:${environment.bloxbergChainId}`][0]);
      accountInfo.vcard = vCard.parse(atob(accountInfo.vcard));
      await vcardValidation(accountInfo.vcard);
      this.accounts.unshift(accountInfo);
      if (this.accounts.length > limit) {
        this.accounts.length = limit;
      }
      this.accountsList.next(this.accounts);
      accountSubject.next(accountInfo);
    });
    return accountSubject.asObservable();
  }

  async getAccountByPhone(phoneNumber: string, limit: number = 100): Promise<Observable<AccountDetails>> {
    let accountSubject: Subject<any> = new Subject<any>();
    this.getAccountDetailsFromMeta(await Phone.toKey(phoneNumber)).pipe(first()).subscribe(async res => {
      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);
      });
    });
    return accountSubject.asObservable();
  }

  resetAccountsList(): void {
    this.accounts = [];
    this.accountsList.next(this.accounts);
  }

  searchAccountByName(name: string): any { return; }

  getCategories(): Observable<any> {
    return this.httpClient.get(`${environment.cicMetaUrl}/categories`);
  }

  getCategoryByProduct(product: string): Observable<any> {
    return this.httpClient.get(`${environment.cicMetaUrl}/categories/${product.toLowerCase()}`);
  }

  getAccountTypes(): Observable<any> {
    return this.httpClient.get(`${environment.cicMetaUrl}/accounttypes`);
  }

  getTransactionTypes(): Observable<any> {
    return this.httpClient.get(`${environment.cicMetaUrl}/transactiontypes`);
  }

  getGenders(): Observable<any> {
    return this.httpClient.get(`${environment.cicMetaUrl}/genders`);
  }
}

result-matching ""

    No results matching ""