diff --git a/projects/explorer/src/app/pages/accounts/account/txs/txs.component.html b/projects/explorer/src/app/pages/accounts/account/txs/txs.component.html index 0d83b0429..6ac9908dd 100644 --- a/projects/explorer/src/app/pages/accounts/account/txs/txs.component.html +++ b/projects/explorer/src/app/pages/accounts/account/txs/txs.component.html @@ -2,6 +2,9 @@ [txs]="txs$ | async" [pageInfo]="paginationInfo$ | async" [pageLength]="pageLength$ | async" + [maxPageNumber]="maxPageNumber$ | async" [pageSizeOptions]="pageSizeOptions" + [txType]="txType$ | async" (paginationChange)="appPaginationChanged($event)" + (txTypeChange)="appTxTypeChanged($event)" > diff --git a/projects/explorer/src/app/pages/accounts/account/txs/txs.component.ts b/projects/explorer/src/app/pages/accounts/account/txs/txs.component.ts index 4ce239811..6fe572fb8 100644 --- a/projects/explorer/src/app/pages/accounts/account/txs/txs.component.ts +++ b/projects/explorer/src/app/pages/accounts/account/txs/txs.component.ts @@ -24,6 +24,8 @@ export class TxsComponent implements OnInit { paginationInfo$: Observable; paginationInfoChanged$: Observable; pageLength$: Observable; + maxPageNumber$: Observable; + txType$: Observable; txs$: Observable; constructor( @@ -34,21 +36,19 @@ export class TxsComponent implements OnInit { this.address$ = this.route.params.pipe(map((params) => params.address)); const timer$ = timer(0, this.pollingInterval * 1000); const sdk$ = timer$.pipe(mergeMap((_) => this.cosmosSDK.sdk$)); - const txsResponse$ = combineLatest([sdk$, this.address$]).pipe( - switchMap(([sdk, address]) => { + this.txType$ = this.route.queryParams.pipe(map((params) => params.txType || 'send')); + const txEvent$ = combineLatest([this.address$, this.txType$]).pipe( + map(([address, type]) => { + return type === 'send' + ? `coin_spent.spender='${address}'` + : `coin_received.receiver='${address}'`; + }), + ); + const txsResponse$ = combineLatest([sdk$, txEvent$]).pipe( + switchMap(([sdk, event]) => { return cosmosclient.rest.tx - .getTxsEvent( - sdk.rest, - [`message.sender='${address}'`], - undefined, - undefined, - undefined, - true, - true, - 2 as any, - ) + .getTxsEvent(sdk.rest, [event], undefined, undefined, undefined, true, true, 2 as any) .then((res) => { - console.log(res); return res.data; }) .catch((error) => { @@ -84,18 +84,28 @@ export class TxsComponent implements OnInit { }), ); + this.maxPageNumber$ = combineLatest([this.txsTotalCount$, this.paginationInfo$]).pipe( + map(([txTotalCount, paginationInfo]) => { + if (txTotalCount === undefined) { + return 0; + } + const maxPageNumber = Math.ceil(Number(txTotalCount) / paginationInfo.pageSize); + return maxPageNumber; + }), + ); + this.paginationInfoChanged$ = this.paginationInfo$.pipe( distinctUntilChanged(), map((paginationInfo) => paginationInfo), ); this.txs$ = this.paginationInfoChanged$.pipe( - withLatestFrom(sdk$, this.address$), - mergeMap(([paginationInfo, sdk, address]) => { + withLatestFrom(sdk$, txEvent$), + mergeMap(([paginationInfo, sdk, event]) => { return cosmosclient.rest.tx .getTxsEvent( sdk.rest, - [`message.sender='${address}'`], + [event], undefined, undefined, paginationInfo.pageSize.toString(), @@ -126,4 +136,14 @@ export class TxsComponent implements OnInit { queryParamsHandling: 'merge', }); } + + appTxTypeChanged(txType: string): void { + this.router.navigate([], { + relativeTo: this.route, + queryParams: { + txType: txType, + }, + queryParamsHandling: 'merge', + }); + } } diff --git a/projects/explorer/src/app/views/accounts/account/account.component.html b/projects/explorer/src/app/views/accounts/account/account.component.html index 712041130..5c65ddfe7 100644 --- a/projects/explorer/src/app/views/accounts/account/account.component.html +++ b/projects/explorer/src/app/views/accounts/account/account.component.html @@ -80,7 +80,7 @@

Balances

question_mark - {{ denomMetadataMap?.[balance.key]?.display || balance.key }} + {{ balance.key | coinDenom | async }} {{ balance.value.amount | coinAmount : balance.key }} @@ -92,4 +92,158 @@

Balances

+ +
+
+

Vesting

+ +
+ + + + + + + +
+
+
+
+ Asset Symbol +
+ + + question_mark + +
+ {{ vest.denom | coinDenom | async }} +
+
{{ vest.amount | coinAmount : vest.denom }}
+
+
+
+ + + + + + + + + + + + + +
Vesting StartVesting End
+ {{ vestingAccount.start_time.toNumber() * 1000 | date : 'yyyy-MM-dd a hh:mm:ss z' }} + + {{ + (vestingAccount.base_vesting_account?.end_time?.toNumber() || 0) * 1000 + | date : 'yyyy-MM-dd a hh:mm:ss z' + }} +
+
+
+ +
Click to See Vesting Detail
+
+

+ A user may choose to delegate their tokens to validators. This may be done with tokens + that are vested or are still vesting. As such, vesting tokens which are delegated will + be listed under Delegated Vesting. Vested tokens which are delegated will be + listed under Delegated Free. Both are variable values that will change based on the + amount being delegated and may be updated as more and more tokens become vested. +

+

+ For more information on vesting, please see the + Cosmos SDK documentation. +

+
+ + + + + + + + + + + + + + + + + + + + + + + +
Delegated Vesting
+
+
+
+ Asset Symbol +
+ + + question_mark + +
+ {{ del.denom | coinDenom | async }} +
+
{{ del.amount | coinAmount : del.denom }}
Delegated Free
+
+
+
+ Asset Symbol +
+ + + question_mark + +
+ {{ free.denom | coinDenom | async }} +
+
{{ free.amount | coinAmount : free.denom }}
+
+
+
+
+
diff --git a/projects/explorer/src/app/views/accounts/account/distribution/distribution.component.html b/projects/explorer/src/app/views/accounts/account/distribution/distribution.component.html index 28975a58b..e0fe74fe4 100644 --- a/projects/explorer/src/app/views/accounts/account/distribution/distribution.component.html +++ b/projects/explorer/src/app/views/accounts/account/distribution/distribution.component.html @@ -16,14 +16,16 @@

Validator Rewards

- - - - - -
Validator Accumulated Commission - {{ c | coin | async }} -
+
+ + + + + +
Validator Accumulated Commission + {{ c | coin | async }} +
+
@@ -37,14 +39,16 @@

Validator Rewards

- - - - - -
Outstanding Reward (For Delegator) - {{ r | coin | async }} -
+
+ + + + + +
Outstanding Reward (For Delegator) + {{ r | coin | async }} +
+
@@ -56,20 +60,22 @@

Validator Rewards

- - - - - - - - - - - - - -
PeriodFraction
{{ slash.validator_period }}{{ slash.fraction }}
+
+ + + + + + + + + + + + + +
PeriodFraction
{{ slash.validator_period }}{{ slash.fraction }}
+
diff --git a/projects/explorer/src/app/views/accounts/account/staking/staking.component.html b/projects/explorer/src/app/views/accounts/account/staking/staking.component.html index 56df94685..bf768ec64 100644 --- a/projects/explorer/src/app/views/accounts/account/staking/staking.component.html +++ b/projects/explorer/src/app/views/accounts/account/staking/staking.component.html @@ -14,34 +14,38 @@

Delegator Rewards

- - - - - -
Total Rewards - {{ eachTotalReward | coin | async }} -
- -

Rewards for each validator

- - +
+
- - - - - - - - + + - -
Validator AddressAmount
{{ reward.validator_address }}{{ eachReward | coin | async }}Total Rewards + {{ eachTotalReward | coin | async }} +
+ + + +

Rewards for each validator

+
+ + + + + + + + + + + + + +
Validator AddressAmount
{{ reward.validator_address }}{{ eachReward | coin | async }}
+
diff --git a/projects/explorer/src/app/views/accounts/account/txs/txs.component.html b/projects/explorer/src/app/views/accounts/account/txs/txs.component.html index 4a899ac14..29754e4be 100644 --- a/projects/explorer/src/app/views/accounts/account/txs/txs.component.html +++ b/projects/explorer/src/app/views/accounts/account/txs/txs.component.html @@ -1,6 +1,60 @@

Transactions

+ + + +

+ +

+
+ + + +

*This account has no transactions

+
+ +
+ + + + + + + + + + + + + + + +
Block HeightTx HashTimestamp
{{ tx.height }}{{ tx.txhash }} + {{ tx.timestamp | date : 'yy/MM/dd HH:mm' }} +
+
+
+
@@ -27,41 +81,5 @@

Transactions

- - -

- -

-
- - - -

*This account has no transactions

-
- - - - - - - - - - - - - - - - -
Block HeightTx HashTimestamp
{{ tx.height }}{{ tx.txhash }} - {{ tx.timestamp | date : 'yy/MM/dd HH:mm' }} -
-
-
diff --git a/projects/explorer/src/app/views/accounts/account/txs/txs.component.ts b/projects/explorer/src/app/views/accounts/account/txs/txs.component.ts index bbd764bec..abf02db75 100644 --- a/projects/explorer/src/app/views/accounts/account/txs/txs.component.ts +++ b/projects/explorer/src/app/views/accounts/account/txs/txs.component.ts @@ -17,9 +17,15 @@ export class TxsComponent implements OnInit { pageInfo?: PaginationInfo | null; @Input() pageLength?: number | null; + @Input() + maxPageNumber?: number | null; + @Input() + txType?: string | null; @Output() paginationChange: EventEmitter = new EventEmitter(); + @Output() + txTypeChange: EventEmitter = new EventEmitter(); constructor() {} @@ -32,6 +38,10 @@ export class TxsComponent implements OnInit { if ($event == 1) { this.pageInfo.pageNumber -= 1; } else if ($event == 2) { + if (this.pageInfo.pageNumber == this.maxPageNumber) { + alert('This is the last page!'); + return; + } this.pageInfo.pageNumber += 1; } if (this.pageInfo.pageNumber < 1) { @@ -47,6 +57,11 @@ export class TxsComponent implements OnInit { }); } + onTxTypeChange($event: string): void { + this.txType = $event; + this.txTypeChange.emit($event); + } + calcItemsIndex(): { start: number; end: number } { if (!this.pageInfo) { return { start: 0, end: 0 }; diff --git a/projects/portal/src/app/pages/balance/balance.component.html b/projects/portal/src/app/pages/balance/balance.component.html index c8ea9666f..ef1cd1d20 100644 --- a/projects/portal/src/app/pages/balance/balance.component.html +++ b/projects/portal/src/app/pages/balance/balance.component.html @@ -11,5 +11,6 @@ [faucets]="faucets$ | async" [faucetSymbols]="faucetSymbols$ | async" [nodeInfo]="nodeInfo$ | async" + [account]="account$ | async" (appWithdrawAllDelegatorReward)="onSubmitWithdrawAllDelegatorReward()" > diff --git a/projects/portal/src/app/pages/balance/balance.component.ts b/projects/portal/src/app/pages/balance/balance.component.ts index 2ceecf726..44055f462 100644 --- a/projects/portal/src/app/pages/balance/balance.component.ts +++ b/projects/portal/src/app/pages/balance/balance.component.ts @@ -1,6 +1,5 @@ import { CosmosRestService } from '../../models/cosmos-rest.service'; import { BankQueryService } from '../../models/cosmos/bank.query.service'; -import { BankService } from '../../models/cosmos/bank.service'; import { DistributionApplicationService } from '../../models/cosmos/distribution.application.service'; import { StoredWallet, WalletType } from '../../models/wallets/wallet.model'; import { WalletService } from '../../models/wallets/wallet.service'; @@ -9,7 +8,7 @@ import { BalanceUsecaseService } from './balance.usecase.service'; import { Component, OnInit } from '@angular/core'; import cosmosclient from '@cosmos-client/core'; import { GetNodeInfo200Response } from '@cosmos-client/core/esm/openapi'; -import { Observable, combineLatest } from 'rxjs'; +import { Observable, combineLatest, of } from 'rxjs'; import { filter, map, mergeMap } from 'rxjs/operators'; @Component({ @@ -42,10 +41,15 @@ export class BalanceComponent implements OnInit { | undefined >; nodeInfo$: Observable; + account$: Observable< + | cosmosclient.proto.cosmos.auth.v1beta1.BaseAccount + | cosmosclient.proto.cosmos.vesting.v1beta1.ContinuousVestingAccount + | unknown + | undefined + >; constructor( private readonly walletService: WalletService, - private readonly bank: BankService, private readonly bankQuery: BankQueryService, private readonly rest: CosmosRestService, private usecase: BalanceUsecaseService, @@ -81,6 +85,18 @@ export class BalanceComponent implements OnInit { ); this.nodeInfo$ = this.rest.getNodeInfo$(); this.accountTypeName$ = this.usecase.accountTypeName$; + this.account$ = address$.pipe( + mergeMap((address) => { + if (address === undefined) { + return of(undefined); + } + return this.rest.getAccount$(address.toString()); + }), + map((account) => { + const { protoJSONToInstance, castProtoJSONOfProtoAny } = cosmosclient.codec; + return account && protoJSONToInstance(castProtoJSONOfProtoAny(account)); + }), + ); } ngOnInit(): void {} diff --git a/projects/portal/src/app/views/accounts/account/account.component.html b/projects/portal/src/app/views/accounts/account/account.component.html index 8da592ece..869732d5a 100644 --- a/projects/portal/src/app/views/accounts/account/account.component.html +++ b/projects/portal/src/app/views/accounts/account/account.component.html @@ -9,21 +9,21 @@

Account Info

Sequence: - {{ baseAccount?.sequence }} + {{ baseAccount.sequence }} Account Number: - {{ baseAccount?.account_number }} + {{ baseAccount.account_number }} Address: - {{ baseAccount?.address }} + {{ baseAccount.address }} @@ -40,9 +40,9 @@

Coins

- {{ balance.amount | number: '1.0-0' }} + {{ balance.amount | number : '1.0-0' }} {{ balance.denom }} - + diff --git a/projects/portal/src/app/views/accounts/account/account.component.ts b/projects/portal/src/app/views/accounts/account/account.component.ts index 1b2452127..148692000 100644 --- a/projects/portal/src/app/views/accounts/account/account.component.ts +++ b/projects/portal/src/app/views/accounts/account/account.component.ts @@ -9,7 +9,6 @@ import cosmosclient from '@cosmos-client/core'; export class AccountComponent implements OnInit, OnChanges { @Input() account?: cosmosclient.proto.cosmos.auth.v1beta1.BaseAccount | unknown | null; - @Input() balances?: cosmosclient.proto.cosmos.base.v1beta1.ICoin[] | null; @@ -19,9 +18,9 @@ export class AccountComponent implements OnInit, OnChanges { txColumnKeys = ['height', 'txhash', 'timestamp', 'gas_wanted', 'gas_used']; - constructor() { } + constructor() {} - ngOnInit(): void { } + ngOnInit(): void {} ngOnChanges() { delete this.baseAccount; @@ -34,7 +33,9 @@ export class AccountComponent implements OnInit, OnChanges { throw Error('Invalid public key!'); } this.publicKey = Buffer.from(publicKey.key).toString('hex'); - } else if (this.account instanceof cosmosclient.proto.cosmos.vesting.v1beta1.ContinuousVestingAccount) { + } else if ( + this.account instanceof cosmosclient.proto.cosmos.vesting.v1beta1.ContinuousVestingAccount + ) { this.vestingAccount = this.account; if (this.vestingAccount.base_vesting_account?.base_account === null) { throw Error('Invalid vesting account!'); diff --git a/projects/portal/src/app/views/balance/balance.component.html b/projects/portal/src/app/views/balance/balance.component.html index 40c78719a..743f40119 100644 --- a/projects/portal/src/app/views/balance/balance.component.html +++ b/projects/portal/src/app/views/balance/balance.component.html @@ -172,7 +172,7 @@

Balances

question_mark - {{ denomMetadataMap?.[balance.key]?.display || balance.key }} + {{ balance.key | coinDenom | async }} {{ balance.value.amount | coinAmount : balance.key }} @@ -221,4 +221,162 @@

Faucet

+ +
+
+
+

Vesting

+ +
+ + + + + + + +
+
+
+
+ Asset Symbol +
+ + + question_mark + +
+ {{ vest.denom | coinDenom | async }} +
+
{{ vest.amount | coinAmount : vest.denom }}
+
+
+
+ + + + + + + + + + + + + +
Vesting StartVesting End
+ {{ + vestingAccount.start_time.toNumber() * 1000 | date : 'yyyy-MM-dd a hh:mm:ss z' + }} + + {{ + (vestingAccount.base_vesting_account?.end_time?.toNumber() || 0) * 1000 + | date : 'yyyy-MM-dd a hh:mm:ss z' + }} +
+
+
+ +
Click to See Vesting Detail
+
+

+ A user may choose to delegate their tokens to validators. This may be done with tokens + that are vested or are still vesting. As such, vesting tokens which are delegated will + be listed under Delegated Vesting. Vested tokens which are delegated will be + listed under Delegated Free. Both are variable values that will change based on the + amount being delegated and may be updated as more and more tokens become vested. +

+

+ For more information on vesting, please see the + Cosmos SDK documentation. +

+
+ + + + + + + + + + + + + + + + + + + + + + + +
Delegated Vesting
+
+
+
+ Asset Symbol +
+ + + question_mark + +
+ {{ del.denom | coinDenom | async }} +
+
{{ del.amount | coinAmount : del.denom }}
Delegated Free
+
+
+
+ Asset Symbol +
+ + + question_mark + +
+ {{ free.denom | coinDenom | async }} +
+
{{ free.amount | coinAmount : free.denom }}
+
+
+
+
+
+
diff --git a/projects/portal/src/app/views/balance/balance.component.ts b/projects/portal/src/app/views/balance/balance.component.ts index 5bd110b90..2f70b6636 100644 --- a/projects/portal/src/app/views/balance/balance.component.ts +++ b/projects/portal/src/app/views/balance/balance.component.ts @@ -1,6 +1,6 @@ import { WalletType } from '../../models/wallets/wallet.model'; import { Clipboard } from '@angular/cdk/clipboard'; -import { Component, Input, OnInit, EventEmitter, Output } from '@angular/core'; +import { Component, Input, OnInit, EventEmitter, Output, OnChanges } from '@angular/core'; import { MatSnackBar } from '@angular/material/snack-bar'; import cosmosclient from '@cosmos-client/core'; import { GetNodeInfo200Response } from '@cosmos-client/core/esm/openapi'; @@ -10,7 +10,7 @@ import { GetNodeInfo200Response } from '@cosmos-client/core/esm/openapi'; templateUrl: './balance.component.html', styleUrls: ['./balance.component.css'], }) -export class ViewBalanceComponent implements OnInit { +export class ViewBalanceComponent implements OnInit, OnChanges { @Input() walletId?: string | null; @Input() walletType?: WalletType | null; @Input() accAddress?: string | null; @@ -36,6 +36,11 @@ export class ViewBalanceComponent implements OnInit { }[] | null; @Input() nodeInfo?: GetNodeInfo200Response | null; + @Input() + account?: cosmosclient.proto.cosmos.auth.v1beta1.BaseAccount | unknown | null; + baseAccount?: cosmosclient.proto.cosmos.auth.v1beta1.BaseAccount; + vestingAccount?: cosmosclient.proto.cosmos.vesting.v1beta1.ContinuousVestingAccount; + @Output() appWithdrawAllDelegatorReward: EventEmitter<{}>; constructor(private readonly snackBar: MatSnackBar, private clipboard: Clipboard) { @@ -44,6 +49,24 @@ export class ViewBalanceComponent implements OnInit { ngOnInit(): void {} + ngOnChanges() { + delete this.baseAccount; + + if (this.account instanceof cosmosclient.proto.cosmos.auth.v1beta1.BaseAccount) { + this.baseAccount = this.account; + } else if ( + this.account instanceof cosmosclient.proto.cosmos.vesting.v1beta1.ContinuousVestingAccount + ) { + this.vestingAccount = this.account; + if (this.vestingAccount.base_vesting_account?.base_account === null) { + throw Error('Invalid vesting account!'); + } + this.baseAccount = new cosmosclient.proto.cosmos.auth.v1beta1.BaseAccount( + this.vestingAccount.base_vesting_account?.base_account, + ); + } + } + copyClipboard(value: string) { if (value.length > 0) { this.clipboard.copy(value); diff --git a/projects/portal/src/app/views/yieldaggregator/vaults/vault/vault.component.html b/projects/portal/src/app/views/yieldaggregator/vaults/vault/vault.component.html index d3691af02..05c4a78d9 100644 --- a/projects/portal/src/app/views/yieldaggregator/vaults/vault/vault.component.html +++ b/projects/portal/src/app/views/yieldaggregator/vaults/vault/vault.component.html @@ -425,58 +425,60 @@

What is the unbonding period?

-
- -
-
-
- -

{{ option.name }}

+
+
+ +
+
+
+ +

{{ option.name }}

+
+

{{ option.description }}

+
+

+ +

+ + + + + + + + + + +
{{ pool.weight | percent : '1.0-2' }}After {{ pool.unbondingTimeSec | secondToDate }} Days
+
+
+
+ Redeem: {{ estimatedRedeemAmount?.total_amount | coinAmount }} + {{ vault?.vault?.symbol }}
-

{{ option.description }}

-
-

- -

- - - - - - - - - - -
{{ pool.name }}{{ pool.weight | percent : '1.0-2' }}After {{ pool.unbondingTimeSec | secondToDate }} Days
+
-
+
+ Fee: 0 {{ vault?.vault?.symbol }}
-
-
- Redeem: {{ estimatedRedeemAmount?.total_amount | coinAmount }} - {{ vault?.vault?.symbol }} -
-
-
-
- Fee: 0 {{ vault?.vault?.symbol }} -
-
- Fee: {{ estimatedRedeemAmount?.fee | coinAmount }} - {{ vault?.vault?.symbol }} -
+
+ Fee: {{ estimatedRedeemAmount?.fee | coinAmount }} + {{ vault?.vault?.symbol }}
-
OR
- -
+
+
OR
+