finish tx detail
This commit is contained in:
parent
8e3c9eea0c
commit
70351f3833
@ -1,31 +1,26 @@
|
||||
<script lang="ts" setup>
|
||||
import { useFormatter } from '@/stores';
|
||||
import type { Tally } from '@/types';
|
||||
import { computed } from '@vue/reactivity';
|
||||
import { ref, type PropType } from 'vue';
|
||||
|
||||
|
||||
const props = defineProps({
|
||||
tally: { type: Object as PropType<{
|
||||
yes: string,
|
||||
no: string,
|
||||
noWithVeto: string,
|
||||
abstain: string
|
||||
}>},
|
||||
tally: { type: Object as PropType<Tally>},
|
||||
pool: {
|
||||
type: Object as PropType<{
|
||||
notBondedTokens: string;
|
||||
bondedTokens: string;
|
||||
not_bonded_tokens: string;
|
||||
bonded_tokens: string;
|
||||
}>,
|
||||
},
|
||||
})
|
||||
const total = computed(() => props.pool?.bonded_tokens)
|
||||
const format = useFormatter()
|
||||
const yes = computed(() => (format.calculatePercent(props.tally?.yes, props.pool?.bondedTokens)))
|
||||
const no = computed(() => ref(format.calculatePercent(props.tally?.no, props.pool?.bondedTokens)))
|
||||
const abstain = computed(() => (format.calculatePercent(props.tally?.abstain, props.pool?.bondedTokens)))
|
||||
const veto = computed(() => (format.calculatePercent(props.tally?.noWithVeto, props.pool?.bondedTokens)))
|
||||
const yes = computed(() => (format.calculatePercent(props.tally?.yes, total.value)))
|
||||
const no = computed(() => ref(format.calculatePercent(props.tally?.no, total.value)))
|
||||
const abstain = computed(() => (format.calculatePercent(props.tally?.abstain, total.value)))
|
||||
const veto = computed(() => (format.calculatePercent(props.tally?.no_with_veto, total.value)))
|
||||
|
||||
|
||||
console.log(yes.value, no.value, abstain.value, veto.value)
|
||||
</script>
|
||||
<template>
|
||||
<div class="progress">
|
||||
|
@ -2,50 +2,33 @@
|
||||
import VueApexCharts from 'vue3-apexcharts'
|
||||
import { useTheme } from 'vuetify'
|
||||
import { hexToRgb } from '@/plugins/vuetify/@layouts/utils'
|
||||
import type { PropType } from 'vue';
|
||||
import { computed, type PropType } from 'vue';
|
||||
import { useFormatter } from '@/stores';
|
||||
import type { CommissionRate } from '@/types'
|
||||
|
||||
const props = defineProps({
|
||||
commission: { type: Object as PropType<{
|
||||
commissionRates: {
|
||||
rate: string,
|
||||
maxRate: string,
|
||||
maxChangeRate: string,
|
||||
},
|
||||
updateTime: string,
|
||||
}>},
|
||||
commission: { type: Object as PropType<CommissionRate>},
|
||||
})
|
||||
console.log('commission:', props)
|
||||
|
||||
const zeros = Math.pow(10, 16)
|
||||
let rate = Number(props.commission?.commissionRates.rate || 0)
|
||||
let change = Number(props.commission?.commissionRates.maxChangeRate || 10)
|
||||
let max = Number(props.commission?.commissionRates.maxRate || 100)
|
||||
let rate = computed(() => Number(props.commission?.commission_rates.rate || 0) * 100)
|
||||
let change = computed(() => Number(props.commission?.commission_rates.max_change_rate || 0) * 100)
|
||||
let max = computed(() => Number(props.commission?.commission_rates.max_rate || 1) * 100)
|
||||
|
||||
if(rate > 100) {
|
||||
rate = rate / zeros
|
||||
}
|
||||
if(change > 100) {
|
||||
change = change / zeros
|
||||
}
|
||||
if(max > 100) {
|
||||
max = max / zeros
|
||||
}
|
||||
|
||||
// const rate = 15 // props.commision?.commissionRates.rate
|
||||
// const change = 15
|
||||
// const max = 20
|
||||
|
||||
const left = rate
|
||||
const right = max - rate
|
||||
const right = computed(() => max.value - rate.value)
|
||||
|
||||
const s1 = left > change ? left - change : 0
|
||||
const s2 = left > change ? change: left
|
||||
const s1 = computed(() => left.value > change.value ? left.value - change.value : 0 )
|
||||
const s2 = computed(() => left.value > change.value ? change.value: left.value)
|
||||
const s3 = 2
|
||||
const s4 = right > change? change: right
|
||||
const s5 = right > change? right - change: 0
|
||||
const s4 = computed(() => right.value > change.value? change.value: right.value)
|
||||
const s5 = computed(() => right.value > change.value? right.value - change.value: 0)
|
||||
|
||||
const series = [s1, s2, s3, s4, s5]
|
||||
const series = computed(() => [s1.value, s2.value, s3, s4.value, s5.value])
|
||||
|
||||
const vuetifyTheme = useTheme()
|
||||
const format = useFormatter()
|
||||
@ -99,7 +82,7 @@ const chartConfig = computed(() => {
|
||||
offsetY: -15,
|
||||
fontWeight: 500,
|
||||
fontSize: '2.125rem',
|
||||
formatter: (value: unknown) => `${rate}%`,
|
||||
formatter: (value: unknown) => `${rate.value}%`,
|
||||
color: primaryText,
|
||||
},
|
||||
total: {
|
||||
@ -107,7 +90,7 @@ const chartConfig = computed(() => {
|
||||
label: 'Commission Rate',
|
||||
fontSize: '1rem',
|
||||
color: secondaryText,
|
||||
formatter: ( ) => `${rate}%`,
|
||||
formatter: ( ) => `${rate.value}%`,
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -127,7 +110,7 @@ const chartConfig = computed(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard title="Commission Rate" :subtitle="`Updated at ${format.toDay(props.commision?.updateTime, 'short')}`">
|
||||
<VCard title="Commission Rate" :subtitle="`Updated at ${format.toDay(props.commission?.update_time, 'short')}`">
|
||||
<VCardText>
|
||||
<VueApexCharts
|
||||
type="donut"
|
||||
|
@ -5,11 +5,11 @@ import { computed } from '@vue/reactivity';
|
||||
import { hashTx } from '@/libs'
|
||||
import { useBlockchain, useFormatter } from '@/stores';
|
||||
const props = defineProps({
|
||||
value: { type: Array<Uint8Array>},
|
||||
value: { type: Array<string>},
|
||||
});
|
||||
|
||||
const txs = computed(() => {
|
||||
return props.value?.map(x => ({ hash: hashTx(x) , tx: decodeTxRaw(x) })) || []
|
||||
return props.value?.map(x => ({ hash: hashTx(fromBase64(x)) , tx: decodeTxRaw(fromBase64(x)) })) || []
|
||||
})
|
||||
|
||||
const format = useFormatter()
|
||||
@ -26,7 +26,7 @@ const chain = useBlockchain()
|
||||
<tbody>
|
||||
<tr v-for="item in txs">
|
||||
<td><RouterLink :to="`/${chain.chainName}/tx/${item.hash}`">{{ item.hash }}</RouterLink></td>
|
||||
<td>{{ format.messages(item.tx.body.messages) }}</td>
|
||||
<td>{{ format.messages(item.tx.body.messages.map(x => ({"@type": x.typeUrl}))) }}</td>
|
||||
<td>{{ item.tx.body.memo }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
@ -33,8 +33,8 @@ chainStore.initial()
|
||||
>
|
||||
<VList>
|
||||
<!-- 👉 Rest -->
|
||||
<VListSubheader v-if="chainStore.current?.endpoints?.rpc" title="Rest Endpoint" />
|
||||
<VListItem v-for="i in chainStore.current?.endpoints?.rpc" link @click="chainStore.setRestEndpoint(i)">
|
||||
<VListSubheader v-if="chainStore.current?.endpoints?.rest" title="Rest Endpoint" />
|
||||
<VListItem v-for="i in chainStore.current?.endpoints?.rest" link @click="chainStore.setRestEndpoint(i)">
|
||||
<VListItemTitle>{{ i.provider }} <VIcon v-if="i.address === chainStore.endpoint?.address" icon="mdi-check" color="success" /></VListItemTitle>
|
||||
<VListItemSubtitle>{{ i.address }}</VListItemSubtitle>
|
||||
</VListItem>
|
||||
|
@ -41,11 +41,14 @@ export function consensusPubkeyToHexAddress(consensusPubkey?: {"@type": string,
|
||||
}
|
||||
|
||||
export function pubKeyToValcons(consensusPubkey: {"@type": string, key: string}, prefix: string) {
|
||||
const pubkey = fromBase64(consensusPubkey.key)
|
||||
if(pubkey) {
|
||||
const addressData = sha256(pubkey).slice(0, 20)
|
||||
return toBech32(`${prefix}valcons`, addressData)
|
||||
if(consensusPubkey && consensusPubkey.key) {
|
||||
const pubkey = fromBase64(consensusPubkey.key)
|
||||
if(pubkey) {
|
||||
const addressData = sha256(pubkey).slice(0, 20)
|
||||
return toBech32(`${prefix}valcons`, addressData)
|
||||
}
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
export function toETHAddress(cosmosAddress: string) {
|
||||
|
@ -10,6 +10,7 @@ export const DEFAULT: RequestRegistry = {
|
||||
bank_supply: { url: "/cosmos/bank/v1beta1/supply", adapter },
|
||||
bank_supply_by_denom: { url: "/cosmos/bank/v1beta1/supply/{denom}", adapter },
|
||||
distribution_params: { url: "/cosmos/distribution/v1beta1/params", adapter },
|
||||
distributino_community_pool: {url: "/cosmos/distribution/v1beta1/community_pool", adapter},
|
||||
distribution_validator_commission: { url: "/cosmos/distribution/v1beta1/validators/{validator_address}/commission", adapter },
|
||||
distribution_validator_outstanding_rewards: { url: "/cosmos/distribution/v1beta1/validators/{validator_address}/outstanding_rewards", adapter },
|
||||
distribution_validator_slashes: { url: "/cosmos/distribution/v1beta1/validators/{validator_address}/slashes", adapter },
|
||||
@ -30,7 +31,7 @@ export const DEFAULT: RequestRegistry = {
|
||||
staking_delegator_validators: { url: "/cosmos/staking/v1beta1/delegators/{delegator_addr}/validators", adapter },
|
||||
staking_params: { url: "/cosmos/staking/v1beta1/params", adapter },
|
||||
staking_pool: { url: "/cosmos/staking/v1beta1/pool", adapter },
|
||||
staking_validators: { url: "/cosmos/staking/v1beta1/validators", adapter },
|
||||
staking_validators: { url: "/cosmos/staking/v1beta1/validators?pagination.limit={limit}&status={status}", adapter },
|
||||
staking_validators_address: { url: "/cosmos/staking/v1beta1/validators/{validator_addr}", adapter },
|
||||
staking_validators_delegations: { url: "/cosmos/staking/v1beta1/validators/{validator_addr}/delegations", adapter },
|
||||
staking_validators_delegations_delegator: { url: "/cosmos/staking/v1beta1/validators/{validator_addr}/delegations/{delegator_addr}", adapter },
|
||||
|
@ -5,9 +5,9 @@ import { adapter, type Request, type RequestRegistry } from './registry';
|
||||
export class CosmosRestClient {
|
||||
endpoint: string;
|
||||
registry: RequestRegistry;
|
||||
constructor(endpoint: string) {
|
||||
constructor(endpoint: string, registry?: RequestRegistry) {
|
||||
this.endpoint = endpoint
|
||||
this.registry = DEFAULT
|
||||
this.registry = registry || DEFAULT
|
||||
}
|
||||
async request<T>(request: Request<T>, args: Record<string, any>, query="") {
|
||||
let url = `${this.endpoint}${request.url}${query}`
|
||||
@ -42,6 +42,9 @@ export class CosmosRestClient {
|
||||
// Distribution Module
|
||||
async getDistributionParams() {
|
||||
return this.request(this.registry.distribution_params, {})
|
||||
}
|
||||
async getDistributionCommunityPool() {
|
||||
return this.request(this.registry.distributino_community_pool, {})
|
||||
}
|
||||
async getDistributionValidatorCommission(validator_address: string) {
|
||||
return this.request(this.registry.distribution_validator_commission, {validator_address})
|
||||
@ -69,8 +72,9 @@ export class CosmosRestClient {
|
||||
async getGovParamsTally() {
|
||||
return this.request(this.registry.gov_params_tally, {})
|
||||
}
|
||||
async getGovProposals() {
|
||||
return this.request(this.registry.gov_proposals, {})
|
||||
async getGovProposals(status: string, limit = 100) {
|
||||
const query = "?proposal_status={status}&pagination.limit={limit}&pagination.reverse=true&pagination.key="
|
||||
return this.request(this.registry.gov_proposals, {status, limit}, query)
|
||||
}
|
||||
async getGovProposal(proposal_id: string) {
|
||||
return this.request(this.registry.gov_proposals_proposal_id, {proposal_id})
|
||||
@ -106,8 +110,8 @@ export class CosmosRestClient {
|
||||
async getStakingPool() {
|
||||
return this.request(this.registry.staking_pool, {})
|
||||
}
|
||||
async getStakingValidators() {
|
||||
return this.request(this.registry.staking_validators, {})
|
||||
async getStakingValidators(status: string, limit = 200) {
|
||||
return this.request(this.registry.staking_validators, {status, limit})
|
||||
}
|
||||
async getStakingValidator(validator_addr: string) {
|
||||
return this.request(this.registry.staking_validators_address, {validator_addr})
|
||||
@ -153,4 +157,15 @@ export class CosmosRestClient {
|
||||
return this.request(this.registry.tx_hash, {hash})
|
||||
}
|
||||
|
||||
// mint
|
||||
async getMintParam() {
|
||||
return this.request(this.registry.mint_params, {})
|
||||
}
|
||||
async getMintInflation() {
|
||||
return this.request(this.registry.mint_inflation, {})
|
||||
}
|
||||
async getMintAnnualProvisions() {
|
||||
return this.request(this.registry.mint_annual_provisions, {})
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -29,6 +29,16 @@ export interface RequestRegistry {
|
||||
distribution_validator_commission: Request<{commission?: {commission?: Coin[]}}>;
|
||||
distribution_validator_outstanding_rewards: Request<{rewards?: {rewards?: Coin[]}}>;
|
||||
distribution_validator_slashes: Request<PaginatedSlashes>;
|
||||
distributino_community_pool: Request<{pool: Coin[]}>;
|
||||
|
||||
mint_inflation: Request<{inflation: string}>;
|
||||
mint_params: Request<{
|
||||
params: {
|
||||
mint_denom: string,
|
||||
blocks_per_year: string
|
||||
}
|
||||
}>;
|
||||
mint_annual_provisions: Request<{annual_provisions: string}>
|
||||
|
||||
slashing_params: Request<any>;
|
||||
slashing_signing_info: Request<PaginatedSigningInfo>;
|
||||
@ -39,7 +49,7 @@ export interface RequestRegistry {
|
||||
gov_proposals: Request<PaginatedProposals>;
|
||||
gov_proposals_proposal_id: Request<{proposal: GovProposal}>;
|
||||
gov_proposals_deposits: Request<PaginatedProposalDeposit>;
|
||||
gov_proposals_tally: Request<Tally>;
|
||||
gov_proposals_tally: Request<{tally: Tally}>;
|
||||
gov_proposals_votes: Request<PaginatedProposalVotes>;
|
||||
gov_proposals_votes_voter: Request<{vote: GovVote}>;
|
||||
|
||||
|
@ -16,7 +16,7 @@ const height = computed(() => {
|
||||
|
||||
onBeforeRouteUpdate(async (to, from, next) => {
|
||||
if (from.path !== to.path) {
|
||||
store.fetchBlock(Number(to.params.height))
|
||||
store.fetchBlock(String(to.params.height))
|
||||
next()
|
||||
}
|
||||
})
|
||||
@ -33,7 +33,7 @@ onBeforeRouteUpdate(async (to, from, next) => {
|
||||
</span>
|
||||
</VCardTitle>
|
||||
<VCardItem class="pt-0">
|
||||
<DynamicComponent :value="store.current.blockId"/>
|
||||
<DynamicComponent :value="store.current.block_id"/>
|
||||
</VCardItem>
|
||||
</VCard>
|
||||
|
||||
@ -51,7 +51,7 @@ onBeforeRouteUpdate(async (to, from, next) => {
|
||||
|
||||
<VCard title="Last Commit" class="mt-5">
|
||||
<VCardItem class="pt-0">
|
||||
<DynamicComponent :value="store.current.block?.lastCommit"/>
|
||||
<DynamicComponent :value="store.current.block?.last_commit"/>
|
||||
</VCardItem>
|
||||
</VCard>
|
||||
</div>
|
||||
|
@ -22,7 +22,7 @@ export const useBlockModule = defineStore('blockModule', {
|
||||
},
|
||||
txsInRecents() {
|
||||
const txs = [] as {hash:string, tx: DecodedTxRaw}[]
|
||||
this.recents.forEach((x:GetLatestBlockResponse) => x.block?.data?.txs.forEach((tx:Uint8Array) => txs.push({
|
||||
this.recents.forEach((x) => x.block?.data?.txs.forEach((tx:Uint8Array) => txs.push({
|
||||
hash: hashTx(tx),
|
||||
tx :decodeTxRaw(tx)
|
||||
})))
|
||||
@ -47,13 +47,13 @@ export const useBlockModule = defineStore('blockModule', {
|
||||
})
|
||||
},
|
||||
async fetchLatest() {
|
||||
this.latest = await this.blockchain.rpc.block()
|
||||
this.latest = await this.blockchain.rpc.getBaseBlockLatest()
|
||||
if(this.recents.length >= 50) this.recents.shift()
|
||||
this.recents.push(this.latest)
|
||||
return this.latest
|
||||
},
|
||||
async fetchBlock(height?: number) {
|
||||
this.current = await this.blockchain.rpc.block(height)
|
||||
async fetchBlock(height: string) {
|
||||
this.current = await this.blockchain.rpc.getBaseBlockAt(height)
|
||||
return this.current
|
||||
},
|
||||
}
|
||||
|
@ -1,14 +1,11 @@
|
||||
<script lang="ts" setup>
|
||||
import TxsElement from '@/components/dynamic/TxsElement.vue';
|
||||
import { useBlockModule } from './block'
|
||||
import DynamicComponent from '@/components/dynamic/DynamicComponent.vue';
|
||||
import { computed } from '@vue/reactivity';
|
||||
import { toBase64, toHex } from '@cosmjs/encoding';
|
||||
import { computed, ref } from '@vue/reactivity';
|
||||
import { useFormatter } from '@/stores';
|
||||
const props = defineProps(["height", "chain"]);
|
||||
|
||||
const store = useBlockModule()
|
||||
store.fetchBlock(props.height)
|
||||
// store.fetchBlock(props.height)
|
||||
const tab = ref('blocks')
|
||||
|
||||
const format = useFormatter()
|
||||
@ -33,8 +30,8 @@ const format = useFormatter()
|
||||
<tbody>
|
||||
<tr v-for="item in store.recents">
|
||||
<td><RouterLink :to="`/${props.chain}/block/${item.block?.header?.height}`">{{ item.block?.header?.height }}</RouterLink></td>
|
||||
<td>{{ toBase64(item.blockId?.hash) }}</td>
|
||||
<td>{{ format.validator(item.block?.header?.proposerAddress) }}</td>
|
||||
<td>{{ item.block_id?.hash }}</td>
|
||||
<td>{{ format.validator(item.block?.header?.proposer_address) }}</td>
|
||||
<td>{{ item.block?.data?.txs.length }}</td>
|
||||
<td>{{ format.toDay(item.block?.header?.time, 'from') }}</td>
|
||||
</tr>
|
||||
|
@ -146,11 +146,11 @@ function shortName(name: string, id: string) {
|
||||
<VExpansionPanels variant="accordion">
|
||||
<VExpansionPanel v-for="(x, i) in store.proposals">
|
||||
<VExpansionPanelTitle disable-icon-rotate>
|
||||
<VChip label color="primary" class="mr-2">{{x.proposalId}}</VChip>
|
||||
<VChip label color="primary" class="mr-2">{{x.proposal_id}}</VChip>
|
||||
<div class="w-100">{{ x.content?.title }}
|
||||
<div class="d-flex mt-1">
|
||||
<small class="text-secondary me-auto"> {{ format.toDay(x.votingEndTime, 'from') }}</small>
|
||||
<ProposalProcess style="width:300px;" :pool="store.pool" :tally="store.tally[Number(x.proposalId)]"></ProposalProcess>
|
||||
<small class="text-secondary me-auto"> {{ format.toDay(x.voting_end_time, 'from') }}</small>
|
||||
<ProposalProcess style="width:300px;" :pool="store.pool" :tally="store.tally[x.proposal_id]"></ProposalProcess>
|
||||
<span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -2,6 +2,7 @@ import { useBlockchain, useCoingecko, useBaseStore, useBankStore, useFormatter,
|
||||
import { useDistributionStore } from "@/stores/useDistributionStore";
|
||||
import { useMintStore } from "@/stores/useMintStore";
|
||||
import { useStakingStore } from "@/stores/useStakingStore";
|
||||
import type { GovProposal, Tally } from "@/types";
|
||||
import numeral from "numeral";
|
||||
import { defineStore } from "pinia";
|
||||
|
||||
@ -64,13 +65,8 @@ export const useIndexModule = defineStore('module-index', {
|
||||
total_volumes: [] as number[],
|
||||
},
|
||||
communityPool: [] as {amount: string, denom: string}[],
|
||||
proposals: [] as Proposal[],
|
||||
tally: {} as Record<number, {
|
||||
yes: string;
|
||||
abstain: string;
|
||||
no: string;
|
||||
noWithVeto: string;
|
||||
}>
|
||||
proposals: [] as GovProposal[],
|
||||
tally: {} as Record<string, Tally>
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
@ -144,7 +140,7 @@ export const useIndexModule = defineStore('module-index', {
|
||||
title: 'Validators',
|
||||
color: 'error',
|
||||
icon: 'mdi-human-queue',
|
||||
stats: String(base.latest.block?.lastCommit?.signatures.length || 0),
|
||||
stats: String(base.latest.block?.last_commit?.signatures.length || 0),
|
||||
change: 0,
|
||||
},
|
||||
{
|
||||
@ -158,7 +154,7 @@ export const useIndexModule = defineStore('module-index', {
|
||||
title: 'Bonded Tokens',
|
||||
color: 'warning',
|
||||
icon: 'mdi-lock',
|
||||
stats: formatter.formatTokenAmount({amount: this.pool.bondedTokens, denom: staking.params.bondDenom }),
|
||||
stats: formatter.formatTokenAmount({amount: this.pool.bonded_tokens, denom: staking.params.bond_denom }),
|
||||
change: 0,
|
||||
},
|
||||
{
|
||||
@ -185,18 +181,18 @@ export const useIndexModule = defineStore('module-index', {
|
||||
this.initCoingecko()
|
||||
useMintStore().fetchInflation()
|
||||
useDistributionStore().fetchCommunityPool().then(x => {
|
||||
this.communityPool = x.pool.filter(t=> t.denom.length < 10).map(t => ({
|
||||
this.communityPool = x.pool.filter(t => t.denom.length < 10).map(t => ({
|
||||
amount: String(parseInt(t.amount)),
|
||||
denom: t.denom
|
||||
}))
|
||||
})
|
||||
const gov = useGovStore()
|
||||
gov.fetchProposals(ProposalStatus.PROPOSAL_STATUS_VOTING_PERIOD).then(x => {
|
||||
gov.fetchProposals(2).then(x => {
|
||||
this.proposals = x.proposals
|
||||
x.proposals.forEach(x1 => {
|
||||
gov.fetchTally(Number(x1.proposalId)).then(t => {
|
||||
gov.fetchTally(x1.proposal_id).then(t => {
|
||||
console.log("log: ", t)
|
||||
if(t.tally) this.tally[Number(x1.proposalId)] = t.tally
|
||||
if(t.tally) this.tally[x1.proposal_id] = t.tally
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -1,11 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
import { useBlockchain, useFormatter, useMintStore, useStakingStore } from '@/stores';
|
||||
import { onMounted } from 'vue';
|
||||
import { onMounted, computed, ref } from 'vue';
|
||||
import ValidatorCommissionRate from '@/components/ValidatorCommissionRate.vue'
|
||||
import { consensusPubkeyToHexAddress, operatorAddressToAccount, pubKeyToValcons, valoperToPrefix } from '@/libs';
|
||||
import { computed } from '@vue/reactivity';
|
||||
import type { Coin } from '@/types';
|
||||
import type { Txs } from '@/types/Txs';
|
||||
import type { Coin, Delegation, PaginatedTxs, Validator } from '@/types';
|
||||
|
||||
const props = defineProps(['validator', 'chain'])
|
||||
|
||||
@ -15,45 +13,44 @@ const format = useFormatter()
|
||||
|
||||
const validator: string = props.validator
|
||||
|
||||
const v = ref({})
|
||||
const v = ref({} as Validator)
|
||||
const cache = JSON.parse(localStorage.getItem('avatars')||'{}')
|
||||
const avatars = ref( cache || {} )
|
||||
const identity = ref("")
|
||||
const rewards = ref([] as Coin[])
|
||||
const rewards = ref([] as Coin[]|undefined)
|
||||
const addresses = ref({} as {
|
||||
account: string
|
||||
operAddress: string
|
||||
hex: string
|
||||
valCons: string,
|
||||
})
|
||||
const selfBonded = ref({} as Coin)
|
||||
const selfBonded = ref({} as Delegation)
|
||||
|
||||
addresses.value.account = operatorAddressToAccount(validator)
|
||||
// load self bond
|
||||
staking.fetchValidatorDelegation(validator, addresses.value.account).then(x => {
|
||||
if(x) {
|
||||
selfBonded.value = x
|
||||
selfBonded.value = x.delegation_response
|
||||
}
|
||||
})
|
||||
|
||||
const txs = ref({} as Txs)
|
||||
const txs = ref({} as PaginatedTxs)
|
||||
|
||||
blockchain.rpc.txs([`message.sender='${addresses.value.account}'`]).then(x => {
|
||||
blockchain.rpc.getTxsBySender(addresses.value.account).then(x => {
|
||||
console.log("txs", x)
|
||||
txs.value = x
|
||||
})
|
||||
|
||||
const apr = computed(()=> {
|
||||
const rate = v.value.commission?.commissionRates.rate || 0
|
||||
const rate = v.value.commission?.commission_rates.rate || 0
|
||||
const inflation = useMintStore().inflation
|
||||
if(Number(inflation)) {
|
||||
return format.percent((1 - rate) * Number(inflation))
|
||||
return format.percent((1 - Number(rate)) * Number(inflation))
|
||||
}
|
||||
return "-"
|
||||
})
|
||||
|
||||
const selfRate = computed(()=> {
|
||||
console.log("self rate", selfBonded.value.balance?.amount, v.value.tokens)
|
||||
if(selfBonded.value.balance?.amount) {
|
||||
return format.calculatePercent(selfBonded.value.balance.amount, v.value.tokens)
|
||||
}
|
||||
@ -62,9 +59,9 @@ const selfRate = computed(()=> {
|
||||
|
||||
onMounted(()=> {
|
||||
if(validator) {
|
||||
staking.fetchValidator(validator.toString()).then(res => {
|
||||
staking.fetchValidator(validator).then(res => {
|
||||
v.value = res.validator
|
||||
identity.value = res.validator?.description?.identity
|
||||
identity.value = res.validator?.description?.identity || ''
|
||||
if(identity.value && !avatars.value[identity.value]) {
|
||||
console.log(identity.value, avatars)
|
||||
staking.keybase(identity.value).then(d => {
|
||||
@ -77,12 +74,11 @@ onMounted(()=> {
|
||||
}
|
||||
})
|
||||
}
|
||||
const prefix = valoperToPrefix(v.value.operatorAddress) || '<Invalid>'
|
||||
addresses.value.hex = consensusPubkeyToHexAddress(v.value.consensusPubkey)
|
||||
addresses.value.valCons = pubKeyToValcons(v.value.consensusPubkey, prefix)
|
||||
const prefix = valoperToPrefix(v.value.operator_address) || '<Invalid>'
|
||||
addresses.value.hex = consensusPubkeyToHexAddress(v.value.consensus_pubkey)
|
||||
addresses.value.valCons = pubKeyToValcons(v.value.consensus_pubkey, prefix)
|
||||
})
|
||||
blockchain.rpc.validatorOutstandingRewards(validator).then(res => {
|
||||
console.log(res)
|
||||
blockchain.rpc.getDistributionValidatorOutstandingRewards(validator).then(res => {
|
||||
rewards.value = res.rewards?.rewards
|
||||
})
|
||||
}
|
||||
@ -114,7 +110,7 @@ onMounted(()=> {
|
||||
<span>Website: </span><span> {{ v.description?.website || '-' }}</span>
|
||||
</VListItem>
|
||||
<VListItem prepend-icon="mdi-phone">
|
||||
<span>Contact: </span><span> {{ v.description?.securityContact }}</span>
|
||||
<span>Contact: </span><span> {{ v.description?.security_contact }}</span>
|
||||
</VListItem>
|
||||
</VList>
|
||||
|
||||
@ -137,7 +133,7 @@ onMounted(()=> {
|
||||
<div class="d-flex">
|
||||
<VAvatar color="secondary" rounded variant="outlined" icon="mdi-coin"></VAvatar>
|
||||
<div class="ml-3 d-flex flex-column justify-center">
|
||||
<h4>{{ format.formatToken2({amount: v.tokens, denom: staking.params.bondDenom}) }}</h4>
|
||||
<h4>{{ format.formatToken2({amount: v.tokens, denom: staking.params.bond_denom}) }}</h4>
|
||||
<span class="text-sm">Bonded Tokens</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -152,7 +148,7 @@ onMounted(()=> {
|
||||
<div class="d-flex">
|
||||
<VAvatar color="secondary" rounded variant="outlined" icon="mdi-flag"></VAvatar>
|
||||
<div class="ml-3 d-flex flex-column justify-center">
|
||||
<h4>{{ v.minSelfDelegation }} {{ staking.params.bondDenom }}</h4>
|
||||
<h4>{{ v.minSelfDelegation }} {{ staking.params.bond_denom }}</h4>
|
||||
<span class="text-sm">Min Self Delegation:</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -167,7 +163,7 @@ onMounted(()=> {
|
||||
<div class="d-flex">
|
||||
<VAvatar color="secondary" rounded variant="outlined" icon="mdi-pound"></VAvatar>
|
||||
<div class="ml-3 d-flex flex-column justify-center">
|
||||
<h4>{{ v.unbondingHeight }}</h4>
|
||||
<h4>{{ v.unbonding_height }}</h4>
|
||||
<span class="text-sm">Unbonding Height</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -175,7 +171,7 @@ onMounted(()=> {
|
||||
<div class="d-flex">
|
||||
<VAvatar color="secondary" rounded variant="outlined" icon="mdi-clock"></VAvatar>
|
||||
<div class="ml-3 d-flex flex-column justify-center">
|
||||
<h4>{{ format.toDay(v.unbondingTime, 'from') }}</h4>
|
||||
<h4>{{ format.toDay(v.unbonding_time, 'from') }}</h4>
|
||||
<span class="text-sm">Unbonding Time</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -209,7 +205,7 @@ onMounted(()=> {
|
||||
</VListItem>
|
||||
<VListItem>
|
||||
<VListItemTitle>Operator Address</VListItemTitle>
|
||||
<VListItemSubtitle class="text-caption">{{ v.operatorAddress }}</VListItemSubtitle>
|
||||
<VListItemSubtitle class="text-caption">{{ v.operator_address }}</VListItemSubtitle>
|
||||
</VListItem>
|
||||
<VListItem>
|
||||
<VListItemTitle>Hex Address</VListItemTitle>
|
||||
@ -233,10 +229,10 @@ onMounted(()=> {
|
||||
<th class="text-left pl-4">Time</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(item, i) in txs.txResponses">
|
||||
<tr v-for="(item, i) in txs.tx_responses">
|
||||
<td>{{ item.height }}</td>
|
||||
<td class="text-truncate" style="max-width: 200px;">{{ item.txhash }}</td>
|
||||
<td>{{ format.messages(txs.txs[i]?.body.messages) }}</td>
|
||||
<td>{{ format.messages(item.tx.body.messages) }}</td>
|
||||
<td width="150">{{ format.toDay(item.timestamp,'from') }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
@ -1,10 +1,10 @@
|
||||
<script lang=ts setup>
|
||||
import { useBaseStore, useFormatter, useStakingStore } from '@/stores';
|
||||
import { toBase64, toHex } from '@cosmjs/encoding';
|
||||
import { pubkeyToAddress } from '@cosmjs/tendermint-rpc';
|
||||
import { computed } from '@vue/reactivity';
|
||||
import { onMounted, ref, type DebuggerEvent } from 'vue';
|
||||
import { consensusPubkeyToHexAddress } from '@/libs'
|
||||
import type { Key, Validator } from '@/types';
|
||||
const staking = useStakingStore()
|
||||
const format = useFormatter()
|
||||
|
||||
@ -13,7 +13,7 @@ const avatars = ref( cache || {} )
|
||||
const latest = ref({} as Record<string, number>)
|
||||
const yesterday = ref({} as Record<string, number>)
|
||||
const tab = ref('active')
|
||||
const unbondList = ref([])
|
||||
const unbondList = ref([] as Validator[])
|
||||
const base = useBaseStore()
|
||||
onMounted(()=> {
|
||||
fetchChange(0)
|
||||
@ -25,39 +25,39 @@ onMounted(()=> {
|
||||
function fetchChange(offset: number) {
|
||||
const base = useBaseStore()
|
||||
const diff = 86400000 / base.blocktime
|
||||
base.fetchAbciInfo().then(h => {
|
||||
// console.log('block:', h)
|
||||
base.fetchValidatorByHeight(h.lastBlockHeight, offset).then(x => {
|
||||
x.validators.forEach(v => {
|
||||
if(v.pubkey) latest.value[pubkeyToAddress(v.pubkey.algorithm, v.pubkey.data)] = Number(v.votingPower)
|
||||
})
|
||||
})
|
||||
const height = Number(h.lastBlockHeight) - diff
|
||||
base.fetchValidatorByHeight(height > 0 ? height : 1, offset).then(old => {
|
||||
old.validators.forEach(v => {
|
||||
if(v.pubkey) yesterday.value[pubkeyToAddress(v.pubkey.algorithm, v.pubkey.data)] = Number(v.votingPower)
|
||||
})
|
||||
// console.log(Object.keys(yesterday.value).map(x => x.toUpperCase()))
|
||||
})
|
||||
})
|
||||
// base.fetchAbciInfo().then(h => {
|
||||
// // console.log('block:', h)
|
||||
// base.fetchValidatorByHeight(h.lastBlockHeight, offset).then(x => {
|
||||
// x.validators.forEach(v => {
|
||||
// if(v.pubkey) latest.value[pubkeyToAddress(v.pubkey.algorithm, v.pubkey.data)] = Number(v.votingPower)
|
||||
// })
|
||||
// })
|
||||
// const height = Number(h.lastBlockHeight) - diff
|
||||
// base.fetchValidatorByHeight(height > 0 ? height : 1, offset).then(old => {
|
||||
// old.validators.forEach(v => {
|
||||
// if(v.pubkey) yesterday.value[pubkeyToAddress(v.pubkey.algorithm, v.pubkey.data)] = Number(v.votingPower)
|
||||
// })
|
||||
// // console.log(Object.keys(yesterday.value).map(x => x.toUpperCase()))
|
||||
// })
|
||||
// })
|
||||
}
|
||||
|
||||
const change24 = (key: {typeUrl: string, value: Uint8Array}) => {
|
||||
const change24 = (key: Key) => {
|
||||
// console.log('hex key:', consensusPubkeyToHexAddress(key))
|
||||
const txt = toBase64(key.value)
|
||||
const txt = key.key
|
||||
const n : number = latest.value[txt];
|
||||
const o : number = yesterday.value[txt]
|
||||
// console.log( txt, n, o)
|
||||
return n >0 && o > 0 ? n - o : 0
|
||||
}
|
||||
|
||||
const change24Text = (key?: {typeUrl: string, value: Uint8Array}) => {
|
||||
const change24Text = (key?: Key) => {
|
||||
if(!key) return ''
|
||||
const v = change24(key)
|
||||
return v!==0 ? format.numberAndSign(v) : ''
|
||||
}
|
||||
|
||||
const change24Color = (key?: {typeUrl: string, value: Uint8Array}) => {
|
||||
const change24Color = (key?: Key) => {
|
||||
if(!key) return ''
|
||||
const v = change24(key)
|
||||
if(v > 0) return 'text-success'
|
||||
@ -71,8 +71,8 @@ const update = (m: DebuggerEvent) => {
|
||||
}
|
||||
|
||||
const list = computed(() => {
|
||||
// return tab.value === 'active' ? staking.validators: unbondList.value
|
||||
return staking.validators
|
||||
return tab.value === 'active' ? staking.validators: unbondList.value
|
||||
// return staking.validators
|
||||
})
|
||||
|
||||
const loadAvatars = () => {
|
||||
@ -116,7 +116,7 @@ const logo = (identity?: string) => {
|
||||
const rank = function(position: number) {
|
||||
let sum = 0
|
||||
for(let i = 0;i < position; i++) {
|
||||
sum += Number(staking.validators[i]?.delegatorShares)
|
||||
sum += Number(staking.validators[i]?.delegator_shares)
|
||||
}
|
||||
const percent = (sum / staking.totalPower)
|
||||
|
||||
@ -135,7 +135,7 @@ const rank = function(position: number) {
|
||||
<VBtn value="active" variant="outlined" >Active</VBtn>
|
||||
<VBtn value="inactive" variant="outlined">Inactive</VBtn>
|
||||
</VBtnToggle>
|
||||
<span class="mt-2">{{ list.length }}/{{ staking.params.maxValidators }}</span>
|
||||
<span class="mt-2">{{ list.length }}/{{ staking.params.max_validators }}</span>
|
||||
</VCardTitle>
|
||||
<VTable class="text-no-wrap table-header-bg rounded-0">
|
||||
<thead>
|
||||
@ -164,7 +164,7 @@ const rank = function(position: number) {
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="(v, i) in list"
|
||||
:key="v.operatorAddress"
|
||||
:key="v.operator_address"
|
||||
>
|
||||
<!-- 👉 rank -->
|
||||
<td>
|
||||
@ -186,7 +186,7 @@ const rank = function(position: number) {
|
||||
<div class="d-flex flex-column">
|
||||
<h6 class="text-sm">
|
||||
<RouterLink
|
||||
:to="{name: 'chain-staking-validator', params: {validator: v.operatorAddress}}"
|
||||
:to="{name: 'chain-staking-validator', params: {validator: v.operator_address}}"
|
||||
class="font-weight-medium user-list-name"
|
||||
>
|
||||
{{ v.description?.moniker }}
|
||||
@ -202,18 +202,18 @@ const rank = function(position: number) {
|
||||
<td class="text-right">
|
||||
<div class="d-flex flex-column">
|
||||
<h6 class="text-sm font-weight-medium">
|
||||
{{ format.formatToken( {amount: parseInt(v.tokens).toString(), denom: staking.params.bondDenom }, true, "0,0") }}
|
||||
{{ format.formatToken( {amount: parseInt(v.tokens).toString(), denom: staking.params.bond_denom }, true, "0,0") }}
|
||||
</h6>
|
||||
<span class="text-xs">{{ format.calculatePercent(v.delegatorShares, staking.totalPower) }}</span>
|
||||
<span class="text-xs">{{ format.calculatePercent(v.delegator_shares, staking.totalPower) }}</span>
|
||||
</div>
|
||||
</td>
|
||||
<!-- 👉 24h Changes -->
|
||||
<td class="text-right text-xs" :class="change24Color(v.consensusPubkey)">
|
||||
{{ change24Text(v.consensusPubkey) }} <VChip label v-if="v.jailed" color="error">Jailed</VChip>
|
||||
<td class="text-right text-xs" :class="change24Color(v.consensus_pubkey)">
|
||||
{{ change24Text(v.consensus_pubkey) }} <VChip label v-if="v.jailed" color="error">Jailed</VChip>
|
||||
</td>
|
||||
<!-- 👉 commission -->
|
||||
<td class="text-right">
|
||||
{{ format.formatCommissionRate(v.commission?.commissionRates?.rate) }}
|
||||
{{ format.formatCommissionRate(v.commission?.commission_rates?.rate) }}
|
||||
</td>
|
||||
<!-- 👉 Action -->
|
||||
<td>
|
||||
|
@ -1,17 +1,19 @@
|
||||
<script lang="ts" setup>
|
||||
import { useBlockchain, useFormatter } from '@/stores';
|
||||
import type { GetTxResponse } from 'cosmjs-types/cosmos/tx/v1beta1/service';
|
||||
import DynamicComponent from '@/components/dynamic/DynamicComponent.vue';
|
||||
import { computed } from '@vue/reactivity';
|
||||
import { fromBase64, toBase64 } from '@cosmjs/encoding';
|
||||
import { computed, ref } from '@vue/reactivity';
|
||||
import type { Tx, TxResponse } from '@/types';
|
||||
|
||||
const props = defineProps(['hash', 'chain'])
|
||||
|
||||
const blockchain = useBlockchain()
|
||||
const format = useFormatter()
|
||||
const tx = ref({} as GetTxResponse)
|
||||
const tx = ref({} as {
|
||||
tx: Tx;
|
||||
tx_response: TxResponse
|
||||
})
|
||||
if(props.hash) {
|
||||
blockchain.rpc.tx(props.hash).then(x => tx.value = x)
|
||||
blockchain.rpc.getTx(props.hash).then(x => tx.value = x)
|
||||
}
|
||||
const messages = computed(() => {
|
||||
return tx.value.tx?.body?.messages||[]
|
||||
@ -19,19 +21,19 @@ const messages = computed(() => {
|
||||
</script>
|
||||
<template>
|
||||
<div>
|
||||
<VCard v-if="tx.txResponse" title="Summary">
|
||||
<VCard v-if="tx.tx_response" title="Summary">
|
||||
<VCardItem class="pt-0">
|
||||
<VTable>
|
||||
<tbody>
|
||||
<tr><td>Tx Hash</td><td>{{ tx.txResponse.txhash }}</td></tr>
|
||||
<tr><td>Height</td><td><RouterLink :to="`/${props.chain}/block/${tx.txResponse.height}`">{{ tx.txResponse.height }}</RouterLink></td></tr>
|
||||
<tr><td>Tx Hash</td><td>{{ tx.tx_response.txhash }}</td></tr>
|
||||
<tr><td>Height</td><td><RouterLink :to="`/${props.chain}/block/${tx.tx_response.height}`">{{ tx.tx_response.height }}</RouterLink></td></tr>
|
||||
<tr><td>Status</td><td>
|
||||
<VChip v-if="tx.txResponse.code === 0" color="success">Success</VChip>
|
||||
<VChip v-if="tx.tx_response.code === 0" color="success">Success</VChip>
|
||||
<span v-else><VChip color="error">Failded</VChip></span>
|
||||
</td></tr>
|
||||
<tr><td>Time</td><td>{{ tx.txResponse.timestamp }} ({{ format.toDay(tx.txResponse.timestamp, "from") }})</td></tr>
|
||||
<tr><td>Gas</td><td>{{ tx.txResponse.gasUsed }} / {{ tx.txResponse.gasWanted }}</td></tr>
|
||||
<tr><td>Fee</td><td>{{ format.formatTokens(tx.tx?.authInfo?.fee?.amount, true, '0,0.[00]') }}</td></tr>
|
||||
<tr><td>Time</td><td>{{ tx.tx_response.timestamp }} ({{ format.toDay(tx.tx_response.timestamp, "from") }})</td></tr>
|
||||
<tr><td>Gas</td><td>{{ tx.tx_response.gas_used }} / {{ tx.tx_response.gas_wanted }}</td></tr>
|
||||
<tr><td>Fee</td><td>{{ format.formatTokens(tx.tx?.auth_info?.fee?.amount, true, '0,0.[00]') }}</td></tr>
|
||||
<tr><td>Memo</td><td>{{ tx.tx.body.memo }}</td></tr>
|
||||
</tbody>
|
||||
</VTable>
|
||||
@ -39,10 +41,9 @@ const messages = computed(() => {
|
||||
</VCard>
|
||||
|
||||
<VCard title="Messages" class="my-5">
|
||||
<VCardItem>
|
||||
<VCardItem style="border-top: 2px dotted gray;">
|
||||
<div v-for="(msg, i) in messages">
|
||||
<div><VChip label color="primary">#{{ i+1 }}</VChip>{{ msg.typeUrl }}</div>
|
||||
<div>{{ toBase64(msg.value) }}</div>
|
||||
<div><DynamicComponent :value="msg" /></div>
|
||||
</div>
|
||||
</VCardItem>
|
||||
</VCard>
|
||||
@ -56,7 +57,7 @@ const messages = computed(() => {
|
||||
</VExpansionPanel>
|
||||
<VExpansionPanel title="Transaction Response">
|
||||
<v-expansion-panel-text>
|
||||
<DynamicComponent :value="tx.txResponse" />
|
||||
<DynamicComponent :value="tx.tx_response" />
|
||||
</v-expansion-panel-text>
|
||||
</VExpansionPanel>
|
||||
</VExpansionPanels>
|
||||
|
@ -5,7 +5,7 @@ async function tt() {
|
||||
const address = "echelon1uattqtrtv8944qkmh44ll97qjacj6tgrekqzm9"
|
||||
const validator = "echelonvaloper1uattqtrtv8944qkmh44ll97qjacj6tgr2cupk4"
|
||||
const client = new CosmosRestClient("https://api.ech.network")
|
||||
let response = await client.getSlashingSigningInfos();
|
||||
let response = await client.getBaseBlockLatest();
|
||||
console.log('response:', response)
|
||||
}
|
||||
tt()
|
||||
|
@ -1,11 +1,11 @@
|
||||
import type { RPCClient } from '@/libs/client.rpc'
|
||||
import type { CosmosRestClient } from '@/libs/client'
|
||||
import 'pinia'
|
||||
import type { Ref } from 'vue'
|
||||
|
||||
declare module 'pinia' {
|
||||
export interface PiniaCustomProperties {
|
||||
// by using a setter we can allow both strings and refs
|
||||
set rpc(value: RPCClient | Ref<RPCClient>)
|
||||
get rpc(): RPCClient
|
||||
set rpc(value: CosmosRestClient | Ref<CosmosRestClient>)
|
||||
get rpc(): CosmosRestClient
|
||||
}
|
||||
}
|
@ -7,9 +7,9 @@ import type { Coin } from "@/types";
|
||||
export const useBankStore = defineStore('bankstore', {
|
||||
state: () => {
|
||||
return {
|
||||
supply: {} as Coin[],
|
||||
supply: {} as Coin,
|
||||
balances: {} as Record<string, Coin[]>,
|
||||
totalSupply: {supply: []} ,
|
||||
totalSupply: {supply: [] as Coin[]} ,
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
@ -26,7 +26,7 @@ export const useBankStore = defineStore('bankstore', {
|
||||
this.supply = {} as Coin
|
||||
const denom = this.staking.params.bondDenom || this.blockchain.current?.assets[0].base
|
||||
if(denom) {
|
||||
this.blockchain.rpc.supplyOf(denom).then(res => {
|
||||
this.blockchain.rpc.getBankSupplyByDenom(denom).then(res => {
|
||||
if(res.amount) this.supply = res.amount
|
||||
})
|
||||
}
|
||||
@ -38,7 +38,7 @@ export const useBankStore = defineStore('bankstore', {
|
||||
// return response
|
||||
// },
|
||||
async fetchSupply(denom: string) {
|
||||
return this.blockchain.rpc.supplyOf( denom )
|
||||
return this.blockchain.rpc.getBankSupplyByDenom( denom )
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -1,15 +1,14 @@
|
||||
import { defineStore } from "pinia";
|
||||
import { useBlockchain } from "@/stores";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
import type { BlockResponse } from "@cosmjs/tendermint-rpc";
|
||||
import type { Block } from "@/types";
|
||||
|
||||
export const useBaseStore = defineStore('baseStore', {
|
||||
state: () => {
|
||||
return {
|
||||
earlest: {} as BlockResponse,
|
||||
latest: {} as BlockResponse,
|
||||
recents: [] as BlockResponse[]
|
||||
earlest: {} as Block,
|
||||
latest: {} as Block,
|
||||
recents: [] as Block[]
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
@ -34,8 +33,8 @@ export const useBaseStore = defineStore('baseStore', {
|
||||
this.recents = []
|
||||
},
|
||||
async fetchLatest() {
|
||||
this.latest = await this.blockchain.rpc.block()
|
||||
if(!this.earlest || this.earlest.block?.header?.chainId != this.latest.block?.header?.chainId) {
|
||||
this.latest = await this.blockchain.rpc.getBaseBlockLatest()
|
||||
if(!this.earlest || this.earlest.block?.header?.chain_id != this.latest.block?.header?.chain_id) {
|
||||
//reset earlest and recents
|
||||
this.earlest = this.latest
|
||||
this.recents = []
|
||||
@ -48,16 +47,16 @@ export const useBaseStore = defineStore('baseStore', {
|
||||
},
|
||||
|
||||
async fetchValidatorByHeight(height?: number, offset = 0) {
|
||||
return this.blockchain.rpc.validatorsAtHeight(height)
|
||||
return this.blockchain.rpc.getBaseValidatorsetAt(String(height))
|
||||
},
|
||||
async fetchLatestValidators(offset = 0) {
|
||||
return this.blockchain.rpc.validatorsAtHeight()
|
||||
return this.blockchain.rpc.getBaseValidatorsetLatest()
|
||||
},
|
||||
async fetchBlock(height?: number) {
|
||||
return this.blockchain.rpc.block(height)
|
||||
return this.blockchain.rpc.getBaseBlockAt(String(height))
|
||||
},
|
||||
async fetchAbciInfo() {
|
||||
return this.blockchain.rpc.abciInfo()
|
||||
return this.blockchain.rpc.getBaseNodeInfo()
|
||||
}
|
||||
// async fetchNodeInfo() {
|
||||
// return this.blockchain.rpc.no()
|
||||
|
@ -2,12 +2,8 @@ import { defineStore } from "pinia";
|
||||
import { useDashboard, type ChainConfig, type Endpoint, EndpointType } from "./useDashboard";
|
||||
import type { VerticalNavItems } from '@/@layouts/types'
|
||||
import { useRouter } from "vue-router";
|
||||
import { useStakingStore } from "./useStakingStore";
|
||||
import { useBankStore } from "./useBankStore";
|
||||
import { useBaseStore } from "./useBaseStore";
|
||||
import { useGovStore } from "./useGovStore";
|
||||
import { ref } from "vue";
|
||||
import { useMintStore } from "./useMintStore";
|
||||
import { CosmosRestClient } from "@/libs/client";
|
||||
import { useBankStore, useBaseStore, useGovStore, useMintStore, useStakingStore } from ".";
|
||||
import { useBlockModule } from "@/modules/[chain]/block/block";
|
||||
|
||||
export const useBlockchain = defineStore("blockchain", {
|
||||
@ -95,16 +91,16 @@ export const useBlockchain = defineStore("blockchain", {
|
||||
actions: {
|
||||
async initial() {
|
||||
await this.randomSetupEndpoint()
|
||||
// await useStakingStore().init()
|
||||
// useBankStore().initial()
|
||||
// useBaseStore().initial()
|
||||
// useGovStore().initial()
|
||||
// useMintStore().initial()
|
||||
// useBlockModule().initial()
|
||||
await useStakingStore().init()
|
||||
useBankStore().initial()
|
||||
useBaseStore().initial()
|
||||
useGovStore().initial()
|
||||
useMintStore().initial()
|
||||
useBlockModule().initial()
|
||||
},
|
||||
|
||||
async randomSetupEndpoint() {
|
||||
const all = this.current?.endpoints?.rpc
|
||||
const all = this.current?.endpoints?.rest
|
||||
if(all) {
|
||||
const rn = Math.random()
|
||||
const endpoint = all[Math.floor(rn * all.length)]
|
||||
@ -115,7 +111,7 @@ export const useBlockchain = defineStore("blockchain", {
|
||||
async setRestEndpoint(endpoint: Endpoint) {
|
||||
this.connErr = ''
|
||||
this.endpoint = endpoint
|
||||
// this.rpc = new RPCClient(endpoint.address)
|
||||
this.rpc = new CosmosRestClient(endpoint.address)
|
||||
// console.log(this.rpc.endpoint)
|
||||
},
|
||||
setCurrent(name: string) {
|
||||
|
@ -13,7 +13,7 @@ export const useDistributionStore = defineStore('distributionStore', {
|
||||
},
|
||||
actions: {
|
||||
async fetchCommunityPool() {
|
||||
return this.blockchain.rpc.communityPool()
|
||||
return this.blockchain.rpc.getDistributionCommunityPool()
|
||||
}
|
||||
}
|
||||
})
|
@ -8,7 +8,7 @@ import updateLocale from 'dayjs/plugin/updateLocale'
|
||||
import utc from 'dayjs/plugin/utc'
|
||||
import localeData from 'dayjs/plugin/localeData'
|
||||
import { useStakingStore } from "./useStakingStore";
|
||||
import { toHex } from "@cosmjs/encoding";
|
||||
import { fromBase64, toHex } from "@cosmjs/encoding";
|
||||
import { consensusPubkeyToHexAddress } from "@/libs";
|
||||
|
||||
dayjs.extend(localeData)
|
||||
@ -90,9 +90,9 @@ export const useFormatter = defineStore('formatter', {
|
||||
}
|
||||
return '-'
|
||||
},
|
||||
validator(address: Uint8Array) {
|
||||
const txt = toHex(address).toUpperCase()
|
||||
const validator = this.staking.validators.find(x => consensusPubkeyToHexAddress(x.consensusPubkey) === txt)
|
||||
validator(address: string) {
|
||||
const txt = toHex(fromBase64(address)).toUpperCase()
|
||||
const validator = this.staking.validators.find(x => consensusPubkeyToHexAddress(x.consensus_pubkey) === txt)
|
||||
return validator?.description?.moniker
|
||||
},
|
||||
calculatePercent(input?: string, total?: string|number ) {
|
||||
@ -103,10 +103,8 @@ export const useFormatter = defineStore('formatter', {
|
||||
formatDecimalToPercent(decimal: string) {
|
||||
return numeral(decimal).format('0.[00]%')
|
||||
},
|
||||
formatCommissionRate(v?: string) {
|
||||
console.log(v)
|
||||
if(!v) return '-'
|
||||
const rate = Number(v) / Number("1000000000000000000")
|
||||
formatCommissionRate(rate?: string) {
|
||||
if(!rate) return '-'
|
||||
return this.percent(rate)
|
||||
},
|
||||
percent(decimal?: string|number) {
|
||||
@ -134,10 +132,10 @@ export const useFormatter = defineStore('formatter', {
|
||||
}
|
||||
return dayjs(time).format('YYYY-MM-DD HH:mm:ss')
|
||||
},
|
||||
messages(msgs: {typeUrl: string}[]) {
|
||||
messages(msgs: {"@type": string}[]) {
|
||||
if(msgs) {
|
||||
const sum: Record<string, number> = msgs.map(msg => {
|
||||
return msg.typeUrl.substring(msg.typeUrl.lastIndexOf('.') + 1).replace('Msg', '')
|
||||
return msg["@type"].substring(msg["@type"].lastIndexOf('.') + 1).replace('Msg', '')
|
||||
}).reduce((s, c) => {
|
||||
const sh: Record<string, number> = s
|
||||
if (sh[c]) {
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { defineStore } from "pinia";
|
||||
import { useBlockchain } from "./useBlockchain";
|
||||
import type { PageRequest } from "@/types";
|
||||
|
||||
export const useGovStore = defineStore('govStore', {
|
||||
state: () => {
|
||||
@ -20,24 +21,17 @@ export const useGovStore = defineStore('govStore', {
|
||||
initial() {
|
||||
this.fetchParams()
|
||||
},
|
||||
async fetchProposals( proposalStatus: ProposalStatus, pagination?: PageRequest ) {
|
||||
const param = {
|
||||
proposalStatus,
|
||||
voter: '',
|
||||
depositor: '',
|
||||
pagination,
|
||||
}
|
||||
const proposals = await this.blockchain.rpc.proposals(proposalStatus, '', '')
|
||||
console.log(proposals)
|
||||
async fetchProposals( status: string, pagination?: PageRequest ) {
|
||||
const proposals = await this.blockchain.rpc.getGovProposals(status)
|
||||
return proposals
|
||||
},
|
||||
async fetchParams() {
|
||||
// this.blockchain.rpc.govParam().then(x => {
|
||||
// this.blockchain.rpc.getGovParamsDeposit().then(x => {
|
||||
// this.params.deposit = x.deposit
|
||||
// })
|
||||
},
|
||||
async fetchTally(proposalId: number) {
|
||||
return this.blockchain.rpc.tally(proposalId)
|
||||
async fetchTally(proposalId: string) {
|
||||
return this.blockchain.rpc.getGovProposalTally(proposalId)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -17,7 +17,7 @@ export const useMintStore = defineStore('mintStore', {
|
||||
this.fetchInflation()
|
||||
},
|
||||
async fetchInflation() {
|
||||
this.blockchain.rpc.inflation().then(x => {
|
||||
this.blockchain.rpc.getMintInflation().then(x => {
|
||||
this.inflation = x.inflation
|
||||
}).catch(() => {
|
||||
this.inflation = "0"
|
||||
|
@ -2,18 +2,30 @@ import { defineStore } from "pinia";
|
||||
import { useBlockchain } from "./useBlockchain";
|
||||
|
||||
import { get } from "@/libs/http";
|
||||
import type { StakingParam, StakingPool, Validator } from "@/types";
|
||||
|
||||
export const useStakingStore = defineStore('stakingStore', {
|
||||
state: () => {
|
||||
return {
|
||||
validators: [] as Validator[],
|
||||
params: {} as QueryParamsResponse,
|
||||
pool: {} as Pool | undefined,
|
||||
params: {} as {
|
||||
"unbonding_time": string,
|
||||
"max_validators": number,
|
||||
"max_entries": number,
|
||||
"historical_entries": number,
|
||||
"bond_denom": string,
|
||||
"min_commission_rate": string,
|
||||
"min_self_delegation": string
|
||||
},
|
||||
pool: {} as {
|
||||
bonded_tokens: string,
|
||||
not_bonded_tokens: string,
|
||||
},
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
totalPower(): number {
|
||||
const sum = (s:number, e: Validator) => { return s + parseInt(e.delegatorShares) }
|
||||
const sum = (s:number, e: Validator) => { return s + parseInt(e.delegator_shares) }
|
||||
return this.validators ? this.validators.reduce(sum, 0): 0
|
||||
},
|
||||
blockchain() {
|
||||
@ -31,12 +43,13 @@ export const useStakingStore = defineStore('stakingStore', {
|
||||
return get(`https://keybase.io/_/api/1.0/user/lookup.json?key_suffix=${identity}&fields=pictures`)
|
||||
},
|
||||
async fetchParams() {
|
||||
const response = await this.blockchain.rpc.stakingParams()
|
||||
const response = await this.blockchain.rpc.getStakingParams()
|
||||
if(response.params) this.params = response.params
|
||||
return this.params
|
||||
},
|
||||
async fetchPool() {
|
||||
const response = await this.blockchain.rpc.stakingPool()
|
||||
const response = await this.blockchain.rpc.getStakingPool()
|
||||
response.pool.bonded_tokens
|
||||
this.pool = response.pool
|
||||
},
|
||||
async fetchAcitveValdiators() {
|
||||
@ -46,14 +59,14 @@ export const useStakingStore = defineStore('stakingStore', {
|
||||
return this.fetchValidators('BOND_STATUS_UNBONDED')
|
||||
},
|
||||
async fetchValidator(validatorAddr: string) {
|
||||
return this.blockchain.rpc.validator(validatorAddr)
|
||||
return this.blockchain.rpc.getStakingValidator(validatorAddr)
|
||||
},
|
||||
async fetchValidatorDelegation(validatorAddr: string, delegatorAddr: string) {
|
||||
return (await this.blockchain.rpc.validatorDelegation(validatorAddr, delegatorAddr)).delegationResponse
|
||||
return await this.blockchain.rpc.getStakingValidatorsDelegationsDelegator(validatorAddr, delegatorAddr)
|
||||
},
|
||||
async fetchValidators(status: string) {
|
||||
return this.blockchain.rpc.validators(status, undefined).then(res => {
|
||||
const vals = res.validators.sort((a, b) => (Number(b.delegatorShares) - Number(a.delegatorShares)))
|
||||
return this.blockchain.rpc.getStakingValidators(status).then(res => {
|
||||
const vals = res.validators.sort((a, b) => (Number(b.delegator_shares) - Number(a.delegator_shares)))
|
||||
if(status==='BOND_STATUS_BONDED') {
|
||||
this.validators = vals
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import type { Key } from "./common"
|
||||
import type { Tx } from "./tx"
|
||||
|
||||
export interface NodeInfo {
|
||||
"default_node_info": {
|
||||
@ -35,9 +36,57 @@ export interface NodeInfo {
|
||||
"cosmos_sdk_version": string,
|
||||
}
|
||||
}
|
||||
export interface BlockId {
|
||||
"hash": string,
|
||||
"part_set_header": {
|
||||
"total": number,
|
||||
"hash": string
|
||||
}
|
||||
}
|
||||
|
||||
export interface Signature
|
||||
{
|
||||
"block_id_flag": string,
|
||||
"validator_address": string,
|
||||
"timestamp": string,
|
||||
"signature": string,
|
||||
}
|
||||
|
||||
export interface Block {
|
||||
|
||||
"block_id": BlockId,
|
||||
"block": {
|
||||
"header": {
|
||||
"version": {
|
||||
"block": string,
|
||||
"app": string
|
||||
},
|
||||
"chain_id": string,
|
||||
"height": string,
|
||||
"time": string,
|
||||
"last_block_id": BlockId,
|
||||
"last_commit_hash": string,
|
||||
"data_hash": string,
|
||||
"validators_hash": string,
|
||||
"next_validators_hash": string,
|
||||
"consensus_hash": string,
|
||||
"app_hash": string,
|
||||
"last_results_hash": string,
|
||||
"evidence_hash": string,
|
||||
"proposer_address": string,
|
||||
},
|
||||
"data": {
|
||||
"txs": any[]
|
||||
},
|
||||
"evidence": {
|
||||
"evidence": any[]
|
||||
},
|
||||
"last_commit": {
|
||||
"height": string,
|
||||
"round": number,
|
||||
"block_id": BlockId,
|
||||
"signatures": Signature[]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export interface TendermintValidator {
|
||||
|
@ -8,6 +8,10 @@ export interface Pagination {
|
||||
total?: string;
|
||||
}
|
||||
|
||||
export class PageRequest {
|
||||
limit?: number;
|
||||
}
|
||||
|
||||
export interface PaginatedResponse {
|
||||
pagination: Pagination;
|
||||
}
|
||||
@ -17,6 +21,6 @@ export class Response<T> {
|
||||
}
|
||||
|
||||
export interface Coin {
|
||||
amount: string|number;
|
||||
amount: string;
|
||||
denom: string;
|
||||
}
|
@ -44,12 +44,10 @@ export interface GovProposal {
|
||||
}
|
||||
|
||||
export interface Tally {
|
||||
tally: {
|
||||
yes: string,
|
||||
abstain: string,
|
||||
no: string,
|
||||
no_with_veto: string
|
||||
}
|
||||
yes: string,
|
||||
abstain: string,
|
||||
no: string,
|
||||
no_with_veto: string
|
||||
}
|
||||
|
||||
export interface GovVote {
|
||||
|
@ -5,4 +5,5 @@ export * from './bank'
|
||||
export * from './common'
|
||||
export * from './distribution'
|
||||
export * from './gov'
|
||||
export * from './staking'
|
||||
export * from './staking'
|
||||
export * from './tx'
|
@ -16,17 +16,19 @@ export interface Validator {
|
||||
},
|
||||
"unbonding_height": string,
|
||||
"unbonding_time": string,
|
||||
"commission": {
|
||||
"commission_rates": {
|
||||
"rate": string,
|
||||
"max_rate": string,
|
||||
"max_change_rate": string
|
||||
},
|
||||
"update_time": string
|
||||
},
|
||||
"commission": CommissionRate,
|
||||
"min_self_delegation": string
|
||||
}
|
||||
|
||||
export interface CommissionRate {
|
||||
"commission_rates": {
|
||||
"rate": string,
|
||||
"max_rate": string,
|
||||
"max_change_rate": string
|
||||
},
|
||||
"update_time": string
|
||||
}
|
||||
|
||||
export interface Delegation {
|
||||
delegation: {
|
||||
delegator_address: string,
|
||||
|
Loading…
Reference in New Issue
Block a user