diff --git a/src/libs/data/data.js b/src/libs/data/data.js
index 88c0ea84..bf1cd07d 100644
--- a/src/libs/data/data.js
+++ b/src/libs/data/data.js
@@ -8,9 +8,9 @@ import duration from 'dayjs/plugin/duration'
import relativeTime from 'dayjs/plugin/relativeTime'
import localeData from 'dayjs/plugin/localeData'
+dayjs.extend(localeData)
dayjs.extend(duration)
dayjs.extend(relativeTime)
-dayjs.extend(localeData)
export function toDuration(value) {
return dayjs.duration(value).humanize()
@@ -39,9 +39,16 @@ export function percent(num) {
return parseFloat((num * 100).toFixed(2))
}
-export function abbr(string, length = 6) {
+export function abbr(string, length = 6, suffix = '...') {
if (string && string.length > length) {
- return `${string.substring(0, length)}...`
+ return `${string.substring(0, length)}${suffix}`
+ }
+ return string
+}
+
+export function abbrRight(string, length = 6, suffix = '...') {
+ if (string && string.length > length) {
+ return `${string.substring(string.length - length)}${suffix}`
}
return string
}
@@ -105,6 +112,9 @@ export function tokenFormatter(tokens) {
export function operatorAddressToAccount(operAddress) {
const { prefix, data } = Bech32.decode(operAddress)
+ if (prefix === 'iva') { // handle special cases
+ return Bech32.encode('iaa', data)
+ }
return Bech32.encode(prefix.replace('valoper', ''), data)
}
@@ -119,6 +129,38 @@ export function consensusPubkeyToHexAddress(consensusPubkey) {
return address
}
+export function getCachedValidators(chainName) {
+ const locals = localStorage.getItem(`validators-${chainName}`)
+ return locals
+}
+
+export function isHexAddress(v) {
+ const re = /^[A-Z\d]{40}$/
+ return re.test(v)
+}
+
+export function getStakingValidatorByHex(chainName, hex) {
+ const locals = localStorage.getItem(`validators-${chainName}`)
+ if (locals) {
+ const val = JSON.parse(locals).find(x => consensusPubkeyToHexAddress(x.consensus_pubkey) === hex)
+ if (val) {
+ return val.description.moniker
+ }
+ }
+ return abbr(hex)
+}
+
+export function getStakingValidatorByAccount(chainName, addr) {
+ const locals = localStorage.getItem(`validators-${chainName}`)
+ if (locals) {
+ const val = JSON.parse(locals).find(x => operatorAddressToAccount(x.operator_address) === addr)
+ if (val) {
+ return val.description.moniker
+ }
+ }
+ return addr
+}
+
export * from 'compare-versions'
export class Data {
diff --git a/src/libs/fetch.js b/src/libs/fetch.js
index e72a8084..9b5aadc1 100644
--- a/src/libs/fetch.js
+++ b/src/libs/fetch.js
@@ -106,7 +106,11 @@ const chainAPI = class ChainFetch {
}
async getValidatorList() {
- return this.get('/staking/validators').then(data => commonProcess(data).map(i => new Validator().init(i)))
+ return this.get('/staking/validators').then(data => {
+ const vals = commonProcess(data).map(i => new Validator().init(i))
+ localStorage.setItem(`validators-${this.config.chain_name}`, JSON.stringify(vals))
+ return vals
+ })
}
async getStakingValidator(address) {
diff --git a/src/router/index.js b/src/router/index.js
index b70175b9..917ba5e8 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -95,7 +95,7 @@ const router = new VueRouter({
{
path: '/:chain/gov/:proposalid',
name: 'proposal',
- component: () => import('@/views/ProposalView.vue'),
+ component: () => import('@/views/GovernanceProposalView.vue'),
meta: {
pageTitle: 'Governance',
breadcrumb: [
diff --git a/src/views/ArrayFieldComponent.vue b/src/views/ArrayFieldComponent.vue
index 920a1f46..2c9ea6d0 100644
--- a/src/views/ArrayFieldComponent.vue
+++ b/src/views/ArrayFieldComponent.vue
@@ -8,6 +8,7 @@
>
{{ formatTokens(data.value) }}
+ {{ formatHexAddress(data.value) }}
diff --git a/src/views/Blocks.vue b/src/views/Blocks.vue
index 069ea6be..71ae45eb 100644
--- a/src/views/Blocks.vue
+++ b/src/views/Blocks.vue
@@ -30,7 +30,7 @@
{{ formatTime(data.item.block.header.time) }}
- {{ data.item.block.header.proposer_address }}
+ {{ formatProposer(data.item.block.header.proposer_address) }}
{{ length(data.item.block.data.txs) }}
@@ -46,6 +46,8 @@ import {
BTable, BCard, BCardHeader, BCardTitle, VBTooltip,
} from 'bootstrap-vue'
import {
+ getCachedValidators,
+ getStakingValidatorByHex,
toDay,
} from '@/libs/data'
// import fetch from 'node-fetch'
@@ -101,6 +103,10 @@ export default {
list.push(height - i)
}
+ if (!getCachedValidators()) {
+ this.$http.getValidatorList()
+ }
+
let promise = Promise.resolve()
list.forEach(item => {
promise = promise.then(() => new Promise(resolve => {
@@ -120,6 +126,9 @@ export default {
methods: {
length: v => (Array.isArray(v) ? v.length : 0),
formatTime: v => toDay(v, 'time'),
+ formatProposer(v) {
+ return getStakingValidatorByHex(this.$http.config.chain_name, v)
+ },
fetch() {
this.$http.getLatestBlock().then(b => {
const has = this.blocks.findIndex(x => x.block.header.height === b.block.header.height)
diff --git a/src/views/ProposalView.vue b/src/views/GovernanceProposalView.vue
similarity index 83%
rename from src/views/ProposalView.vue
rename to src/views/GovernanceProposalView.vue
index c6a08d2b..8b89f8d4 100644
--- a/src/views/ProposalView.vue
+++ b/src/views/GovernanceProposalView.vue
@@ -48,7 +48,7 @@
{{ $t('proposal_proposer') }}
- {{ proposer.proposer }}
+ {{ formatAddress(proposer.proposer) }}
@@ -202,7 +202,7 @@ import {
} from 'bootstrap-vue'
// import fetch from 'node-fetch'
-import { tokenFormatter } from '@/libs/data/data'
+import { getCachedValidators, getStakingValidatorByAccount, tokenFormatter } from '@/libs/data/data'
import { Proposal, Proposer } from '@/libs/data'
import ObjectFieldComponent from './ObjectFieldComponent.vue'
// import { formatToken } from '@/libs/data/data'
@@ -232,7 +232,11 @@ export default {
deposits: [],
votes: [],
votes_fields: [
- { key: 'voter', sortable: true },
+ {
+ key: 'voter',
+ sortable: true,
+ formatter: v => this.formatAddress(v),
+ },
{
key: 'option',
sortable: true,
@@ -253,7 +257,10 @@ export default {
},
],
deposit_fields: [
- 'depositor',
+ {
+ key: 'depositor',
+ formatter: v => this.formatAddress(v),
+ },
{
key: 'amount',
sortable: true,
@@ -273,6 +280,10 @@ export default {
this.proposal = p
})
+ if (!getCachedValidators()) {
+ this.$http.getValidatorList()
+ }
+
this.$http.getGovernanceProposer(pid).then(res => {
this.proposer = res
})
@@ -283,46 +294,11 @@ export default {
this.votes = res
})
},
-
- // asyncComputed: {
- // proposal: {
- // get() {
- // const pid = this.$route.params.proposalid
- // // const api = new ChainAPI(this.$route)
- // return this.$http.getGovernance(pid).then(p => {
- // if (p.status === 2) {
- // this.$http.getGovernanceTally(pid, 0).then(t => p.updateTally(t)).catch(e => console.log('failed on update voting tally:', e))
- // }
- // return p
- // })
- // },
- // default: new Proposal(),
- // },
- // proposer: {
- // get() {
- // const pid = this.$route.params.proposalid
- // // const api = new ChainAPI(this.$route)
- // return this.$http.getGovernanceProposer(pid)
- // },
- // default: new Proposer(),
- // },
- // deposits: {
- // get() {
- // const pid = this.$route.params.proposalid
- // // const api = new ChainAPI(this.$route)
- // return this.$http.getGovernanceDeposits(pid)
- // },
- // default: [],
- // },
- // votes: {
- // get() {
- // const pid = this.$route.params.proposalid
- // // const api = new ChainAPI(this.$route)
- // return this.$http.getGovernanceVotes(pid)
- // },
- // default: [],
- // },
- // },
+ methods: {
+ formatAddress(v) {
+ return getStakingValidatorByAccount(this.$http.config.chain_name, v)
+ },
+ },
}
diff --git a/src/views/ObjectFieldComponent.vue b/src/views/ObjectFieldComponent.vue
index 310df13d..54ea3668 100644
--- a/src/views/ObjectFieldComponent.vue
+++ b/src/views/ObjectFieldComponent.vue
@@ -21,6 +21,9 @@
{{ value.join(', ') }}
+
+ {{ formatHexAddress(value) }}
+
@@ -60,7 +63,7 @@ import {
BTableSimple, BTr, BTd, BTabs, BTab,
} from 'bootstrap-vue'
import {
- abbr, isStringArray, isToken, tokenFormatter,
+ abbr, getStakingValidatorByHex, isHexAddress, isStringArray, isToken, tokenFormatter,
} from '@/libs/data'
import ArrayFieldComponent from './ArrayFieldComponent.vue'
@@ -100,6 +103,12 @@ export default {
isTokenField(value) {
return isToken(value)
},
+ isHex(value) {
+ return isHexAddress(value)
+ },
+ formatHexAddress(v) {
+ return getStakingValidatorByHex(this.$http.config.chain_name, v)
+ },
isArrayText(value) {
return isStringArray(value)
},