Skip to content

Commit

Permalink
Merge pull request #126 from UnUniFi/develop
Browse files Browse the repository at this point in the history
release v1.0.0-beta.4
  • Loading branch information
YasunoriMATSUOKA authored Apr 27, 2022
2 parents dae6cf7 + db824e5 commit 7c0107a
Show file tree
Hide file tree
Showing 26 changed files with 472 additions and 198 deletions.
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
<view-block [block]="block$ | async" [validatorsets]="validatorsets$ | async"></view-block>
<view-block
[block]="block$ | async"
[nextBlock]="nextBlock$ | async"
[previousBlock]="previousBlock$ | async"
[transactions]="txs$ | async"
[txTypes]="txTypes$ | async"
></view-block>
71 changes: 65 additions & 6 deletions projects/explorer/src/app/pages/blocks/block/block.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { rest } from '@cosmos-client/core';
import { InlineResponse20036 } from '@cosmos-client/core/esm/openapi';
import { CosmosBaseTendermintV1beta1GetValidatorSetByHeightResponse } from '@cosmos-client/core/esm/openapi/api';
import { CosmosTxV1beta1GetTxsEventResponse } from '@cosmos-client/core/esm/openapi/api';
import { CosmosSDKService } from 'projects/explorer/src/app/models/cosmos-sdk.service';
import { combineLatest, Observable } from 'rxjs';
import { map, mergeMap } from 'rxjs/operators';
import { map, filter, mergeMap } from 'rxjs/operators';

@Component({
selector: 'app-block',
Expand All @@ -15,7 +15,11 @@ import { map, mergeMap } from 'rxjs/operators';
export class BlockComponent implements OnInit {
blockHeight$: Observable<string>;
block$: Observable<InlineResponse20036>;
validatorsets$: Observable<CosmosBaseTendermintV1beta1GetValidatorSetByHeightResponse>;
nextBlock$: Observable<number>;
previousBlock$: Observable<number>;
latestBlockHeight$: Observable<string>;
txs$: Observable<CosmosTxV1beta1GetTxsEventResponse | undefined>;
txTypes$: Observable<string[] | undefined>;

constructor(private route: ActivatedRoute, private cosmosSDK: CosmosSDKService) {
this.blockHeight$ = this.route.params.pipe(map((params) => params.block_height));
Expand All @@ -24,11 +28,66 @@ export class BlockComponent implements OnInit {
rest.tendermint.getBlockByHeight(sdk.rest, BigInt(height)).then((res) => res.data),
),
);
this.validatorsets$ = combineLatest([this.cosmosSDK.sdk$, this.blockHeight$]).pipe(
mergeMap(([sdk, height]) =>
rest.tendermint.getValidatorSetByHeight(sdk.rest, height).then((res) => res.data),

this.txs$ = combineLatest([this.cosmosSDK.sdk$, this.blockHeight$, this.block$]).pipe(
filter(([sdk, height, block]) => (block.block?.data?.txs?.length || 0) > 0),
mergeMap(([sdk, height, block]) =>
rest.tx
.getTxsEvent(sdk.rest, [`tx.height=${height}`], undefined, undefined, undefined, true)
.then((res) => {
console.log('res', res);
return res.data;
})
.catch((error) => {
console.error(error);
return undefined;
}),
),
);
this.txTypes$ = this.txs$.pipe(
map((txs) => {
if (!txs?.txs) {
return undefined;
}
const txTypeList = txs?.txs?.map((tx) => {
if (!tx.body?.messages) {
return '';
}
const txTypes = tx.body?.messages.map((message) => {
if (!message) {
return [];
}
const txTypeRaw = (message as any)['@type'] as string;
const startLength = txTypeRaw.lastIndexOf('.');
const txType = txTypeRaw.substring(startLength + 1, txTypeRaw.length);
return txType;
});
return txTypes.join();
});
return txTypeList;
}),
);

this.latestBlockHeight$ = this.cosmosSDK.sdk$.pipe(
mergeMap((sdk) => rest.tendermint.getLatestBlock(sdk.rest).then((res) => res.data)),
map((block) => block.block?.header?.height || ''),
);

this.nextBlock$ = combineLatest([this.latestBlockHeight$, this.blockHeight$]).pipe(
map(([latestBlockHeight, height]) => {
if (latestBlockHeight == '') {
return Number(height);
}
if (Number(height) + 1 > Number(latestBlockHeight)) {
return Number(height);
}
return Number(height) + 1;
}),
);

this.previousBlock$ = this.blockHeight$.pipe(
map((height) => (0 > Number(height) ? Number(height) : Number(height) - 1)),
);
}

ngOnInit(): void {}
Expand Down
2 changes: 1 addition & 1 deletion projects/explorer/src/app/pages/txs/tx/tx.component.html
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<view-tx [tx]="tx$ | async"></view-tx>
<view-tx [tx]="tx$ | async" [txType]="txType$ | async"></view-tx>
19 changes: 18 additions & 1 deletion projects/explorer/src/app/pages/txs/tx/tx.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,29 @@ import { map, mergeMap } from 'rxjs/operators';
export class TxComponent implements OnInit {
txHash$: Observable<string>;
tx$: Observable<CosmosTxV1beta1GetTxResponse>;

txType$: Observable<string[] | undefined>;
constructor(private route: ActivatedRoute, private cosmosSDK: CosmosSDKService) {
this.txHash$ = this.route.params.pipe(map((params) => params.tx_hash));
this.tx$ = combineLatest([this.cosmosSDK.sdk$, this.txHash$]).pipe(
mergeMap(([sdk, hash]) => rest.tx.getTx(sdk.rest, hash).then((res) => res.data)),
);
this.tx$.subscribe((x) => console.log(x));
this.txType$ = this.tx$.pipe(
map((tx) => {
if (!tx?.tx?.body?.messages) {
return;
}
return tx?.tx?.body?.messages.map((message) => {
const txTypeRaw = (message as any)['@type'] as string;
const startLength = txTypeRaw.lastIndexOf('.');
const txType = txTypeRaw.substring(startLength + 1, txTypeRaw.length);
return txType;
});
}),
);

//debug
this.txType$.subscribe((x) => console.log('A', x));
}

ngOnInit() {}
Expand Down
171 changes: 138 additions & 33 deletions projects/explorer/src/app/views/blocks/block/block.component.html
Original file line number Diff line number Diff line change
@@ -1,51 +1,156 @@
<h2>Block</h2>
<mat-card>
<div class="flex flex-row items-end">
<h2 class="mb-0">Block #{{ block?.block?.header?.height }}</h2>
<span class="flex-auto"></span>
<mat-icon routerLink="/blocks/{{ previousBlock }}" class="mr-4" color="primary"
>navigate_before</mat-icon
>
<mat-icon routerLink="/blocks/{{ nextBlock }}" class="mr-2" color="primary"
>navigate_next</mat-icon
>
</div>
<h3 class="ml-4 mb-0">Block details</h3>
<mat-card class="mb-4">
<mat-list>
<mat-list-item>
<span class="whitespace-nowrap">Time:</span>
<span class="flex-auto"></span>
<span class="ml-2 break-all text-sm sm:text-base">
{{ block?.block?.header?.time | date: 'yyyy-M-d a h:mm:ss z' }}
</span>
<mat-divider></mat-divider>
</mat-list-item>
<mat-list-item>
<span class="whitespace-nowrap">Height:</span>
<span class="flex-auto"></span>
<span class="ml-2 break-all text-sm sm:text-base">{{ block?.block?.header?.height }}</span>
<mat-divider></mat-divider>
</mat-list-item>
<mat-list-item>
<span class="whitespace-nowrap">Number of Transactions:</span>
<span class="flex-auto"></span>
<span class="ml-2 break-all text-sm sm:text-base">{{ block?.block?.data?.txs?.length }}</span>
<mat-divider></mat-divider>
</mat-list-item>
<mat-list-item>
<span class="whitespace-nowrap">BlockHash:</span>
<span class="flex-auto"></span>
<span class="ml-2 break-all text-xs sm:text-base">{{ block?.block_id?.hash }}</span>
<mat-divider></mat-divider>
</mat-list-item>
<mat-divider [inset]="true"></mat-divider>

<mat-list-item>
<span class="whitespace-nowrap">BlockHeight:</span>
<span class="whitespace-nowrap">Proposer:</span>
<span class="flex-auto"></span>
<span class="ml-2 break-all text-sm sm:text-base">{{ block?.block?.header?.height }}</span>
<span class="ml-2 break-all text-xs sm:text-base">{{
block?.block?.header?.proposer_address
}}</span>
</mat-list-item>
<mat-divider [inset]="true"></mat-divider>
</mat-list>
</mat-card>

<h3 class="mb-0 ml-4">Transactions</h3>
<mat-card class="mb-2">
<mat-list>
<mat-list-item>
<span class="whitespace-nowrap">Timestamp:</span>
<span class="break-all truncate">Hash</span>
<span class="flex-auto"></span>
<span class="ml-2 break-all text-sm sm:text-base">
{{ block?.block?.header?.time | date : 'yyyy-M-d a h:mm:ss z' }}
</span>
<span class="break-all truncate">Type</span>
<span class="flex-auto"></span>
<span class="break-all truncate">From</span>
<span class="flex-auto"></span>
<span class="break-all truncate pr-10">To</span>
<span class="flex-auto"></span>
<span class="break-all truncate">Total Amount</span>

<mat-divider></mat-divider>
</mat-list-item>
</mat-list>
</mat-card>
<ng-container
*ngIf="
(transactions?.tx_responses?.length || 0) > 0;
then existTransactions;
else emptyTransactions
"
>
</ng-container>

<h3>Validator sets</h3>
<ng-container *ngFor="let validatorset of validatorsets?.validators">
<mat-card class="mb-2">
<mat-list>
<mat-list-item>
<span class="whitespace-nowrap">Address:</span>
<span class="flex-auto"></span>
<span class="ml-2 break-all text-sm sm:text-base">{{ validatorset.address }}</span>
</mat-list-item>
<mat-divider [inset]="true"></mat-divider>
<mat-list-item>
<span class="whitespace-nowrap">Voting Power:</span>
<ng-template #emptyTransactions>
<span>*No Transactions</span>
</ng-template>

<ng-template #existTransactions>
<mat-nav-list>
<mat-list-item
routerLink="/txs/{{ tx.txhash }}"
*ngFor="let tx of transactions?.tx_responses; let i = index; last as last"
>
<span class="pr-2 w-1/12 text-sm truncate">{{ tx.txhash }}</span>
<span class="flex-auto"></span>
<span class="ml-2 break-all text-sm sm:text-base">{{ validatorset.voting_power }}</span>
</mat-list-item>
<mat-divider [inset]="true"></mat-divider>
<mat-list-item>
<span class="whitespace-nowrap">Proposer Priority:</span>

<span class="w-1/6 truncate">{{ txTypes?.[i] }}</span>
<span class="flex-auto"></span>
<span class="ml-2 break-all text-sm sm:text-base">{{ validatorset.proposer_priority }}</span>

<ng-container *ngIf="tx.logs?.[0]?.events?.[1]?.type === 'oracle_updated_price' ">
<span
class="w-1/5 break-all truncate"
>{{ tx.logs?.[0]?.events?.[0]?.attributes?.[2]?.value }}</span
>
<span class="flex-auto"></span>
<span
class="w-1/5 break-all truncate"
>{{tx.logs?.[0]?.events?.[1]?.attributes?.[0]?.value}}</span
>
<span class="flex-auto"></span>
<span
class="w-1/6 break-all truncate"
>{{ tx.logs?.[0]?.events?.[1]?.attributes?.[2]?.value }}</span
>
</ng-container>

<ng-container *ngIf="tx.logs?.[0]?.events?.[3]?.type == 'transfer'">
<span
class="w-1/5 break-all truncate"
>{{ tx.logs?.[0]?.events?.[3]?.attributes?.[1]?.value }}</span
>
<span class="flex-auto"></span>
<span
class="w-1/5 break-all truncate"
>{{tx.logs?.[0]?.events?.[3]?.attributes?.[0]?.value}}</span
>
<span class="flex-auto"></span>
<span
class="w-1/6 break-all truncate"
>{{ tx.logs?.[0]?.events?.[3]?.attributes?.[2]?.value }}</span
>
</ng-container>
<mat-divider *ngIf="!last"></mat-divider>
</mat-list-item>
</mat-list>
</mat-card>
</ng-container>
</mat-nav-list>
</ng-template>
</mat-card>

<!--
<h3>Msgs</h3>
<ng-template ngFor let-message [ngForOf]="tx?.tx?.body?.messages">
<ng-container *ngIf="unpackMsg(message) as msg">
<mat-card>
<mat-list>
<mat-list-item>
<span class="whitespace-nowrap">Type: </span>
<span class="flex-auto"></span>
<span class="ml-2 break-all">{{ constructorName(msg) }}</span>
</mat-list-item>
<mat-divider [inset]="true"></mat-divider>
<ng-template ngFor let-data [ngForOf]="entries(msg)" let-last="last">
<mat-list-item>
<span class="whitespace-nowrap">{{ data[0] }}</span>
<span class="flex-auto"></span>
<span class="ml-2 break-all text-xs sm:text-base">{{ data[1] | json }}</span>
</mat-list-item>
<mat-divider [inset]="true" *ngIf="!last"></mat-divider>
</ng-template>
</mat-list>
</mat-card>
</ng-container>
</ng-template>
-->
14 changes: 12 additions & 2 deletions projects/explorer/src/app/views/blocks/block/block.component.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Component, Input, OnInit } from '@angular/core';
import { InlineResponse20036 } from '@cosmos-client/core/esm/openapi';
import { CosmosBaseTendermintV1beta1GetValidatorSetByHeightResponse } from '@cosmos-client/core/esm/openapi/api';
import { CosmosTxV1beta1GetTxsEventResponse } from '@cosmos-client/core/esm/openapi/api';

@Component({
selector: 'view-block',
Expand All @@ -10,8 +10,18 @@ import { CosmosBaseTendermintV1beta1GetValidatorSetByHeightResponse } from '@cos
export class BlockComponent implements OnInit {
@Input()
block?: InlineResponse20036 | null;

@Input()
nextBlock?: number | null;

@Input()
previousBlock?: number | null;

@Input()
transactions?: CosmosTxV1beta1GetTxsEventResponse | null;

@Input()
validatorsets?: CosmosBaseTendermintV1beta1GetValidatorSetByHeightResponse | null;
txTypes?: string[] | null;

constructor() {}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
>
<mat-icon matListIcon [ngStyle]="{ color: getColorCode(validator.val) }"> circle </mat-icon>
<span class="w-1/2 break-all text-sm truncate sm:text-base">{{
validator.val.operator_address
validator.val.description?.moniker
}}</span>
<span class="flex-auto"></span>
<span class="break-all text-sm sm:text-base">{{ validator.share | percent: '1.2-2' }}</span>
Expand Down
2 changes: 2 additions & 0 deletions projects/explorer/src/app/views/material.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { MatCardModule } from '@angular/material/card';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatDialogModule } from '@angular/material/dialog';
import { MatDividerModule } from '@angular/material/divider';
import { MatExpansionModule } from '@angular/material/expansion';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
Expand Down Expand Up @@ -44,6 +45,7 @@ import { MatToolbarModule } from '@angular/material/toolbar';
MatTableModule,
ClipboardModule,
MatSliderModule,
MatExpansionModule,
MatButtonToggleModule,
],
})
Expand Down
Loading

0 comments on commit 7c0107a

Please sign in to comment.