Merge branch 'master' into feature-multi-language

This commit is contained in:
Erialos 2022-11-30 16:32:05 -07:00
commit f0fa01d703
7 changed files with 207 additions and 100 deletions

View File

@ -9,16 +9,16 @@ export default class ProposalTally {
} }
init(element, total) { init(element, total) {
const subtotal = Number(element.yes) + Number(element.no) + Number(element.abstain) + Number(element.no_with_veto) const subtotal = Number(element.yes || element.yes_count) + Number(element.no || element.no_count) + Number(element.abstain || element.abstain_count) + Number(element.no_with_veto || element.no_with_veto_count)
if (total < 1) { if (total < 1) {
this.total = subtotal + 1 this.total = subtotal + 1
} else { } else {
this.total = total this.total = total
} }
this.yes = Number(element.yes) / this.total this.yes = Number(element.yes || element.yes_count) / this.total
this.no = Number(element.no) / this.total this.no = Number(element.no || element.no_count) / this.total
this.veto = Number(element.no_with_veto) / this.total this.veto = Number(element.no_with_veto || element.no_with_veto_count) / this.total
this.abstain = Number(element.abstain) / this.total this.abstain = Number(element.abstain || element.abstain_count) / this.total
this.turnout = subtotal / this.total this.turnout = subtotal / this.total
return this return this
} }

View File

@ -16,6 +16,7 @@ export default class Proposal {
this.voting_start_time = '0000-00-00' this.voting_start_time = '0000-00-00'
this.total_deposit = '-' this.total_deposit = '-'
this.contents = null this.contents = null
this.metadata = {}
} }
init(element, total) { init(element, total) {
@ -29,7 +30,7 @@ export default class Proposal {
this.voting_start_time = element.voting_start_time this.voting_start_time = element.voting_start_time
// eslint-disable-next-line prefer-destructuring // eslint-disable-next-line prefer-destructuring
this.total_deposit = element.total_deposit[0] this.total_deposit = element.total_deposit[0]
this.contents = element.content.value || element.content if (element.content) this.contents = element.content.value || element.content
if (this.contents) { if (this.contents) {
this.title = this.contents.title this.title = this.contents.title
this.description = this.contents.description this.description = this.contents.description
@ -38,6 +39,7 @@ export default class Proposal {
this.type = element.content['@type'] this.type = element.content['@type']
} }
} }
this.metadata = element.metadata
return this return this
} }
@ -51,6 +53,12 @@ export default class Proposal {
versionFixed(ver) { versionFixed(ver) {
if (compareVersions(ver, '0.46') >= 0) { if (compareVersions(ver, '0.46') >= 0) {
[this.contents] = this.element.messages
if (this.contents) this.type = this.contents['@type']
if (this.contents['@type'] === '/cosmos.gov.v1.MsgExecLegacyContent') {
this.title = this.contents.content.title
this.description = this.contents.content.description
}
if (this.element.metadata) { if (this.element.metadata) {
this.title = this.element.metadata.title || this.element.metadata this.title = this.element.metadata.title || this.element.metadata
this.description = this.element.metadata.description || this.element.metadata this.description = this.element.metadata.description || this.element.metadata

View File

@ -128,8 +128,8 @@ export default class ChainFetch {
// return ret // return ret
// }) // })
return Promise.all([ return Promise.all([
this.get(`/cosmos/distribution/v1beta1/validators/${address}/commission`), this.get(`/cosmos/distribution/v1beta1/validators/${address}/commission`, null, true),
this.get(`/cosmos/distribution/v1beta1/validators/${address}/outstanding_rewards`), this.get(`/cosmos/distribution/v1beta1/validators/${address}/outstanding_rewards`, null, true),
]).then(data => { ]).then(data => {
const ret = ValidatorDistribution.create({ const ret = ValidatorDistribution.create({
operator_address: address, operator_address: address,
@ -145,6 +145,9 @@ export default class ChainFetch {
} }
async getBankTotal(denom) { async getBankTotal(denom) {
if (compareVersions(this.config.sdk_version, '0.46.5') > 0) {
return this.get(`/cosmos/bank/v1beta1/supply/by_denom?denom=${denom}`).then(data => commonProcess(data).amount)
}
if (compareVersions(this.config.sdk_version, '0.40') < 0) { if (compareVersions(this.config.sdk_version, '0.40') < 0) {
return this.get(`/supply/total/${denom}`).then(data => ({ amount: commonProcess(data), denom })) return this.get(`/supply/total/${denom}`).then(data => ({ amount: commonProcess(data), denom }))
} }
@ -159,7 +162,7 @@ export default class ChainFetch {
} }
async getStakingPool() { async getStakingPool() {
return this.get('/cosmos/staking/v1beta1/pool').then(data => new StakingPool().init(commonProcess(data.pool))) return this.get('/cosmos/staking/v1beta1/pool', null, true).then(data => new StakingPool().init(commonProcess(data.pool)))
} }
async getMintingInflation() { async getMintingInflation() {
@ -176,7 +179,7 @@ export default class ChainFetch {
} }
async getStakingParameters() { async getStakingParameters() {
return this.get('/cosmos/staking/v1beta1/params').then(data => { return this.get('/cosmos/staking/v1beta1/params', null, true).then(data => {
this.getSelectedConfig() this.getSelectedConfig()
return StakingParameters.create(commonProcess(data.params), this.config.chain_name) return StakingParameters.create(commonProcess(data.params), this.config.chain_name)
}) })
@ -223,7 +226,7 @@ export default class ChainFetch {
} }
async getStakingValidator(address) { async getStakingValidator(address) {
return this.get(`/cosmos/staking/v1beta1/validators/${address}`).then(data => new Validator().init(commonProcess(data).validator)) return this.get(`/cosmos/staking/v1beta1/validators/${address}`, null, true).then(data => new Validator().init(commonProcess(data).validator))
} }
async getSlashingParameters() { async getSlashingParameters() {
@ -277,23 +280,27 @@ export default class ChainFetch {
} }
async getDistributionParameters() { async getDistributionParameters() {
return this.get('/cosmos/distribution/v1beta1/params').then(data => commonProcess(data.params)) return this.get('/cosmos/distribution/v1beta1/params', null, true).then(data => commonProcess(data.params))
} }
async getGovernanceParameterDeposit() { async getGovernanceParameterDeposit() {
return this.get('/cosmos/gov/v1beta1/params/deposit').then(data => commonProcess(data.deposit_params)) const ver = compareVersions(this.config.sdk_version, '0.46.5') < 0 ? 'v1beta1' : 'v1'
return this.get(`/cosmos/gov/${ver}/params/deposit`).then(data => commonProcess(data.deposit_params))
} }
async getGovernanceParameterTallying() { async getGovernanceParameterTallying() {
return this.get('/cosmos/gov/v1beta1/params/tallying').then(data => commonProcess(data.tally_params)) const ver = compareVersions(this.config.sdk_version, '0.46.5') < 0 ? 'v1beta1' : 'v1'
return this.get(`/cosmos/gov/${ver}/params/tallying`).then(data => commonProcess(data.tally_params))
} }
async getGovernanceParameterVoting() { async getGovernanceParameterVoting() {
return this.get('/cosmos/gov/v1beta1/params/voting').then(data => commonProcess(data.voting_params)) const ver = compareVersions(this.config.sdk_version, '0.46.5') < 0 ? 'v1beta1' : 'v1'
return this.get(`/cosmos/gov/${ver}/params/voting`).then(data => commonProcess(data.voting_params))
} }
async getGovernanceTally(pid, total, conf) { async getGovernanceTally(pid, total, conf) {
return this.get(`/cosmos/gov/v1beta1/proposals/${pid}/tally`, conf).then(data => new ProposalTally().init(commonProcess(data).tally, total)) const ver = compareVersions(this.config.sdk_version, '0.46.5') < 0 ? 'v1beta1' : 'v1'
return this.get(`/cosmos/gov/${ver}/proposals/${pid}/tally`, conf).then(data => new ProposalTally().init(commonProcess(data).tally, total))
} }
getGovernance(pid) { getGovernance(pid) {
@ -303,7 +310,9 @@ export default class ChainFetch {
return p return p
}) })
} }
return this.get(`/cosmos/gov/v1beta1/proposals/${pid}`).then(data => {
const ver = compareVersions(this.config.sdk_version, '0.46.5') < 0 ? 'v1beta1' : 'v1'
return this.get(`/cosmos/gov/${ver}/proposals/${pid}`).then(data => {
const p = new Proposal().init(commonProcess(data).proposal, 0) const p = new Proposal().init(commonProcess(data).proposal, 0)
p.versionFixed(this.config.sdk_version) p.versionFixed(this.config.sdk_version)
return p return p
@ -324,7 +333,9 @@ export default class ChainFetch {
return Array.isArray(result) ? result.reverse().map(d => new Deposit().init(d)) : result return Array.isArray(result) ? result.reverse().map(d => new Deposit().init(d)) : result
}) })
} }
return this.get(`/cosmos/gov/v1beta1/proposals/${pid}/deposits`).then(data => {
const ver = compareVersions(this.config.sdk_version, '0.46.5') < 0 ? 'v1beta1' : 'v1'
return this.get(`/cosmos/gov/${ver}/proposals/${pid}/deposits`).then(data => {
const result = commonProcess(data) const result = commonProcess(data)
return Array.isArray(result) ? result.reverse().map(d => new Deposit().init(d)) : result return Array.isArray(result) ? result.reverse().map(d => new Deposit().init(d)) : result
}) })
@ -340,12 +351,15 @@ export default class ChainFetch {
if (this.config.chain_name === 'shentu') { if (this.config.chain_name === 'shentu') {
return this.get(`/shentu/gov/v1alpha1/proposals/${pid}/votes?pagination.key=${encodeURIComponent(next)}&pagination.limit=${limit}&pagination.reverse=true`) return this.get(`/shentu/gov/v1alpha1/proposals/${pid}/votes?pagination.key=${encodeURIComponent(next)}&pagination.limit=${limit}&pagination.reverse=true`)
} }
return this.get(`/cosmos/gov/v1beta1/proposals/${pid}/votes?pagination.key=${encodeURIComponent(next)}&pagination.limit=${limit}&pagination.reverse=true`) const ver = compareVersions(this.config.sdk_version, '0.46.5') < 0 ? 'v1beta1' : 'v1'
return this.get(`/cosmos/gov/${ver}/proposals/${pid}/votes?pagination.key=${encodeURIComponent(next)}&pagination.limit=${limit}&pagination.reverse=true`)
} }
async getGovernanceListByStatus(status, chain = null) { async getGovernanceListByStatus(status, chain = null) {
const conf = chain || this.config const conf = chain || this.config
const url = conf.chain_name === 'shentu' ? `/shentu/gov/v1alpha1/proposals?pagination.limit=100&proposal_status=${status}` : `/cosmos/gov/v1beta1/proposals?pagination.limit=100&proposal_status=${status}`
const ver = compareVersions(this.config.sdk_version, '0.46.5') < 0 ? 'v1beta1' : 'v1'
const url = conf.chain_name === 'shentu' ? `/shentu/gov/v1alpha1/proposals?pagination.limit=100&proposal_status=${status}` : `/cosmos/gov/${ver}/proposals?pagination.limit=100&proposal_status=${status}`
return this.get(url, conf).then(data => { return this.get(url, conf).then(data => {
let proposals = commonProcess(data) let proposals = commonProcess(data)
if (Array.isArray(proposals.proposals)) { if (Array.isArray(proposals.proposals)) {
@ -367,9 +381,10 @@ export default class ChainFetch {
} }
async getGovernanceProposalVote(pid, voter, chain) { async getGovernanceProposalVote(pid, voter, chain) {
const ver = compareVersions(this.config.sdk_version, '0.46.5') < 0 ? 'v1beta1' : 'v1'
const url = this.config.chain_name === 'shentu' const url = this.config.chain_name === 'shentu'
? `/shentu/gov/v1alpha1/proposals/${pid}/votes/${voter}` ? `/shentu/gov/v1alpha1/proposals/${pid}/votes/${voter}`
: `/cosmos/gov/v1beta1/proposals/${pid}/votes/${voter}` : `/cosmos/gov/${ver}/proposals/${pid}/votes/${voter}`
return this.get(url, chain).then(data => { return this.get(url, chain).then(data => {
if (data.code === 3) { if (data.code === 3) {
throw new Error('not found') throw new Error('not found')
@ -385,9 +400,10 @@ export default class ChainFetch {
async getGovernanceList(next = '', chain = null) { async getGovernanceList(next = '', chain = null) {
const key = next || '' const key = next || ''
const ver = compareVersions(this.config.sdk_version, '0.46.5') < 0 ? 'v1beta1' : 'v1'
const url = this.config.chain_name === 'shentu' const url = this.config.chain_name === 'shentu'
? `/shentu/gov/v1alpha1/proposals?pagination.limit=20&pagination.reverse=true&pagination.key=${key}` ? `/shentu/gov/v1alpha1/proposals?pagination.limit=20&pagination.reverse=true&pagination.key=${key}`
: `/cosmos/gov/v1beta1/proposals?pagination.limit=20&pagination.reverse=true&pagination.key=${key}` : `/cosmos/gov/${ver}/proposals?pagination.limit=20&pagination.reverse=true&pagination.key=${key}`
return this.get(url, chain).then(data => { return this.get(url, chain).then(data => {
let proposals = commonProcess(data) let proposals = commonProcess(data)
if (Array.isArray(proposals.proposals)) { if (Array.isArray(proposals.proposals)) {
@ -421,22 +437,22 @@ export default class ChainFetch {
async getStakingReward(address, config = null) { async getStakingReward(address, config = null) {
if (compareVersions(config ? config.sdk_version : this.config.sdk_version, '0.40') < 0) { if (compareVersions(config ? config.sdk_version : this.config.sdk_version, '0.40') < 0) {
return this.get(`/distribution/delegators/${address}/rewards`, config).then(data => commonProcess(data)) return this.get(`/distribution/delegators/${address}/rewards`, config, true).then(data => commonProcess(data))
} }
return this.get(`/cosmos/distribution/v1beta1/delegators/${address}/rewards`, config).then(data => commonProcess(data)) return this.get(`/cosmos/distribution/v1beta1/delegators/${address}/rewards`, config, true).then(data => commonProcess(data))
} }
async getValidatorSlashs(address, config = null) { async getValidatorSlashs(address, config = null) {
return this.get(`/cosmos/distribution/v1beta1/validators/${address}/slashes`, config).then(data => commonProcess(data)) return this.get(`/cosmos/distribution/v1beta1/validators/${address}/slashes`, config, true).then(data => commonProcess(data))
} }
async getStakingValidators(address) { async getStakingValidators(address) {
return this.get(`/cosmos/distribution/v1beta1/delegators/${address}/validators?pagination.size=200`).then(data => commonProcess(data.validators)) return this.get(`/cosmos/distribution/v1beta1/delegators/${address}/validators?pagination.size=200`, null, true).then(data => commonProcess(data.validators))
} }
async getStakingDelegations(address, config = null) { async getStakingDelegations(address, config = null) {
if (compareVersions(config ? config.sdk_version : this.config.sdk_version, '0.40') < 0) { if (compareVersions(config ? config.sdk_version : this.config.sdk_version, '0.40') < 0) {
return this.get(`/staking/delegators/${address}/delegations`, config).then(data => commonProcess(data).map(x => { return this.get(`/staking/delegators/${address}/delegations`, config, true).then(data => commonProcess(data).map(x => {
const xh = x const xh = x
if (!xh.delegation) { if (!xh.delegation) {
xh.delegation = { xh.delegation = {
@ -447,21 +463,21 @@ export default class ChainFetch {
return xh return xh
})) }))
} }
return this.get(`/cosmos/staking/v1beta1/delegations/${address}`, config).then(data => commonProcess(data)) return this.get(`/cosmos/staking/v1beta1/delegations/${address}`, config, true).then(data => commonProcess(data))
} }
async getStakingRedelegations(address, config = null) { async getStakingRedelegations(address, config = null) {
if (compareVersions(config ? config.sdk_version : this.config.sdk_version, '0.40') < 0) { if (compareVersions(config ? config.sdk_version : this.config.sdk_version, '0.40') < 0) {
return this.get(`/staking/redelegations?delegator=${address}`, config).then(data => commonProcess(data)) return this.get(`/staking/redelegations?delegator=${address}`, config, true).then(data => commonProcess(data))
} }
return this.get(`/cosmos/staking/v1beta1/delegators/${address}/redelegations`, config).then(data => commonProcess(data)) return this.get(`/cosmos/staking/v1beta1/delegators/${address}/redelegations`, config, true).then(data => commonProcess(data))
} }
async getStakingUnbonding(address, config = null) { async getStakingUnbonding(address, config = null) {
if (compareVersions(config ? config.sdk_version : this.config.sdk_version, '0.40') < 0) { if (compareVersions(config ? config.sdk_version : this.config.sdk_version, '0.40') < 0) {
return this.get(`/staking/delegators/${address}/unbonding_delegations`, config).then(data => commonProcess(data)) return this.get(`/staking/delegators/${address}/unbonding_delegations`, config, true).then(data => commonProcess(data))
} }
return this.get(`/cosmos/staking/v1beta1/delegators/${address}/unbonding_delegations`, config).then(data => commonProcess(data)) return this.get(`/cosmos/staking/v1beta1/delegators/${address}/unbonding_delegations`, config, true).then(data => commonProcess(data))
} }
async getBankBalances(address, config = null) { async getBankBalances(address, config = null) {
@ -469,7 +485,7 @@ export default class ChainFetch {
} }
async getCommunityPool(config = null) { async getCommunityPool(config = null) {
return this.get('/cosmos/distribution/v1beta1/community_pool', config).then(data => commonProcess(data)) return this.get('/cosmos/distribution/v1beta1/community_pool', config, true).then(data => commonProcess(data))
} }
async getAllIBCDenoms(config = null) { async getAllIBCDenoms(config = null) {

View File

@ -333,6 +333,7 @@
<!-- size --> <!-- size -->
<b-button-group <b-button-group
size="sm" size="sm"
class="d-none"
> >
<b-button <b-button
v-b-modal.operation-modal v-b-modal.operation-modal
@ -362,18 +363,41 @@
<feather-icon icon="LogOutIcon" /> <feather-icon icon="LogOutIcon" />
</b-button> </b-button>
</b-button-group> </b-button-group>
<b-dropdown
v-b-modal.operation-modal
split
variant="outline-primary"
text="Delegate"
class="mr-1"
size="sm"
@click="selectDelegation(data,'Delegate')"
>
<template #button-content>
Delegate
</template>
<b-dropdown-item
v-b-modal.operation-modal
@click="selectDelegation(data,'Redelegate')"
>
Redelegate
</b-dropdown-item>
<b-dropdown-item
v-b-modal.operation-modal
@click="selectDelegation(data,'Unbond')"
>
Unbond
</b-dropdown-item>
</b-dropdown>
<b-button
v-b-modal.operation-modal
variant="outline-primary"
size="sm"
@click="selectWithdraw()"
>
Widthdraw Rewards
</b-button>
</template> </template>
</b-table> </b-table>
<b-card-footer class="text-right">
<b-button
v-b-modal.operation-modal
variant="outline-primary"
@click="selectWithdraw()"
>
<feather-icon icon="AwardIcon" />
Widthdraw Rewards
</b-button>
</b-card-footer>
</b-card> </b-card>
</b-col> </b-col>
</b-row> </b-row>
@ -459,6 +483,7 @@
:proposal-id="selectedProposalId" :proposal-id="selectedProposalId"
:proposal-title="selectedTitle" :proposal-title="selectedTitle"
/> />
<div id="txevent" />
</div> </div>
</template> </template>
@ -466,6 +491,7 @@
import { import {
BRow, BCol, BAlert, BCard, BTable, BFormCheckbox, BCardHeader, BCardTitle, BMedia, BMediaAside, BMediaBody, BAvatar, BRow, BCol, BAlert, BCard, BTable, BFormCheckbox, BCardHeader, BCardTitle, BMedia, BMediaAside, BMediaBody, BAvatar,
BCardBody, BLink, BButtonGroup, BButton, BTooltip, VBModal, VBTooltip, BCardFooter, BProgress, BProgressBar, BBadge, BCardBody, BLink, BButtonGroup, BButton, BTooltip, VBModal, VBTooltip, BCardFooter, BProgress, BProgressBar, BBadge,
BDropdown, BDropdownItem,
} from 'bootstrap-vue' } from 'bootstrap-vue'
import { import {
formatNumber, formatTokenAmount, isToken, percent, timeIn, toDay, toDuration, tokenFormatter, getLocalAccounts, formatNumber, formatTokenAmount, isToken, percent, timeIn, toDay, toDuration, tokenFormatter, getLocalAccounts,
@ -487,6 +513,8 @@ export default {
BButtonGroup, BButtonGroup,
BTooltip, BTooltip,
BButton, BButton,
BDropdown,
BDropdownItem,
BRow, BRow,
BCol, BCol,
BAlert, BAlert,
@ -646,6 +674,22 @@ export default {
}) })
} }
}, },
mounted() {
const elem = document.getElementById('txevent')
elem.addEventListener('txcompleted', () => {
const key = this.$store?.state?.chains?.defaultWallet
if (key) {
const accounts = getLocalAccounts() || {}
const account = Object.entries(accounts)
.map(v => ({ wallet: v[0], address: v[1].address.find(x => x.chain === this.$store.state.chains.selected.chain_name) }))
.filter(v => v.address)
.find(x => x.wallet === key)
if (account) {
this.fetchAccount(account.address.addr)
}
}
})
},
methods: { methods: {
caculateTallyResult(tally) { caculateTallyResult(tally) {
if (this.tallyParam && tally && this.totalPower > 0) { if (this.tallyParam && tally && this.totalPower > 0) {
@ -699,8 +743,6 @@ export default {
return '-' return '-'
}, },
fetchAccount(address) { fetchAccount(address) {
const conf = this.$http.getSelectedConfig()
const decimal = conf.assets[0].exponent || '6'
this.address = address this.address = address
this.$http.getBankAccountBalance(address).then(bal => { this.$http.getBankAccountBalance(address).then(bal => {
this.walletBalances = this.formatToken(bal) this.walletBalances = this.formatToken(bal)

View File

@ -12,7 +12,7 @@
variant="light-info" variant="light-info"
class="text-right" class="text-right"
> >
{{$t('governance-proposal.proposal_status_deposit')}} Deposit
</b-badge> </b-badge>
<b-badge <b-badge
v-if="proposal.status == 2" v-if="proposal.status == 2"
@ -20,7 +20,7 @@
variant="light-primary" variant="light-primary"
class="text-right" class="text-right"
> >
{{$t('governance-proposal.proposal_status_voting')}} Voting
</b-badge> </b-badge>
<b-badge <b-badge
v-if="proposal.status == 3" v-if="proposal.status == 3"
@ -28,7 +28,7 @@
variant="light-success" variant="light-success"
class="text-right" class="text-right"
> >
{{$t('governance-proposal.proposal_status_passed')}} Passed
</b-badge> </b-badge>
<b-badge <b-badge
v-if="proposal.status == 4" v-if="proposal.status == 4"
@ -36,12 +36,17 @@
variant="light-danger" variant="light-danger"
class="text-right" class="text-right"
> >
{{$t('governance-proposal.proposal_status_rejected')}} Rejected
</b-badge> </b-badge>
{{ proposal.title }} {{ proposal.title }}
</b-card-title> </b-card-title>
</b-card-header> </b-card-header>
<b-card-body> <b-card-body>
<div>
<object-field-component
:tablefield="proposal.contents"
:small="false"
/></div>
<b-table-simple <b-table-simple
stacked="sm" stacked="sm"
hover hover
@ -50,38 +55,46 @@
<tbody> <tbody>
<b-tr> <b-tr>
<b-td style="text-transform: capitalize; vertical-align: top; width:200px"> <b-td style="text-transform: capitalize; vertical-align: top; width:200px">
{{ $t('governance-proposal.proposal_proposer') }} {{ $t('proposal_total_deposit') }}
</b-td><b-td><router-link :to="`../account/${proposer.proposer}`">
{{ formatAddress(proposer.proposer) }}
</router-link> </b-td>
</b-tr>
<b-tr>
<b-td>
{{ $t('governance-proposal.proposal_total_deposit') }}
</b-td><b-td>{{ formatToken(proposal.total_deposit) }} </b-td> </b-td><b-td>{{ formatToken(proposal.total_deposit) }} </b-td>
</b-tr> </b-tr>
<b-tr> <b-tr>
<b-td> <b-td>
{{ $t('governance-proposal.proposal_submit_time') }} {{ $t('proposal_submit_time') }}
</b-td><b-td>{{ formatDate(proposal.submit_time) }}</b-td> </b-td><b-td>{{ formatDate(proposal.submit_time) }}</b-td>
</b-tr> </b-tr>
<b-tr> <b-tr>
<b-td> <b-td>
{{ $t('governance-proposal.voting_time') }} {{ $t('voting_time') }}
</b-td><b-td>{{ formatDate(proposal.voting_start_time) }} - {{ formatDate(proposal.voting_end_time) }}</b-td> </b-td><b-td>{{ formatDate(proposal.voting_start_time) }} - {{ formatDate(proposal.voting_end_time) }}</b-td>
</b-tr> </b-tr>
<b-tr v-if="proposal.metadata">
<b-td>
Metadata
</b-td><b-td>{{ proposal.metadata }}</b-td>
</b-tr>
</tbody> </tbody>
</b-table-simple> </b-table-simple>
<div>
<object-field-component
:tablefield="proposal.contents"
:small="false"
/></div>
<b-table-simple v-if="proposal.type.indexOf('SoftwareUpgrade') > 0"> <b-table-simple v-if="proposal.type.indexOf('SoftwareUpgrade') > 0">
<b-tr> <b-tr>
<b-td class="text-center"> <b-td class="text-center">
{{ $t('governance-proposal.upgrade_time') }} {{ upgradeTime }} {{ $t('upgrade_time') }} {{ upgradeTime }}
<flip-countdown :deadline="upgradeTime" /> <flip-countdown :deadline="upgradeTime" />
<b-input-group prepend="Estimated by block time: ">
<b-form-select v-model="blocktime">
<b-form-select-option value="7">
7s
</b-form-select-option>
<b-form-select-option value="6">
6s
</b-form-select-option>
<b-form-select-option value="2">
2s
</b-form-select-option>
<b-form-select-option value="1">
1s
</b-form-select-option>
</b-form-select></b-input-group>
</b-td> </b-td>
</b-tr> </b-tr>
</b-table-simple> </b-table-simple>
@ -91,7 +104,7 @@
<b-button <b-button
variant="outline-primary" variant="outline-primary"
> >
{{ $t('governance-proposal.btn_back_list') }} {{ $t('btn_back_list') }}
</b-button> </b-button>
</router-link> </router-link>
<b-button <b-button
@ -101,14 +114,14 @@
class="btn float-right mg-2" class="btn float-right mg-2"
@click="openModal('Vote')" @click="openModal('Vote')"
> >
{{ $t('governance-proposal.btn_vote') }} {{ $t('btn_vote') }}
</b-button> </b-button>
</b-card-footer> </b-card-footer>
</b-card> </b-card>
<b-card no-body> <b-card no-body>
<b-card-header> <b-card-header>
<b-card-title> <b-card-title>
{{ $t('governance-proposal.proposal_votes') }} Votes
</b-card-title> </b-card-title>
</b-card-header> </b-card-header>
<b-card-body> <b-card-body>
@ -153,22 +166,22 @@
<b-tooltip <b-tooltip
:target="'vote-yes'+proposal.id" :target="'vote-yes'+proposal.id"
> >
{{ percent(proposal.tally.yes) }}% {{ $t('governance-proposal.proposal_votes_yes') }} {{ percent(proposal.tally.yes) }}% voted Yes
</b-tooltip> </b-tooltip>
<b-tooltip <b-tooltip
:target="'vote-no'+proposal.id" :target="'vote-no'+proposal.id"
> >
{{ percent(proposal.tally.no) }}% {{ $t('governance-proposal.proposal_votes_no') }} {{ percent(proposal.tally.no) }}% voted No
</b-tooltip> </b-tooltip>
<b-tooltip <b-tooltip
:target="'vote-veto'+proposal.id" :target="'vote-veto'+proposal.id"
> >
{{ percent(proposal.tally.veto) }}% {{ $t('governance-proposal.proposal_votes_nwv') }} {{ percent(proposal.tally.veto) }}% voted No With Veto
</b-tooltip> </b-tooltip>
<b-tooltip <b-tooltip
:target="'vote-abstain'+proposal.id" :target="'vote-abstain'+proposal.id"
> >
{{ percent(proposal.tally.abstain) }}% {{ $t('governance-proposal.proposal_votes_abstain') }} {{ percent(proposal.tally.abstain) }}% voted Abstain
</b-tooltip> </b-tooltip>
<div <div
@ -198,7 +211,7 @@
@click="loadVotes()" @click="loadVotes()"
> >
<feather-icon icon="PlusIcon" /> <feather-icon icon="PlusIcon" />
{{ $t('governance-proposal.proposal_votes_load') }} Load More Votes
</div> </div>
</div></b-card-body> </div></b-card-body>
</b-card> </b-card>
@ -208,7 +221,7 @@
> >
<b-card-header> <b-card-header>
<b-card-title> <b-card-title>
{{ $t('governance-proposal.proposal_deposits') }} ({{ formatToken(proposal.total_deposit) }}) Deposits ({{ formatToken(proposal.total_deposit) }})
</b-card-title> </b-card-title>
</b-card-header> </b-card-header>
<b-card-body> <b-card-body>
@ -231,7 +244,7 @@
<b-button <b-button
variant="outline-primary" variant="outline-primary"
> >
{{ $t('governance-proposal.btn_back_list') }} {{ $t('btn_back_list') }}
</b-button> </b-button>
</router-link> </router-link>
<b-button <b-button
@ -241,7 +254,7 @@
class="btn float-right mg-2" class="btn float-right mg-2"
@click="openModal('GovDeposit')" @click="openModal('GovDeposit')"
> >
{{ $t('governance-proposal.btn_deposit') }} {{ $t('btn_deposit') }}
</b-button> </b-button>
<b-button <b-button
v-b-modal.operation-modal v-b-modal.operation-modal
@ -250,7 +263,7 @@
class="btn float-right mg-2 mr-1" class="btn float-right mg-2 mr-1"
@click="openModal('Vote')" @click="openModal('Vote')"
> >
{{ $t('governance-proposal.btn_vote') }} {{ $t('btn_vote') }}
</b-button> </b-button>
</b-card-footer> </b-card-footer>
</b-card> </b-card>
@ -265,7 +278,7 @@
<script> <script>
import { import {
BCard, BCardBody, BCardFooter, BButton, BTable, BTableSimple, BTr, BTd, BCardTitle, BCardHeader, BCard, BCardBody, BCardFooter, BButton, BTable, BTableSimple, BTr, BTd, BCardTitle, BCardHeader,
BProgressBar, BProgress, BTooltip, BBadge, BProgressBar, BProgress, BTooltip, BBadge, BFormSelect, BFormSelectOption, BInputGroup, BInputGroupPrepend,
} from 'bootstrap-vue' } from 'bootstrap-vue'
import FlipCountdown from 'vue2-flip-countdown' import FlipCountdown from 'vue2-flip-countdown'
// import fetch from 'node-fetch' // import fetch from 'node-fetch'
@ -296,12 +309,17 @@ export default {
BProgress, BProgress,
BTooltip, BTooltip,
BBadge, BBadge,
BFormSelect,
BFormSelectOption,
BInputGroup,
BInputGroupPrepend,
ObjectFieldComponent, ObjectFieldComponent,
FlipCountdown, FlipCountdown,
OperationModal, OperationModal,
}, },
data() { data() {
return { return {
blocktime: 6,
tallyParam: null, tallyParam: null,
latest: {}, latest: {},
next: null, next: null,
@ -360,7 +378,7 @@ export default {
if (Number(this.proposal?.contents.plan.height || 0) > 0 && this.latest?.block) { if (Number(this.proposal?.contents.plan.height || 0) > 0 && this.latest?.block) {
const blocks = Number(this.proposal.contents.plan.height) - Number(this.latest.block?.header?.height || 0) const blocks = Number(this.proposal.contents.plan.height) - Number(this.latest.block?.header?.height || 0)
if (blocks > 0) { if (blocks > 0) {
const endtime = dayjs().add(blocks * 6, 'second').format('YYYY-MM-DD HH:mm:ss') const endtime = dayjs().add(blocks * this.blocktime, 'second').format('YYYY-MM-DD HH:mm:ss')
return endtime return endtime
} }
} }
@ -395,10 +413,9 @@ export default {
if (!getCachedValidators()) { if (!getCachedValidators()) {
this.$http.getValidatorList() this.$http.getValidatorList()
} }
// this.$http.getGovernanceProposer(pid).then(res => {
this.$http.getGovernanceProposer(pid).then(res => { // this.proposer = res
this.proposer = res // })
})
this.$http.getGovernanceDeposits(pid).then(res => { this.$http.getGovernanceDeposits(pid).then(res => {
this.deposits = res this.deposits = res
}).catch(() => {}) }).catch(() => {})

View File

@ -277,25 +277,20 @@ export default {
}) })
return Object.values(valCounter).sort((a, b) => b.counter - a.counter) return Object.values(valCounter).sort((a, b) => b.counter - a.counter)
}, },
h() {
return this.height
},
}, },
created() { created() {
const cached = JSON.parse(getCachedValidators(this.$route.params.chain)) const cached = JSON.parse(getCachedValidators(this.$route.params.chain))
if (cached) { if (cached) {
this.validators = cached this.validators = cached
} }
this.fetchMissingInfo()
this.$http.getValidatorList().then(res => { this.$http.getValidatorList().then(res => {
this.validators = res this.validators = res
}) })
this.$http.getSlashingSigningInfo().then(res => {
if (res.info) {
res.info.forEach(x => {
if (x.address) {
const hex = toBase64(fromBech32(x.address).data)
this.missing[hex] = x
}
})
}
})
this.initBlocks() this.initBlocks()
}, },
beforeDestroy() { beforeDestroy() {
@ -304,6 +299,18 @@ export default {
clearInterval(this.timer) clearInterval(this.timer)
}, },
methods: { methods: {
fetchMissingInfo() {
this.$http.getSlashingSigningInfo().then(res => {
if (res.info) {
res.info.forEach(x => {
if (x.address) {
const hex = toBase64(fromBech32(x.address).data)
this.missing[hex] = x
}
})
}
})
},
pinValidator() { pinValidator() {
localStorage.setItem('pinned', this.pinned) localStorage.setItem('pinned', this.pinned)
}, },
@ -319,13 +326,15 @@ export default {
const blocks = [] const blocks = []
// update height // update height
let promise = Promise.resolve() let promise = Promise.resolve()
for (let i = height - 1; i > height - 50; i -= 1) { for (let i = height - 1; i > height - 48; i -= 1) {
blocks.unshift({ sigs: {}, height: i > 0 ? i : 0 }) blocks.unshift({ sigs: {}, height: i > 0 ? i : 0 })
if (i > height - 48 && i > 0) { promise = promise.then(() => new Promise(resolve => {
promise = promise.then(() => new Promise(resolve => { if (i > this.blocks[0].height && i > 0) { // filter useless loading
this.fetch_status(i, resolve) this.fetch_status(i, resolve)
})) } else {
} resolve()
}
}))
} }
const sigs = this.initColor() const sigs = this.initColor()
@ -386,7 +395,10 @@ export default {
res.block.last_commit.signatures.forEach(x => { res.block.last_commit.signatures.forEach(x => {
if (x.validator_address) sigs[x.validator_address] = 'bg-success' if (x.validator_address) sigs[x.validator_address] = 'bg-success'
}) })
this.height = res.block.header.height this.height = Number(res.block.header.height)
if (this.height % 100 === 0) { // update the missing number each 100
this.fetchMissingInfo()
}
const block = this.blocks.find(b => b.height === res.block.last_commit.height) const block = this.blocks.find(b => b.height === res.block.last_commit.height)
if (typeof block === 'undefined') { // mei if (typeof block === 'undefined') { // mei
// this.$set(block, 0, typeof sigs !== 'undefined') // this.$set(block, 0, typeof sigs !== 'undefined')

View File

@ -197,6 +197,15 @@
:items="deleTable" :items="deleTable"
stacked="sm" stacked="sm"
> >
<template #cell(validator)="data">
<span>
<router-link
:to="`../staking/${data.value.address}`"
>
{{ data.value.moniker }}
</router-link>
</span>
</template>
<template #cell(action)="data"> <template #cell(action)="data">
<!-- size --> <!-- size -->
<b-button-group <b-button-group
@ -627,7 +636,10 @@ export default {
this.delegations.forEach(e => { this.delegations.forEach(e => {
const reward = this.reward.rewards.find(r => r.validator_address === e.delegation.validator_address) const reward = this.reward.rewards.find(r => r.validator_address === e.delegation.validator_address)
re.push({ re.push({
validator: getStakingValidatorOperator(this.$http.config.chain_name, e.delegation.validator_address, 8), validator: {
moniker: getStakingValidatorOperator(this.$http.config.chain_name, e.delegation.validator_address, 8),
address: e.delegation.validator_address,
},
token: formatToken(e.balance, {}, decimal), token: formatToken(e.balance, {}, decimal),
reward: tokenFormatter(reward.reward, this.denoms), reward: tokenFormatter(reward.reward, this.denoms),
action: e.delegation.validator_address, action: e.delegation.validator_address,