Skip to content
2 changes: 1 addition & 1 deletion front/src/app/app.component.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<ng-progress></ng-progress>
<app-toastr></app-toastr>
<app-header></app-header>
<div class="app-container py-4" [ngClass]="{'app-container--loading': isPageLoading}">
<div class="app-container py-4" [ngClass]="{'app-container--loading': layoutService.isPageLoading$ | async}">
<div class="loader">
<img src="../assets/icons/loader.svg" alt="Loading">
</div>
Expand Down
6 changes: 0 additions & 6 deletions front/src/app/app.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,4 @@ describe('AppComponent', () => {
it('should create the app', async(() => {
expect(comp).toBeTruthy();
}));
/**
* DEFAULT VALUES
*/
it(`should have as isPageLoading 'false'`, async(() => {
expect(comp.isPageLoading).toEqual(false);
}));
});
17 changes: 2 additions & 15 deletions front/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,7 @@ import { Subscription } from 'rxjs';
styleUrls: ['./app.component.scss']
})
@AutoUnsubscribe('_subsArr$')
export class AppComponent implements OnInit {
isPageLoading = false;

private _subsArr$: Subscription[] = [];

constructor(private _layoutService: LayoutService, private _cdr: ChangeDetectorRef) {
}

ngOnInit() {
this._subsArr$.push(
this._layoutService.isPageLoading.subscribe((state: boolean) => {
this.isPageLoading = state;
this._cdr.detectChanges();
})
);
export class AppComponent {
constructor(public layoutService: LayoutService) {
}
}
6 changes: 3 additions & 3 deletions front/src/app/components/interactor/interactor.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@ <h6 class="mb-4 text-center text-primary" *ngIf="!hasData">Interact with a Smart
rows="5"
required
></textarea>
<div class="mt-1">
<div class="mt-1" *ngIf="!addressContract?.valid">
or select template:
<select formControlName="erc">
<option *ngFor="let value of abiTemplates" [value]="value">{{value}}</option>
</select>
</div>
</div>
</div>
<ng-container *ngIf="contract != null">
<ng-container *ngIf="web3Contract != null">
<div class="form-group row">
<label for="contract-function" class="col-md-2">Choose Contract Function:</label>
<div class="col-md-10">
Expand All @@ -53,7 +53,7 @@ <h6 class="mb-4 text-center text-primary" *ngIf="!hasData">Interact with a Smart
</option>
</ng-container>
</optgroup>
<optgroup label="Paid (wallet required)" [disabled]="!_walletService.account">
<optgroup label="Paid (wallet required)" [disabled]="!(walletService.logged$ | async)">
<ng-container *ngFor="let abiItem of abiFunctions; let i = index;">
<option
*ngIf="abiItem.payable || !abiItem.constant"
Expand Down
57 changes: 31 additions & 26 deletions front/src/app/components/interactor/interactor.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,16 @@ export class InteractorComponent implements OnInit {
contractBadges: Badge[] = [];
abiTemplates = [ErcName.Go20, ErcName.Go721, ErcName.Go165, ErcName.Upgradeable, ErcName.AllFunctions];

contract: Web3Contract;
web3Contract: Web3Contract;
abiFunctions: AbiItem[];
selectedFunction: AbiItem;
functionResult: {output:any[][], error: string};
functionResult: { output: any[][], error: string };
addr: Address;

hasData = false;

addressContract: Contract;

@Input('contractData')
set address([addr, contract]: [Address, Contract]) {
this.hasData = true;
Expand All @@ -73,8 +75,8 @@ export class InteractorComponent implements OnInit {
}

constructor(
public walletService: WalletService,
private _fb: FormBuilder,
private _walletService: WalletService,
private _toastrService: ToastrService,
private _commonService: CommonService,
private _activatedRoute: ActivatedRoute,
Expand All @@ -101,7 +103,7 @@ export class InteractorComponent implements OnInit {
this._subsArr$.push(this.form.get('contractAddress').valueChanges.pipe(
debounceTime(500),
distinctUntilChanged(),
).subscribe(val => {
).subscribe((val: string) => {
this.updateContract();
this.getContractData(val);
}));
Expand All @@ -117,7 +119,7 @@ export class InteractorComponent implements OnInit {
this._subsArr$.push((this.form.get('functionParameters') as FormArray).valueChanges.pipe(
debounceTime(1200),
distinctUntilChanged(),
).subscribe((values) => {
).subscribe((values: string[]) => {
this.estimateFunctionGas(values);
}));
this._subsArr$.push(this.form.get('erc').valueChanges.subscribe(value => {
Expand Down Expand Up @@ -174,14 +176,14 @@ export class InteractorComponent implements OnInit {
* @param params
*/
callABIFunction(func: AbiItem, params: string[] = []): void {
this._walletService.call(this.contract.options.address, func, params).subscribe((decoded: object) => {
this.walletService.call(this.web3Contract.options.address, func, params).subscribe((decoded: object) => {
if (!decoded) {
this.functionResult = {error:'Result is empty', output:null};
this.functionResult = {error: 'Result is empty', output: null};
return;
}
this.functionResult = {output:getDecodedData(decoded, func, this.addr), error: null};
this.functionResult = {output: getDecodedData(decoded, func, this.addr), error: null};
}, err => {
this.functionResult = {error:err, output:null};
this.functionResult = {error: err, output: null};
});
}

Expand All @@ -202,6 +204,7 @@ export class InteractorComponent implements OnInit {
private handleContractData(address: Address, contract: Contract) {
this.addr = address;
this.contractBadges = makeContractBadges(address, contract);
this.addressContract = contract;
if (contract.abi && contract.abi.length) {
this.form.patchValue({
contractABI: JSON.stringify(contract.abi, null, 2),
Expand Down Expand Up @@ -241,7 +244,7 @@ export class InteractorComponent implements OnInit {
return;
}

this._walletService.estimateGas(tx).pipe(
this.walletService.estimateGas(tx).pipe(
// filter((gasLimit: number) => !this.isProcessing),
).subscribe((gasLimit: number) => {
this.form.get('gasLimit').patchValue(gasLimit);
Expand All @@ -252,12 +255,12 @@ export class InteractorComponent implements OnInit {
}

formTx(params: string[]): TransactionConfig {
const m = this.contract.methods[this.selectedFunction.name](...params);
const m = this.web3Contract.methods[this.selectedFunction.name](...params);

const tx: TransactionConfig = {
to: this.contract.options.address,
to: this.web3Contract.options.address,
data: m.encodeABI(),
from: this._walletService.account.address,
from: this.walletService.accountAddress,
};

if (this.selectedFunction.payable) {
Expand All @@ -282,7 +285,7 @@ export class InteractorComponent implements OnInit {
return;
}

this.contract = null;
this.web3Contract = null;
let abiItem: AbiItem[];

try {
Expand All @@ -292,17 +295,7 @@ export class InteractorComponent implements OnInit {
return;
}

this.initContract(addrHash, abiItem);
}

private initContract(addrHash: string, abiItems: AbiItem[]) {
this._walletService.w3Call.subscribe((web3: Web3) => {
this.contract = new web3.eth.Contract(abiItems, addrHash);
this.abiFunctions = getAbiMethods(abiItems);
}, err => {
this._toastrService.danger('Can\'t initiate contract, check entered data');
console.error(`Failed to initiate contract (${addrHash}): ${err}`)
});
this._initContract(addrHash, abiItem);
}

useContract(): void {
Expand All @@ -329,7 +322,7 @@ export class InteractorComponent implements OnInit {
}

tx.gas = this.form.get('gasLimit').value;
this._walletService.sendTx(tx);
this.walletService.sendTx(tx);
}

onAbiTemplateSelect(ercName: ErcName) {
Expand All @@ -342,4 +335,16 @@ export class InteractorComponent implements OnInit {
});
});
}

private _initContract(addrHash: string, abiItems: AbiItem[]) {
this.walletService.initContract(addrHash, abiItems).subscribe(
(contract) => {
this.web3Contract = contract;
this.abiFunctions = getAbiMethods(abiItems);
}, (err) => {
this._toastrService.danger('Can\'t initiate contract, check entered data');
console.error(`Failed to initiate contract (${addrHash}): ${err}`);
}
);
}
}
16 changes: 10 additions & 6 deletions front/src/app/guards/wallet.guard.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
/*CORE*/
import {Injectable} from '@angular/core';
import {CanActivate, Router} from '@angular/router';
import {Observable} from 'rxjs';
import {filter, mergeMap, tap} from 'rxjs/operators';
/*SERVICES*/
import {WalletService} from '../services/wallet.service';

Expand All @@ -14,11 +16,13 @@ export class WalletGuard implements CanActivate {
) {
}

canActivate(): boolean {
if (!this._walletService.account) {
this._router.navigate(['wallet']);
return false;
}
return true;
canActivate(): Observable<boolean> {
return this._walletService.logged$.pipe(
tap((logged: boolean) => {
if (!logged) {
this._router.navigate(['wallet']);
}
}),
);
}
}
2 changes: 1 addition & 1 deletion front/src/app/models/query_params.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {BehaviorSubject, Subject} from 'rxjs';
import {removeEmpty} from '../utils/functions';

interface IParams {
export interface IParams {
limit: number;
skip: number;
}
Expand Down
10 changes: 5 additions & 5 deletions front/src/app/scenes/contracts/contracts.component.spec.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { ContractsComponent } from './contracts.component';
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {ContractsComponent} from './contracts.component';
import {AppModule} from '../../app.module';

describe('ContractsComponent', () => {
let component: ContractsComponent;
let fixture: ComponentFixture<ContractsComponent>;

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ContractsComponent ]
imports: [AppModule],
})
.compileComponents();
.compileComponents();
}));

beforeEach(() => {
Expand Down
9 changes: 7 additions & 2 deletions front/src/app/scenes/richlist/richlist.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {MetaService} from '../../services/meta.service';
/*MODELS*/
import {RichList} from '../../models/rich_list.model';
import {Address} from '../../models/address.model';
import {QueryParams} from '../../models/query_params';
import {IParams, QueryParams} from '../../models/query_params';
/*UTILS*/
import {AutoUnsubscribe} from '../../decorators/auto-unsubscribe';
import {META_TITLES} from '../../utils/constants';
Expand Down Expand Up @@ -55,7 +55,9 @@ export class RichlistComponent implements OnInit, OnDestroy {

initSub() {
this._subsArr$.push(this.richListQueryParams.state.pipe(
tap(() => this.isLoading = true),
tap<IParams>(() => {
this.isLoading = true;
}),
flatMap(params => this._commonService.getRichlist(params)),
filter((data: RichList) => !!data),
).subscribe((data: RichList) => {
Expand All @@ -68,6 +70,9 @@ export class RichlistComponent implements OnInit, OnDestroy {
}
this.isLoading = false;
this._layoutService.offLoading();
}, (err) => {
this.isLoading = false;
this._layoutService.offLoading();
}));
}
}
15 changes: 5 additions & 10 deletions front/src/app/scenes/transaction/transaction.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,16 @@ import {Component, OnDestroy, OnInit} from '@angular/core';
import {ActivatedRoute, ParamMap} from '@angular/router';
import {forkJoin, interval, Observable, of, Subscription} from 'rxjs';
import {catchError, map, mergeMap, startWith, tap} from 'rxjs/operators';
import {fromPromise} from 'rxjs/internal-compatibility';
/*SERVICES*/
import {CommonService} from '../../services/common.service';
import {LayoutService} from '../../services/layout.service';
import {WalletService} from '../../services/wallet.service';
import {MetaService} from '../../services/meta.service';
/*MODELS*/
import {ProcessedLog, ProcessedABIItem, Transaction, TxLog, ProcessedABIData} from '../../models/transaction.model';
import {ProcessedABIData, ProcessedABIItem, ProcessedLog, Transaction, TxLog} from '../../models/transaction.model';
import {ContractAbiByID, ContractEventsAbi} from '../../utils/types';
import Web3 from 'web3';
import {AbiItem, AbiInput} from 'web3-utils';
import {AbiInput, AbiItem} from 'web3-utils';
import {Address} from '../../models/address.model';
import {Contract} from '../../models/contract.model';
/*UTILS*/
Expand All @@ -38,11 +37,7 @@ export class TransactionComponent implements OnInit, OnDestroy {

recentBlockNumber$: Observable<number> = interval(5000).pipe(
startWith(0),
mergeMap(() => {
return this._walletService.w3Call.pipe(mergeMap((web3: Web3) => {
return fromPromise<number>(web3.eth.getBlockNumber());
}));
}),
mergeMap(() => this._walletService.getBlockNumber()),
);

private _subsArr$: Subscription[] = [];
Expand Down Expand Up @@ -87,7 +82,7 @@ export class TransactionComponent implements OnInit, OnDestroy {
this._commonService.abiByID$,
tx.to ? this._commonService.getAddress(tx.to) : of(null),
tx.to ? this._commonService.getContract(tx.to) : of(null),
this._walletService.w3Call,
this._walletService.w3$,
]).pipe(
map((res) => this.processTransactionInputTo(res)),
);
Expand All @@ -107,7 +102,7 @@ export class TransactionComponent implements OnInit, OnDestroy {
if (!!tx.parsedLogs.length) {
forkJoin([
this._commonService.eventsAbi$,
this._walletService.w3Call,
this._walletService.w3$,
]).pipe(
mergeMap((res) => this.processTransactionLogs(res))
).subscribe(logs => {
Expand Down
Loading