@@ -99,13 +102,18 @@
Nothing found
- We couldn't find the validators you are looking for. Try searching by Index, Public Key or ETH address.
+ We couldn't find the validators you are looking for. Try searching by index, public key, deposit / withdrawal address or withdrawal
+ credential.
Add Validators
- You can add your validators by searching for a public key, validator index or your ETH address.
+
+ You can add your validators by searching for a public key, validator index, your deposit / withdrawal address or withdrawal credential.
+
diff --git a/src/app/tab-validators/tab-validators.page.scss b/src/app/tab-validators/tab-validators.page.scss
index f59a2834..62aecf8c 100644
--- a/src/app/tab-validators/tab-validators.page.scss
+++ b/src/app/tab-validators/tab-validators.page.scss
@@ -93,3 +93,10 @@ cdk-virtual-scroll-viewport {
margin-top: 55px;
margin-bottom: 10px;
}
+
+.hidden {
+ height: 0;
+ width: 0;
+ overflow: hidden;
+ visibility: hidden;
+}
diff --git a/src/app/tab-validators/tab-validators.page.ts b/src/app/tab-validators/tab-validators.page.ts
index 38b9dd20..b14223b2 100644
--- a/src/app/tab-validators/tab-validators.page.ts
+++ b/src/app/tab-validators/tab-validators.page.ts
@@ -18,9 +18,9 @@
* // along with Beaconchain Dashboard. If not, see .
*/
-import { Component } from '@angular/core'
+import { Component, ViewChild } from '@angular/core'
import { ValidatorUtils, Validator, ValidatorState } from '../utils/ValidatorUtils'
-import { ModalController, Platform } from '@ionic/angular'
+import { IonSearchbar, ModalController, Platform } from '@ionic/angular'
import { ValidatordetailPage } from '../pages/validatordetail/validatordetail.page'
import { ApiService } from '../services/api.service'
import { AlertController } from '@ionic/angular'
@@ -67,6 +67,8 @@ export class Tab2Page {
selected = new Map()
+ @ViewChild('searchbarRef', { static: true }) searchbarRef: IonSearchbar
+
constructor(
private validatorUtils: ValidatorUtils,
public modalController: ModalController,
@@ -81,6 +83,10 @@ export class Tab2Page {
public unit: UnitconvService
) {
this.validatorUtils.registerListener(() => {
+ if (this.searchResultMode && this.searchbarRef) {
+ this.searchResultMode = false
+ this.searchbarRef.value = null
+ }
this.refresh()
})
this.merchant.getCurrentPlanMaxValidator().then((result) => {
@@ -101,7 +107,7 @@ export class Tab2Page {
if (!this.searchResultMode) {
this.dataSource.setLoadFrom(this.getDefaultDataRetriever())
}
- this.dataSource.reset()
+ await this.dataSource.reset()
}
async syncRemote() {
@@ -189,13 +195,13 @@ export class Tab2Page {
}
}
- async removeAllDialog() {
+ removeAllDialog() {
this.showDialog('Remove all', 'Do you want to remove {AMOUNT} validators from your dashboard?', () => {
this.confirmRemoveAll()
})
}
- async addAllDialog() {
+ addAllDialog() {
this.showDialog('Add all', 'Do you want to add {AMOUNT} validators to your dashboard?', () => {
this.confirmAddAll()
})
@@ -223,18 +229,18 @@ export class Tab2Page {
}
async confirmRemoveAll() {
- this.validatorUtils.deleteAll()
- this.dataSource.reset()
+ await this.validatorUtils.deleteAll()
+ await this.dataSource.reset()
}
async confirmAddAll() {
const responses: ValidatorResponse[] = []
- this.dataSource.getItems().forEach(async (item) => {
+ this.dataSource.getItems().forEach((item) => {
responses.push(item.data)
})
- this.validatorUtils.convertToValidatorModelsAndSaveLocal(false, responses)
- this.dataSource.reset()
+ await this.validatorUtils.convertToValidatorModelsAndSaveLocal(false, responses)
+ await this.dataSource.reset()
}
searchEvent(event) {
@@ -250,8 +256,9 @@ export class Tab2Page {
this.searchResultMode = true
this.loading = true
const isETH1Address = searchString.startsWith('0x') && searchString.length == 42
+ const isWithdrawalCredential = searchString.startsWith('0x') && searchString.length == 66
- if (isETH1Address) await this.searchETH1(searchString)
+ if (isETH1Address || isWithdrawalCredential) await this.searchETH1(searchString)
else await this.searchByPubKeyOrIndex(searchString)
// this.loading = false would be preferable here but somehow the first time it is called the promises resolve instantly without waiting
@@ -278,12 +285,12 @@ export class Tab2Page {
private async searchETH1(target) {
this.dataSource.setLoadFrom(() => {
return this.validatorUtils
- .searchValidatorsViaETH1(target)
+ .searchValidatorsViaETHAddress(target)
.catch(async (error) => {
if (error && error.message && error.message.indexOf('only a maximum of') > 0) {
console.log('SET reachedMaxValidators to true')
this.reachedMaxValidators = true
- return this.validatorUtils.searchValidatorsViaETH1(target, this.currentPackageMaxValidators - 1)
+ return this.validatorUtils.searchValidatorsViaETHAddress(target, this.currentPackageMaxValidators - 1)
}
return []
})
@@ -478,7 +485,7 @@ export class Tab2Page {
buttons: [
{
text: 'Remove',
- handler: async () => {
+ handler: () => {
this.validatorUtils.saveRocketpoolCollateralShare(onlyOneNodeAddress.rocketpool.node_address, null)
this.cancelSelect()
this.validatorUtils.notifyListeners()
@@ -486,7 +493,7 @@ export class Tab2Page {
},
{
text: 'Save',
- handler: async (alertData) => {
+ handler: (alertData) => {
const shares = alertData.share
if (shares < minShareStake) {
Toast.show({
@@ -546,7 +553,9 @@ export class Tab2Page {
cssClass: 'my-custom-class',
header: 'Define stake share',
message:
- 'If you own partial amounts of these validators, specify the amount of ether for a custom dashboard. First value defines your consensus share, second value your execution share.',
+ 'If you own partial amounts of these validators, specify the amount of ' +
+ this.api.getCurrenciesFormatted() +
+ ' for a custom dashboard. First value defines your consensus share, second value your execution share.',
inputs: [
{
name: 'share',
@@ -564,7 +573,7 @@ export class Tab2Page {
buttons: [
{
text: 'Remove',
- handler: async () => {
+ handler: () => {
for (let i = 0; i < validatorSubArray.length; i++) {
validatorSubArray[i].share = null
validatorSubArray[i].execshare = null
@@ -576,7 +585,7 @@ export class Tab2Page {
},
{
text: 'Save',
- handler: async (alertData) => {
+ handler: (alertData) => {
const shares = alertData.share
const sharesEL = alertData.execshare
if ((shares && shares < minShareStake) || (sharesEL && sharesEL < minShareStake)) {
@@ -616,14 +625,4 @@ export class Tab2Page {
await alert.present()
}
-
- switchCurrencyPipe() {
- if (this.unit.pref == 'ETHER') {
- if (UnitconvService.currencyPipe == null) return
- this.unit.pref = UnitconvService.currencyPipe
- } else {
- UnitconvService.currencyPipe = this.unit.pref
- this.unit.pref = 'ETHER'
- }
- }
}
diff --git a/src/app/tabs/tabs.page.ts b/src/app/tabs/tabs.page.ts
index 6364815f..9dd73da5 100644
--- a/src/app/tabs/tabs.page.ts
+++ b/src/app/tabs/tabs.page.ts
@@ -80,7 +80,7 @@ export class TabsPage {
}
const hasTheming = await this.merchant.hasPremiumTheming()
- if (!hasTheming) {
+ if (!hasTheming && this.theme.currentThemeColor != 'gnosis') {
this.theme.resetTheming()
}
}
diff --git a/src/app/utils/BlockUtils.ts b/src/app/utils/BlockUtils.ts
index e577e73d..00ea5d0b 100644
--- a/src/app/utils/BlockUtils.ts
+++ b/src/app/utils/BlockUtils.ts
@@ -21,7 +21,6 @@
import { ApiService } from '../services/api.service'
import { Injectable } from '@angular/core'
import { BlockProducedByRequest, BlockResponse, DashboardRequest } from '../requests/requests'
-import { CacheModule } from './CacheModule'
import BigNumber from 'bignumber.js'
import { ValidatorUtils } from './ValidatorUtils'
@@ -33,10 +32,8 @@ const MONTH = 60 * 60 * 24 * 30
@Injectable({
providedIn: 'root',
})
-export class BlockUtils extends CacheModule {
- constructor(public api: ApiService, public validatorUtils: ValidatorUtils) {
- super()
- }
+export class BlockUtils {
+ constructor(public api: ApiService, public validatorUtils: ValidatorUtils) {}
async getBlockRewardWithShare(block: BlockResponse): Promise {
const proposer = block.posConsensus.proposerIndex
@@ -85,7 +82,7 @@ export class BlockUtils extends CacheModule {
luckPercentage: proposalLuckStats.proposal_luck,
timeFrameName: proposalLuckStats.time_frame_name,
userValidators: valis.length,
- expectedBlocksPerMonth: MONTH / (proposalLuckStats.average_proposal_interval * 12),
+ expectedBlocksPerMonth: MONTH / (proposalLuckStats.average_proposal_interval * this.api.getNetwork().slotsTime),
nextBlockEstimate: proposalLuckStats.next_proposal_estimate_ts * 1000,
} as Luck
}
diff --git a/src/app/utils/CacheModule.ts b/src/app/utils/CacheModule.ts
index cdc16266..bdb96c32 100644
--- a/src/app/utils/CacheModule.ts
+++ b/src/app/utils/CacheModule.ts
@@ -18,9 +18,11 @@
* // along with Beaconchain Dashboard. If not, see .
*/
-import { StorageService } from '../services/storage.service'
+import { StorageService, replacer } from '../services/storage.service'
import { Validator } from './ValidatorUtils'
+const LOGTAG = '[CacheModule]'
+
interface CachedData {
maxStaleTime: number
time: number
@@ -32,42 +34,93 @@ export class CacheModule {
private keyPrefix = ''
private hardStorage: StorageService = null
- initialized: Promise