Add cic registry class for querying resource information on the network.

This commit is contained in:
Spencer Ofwiti 2021-03-06 09:28:29 +03:00
parent 2b99dd8c62
commit 7447bf2499
13 changed files with 88 additions and 217 deletions

View File

@ -1,10 +1,9 @@
// @ts-ignore // @ts-ignore
import * as accountIndex from '@src/assets/json/accountIndex.abi.json'; 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'); const Web3 = require('web3');
const web3 = new Web3(environment.web3Provider); const web3 = new Web3(environment.web3Provider);
// @ts-ignore
const abi = accountIndex.default; const abi = accountIndex.default;
export class AccountIndex { export class AccountIndex {

View File

@ -7,3 +7,4 @@ export * from '@app/_helpers/array-sum';
export * from '@app/_helpers/accountIndex'; export * from '@app/_helpers/accountIndex';
export * from '@app/_helpers/http-getter'; export * from '@app/_helpers/http-getter';
export * from '@app/_helpers/pgp-signer'; export * from '@app/_helpers/pgp-signer';
export * from '@app/_helpers/registry';

View File

@ -0,0 +1,7 @@
import { Registry } from './registry';
describe('Registry', () => {
it('should create an instance', () => {
expect(new Registry()).toBeTruthy();
});
});

View File

@ -0,0 +1,32 @@
// @ts-ignore
import * as registry from '@src/assets/js/block-sync/data/Registry.json';
import {environment} from '@src/environments/environment';
const Web3 = require('web3');
const web3 = new Web3(environment.web3Provider);
const abi = registry.default;
export class Registry {
contractAddress: string;
signerAddress: string;
contract: any;
constructor(contractAddress: string, signerAddress?: string) {
this.contractAddress = contractAddress;
this.contract = new web3.eth.Contract(abi, contractAddress);
if (signerAddress) {
this.signerAddress = signerAddress;
} else {
this.signerAddress = web3.eth.accounts[0];
}
}
public async owner(): Promise<string> {
return await this.contract.methods.owner().call();
}
public async addressOf(identifier: string): Promise<string> {
const id = '0x' + web3.utils.padRight(new Buffer(identifier).toString('hex'), 64);
return await this.contract.methods.addressOf(id).call();
}
}

View File

@ -5,7 +5,9 @@ export interface AccountDetails {
evm: { evm: {
'bloxberg:8996': string[]; 'bloxberg:8996': string[];
'oldchain:1': string[]; 'oldchain:1': string[];
} };
latitude: number;
longitude: number;
}; };
location: { location: {
area_name: string; area_name: string;

View File

@ -5,7 +5,6 @@ import {BehaviorSubject, Observable} from 'rxjs';
import {environment} from '@src/environments/environment'; import {environment} from '@src/environments/environment';
import {Envelope, User} from 'cic-client-meta'; import {Envelope, User} from 'cic-client-meta';
import {UserService} from '@app/_services/user.service'; import {UserService} from '@app/_services/user.service';
import { AccountIndex } from '@app/_helpers';
import { Keccak } from 'sha3'; import { Keccak } from 'sha3';
import { utils } from 'ethers'; import { utils } from 'ethers';
import {add0x, fromHex, strip0x, toHex} from '@src/assets/js/ethtx/dist/hex'; import {add0x, fromHex, strip0x, toHex} from '@src/assets/js/ethtx/dist/hex';
@ -13,6 +12,7 @@ import {Tx} from '@src/assets/js/ethtx/dist';
import {toValue} from '@src/assets/js/ethtx/dist/tx'; import {toValue} from '@src/assets/js/ethtx/dist/tx';
import * as secp256k1 from 'secp256k1'; import * as secp256k1 from 'secp256k1';
import {AuthService} from '@app/_services/auth.service'; import {AuthService} from '@app/_services/auth.service';
import {Registry} from '@app/_helpers';
const Web3 = require('web3'); const Web3 = require('web3');
const vCard = require('vcard-parser'); const vCard = require('vcard-parser');
@ -24,8 +24,8 @@ 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;
request = new AccountIndex(environment.contractAddress);
web3 = new Web3(environment.web3Provider); web3 = new Web3(environment.web3Provider);
registry = new Registry(environment.registryAddress);
constructor( constructor(
private http: HttpClient, private http: HttpClient,
@ -83,6 +83,7 @@ export class TransactionService {
} }
async transferRequest(tokenAddress: string, senderAddress: string, recipientAddress: string, value: number): Promise<any> { async transferRequest(tokenAddress: string, senderAddress: string, recipientAddress: string, value: number): Promise<any> {
const transferAuthAddress = await this.registry.addressOf('TransferAuthorization');
const hashFunction = new Keccak(256); const hashFunction = new Keccak(256);
hashFunction.update('createRequest(address,address,address,uint256)'); hashFunction.update('createRequest(address,address,address,uint256)');
const hash = hashFunction.digest(); const hash = hashFunction.digest();
@ -94,7 +95,7 @@ export class TransactionService {
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 = await this.web3.eth.getGasPrice();
tx.gasLimit = 8000000; tx.gasLimit = 8000000;
tx.to = fromHex(strip0x(recipientAddress)); tx.to = fromHex(strip0x(transferAuthAddress));
tx.value = toValue(value); tx.value = toValue(value);
tx.data = data; tx.data = data;
const txMsg = tx.message(); const txMsg = tx.message();

View File

@ -3,7 +3,7 @@ import {BehaviorSubject, Observable} from 'rxjs';
import {HttpClient, HttpHeaders, HttpParams} from '@angular/common/http'; import {HttpClient, HttpHeaders, HttpParams} from '@angular/common/http';
import {environment} from '@src/environments/environment'; import {environment} from '@src/environments/environment';
import {first} from 'rxjs/operators'; import {first} from 'rxjs/operators';
import {AccountIndex, MutableKeyStore, MutablePgpKeyStore, PGPSigner, Signer} from '@app/_helpers'; import {AccountIndex, MutableKeyStore, MutablePgpKeyStore, PGPSigner, Registry, Signer} from '@app/_helpers';
import {ArgPair, Envelope, Syncable, User} from 'cic-client-meta'; import {ArgPair, Envelope, Syncable, User} from 'cic-client-meta';
const vCard = require('vcard-parser'); const vCard = require('vcard-parser');
@ -14,7 +14,7 @@ export class UserService {
headers: HttpHeaders = new HttpHeaders({'x-cic-automerge': 'client'}); headers: HttpHeaders = new HttpHeaders({'x-cic-automerge': 'client'});
keystore: MutableKeyStore = new MutablePgpKeyStore(); keystore: MutableKeyStore = new MutablePgpKeyStore();
signer: Signer = new PGPSigner(this.keystore); signer: Signer = new PGPSigner(this.keystore);
accountIndexQuery = new AccountIndex(environment.contractAddress); registry = new Registry(environment.registryAddress);
accountsMeta = []; accountsMeta = [];
accounts: any = []; accounts: any = [];
@ -29,7 +29,8 @@ export class UserService {
private staffList = new BehaviorSubject<any>(this.staff); private staffList = new BehaviorSubject<any>(this.staff);
staffSubject = this.staffList.asObservable(); staffSubject = this.staffList.asObservable();
constructor(private http: HttpClient) { } constructor(private http: HttpClient) {
}
resetPin(phone: string): Observable<any> { resetPin(phone: string): Observable<any> {
const params = new HttpParams().set('phoneNumber', phone); const params = new HttpParams().set('phoneNumber', phone);
@ -153,7 +154,10 @@ export class UserService {
} }
async loadAccounts(limit: number, offset: number = 0): Promise<void> { async loadAccounts(limit: number, offset: number = 0): Promise<void> {
const accountAddresses = await this.accountIndexQuery.last(await this.accountIndexQuery.totalAccounts()); const accountIndexAddress = await this.registry.addressOf('AccountRegistry');
const accountIndexQuery = new AccountIndex(accountIndexAddress);
const accountAddresses = await accountIndexQuery.last(await accountIndexQuery.totalAccounts());
console.log(accountAddresses);
for (const accountAddress of accountAddresses.slice(offset, offset + limit)) { for (const accountAddress of accountAddresses.slice(offset, offset + limit)) {
this.getAccountDetailsFromMeta(await User.toKey(accountAddress)).pipe(first()).subscribe(res => { this.getAccountDetailsFromMeta(await User.toKey(accountAddress)).pipe(first()).subscribe(res => {
const account = Envelope.fromJSON(JSON.stringify(res)).unwrap(); const account = Envelope.fromJSON(JSON.stringify(res)).unwrap();

View File

@ -9,22 +9,22 @@
<div id="content"> <div id="content">
<app-topbar></app-topbar> <app-topbar></app-topbar>
<!-- Start Content--> <!-- Start Content-->
<div class="container-fluid" appMenuSelection> <div class="container-fluid" appMenuSelection>
<nav aria-label="breadcrumb"> <nav aria-label="breadcrumb">
<ol class="breadcrumb"> <ol class="breadcrumb">
<li class="breadcrumb-item"><a routerLink="/home">Home</a></li> <li class="breadcrumb-item"><a routerLink="/home">Home</a></li>
<li class="breadcrumb-item"><a routerLink="/accounts">Accounts</a></li> <li class="breadcrumb-item"><a routerLink="/accounts">Accounts</a></li>
<li class="breadcrumb-item active" aria-current="page">{{account?.name}}</li> <!-- <li *ngIf="account" class="breadcrumb-item active" aria-current="page">{{account?.fn[0].value}}</li>-->
</ol> </ol>
</nav> </nav>
<div class="card mb-3"> <div class="card mb-3">
<div class="row card-body"> <div class="row card-body">
<h3> <h3>
<strong> {{account?.name}} </strong> <strong> {{account?.fn[0].value}} </strong>
</h3> </h3>
<span class="ml-auto"><strong>Balance:</strong> {{account?.balance}} RCU</span> <span class="ml-auto"><strong>Balance:</strong> {{account?.balance}} RCU</span>
<span class="ml-2"><strong>Created:</strong> {{account?.created}}</span> <span class="ml-2"><strong>Created:</strong> {{account?.date_registered | date}}</span>
<span class="ml-2"><strong>Address:</strong><a href="{{bloxbergLink}}" target="_blank"> {{account?.address}} </a></span> <!-- <span class="ml-2"><strong>Address:</strong><a href="{{bloxbergLink}}" target="_blank"> {{account?.identities.evm['bloxberg:8996']}} </a></span>-->
</div> </div>
</div> </div>
<app-disbursement *ngIf="isDisbursing" (cancelDisbursmentEvent)="addTransfer()" [account]="account"> <app-disbursement *ngIf="isDisbursing" (cancelDisbursmentEvent)="addTransfer()" [account]="account">

View File

@ -9,6 +9,7 @@ import {first} from 'rxjs/operators';
import {FormBuilder, FormGroup, Validators} from '@angular/forms'; import {FormBuilder, FormGroup, Validators} from '@angular/forms';
import {CustomErrorStateMatcher} from '@app/_helpers'; import {CustomErrorStateMatcher} from '@app/_helpers';
import {Envelope, User} from 'cic-client-meta'; import {Envelope, User} from 'cic-client-meta';
const vCard = require('vcard-parser');
@Component({ @Component({
selector: 'app-account-details', selector: 'app-account-details',
@ -74,49 +75,30 @@ export class AccountDetailsComponent implements OnInit {
locationType: ['', Validators.required], locationType: ['', Validators.required],
referrer: ['', Validators.required] referrer: ['', Validators.required]
}); });
this.route.paramMap.subscribe((params: Params) => { this.route.paramMap.subscribe(async (params: Params) => {
this.userService.getAccountById(params.get('id')).pipe(first()).subscribe(async account => { this.userService.getAccountDetailsFromMeta(await User.toKey(params.get('id'))).pipe(first()).subscribe(res => {
this.account = account; this.metaAccount = Envelope.fromJSON(JSON.stringify(res)).unwrap();
this.userService.getAccountDetailsFromMeta(await User.toKey(account.address)).pipe(first()).subscribe(res => { this.account = this.metaAccount.m.data;
this.metaAccount = Envelope.fromJSON(JSON.stringify(res)).unwrap(); this.account.vcard = vCard.parse(atob(this.account.vcard));
const accountInfo = this.metaAccount.m.data; console.log(this.account);
console.log(accountInfo); this.accountInfoForm.patchValue({
this.accountInfoForm.patchValue({ status: this.account.status,
status: accountInfo.status, name: this.account.vcard?.fn[0].value,
name: accountInfo.name, phoneNumber: this.account.vcard?.tel[0].value,
phoneNumber: accountInfo.phoneNumber, age: this.account.age,
age: accountInfo.age, type: this.account.type,
type: accountInfo.type, token: this.account.token,
token: accountInfo.token, failedPinAttempts: this.account.failedPinAttempts,
failedPinAttempts: accountInfo.failedPinAttempts, bio: this.account.bio,
bio: accountInfo.bio, gender: this.account.gender,
gender: accountInfo.gender, businessCategory: this.account.businessCategory,
businessCategory: accountInfo.businessCategory, userLocation: this.account.location.area_name,
userLocation: accountInfo.userLocation, location: this.account.location,
location: accountInfo.location, locationType: this.account.locationType,
locationType: accountInfo.locationType, referrer: this.account.referrer
referrer: accountInfo.referrer
});
}, error => {
this.accountInfoForm.patchValue({
status: account.status,
name: account.name,
phoneNumber: account.phone,
age: account.age,
type: account.type,
token: account.token,
failedPinAttempts: account.failedPinAttempts,
bio: account.bio,
gender: account.gender,
businessCategory: account.category,
userLocation: account.userLocation,
location: account.location,
locationType: account.locationType,
referrer: account.referrer
});
}); });
this.bloxbergLink = 'https://blockexplorer.bloxberg.org/address/' + this.account.address + '/transactions'; this.bloxbergLink = 'https://blockexplorer.bloxberg.org/address/' + this.account.identities.evm['bloxberg:8996'] + '/transactions';
this.userService.getHistoryByUser(this.account?.id).pipe(first()).subscribe(history => { this.userService.getHistoryByUser(params.get('id')).pipe(first()).subscribe(history => {
this.historyDataSource = new MatTableDataSource<any>(history); this.historyDataSource = new MatTableDataSource<any>(history);
this.historyDataSource.paginator = this.historyTablePaginator; this.historyDataSource.paginator = this.historyTablePaginator;
this.historyDataSource.sort = this.historyTableSort; this.historyDataSource.sort = this.historyTableSort;

View File

@ -55,7 +55,7 @@ export class AccountsComponent implements OnInit {
} }
viewAccount(account): void { viewAccount(account): void {
this.router.navigateByUrl(`/accounts/${account.id}`).then(); this.router.navigateByUrl(`/accounts/${account.identities.evm['bloxberg:8996']}`).then();
} }
approveAccount(): void { approveAccount(): void {

View File

@ -1,153 +0,0 @@
[
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "addedAccount",
"type": "address"
},
{
"indexed": true,
"internalType": "uint256",
"name": "accountIndex",
"type": "uint256"
}
],
"name": "AccountAdded",
"type": "event"
},
{
"inputs": [
{
"internalType": "address",
"name": "_account",
"type": "address"
}
],
"name": "add",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_writer",
"type": "address"
}
],
"name": "addWriter",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_writer",
"type": "address"
}
],
"name": "deleteWriter",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "accounts",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "accountsIndex",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "count",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_account",
"type": "address"
}
],
"name": "have",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
}
]

View File

@ -9,8 +9,6 @@ export const environment = {
web3Provider: 'ws://localhost:63546', web3Provider: 'ws://localhost:63546',
cicUssdUrl: 'http://localhost:63315', cicUssdUrl: 'http://localhost:63315',
cicEthUrl: 'http://localhost:63314', cicEthUrl: 'http://localhost:63314',
contractAddress: '0xd0097a901AF4ac2E63A5b6E86be8Ad91f10b05d7',
registryAddress: '0xf374d7B507767101a4bf3bA2a6B99AC737A44f6d', registryAddress: '0xf374d7B507767101a4bf3bA2a6B99AC737A44f6d',
trustedDeclaratorAddress: '0xEb3907eCad74a0013c259D5874AE7f22DcBcC95C', trustedDeclaratorAddress: '0xEb3907eCad74a0013c259D5874AE7f22DcBcC95C'
transferAuthorizationAddress: '0xB542fd8bCb777f058997b7D8D06381A0571BF224'
}; };

View File

@ -13,10 +13,8 @@ export const environment = {
web3Provider: 'ws://localhost:63546', web3Provider: 'ws://localhost:63546',
cicUssdUrl: 'http://localhost:63315', cicUssdUrl: 'http://localhost:63315',
cicEthUrl: 'http://localhost:63314', cicEthUrl: 'http://localhost:63314',
contractAddress: '0xd0097a901AF4ac2E63A5b6E86be8Ad91f10b05d7',
registryAddress: '0xf374d7B507767101a4bf3bA2a6B99AC737A44f6d', registryAddress: '0xf374d7B507767101a4bf3bA2a6B99AC737A44f6d',
trustedDeclaratorAddress: '0xEb3907eCad74a0013c259D5874AE7f22DcBcC95C', trustedDeclaratorAddress: '0xEb3907eCad74a0013c259D5874AE7f22DcBcC95C'
transferAuthorizationAddress: '0xB542fd8bCb777f058997b7D8D06381A0571BF224'
}; };
/* /*