Make address human readable

This commit is contained in:
liangping 2021-08-08 18:08:09 +08:00
parent eaac3b295a
commit de77ea57c1
7 changed files with 99 additions and 52 deletions

View File

@ -8,9 +8,9 @@ import duration from 'dayjs/plugin/duration'
import relativeTime from 'dayjs/plugin/relativeTime' import relativeTime from 'dayjs/plugin/relativeTime'
import localeData from 'dayjs/plugin/localeData' import localeData from 'dayjs/plugin/localeData'
dayjs.extend(localeData)
dayjs.extend(duration) dayjs.extend(duration)
dayjs.extend(relativeTime) dayjs.extend(relativeTime)
dayjs.extend(localeData)
export function toDuration(value) { export function toDuration(value) {
return dayjs.duration(value).humanize() return dayjs.duration(value).humanize()
@ -39,9 +39,16 @@ export function percent(num) {
return parseFloat((num * 100).toFixed(2)) return parseFloat((num * 100).toFixed(2))
} }
export function abbr(string, length = 6) { export function abbr(string, length = 6, suffix = '...') {
if (string && string.length > length) { 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 return string
} }
@ -105,6 +112,9 @@ export function tokenFormatter(tokens) {
export function operatorAddressToAccount(operAddress) { export function operatorAddressToAccount(operAddress) {
const { prefix, data } = Bech32.decode(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) return Bech32.encode(prefix.replace('valoper', ''), data)
} }
@ -119,6 +129,38 @@ export function consensusPubkeyToHexAddress(consensusPubkey) {
return address 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 * from 'compare-versions'
export class Data { export class Data {

View File

@ -106,7 +106,11 @@ const chainAPI = class ChainFetch {
} }
async getValidatorList() { 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) { async getStakingValidator(address) {

View File

@ -95,7 +95,7 @@ const router = new VueRouter({
{ {
path: '/:chain/gov/:proposalid', path: '/:chain/gov/:proposalid',
name: 'proposal', name: 'proposal',
component: () => import('@/views/ProposalView.vue'), component: () => import('@/views/GovernanceProposalView.vue'),
meta: { meta: {
pageTitle: 'Governance', pageTitle: 'Governance',
breadcrumb: [ breadcrumb: [

View File

@ -8,6 +8,7 @@
> >
<template #cell()="data"> <template #cell()="data">
<span v-if="isTokenField(data.value)">{{ formatTokens(data.value) }}</span> <span v-if="isTokenField(data.value)">{{ formatTokens(data.value) }}</span>
<span v-else-if="isHex(data.value)">{{ formatHexAddress(data.value) }}</span>
<array-field-component <array-field-component
v-else-if="isArrayText(data.value)" v-else-if="isArrayText(data.value)"
:tablefield="eval_value(data.value)" :tablefield="eval_value(data.value)"
@ -25,7 +26,7 @@ import { BTable } from 'bootstrap-vue'
// import fetch from 'node-fetch' // import fetch from 'node-fetch'
import { import {
abbr, isToken, toDay, tokenFormatter, abbr, getStakingValidatorByHex, isHexAddress, isToken, toDay, tokenFormatter,
} from '@/libs/data/data' } from '@/libs/data/data'
// import { Proposal, Proposer } from '@/libs/data' // import { Proposal, Proposer } from '@/libs/data'
// import { formatToken } from '@/libs/data/data' // import { formatToken } from '@/libs/data/data'
@ -65,6 +66,12 @@ export default {
formatTokens(value) { formatTokens(value) {
return tokenFormatter(value) return tokenFormatter(value)
}, },
isHex(value) {
return isHexAddress(value)
},
formatHexAddress(v) {
return getStakingValidatorByHex(this.$http.config.chain_name, v)
},
}, },
} }
</script> </script>

View File

@ -30,7 +30,7 @@
{{ formatTime(data.item.block.header.time) }} {{ formatTime(data.item.block.header.time) }}
</template> </template>
<template #cell(proposer)="data"> <template #cell(proposer)="data">
{{ data.item.block.header.proposer_address }} {{ formatProposer(data.item.block.header.proposer_address) }}
</template> </template>
<template #cell(txs)="data"> <template #cell(txs)="data">
{{ length(data.item.block.data.txs) }} {{ length(data.item.block.data.txs) }}
@ -46,6 +46,8 @@ import {
BTable, BCard, BCardHeader, BCardTitle, VBTooltip, BTable, BCard, BCardHeader, BCardTitle, VBTooltip,
} from 'bootstrap-vue' } from 'bootstrap-vue'
import { import {
getCachedValidators,
getStakingValidatorByHex,
toDay, toDay,
} from '@/libs/data' } from '@/libs/data'
// import fetch from 'node-fetch' // import fetch from 'node-fetch'
@ -101,6 +103,10 @@ export default {
list.push(height - i) list.push(height - i)
} }
if (!getCachedValidators()) {
this.$http.getValidatorList()
}
let promise = Promise.resolve() let promise = Promise.resolve()
list.forEach(item => { list.forEach(item => {
promise = promise.then(() => new Promise(resolve => { promise = promise.then(() => new Promise(resolve => {
@ -120,6 +126,9 @@ export default {
methods: { methods: {
length: v => (Array.isArray(v) ? v.length : 0), length: v => (Array.isArray(v) ? v.length : 0),
formatTime: v => toDay(v, 'time'), formatTime: v => toDay(v, 'time'),
formatProposer(v) {
return getStakingValidatorByHex(this.$http.config.chain_name, v)
},
fetch() { fetch() {
this.$http.getLatestBlock().then(b => { this.$http.getLatestBlock().then(b => {
const has = this.blocks.findIndex(x => x.block.header.height === b.block.header.height) const has = this.blocks.findIndex(x => x.block.header.height === b.block.header.height)

View File

@ -48,7 +48,7 @@
<b-tr> <b-tr>
<b-td> <b-td>
{{ $t('proposal_proposer') }} {{ $t('proposal_proposer') }}
</b-td><b-td>{{ proposer.proposer }} </b-td> </b-td><b-td>{{ formatAddress(proposer.proposer) }} </b-td>
</b-tr> </b-tr>
<b-tr> <b-tr>
<b-td> <b-td>
@ -202,7 +202,7 @@ import {
} from 'bootstrap-vue' } from 'bootstrap-vue'
// import fetch from 'node-fetch' // 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 { Proposal, Proposer } from '@/libs/data'
import ObjectFieldComponent from './ObjectFieldComponent.vue' import ObjectFieldComponent from './ObjectFieldComponent.vue'
// import { formatToken } from '@/libs/data/data' // import { formatToken } from '@/libs/data/data'
@ -232,7 +232,11 @@ export default {
deposits: [], deposits: [],
votes: [], votes: [],
votes_fields: [ votes_fields: [
{ key: 'voter', sortable: true }, {
key: 'voter',
sortable: true,
formatter: v => this.formatAddress(v),
},
{ {
key: 'option', key: 'option',
sortable: true, sortable: true,
@ -253,7 +257,10 @@ export default {
}, },
], ],
deposit_fields: [ deposit_fields: [
'depositor', {
key: 'depositor',
formatter: v => this.formatAddress(v),
},
{ {
key: 'amount', key: 'amount',
sortable: true, sortable: true,
@ -273,6 +280,10 @@ export default {
this.proposal = p this.proposal = p
}) })
if (!getCachedValidators()) {
this.$http.getValidatorList()
}
this.$http.getGovernanceProposer(pid).then(res => { this.$http.getGovernanceProposer(pid).then(res => {
this.proposer = res this.proposer = res
}) })
@ -283,46 +294,11 @@ export default {
this.votes = res this.votes = res
}) })
}, },
methods: {
// asyncComputed: { formatAddress(v) {
// proposal: { return getStakingValidatorByAccount(this.$http.config.chain_name, v)
// 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: [],
// },
// },
} }
</script> </script>

View File

@ -21,6 +21,9 @@
<b-td v-else-if="isArrayText(value)"> <b-td v-else-if="isArrayText(value)">
{{ value.join(', ') }} {{ value.join(', ') }}
</b-td> </b-td>
<b-td v-else-if="isHex(value)">
{{ formatHexAddress(value) }}
</b-td>
<b-td v-else-if="Array.isArray(value)"> <b-td v-else-if="Array.isArray(value)">
<array-field-component :tablefield="value" /> <array-field-component :tablefield="value" />
</b-td> </b-td>
@ -60,7 +63,7 @@ import {
BTableSimple, BTr, BTd, BTabs, BTab, BTableSimple, BTr, BTd, BTabs, BTab,
} from 'bootstrap-vue' } from 'bootstrap-vue'
import { import {
abbr, isStringArray, isToken, tokenFormatter, abbr, getStakingValidatorByHex, isHexAddress, isStringArray, isToken, tokenFormatter,
} from '@/libs/data' } from '@/libs/data'
import ArrayFieldComponent from './ArrayFieldComponent.vue' import ArrayFieldComponent from './ArrayFieldComponent.vue'
@ -100,6 +103,12 @@ export default {
isTokenField(value) { isTokenField(value) {
return isToken(value) return isToken(value)
}, },
isHex(value) {
return isHexAddress(value)
},
formatHexAddress(v) {
return getStakingValidatorByHex(this.$http.config.chain_name, v)
},
isArrayText(value) { isArrayText(value) {
return isStringArray(value) return isStringArray(value)
}, },