Add fetching of transaction participants from cic-meta.

Add token registry to query tokens.
This commit is contained in:
Spencer Ofwiti 2021-03-10 12:47:01 +03:00
parent 7447bf2499
commit 32ab27730b
23 changed files with 262 additions and 125 deletions

View File

@ -22,7 +22,7 @@ export class AccountIndex {
}
public async totalAccounts(): Promise<number> {
return this.contract.methods.count().call();
return await this.contract.methods.count().call();
}
public async haveAccount(address: string): Promise<boolean> {

View File

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

View File

@ -1,7 +1,8 @@
import { Registry } from './registry';
import { Registry } from '@app/_helpers/registry';
import {environment} from '@src/environments/environment';
describe('Registry', () => {
it('should create an instance', () => {
expect(new Registry()).toBeTruthy();
expect(new Registry(environment.registryAddress)).toBeTruthy();
});
});

View File

@ -0,0 +1,8 @@
import { TokenRegistry } from '@app/_helpers/token-registry';
import {environment} from '@src/environments/environment';
describe('TokenRegistry', () => {
it('should create an instance', () => {
expect(new TokenRegistry(environment.registryAddress)).toBeTruthy();
});
});

View File

@ -0,0 +1,36 @@
// @ts-ignore
import * as registryClient from '@src/assets/js/block-sync/data/RegistryClient.json';
import Web3 from 'web3';
import {environment} from '@src/environments/environment';
const web3 = new Web3(environment.web3Provider);
const abi = registryClient.default;
export class TokenRegistry {
contractAddress: string;
signerAddress: string;
contract: any;
constructor(contractAddress: string, signerAddress?: string) {
this.contractAddress = contractAddress;
this.contract = new web3.eth.Contract(abi, this.contractAddress);
if (signerAddress) {
this.signerAddress = signerAddress;
} else {
this.signerAddress = web3.eth.accounts[0];
}
}
public async totalTokens(): Promise<number> {
return await this.contract.methods.registryCount().call();
}
public async entry(serial: number): Promise<string> {
return await this.contract.methods.entry(serial).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

@ -52,3 +52,40 @@ export interface MetaResponse {
id: string;
m: Meta;
}
export const defaultAccount: AccountDetails = {
date_registered: Date.now(),
gender: 'other',
identities: {
evm: {
'bloxberg:8996': [''],
'oldchain:1': [''],
},
latitude: 0,
longitude: 0,
},
location: {
area_name: 'Kilifi',
},
products: [],
vcard: {
email: [{
value: '',
}],
fn: [{
value: 'GE',
}],
n: [{
value: ['GE'],
}],
tel: [{
meta: {
TYP: [],
},
value: '',
}],
version: [{
value: '3.0',
}],
},
};

View File

@ -3,11 +3,18 @@ import {HttpClient} from '@angular/common/http';
import {environment} from '@src/environments/environment';
import {first} from 'rxjs/operators';
import {BehaviorSubject} from 'rxjs';
import {HttpGetter, Registry, TokenRegistry} from '@app/_helpers';
import {CICRegistry} from 'cic-client';
import Web3 from 'web3';
@Injectable({
providedIn: 'root'
})
export class TokenService {
web3 = new Web3(environment.web3Provider);
fileGetter = new HttpGetter();
registry = new Registry(environment.registryAddress);
cicRegistry = new CICRegistry(this.web3, environment.registryAddress, this.fileGetter, ['../../assets/js/block-sync/data']);
tokens: any = '';
private tokensList = new BehaviorSubject<any>(this.tokens);
tokensSubject = this.tokensList.asObservable();
@ -16,11 +23,19 @@ export class TokenService {
private http: HttpClient
) { }
getTokens(): any {
this.http.get(`${environment.cicCacheUrl}/tokens`).pipe(first()).subscribe(tokens => this.tokensList.next(tokens));
async getTokens(): Promise<any> {
const tokenRegistryQuery = new TokenRegistry(await this.registry.addressOf('TokenRegistry'));
const count = await tokenRegistryQuery.totalTokens();
return Array.from({length: count}, async (v, i) => await tokenRegistryQuery.entry(i));
}
getTokenBySymbol(symbol: string): any {
return this.http.get(`${environment.cicCacheUrl}/tokens/${symbol}`);
}
async getTokenBalance(address: string): Promise<number> {
const tokenRegistryQuery = new TokenRegistry(await this.registry.addressOf('TokenRegistry'));
const sarafuToken = await this.cicRegistry.addToken(await tokenRegistryQuery.entry(0));
return await sarafuToken.methods.balanceOf(address).call();
}
}

View File

@ -13,6 +13,7 @@ import {toValue} from '@src/assets/js/ethtx/dist/tx';
import * as secp256k1 from 'secp256k1';
import {AuthService} from '@app/_services/auth.service';
import {Registry} from '@app/_helpers';
import {defaultAccount} from '@app/_models';
const Web3 = require('web3');
const vCard = require('vcard-parser');
@ -48,20 +49,39 @@ export class TransactionService {
}
async setTransaction(transaction, cacheSize: number): Promise<void> {
const cachedTransaction = this.transactions.find(cachedTx => cachedTx.tx.txHash === transaction.tx.txHash);
if (cachedTransaction) { return; }
transaction.value = Number(transaction.value);
transaction.type = 'transaction';
transaction.sender = await this.getUser(transaction.from);
transaction.recipient = await this.getUser(transaction.to);
await this.addTransaction(transaction, cacheSize);
if (this.transactions.find(cachedTx => cachedTx.tx.txHash === transaction.tx.txHash)) { return; }
try {
this.userService.getAccountDetailsFromMeta(await User.toKey(transaction.from)).pipe(first()).subscribe(async (res) => {
transaction.sender = this.getAccountInfo(res);
}, error => {
transaction.sender = defaultAccount;
});
this.userService.getAccountDetailsFromMeta(await User.toKey(transaction.to)).pipe(first()).subscribe(async (res) => {
transaction.recipient = this.getAccountInfo(res);
}, error => {
transaction.recipient = defaultAccount;
});
} finally {
await this.addTransaction(transaction, cacheSize);
}
}
async setConversion(conversion, cacheSize): Promise<void> {
const cachedConversion = this.transactions.find(cachedTx => cachedTx.tx.txHash === conversion.tx.txHash);
if (cachedConversion) { return; }
if (this.transactions.find(cachedTx => cachedTx.tx.txHash === conversion.tx.txHash)) { return; }
conversion.type = 'conversion';
conversion.sender = conversion.recipient = await this.getUser(conversion.trader);
await this.addTransaction(conversion, cacheSize);
conversion.fromValue = Number(conversion.fromValue);
conversion.toValue = Number(conversion.toValue);
try {
this.userService.getAccountDetailsFromMeta(await User.toKey(conversion.trader)).pipe(first()).subscribe(async (res) => {
conversion.sender = conversion.recipient = this.getAccountInfo(res);
}, error => {
conversion.sender = conversion.recipient = defaultAccount;
});
} finally {
await this.addTransaction(conversion, cacheSize);
}
}
async addTransaction(transaction, cacheSize: number): Promise<void> {
@ -72,14 +92,10 @@ export class TransactionService {
this.transactionList.next(this.transactions);
}
async getUser(address: string): Promise<any> {
return this.userService.getAccountDetailsFromMeta(await User.toKey(address)).pipe(first()).subscribe(res => {
const account = Envelope.fromJSON(JSON.stringify(res)).unwrap();
const accountInfo = account.m.data;
accountInfo.vcard = vCard.parse(atob(accountInfo.vcard));
this.userInfo = accountInfo;
return accountInfo;
});
getAccountInfo(account: string): any {
let accountInfo = Envelope.fromJSON(JSON.stringify(account)).unwrap().m.data;
accountInfo.vcard = vCard.parse(atob(accountInfo.vcard));
return accountInfo;
}
async transferRequest(tokenAddress: string, senderAddress: string, recipientAddress: string, value: number): Promise<any> {

View File

@ -134,7 +134,7 @@ export class UserService {
}
getUser(userKey: string): any {
this.http.get(`${environment.cicMetaUrl}/${userKey}`, { headers: this.headers }).pipe(first()).subscribe(async res => {
return this.http.get(`${environment.cicMetaUrl}/${userKey}`, { headers: this.headers }).pipe(first()).subscribe(async res => {
return Envelope.fromJSON(JSON.stringify(res)).unwrap();
});
}
@ -154,19 +154,27 @@ export class UserService {
}
async loadAccounts(limit: number, offset: number = 0): Promise<void> {
this.resetAccountsList();
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)) {
this.getAccountDetailsFromMeta(await User.toKey(accountAddress)).pipe(first()).subscribe(res => {
const account = Envelope.fromJSON(JSON.stringify(res)).unwrap();
this.accountsMeta.push(account);
const accountInfo = account.m.data;
accountInfo.vcard = vCard.parse(atob(accountInfo.vcard));
this.accounts.push(accountInfo);
this.accounts.unshift(accountInfo);
if (this.accounts.length > limit) {
this.accounts.length = limit;
}
this.accountsList.next(this.accounts);
});
}
}
resetAccountsList(): void {
this.accounts = [];
this.accountsList.next(this.accounts);
}
}

View File

@ -1,5 +1,5 @@
import {Component, HostListener} from '@angular/core';
import {TransactionService} from '@app/_services';
import {TokenService, TransactionService} from '@app/_services';
import {AuthService} from '@app/_services';
@Component({
@ -15,9 +15,11 @@ export class AppComponent {
constructor(
private authService: AuthService,
private tokenService: TokenService,
private transactionService: TransactionService,
) {
this.authService.mutableKeyStore.loadKeyring().then(r => this.authService.getPublicKeys().then());
this.tokenService.getTokens().then(async r => console.log('Tokens:', await r));
this.mediaQuery.addListener(this.onResize);
this.onResize(this.mediaQuery);
}

View File

@ -17,18 +17,6 @@
<!-- <li *ngIf="account" class="breadcrumb-item active" aria-current="page">{{account?.fn[0].value}}</li>-->
</ol>
</nav>
<div class="card mb-3">
<div class="row card-body">
<h3>
<strong> {{account?.fn[0].value}} </strong>
</h3>
<span class="ml-auto"><strong>Balance:</strong> {{account?.balance}} RCU</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?.identities.evm['bloxberg:8996']}} </a></span>-->
</div>
</div>
<app-disbursement *ngIf="isDisbursing" (cancelDisbursmentEvent)="addTransfer()" [account]="account">
</app-disbursement>
<div *ngIf="!account" class="text-center">
<div class="spinner-grow text-primary m-1" role="status" style="width: 3rem; height: 3rem;">
<span class="sr-only">Loading...</span>
@ -41,6 +29,18 @@
</div>
</div>
<div *ngIf="account" class="card mt-3 mb-3">
<div class="card mb-3">
<div class="row card-body">
<h3>
<strong> {{account?.vcard?.fn[0].value}} </strong>
</h3>
<span class="ml-auto"><strong>Balance:</strong> {{accountBalance}} RCU</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?.identities.evm['bloxberg:8996']}} </a></span>
</div>
</div>
<app-disbursement *ngIf="isDisbursing" (cancelDisbursmentEvent)="addTransfer()" [account]="account">
</app-disbursement>
<mat-card-title class="card-header">
<div class="row">
DETAILS

View File

@ -3,7 +3,7 @@ import {MatTableDataSource} from '@angular/material/table';
import {SelectionModel} from '@angular/cdk/collections';
import {MatPaginator} from '@angular/material/paginator';
import {MatSort} from '@angular/material/sort';
import {LocationService, TransactionService, UserService} from '@app/_services';
import {LocationService, TokenService, TransactionService, UserService} from '@app/_services';
import {ActivatedRoute, Params, Router} from '@angular/router';
import {first} from 'rxjs/operators';
import {FormBuilder, FormGroup, Validators} from '@angular/forms';
@ -34,6 +34,7 @@ export class AccountDetailsComponent implements OnInit {
accountInfoForm: FormGroup;
account: any;
accountBalance: number;
metaAccount: any;
accounts: any[] = [];
accountsType = 'all';
@ -57,7 +58,8 @@ export class AccountDetailsComponent implements OnInit {
private transactionService: TransactionService,
private userService: UserService,
private route: ActivatedRoute,
private router: Router
private router: Router,
private tokenService: TokenService
) {
this.accountInfoForm = this.formBuilder.group({
status: ['', Validators.required],
@ -79,6 +81,7 @@ export class AccountDetailsComponent implements OnInit {
this.userService.getAccountDetailsFromMeta(await User.toKey(params.get('id'))).pipe(first()).subscribe(res => {
this.metaAccount = Envelope.fromJSON(JSON.stringify(res)).unwrap();
this.account = this.metaAccount.m.data;
this.tokenService.getTokenBalance(this.account.identities.evm['bloxberg:8996'][0]).then(r => this.accountBalance = r);
this.account.vcard = vCard.parse(atob(this.account.vcard));
console.log(this.account);
this.accountInfoForm.patchValue({

View File

@ -14,27 +14,29 @@
<li class="list-group-item">
<span>Sender: {{transaction.sender?.vcard.fn[0].value}}</span><br><br>
<span>Sender Address: {{transaction.from}}</span><br><br>
<button mat-raised-button color="primary" class="btn btn-outline-info" routerLink="/accounts/1">View Sender</button>
<button mat-raised-button color="primary" class="btn btn-outline-info" (click)="viewSender()">View Sender</button>
</li>
<li class="list-group-item">
<span>Recipient: {{transaction.recipient?.vcard.fn[0].value}}</span><br><br>
<span>Recipient Address: {{transaction.to}}</span><br><br>
<button mat-raised-button color="primary" class="btn btn-outline-info" routerLink="/accounts/1">View Recipient</button>
<button mat-raised-button color="primary" class="btn btn-outline-info" (click)="viewRecipient()">View Recipient</button>
</li>
<li class="list-group-item">
<span>Amount: {{transaction.token.symbol + ' ' + transaction.value}}</span>
<span>Amount: SRF {{transaction.value | tokenRatio}}</span>
</li>
</ul>
<h4 class="mt-2">Token: </h4>
<ul class="list-group list-group-flush">
<li class="list-group-item">
<span>Address: {{transaction.token.address}}</span>
<span>Address: {{transaction.token._address}}</span>
</li>
<li class="list-group-item">
<span>Name: {{transaction.token.name}}</span>
<!-- <span>Name: {{transaction.token.name}}</span>-->
<span>Name: Sarafu Token</span>
</li>
<li class="list-group-item">
<span>Symbol: {{transaction.token.symbol}}</span>
<!-- <span>Symbol: {{transaction.token.symbol}}</span>-->
<span>Symbol: SRF</span>
</li>
</ul>
</div>

View File

@ -1,4 +1,5 @@
import {Component, Input, OnInit} from '@angular/core';
import {Router} from '@angular/router';
@Component({
selector: 'app-transaction-details',
@ -8,9 +9,16 @@ import {Component, Input, OnInit} from '@angular/core';
export class TransactionDetailsComponent implements OnInit {
@Input() transaction;
constructor() { }
constructor(private router: Router) { }
ngOnInit(): void {
}
viewSender(): void {
this.router.navigateByUrl(`/accounts/${this.transaction.from}`).then();
}
viewRecipient(): void {
this.router.navigateByUrl(`/accounts/${this.transaction.to}`).then();
}
}

View File

@ -56,82 +56,75 @@
<mat-icon matSuffix>search</mat-icon>
</mat-form-field>
<mat-table class="mat-elevation-z10" [dataSource]="transactionDataSource" matSort matSortActive="created"
<table mat-table class="mat-elevation-z10" [dataSource]="transactionDataSource" matSort matSortActive="created"
matSortDirection="desc" matSortDisableClear>
<ng-container matColumnDef="view">
<mat-header-cell *matHeaderCellDef> View </mat-header-cell>
<mat-cell *matCellDef="let transaction" (click)="viewTransaction(transaction)">
<i class="fa fa-eye"></i>
</mat-cell>
</ng-container>
<ng-container matColumnDef="sender">
<mat-header-cell *matHeaderCellDef mat-sort-header> Sender </mat-header-cell>
<mat-cell *matCellDef="let transaction"> {{transaction.sender?.vcard.fn[0].value}} </mat-cell>
<th mat-header-cell *matHeaderCellDef mat-sort-header> Sender </th>
<td mat-cell *matCellDef="let transaction"> {{transaction?.sender?.vcard.fn[0].value}} </td>
</ng-container>
<ng-container matColumnDef="senderLocation">
<mat-header-cell *matHeaderCellDef mat-sort-header> Sender Location </mat-header-cell>
<mat-cell *matCellDef="let transaction"> {{transaction.sender?.location.area_name}} </mat-cell>
</ng-container>
<!-- <ng-container matColumnDef="senderLocation">-->
<!-- <mat-header-cell *matHeaderCellDef mat-sort-header> Sender Location </mat-header-cell>-->
<!-- <mat-cell *matCellDef="let transaction"> {{transaction?.sender?.location.area_name}} </mat-cell>-->
<!-- </ng-container>-->
<ng-container matColumnDef="recipient">
<mat-header-cell *matHeaderCellDef mat-sort-header> Recipient </mat-header-cell>
<mat-cell *matCellDef="let transaction"> {{transaction.recipient?.vcard.fn[0].value}} </mat-cell>
<th mat-header-cell *matHeaderCellDef mat-sort-header> Recipient </th>
<td mat-cell *matCellDef="let transaction"> {{transaction?.recipient?.vcard.fn[0].value}} </td>
</ng-container>
<ng-container matColumnDef="recipientLocation">
<mat-header-cell *matHeaderCellDef mat-sort-header> Recipient Location </mat-header-cell>
<mat-cell *matCellDef="let transaction"> {{transaction.recipient?.location.area_name}} </mat-cell>
</ng-container>
<!-- <ng-container matColumnDef="recipientLocation">-->
<!-- <mat-header-cell *matHeaderCellDef mat-sort-header> Recipient Location </mat-header-cell>-->
<!-- <mat-cell *matCellDef="let transaction"> {{transaction?.recipient?.location.area_name}} </mat-cell>-->
<!-- </ng-container>-->
<ng-container matColumnDef="token">
<mat-header-cell *matHeaderCellDef mat-sort-header> Token </mat-header-cell>
<mat-cell *matCellDef="let transaction">
<span *ngIf="transaction.type == 'transaction'">{{transaction.token.name}}</span>
<span *ngIf="transaction.type == 'conversion'">{{transaction.destinationToken.name}}</span>
</mat-cell>
</ng-container>
<!-- <ng-container matColumnDef="token">-->
<!-- <mat-header-cell *matHeaderCellDef mat-sort-header> Token </mat-header-cell>-->
<!-- <mat-cell *matCellDef="let transaction">-->
<!-- <span *ngIf="transaction.type == 'transaction'">{{transaction?.token.name}}</span>-->
<!-- <span *ngIf="transaction.type == 'conversion'">{{transaction?.destinationToken.name}}</span>-->
<!-- </mat-cell>-->
<!-- </ng-container>-->
<ng-container matColumnDef="value">
<mat-header-cell *matHeaderCellDef mat-sort-header> Value </mat-header-cell>
<mat-cell *matCellDef="let transaction">
<span *ngIf="transaction.type == 'transaction'">{{transaction.value | tokenRatio}}</span>
<span *ngIf="transaction.type == 'conversion'">{{transaction.toValue | tokenRatio}}</span>
</mat-cell>
<th mat-header-cell *matHeaderCellDef mat-sort-header> Value </th>
<td mat-cell *matCellDef="let transaction">
<span *ngIf="transaction.type == 'transaction'">{{transaction?.value | tokenRatio}}</span>
<span *ngIf="transaction.type == 'conversion'">{{transaction?.toValue | tokenRatio}}</span>
</td>
</ng-container>
<ng-container matColumnDef="created">
<mat-header-cell *matHeaderCellDef mat-sort-header> Created </mat-header-cell>
<mat-cell *matCellDef="let transaction"> {{transaction.tx.timestamp | date}} </mat-cell>
<th mat-header-cell *matHeaderCellDef mat-sort-header> Created </th>
<td mat-cell *matCellDef="let transaction"> {{transaction?.tx.timestamp | date}} </td>
</ng-container>
<ng-container matColumnDef="type">
<mat-header-cell *matHeaderCellDef mat-sort-header> TYPE </mat-header-cell>
<mat-cell *matCellDef="let transaction">
<span class="badge badge-success badge-pill"> {{transaction.type}} </span>
</mat-cell>
<th mat-header-cell *matHeaderCellDef mat-sort-header> TYPE </th>
<td mat-cell *matCellDef="let transaction">
<span class="badge badge-success badge-pill"> {{transaction?.type}} </span>
</td>
</ng-container>
<ng-container matColumnDef="select">
<mat-header-cell *matHeaderCellDef>
<mat-checkbox (change)="$event ? masterToggle(transactionSelection, transactionDataSource) : null"
[checked]="transactionSelection.hasValue() && isAllSelected(transactionSelection, transactionDataSource)"
[indeterminate]="transactionSelection.hasValue() && !isAllSelected(transactionSelection, transactionDataSource)">
</mat-checkbox>
</mat-header-cell>
<mat-cell *matCellDef="let transaction">
<mat-checkbox (click)="$event.stopPropagation()"
(change)="$event ? transactionSelection.toggle(transaction) : null"
[checked]="transactionSelection.isSelected(transaction)">
</mat-checkbox>
</mat-cell>
</ng-container>
<!-- <ng-container matColumnDef="select">-->
<!-- <mat-header-cell *matHeaderCellDef>-->
<!-- <mat-checkbox (change)="$event ? masterToggle(transactionSelection, transactionDataSource) : null"-->
<!-- [checked]="transactionSelection.hasValue() && isAllSelected(transactionSelection, transactionDataSource)"-->
<!-- [indeterminate]="transactionSelection.hasValue() && !isAllSelected(transactionSelection, transactionDataSource)">-->
<!-- </mat-checkbox>-->
<!-- </mat-header-cell>-->
<!-- <mat-cell *matCellDef="let transaction">-->
<!-- <mat-checkbox (click)="$event.stopPropagation()"-->
<!-- (change)="$event ? transactionSelection.toggle(transaction) : null"-->
<!-- [checked]="transactionSelection.isSelected(transaction)">-->
<!-- </mat-checkbox>-->
<!-- </mat-cell>-->
<!-- </ng-container>-->
<mat-header-row *matHeaderRowDef="transactionDisplayedColumns"></mat-header-row>
<mat-row *matRowDef="let transaction; columns: transactionDisplayedColumns" (click)="viewTransaction(transaction)"></mat-row>
</mat-table>
<tr mat-header-row *matHeaderRowDef="transactionDisplayedColumns"></tr>
<tr mat-row *matRowDef="let transaction; columns: transactionDisplayedColumns;" (click)="viewTransaction(transaction)"></tr>
</table>
<mat-paginator [pageSize]="10" [pageSizeOptions]="[10, 20, 50, 100]" showFirstLastButtons></mat-paginator>

View File

@ -12,7 +12,7 @@ import {MatSort} from '@angular/material/sort';
})
export class TransactionsComponent implements OnInit, AfterViewInit {
transactionDataSource: MatTableDataSource<any>;
transactionDisplayedColumns = ['view', 'sender', 'senderLocation', 'recipient', 'recipientLocation', 'token', 'value', 'created', 'type', 'select'];
transactionDisplayedColumns = ['sender', 'recipient', 'value', 'created', 'type'];
initialSelection = [];
allowMultiSelect = true;
transactionSelection: SelectionModel<any>;

View File

@ -16,6 +16,7 @@ import {MatButtonModule} from '@angular/material/button';
import {MatIconModule} from '@angular/material/icon';
import {MatSelectModule} from '@angular/material/select';
import {MatCardModule} from '@angular/material/card';
import {MatRippleModule} from '@angular/material/core';
@NgModule({
@ -23,21 +24,22 @@ import {MatCardModule} from '@angular/material/card';
exports: [
TransactionDetailsComponent
],
imports: [
CommonModule,
TransactionsRoutingModule,
DataTablesModule,
SharedModule,
MatTableModule,
MatCheckboxModule,
MatPaginatorModule,
MatSortModule,
MatFormFieldModule,
MatInputModule,
MatButtonModule,
MatIconModule,
MatSelectModule,
MatCardModule
]
imports: [
CommonModule,
TransactionsRoutingModule,
DataTablesModule,
SharedModule,
MatTableModule,
MatCheckboxModule,
MatPaginatorModule,
MatSortModule,
MatFormFieldModule,
MatInputModule,
MatButtonModule,
MatIconModule,
MatSelectModule,
MatCardModule,
MatRippleModule
]
})
export class TransactionsModule { }

View File

@ -3,6 +3,6 @@ import {Pipe, PipeTransform} from '@angular/core';
@Pipe({name: 'tokenRatio'})
export class TokenRatioPipe implements PipeTransform {
transform(value: any, ...args): any {
return Number(value) / Math.pow(10, 18);
return Number(value) / Math.pow(10, 6);
}
}

View File

@ -1,7 +1,7 @@
<!-- Topbar Start -->
<nav class="navbar navbar-expand-lg navbar-light bg-light sticky-top">
<div class="container-fluid">
<button type="button" id="sidebarCollapse" class="navbar-btn menutoggle" appMenuToggle>
<button type="button" id="sidebarCollapse" class="navbar-btn menutoggle" aria-label="Sidebar toggle" appMenuToggle>
<span></span>
<span></span>
<span></span>

View File

@ -0,0 +1 @@
[{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"addressOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"entry","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"registryCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

View File

@ -1,7 +1,7 @@
export const environment = {
production: true,
bloxbergChainId: 8996,
cicAuthUrl: 'http://localhost:4444',
cicAuthUrl: 'http://localhost:8080',
cicMetaUrl: 'http://localhost:63380',
publicKeysUrl: 'http://localhost:8000',
cicCacheUrl: 'http://localhost:63313',

View File

@ -5,7 +5,7 @@
export const environment = {
production: false,
bloxbergChainId: 8996,
cicAuthUrl: 'http://localhost:4444',
cicAuthUrl: 'http://localhost:8080',
cicMetaUrl: 'http://localhost:63380',
publicKeysUrl: 'http://localhost:8000',
cicCacheUrl: 'http://localhost:63313',

View File

@ -12,7 +12,7 @@ p {
font-size: 1.1em;
font-weight: 300;
line-height: 1.7em;
color: #999;
color: #000000;
}
a, a:hover, a:focus {
@ -349,6 +349,10 @@ button {
html, body { height: 100%; }
body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }
.full-width {
.full-width, table {
width: 100%;
}
li.breadcrumb-item.active, footer.footer {
color: black;
}