forked from cerc-io/cosmos-explorer
add account details
This commit is contained in:
parent
d6d56ba7c0
commit
fc8aab6ce0
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"chain_name": "osmosis",
|
"chain_name": "osmosis",
|
||||||
"coingecko": "osmosis",
|
"coingecko": "osmosis",
|
||||||
"api": ["https://api-osmosis-ia.cosmosia.notional.ventures", "https://osmosis-api.polkachu.com", "https://osmo.api.ping.pub", "https://lcd-osmosis.blockapsis.com"],
|
"api": ["https://api-osmosis-ia.cosmosia.notional.ventures", "https://osmosis-api.polkachu.com", "https://lcd-osmosis.blockapsis.com"],
|
||||||
"rpc": ["https://rpc-osmosis-ia.cosmosia.notional.ventures:443", "https://osmosis-rpc.polkachu.com:443", "https://osmosis.validator.network:443", "https://rpc-osmosis.blockapsis.com:443"],
|
"rpc": ["https://rpc-osmosis-ia.cosmosia.notional.ventures:443", "https://osmosis-rpc.polkachu.com:443", "https://osmosis.validator.network:443", "https://rpc-osmosis.blockapsis.com:443"],
|
||||||
"snapshot_provider": "",
|
"snapshot_provider": "",
|
||||||
"sdk_version": "0.46.1",
|
"sdk_version": "0.46.1",
|
||||||
|
@ -10,10 +10,11 @@ export const DEFAULT: RequestRegistry = {
|
|||||||
bank_supply: { url: "/cosmos/bank/v1beta1/supply", adapter },
|
bank_supply: { url: "/cosmos/bank/v1beta1/supply", adapter },
|
||||||
bank_supply_by_denom: { url: "/cosmos/bank/v1beta1/supply/{denom}", adapter },
|
bank_supply_by_denom: { url: "/cosmos/bank/v1beta1/supply/{denom}", adapter },
|
||||||
distribution_params: { url: "/cosmos/distribution/v1beta1/params", adapter },
|
distribution_params: { url: "/cosmos/distribution/v1beta1/params", adapter },
|
||||||
distributino_community_pool: { url: "/cosmos/distribution/v1beta1/community_pool", adapter },
|
distribution_community_pool: { url: "/cosmos/distribution/v1beta1/community_pool", adapter },
|
||||||
distribution_validator_commission: { url: "/cosmos/distribution/v1beta1/validators/{validator_address}/commission", 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_outstanding_rewards: { url: "/cosmos/distribution/v1beta1/validators/{validator_address}/outstanding_rewards", adapter },
|
||||||
distribution_validator_slashes: { url: "/cosmos/distribution/v1beta1/validators/{validator_address}/slashes", adapter },
|
distribution_validator_slashes: { url: "/cosmos/distribution/v1beta1/validators/{validator_address}/slashes", adapter },
|
||||||
|
distribution_delegator_rewards: { url: "/cosmos/distribution/v1beta1/delegators/{delegator_addr}/rewards", adapter },
|
||||||
slashing_params: { url: "/cosmos/slashing/v1beta1/params", adapter },
|
slashing_params: { url: "/cosmos/slashing/v1beta1/params", adapter },
|
||||||
slashing_signing_info: { url: "/cosmos/slashing/v1beta1/signing_infos", adapter },
|
slashing_signing_info: { url: "/cosmos/slashing/v1beta1/signing_infos", adapter },
|
||||||
gov_params_voting: { url: "/cosmos/gov/v1beta1/params/voting", adapter },
|
gov_params_voting: { url: "/cosmos/gov/v1beta1/params/voting", adapter },
|
||||||
|
@ -44,7 +44,10 @@ export class CosmosRestClient {
|
|||||||
return this.request(this.registry.distribution_params, {})
|
return this.request(this.registry.distribution_params, {})
|
||||||
}
|
}
|
||||||
async getDistributionCommunityPool() {
|
async getDistributionCommunityPool() {
|
||||||
return this.request(this.registry.distributino_community_pool, {})
|
return this.request(this.registry.distribution_community_pool, {})
|
||||||
|
}
|
||||||
|
async getDistributionDelegatorRewards(delegator_addr: string) {
|
||||||
|
return this.request(this.registry.distribution_delegator_rewards, {delegator_addr})
|
||||||
}
|
}
|
||||||
async getDistributionValidatorCommission(validator_address: string) {
|
async getDistributionValidatorCommission(validator_address: string) {
|
||||||
return this.request(this.registry.distribution_validator_commission, {validator_address})
|
return this.request(this.registry.distribution_validator_commission, {validator_address})
|
||||||
|
@ -29,7 +29,8 @@ export interface RequestRegistry {
|
|||||||
distribution_validator_commission: Request<{commission?: {commission?: Coin[]}}>;
|
distribution_validator_commission: Request<{commission?: {commission?: Coin[]}}>;
|
||||||
distribution_validator_outstanding_rewards: Request<{rewards?: {rewards?: Coin[]}}>;
|
distribution_validator_outstanding_rewards: Request<{rewards?: {rewards?: Coin[]}}>;
|
||||||
distribution_validator_slashes: Request<PaginatedSlashes>;
|
distribution_validator_slashes: Request<PaginatedSlashes>;
|
||||||
distributino_community_pool: Request<{pool: Coin[]}>;
|
distribution_community_pool: Request<{pool: Coin[]}>;
|
||||||
|
distribution_delegator_rewards: Request<any>;
|
||||||
|
|
||||||
mint_inflation: Request<{inflation: string}>;
|
mint_inflation: Request<{inflation: string}>;
|
||||||
mint_params: Request<{
|
mint_params: Request<{
|
||||||
|
216
src/modules/[chain]/account/[address].vue
Normal file
216
src/modules/[chain]/account/[address].vue
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { useBlockchain, useFormatter } from '@/stores';
|
||||||
|
import DynamicComponent from '@/components/dynamic/DynamicComponent.vue';
|
||||||
|
import { computed, ref } from '@vue/reactivity';
|
||||||
|
import 'vue-json-pretty/lib/styles.css';
|
||||||
|
import type { AuthAccount, Delegation, TxResponse, DelegatorRewards } from '@/types';
|
||||||
|
import type { Coin } from '@cosmjs/amino';
|
||||||
|
|
||||||
|
const props = defineProps(['address', 'chain'])
|
||||||
|
|
||||||
|
const blockchain = useBlockchain()
|
||||||
|
const format = useFormatter()
|
||||||
|
const account = ref({} as AuthAccount)
|
||||||
|
const txs = ref({} as TxResponse[])
|
||||||
|
const delegations = ref([] as Delegation[])
|
||||||
|
const rewards = ref({} as DelegatorRewards)
|
||||||
|
const balances = ref([] as Coin[])
|
||||||
|
const totalAmount = computed(()=> {
|
||||||
|
let total = 0;
|
||||||
|
delegations.value?.forEach(x => {
|
||||||
|
total += Number(x.balance.amount)
|
||||||
|
})
|
||||||
|
rewards.value?.total?.forEach(x => {
|
||||||
|
total += Number(x.amount)
|
||||||
|
})
|
||||||
|
balances.value?.forEach(x => {
|
||||||
|
total += Number(x.amount)
|
||||||
|
})
|
||||||
|
return total
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
function loadAccount(address: string) {
|
||||||
|
blockchain.rpc.getAuthAccount(address).then(x => {
|
||||||
|
account.value = x.account
|
||||||
|
})
|
||||||
|
blockchain.rpc.getTxsBySender(address).then(x => {
|
||||||
|
txs.value = x.tx_responses
|
||||||
|
})
|
||||||
|
blockchain.rpc.getDistributionDelegatorRewards(address).then(x => {
|
||||||
|
rewards.value = x
|
||||||
|
})
|
||||||
|
blockchain.rpc.getStakingDelegations(address).then(x => {
|
||||||
|
delegations.value = x.delegation_responses
|
||||||
|
})
|
||||||
|
blockchain.rpc.getBankBalances(address).then(x => {
|
||||||
|
balances.value = x.balances
|
||||||
|
})
|
||||||
|
}
|
||||||
|
loadAccount(props.address)
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<div v-if="account">
|
||||||
|
<VCard>
|
||||||
|
<VList>
|
||||||
|
<VListItem>
|
||||||
|
<template #prepend>
|
||||||
|
<VAvatar
|
||||||
|
rounded
|
||||||
|
variant="tonal"
|
||||||
|
size="45"
|
||||||
|
color="primary"
|
||||||
|
>
|
||||||
|
<VIcon icon="mdi-qrcode" />
|
||||||
|
</VAvatar>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<VListItemTitle class="text-sm font-weight-semibold">
|
||||||
|
Address:
|
||||||
|
</VListItemTitle>
|
||||||
|
<VListItemSubtitle class="text-xs">
|
||||||
|
{{ address }}
|
||||||
|
</VListItemSubtitle>
|
||||||
|
</VListItem>
|
||||||
|
</VList>
|
||||||
|
</VCard>
|
||||||
|
|
||||||
|
<VCard class="mt-5">
|
||||||
|
<VCardTitle>Assets</VCardTitle>
|
||||||
|
<VCardItem>
|
||||||
|
<VRow>
|
||||||
|
<VCol cols="12" md="4">
|
||||||
|
xx
|
||||||
|
</VCol>
|
||||||
|
<VCol cols="12" md="8">
|
||||||
|
<VList class="card-list">
|
||||||
|
<VListItem v-for="v in balances">
|
||||||
|
<template #prepend>
|
||||||
|
<VAvatar
|
||||||
|
rounded
|
||||||
|
variant="tonal"
|
||||||
|
size="45"
|
||||||
|
color="success"
|
||||||
|
>
|
||||||
|
<VIcon icon="mdi-card" />
|
||||||
|
</VAvatar>
|
||||||
|
</template>
|
||||||
|
<VListItemTitle class="text-sm font-weight-semibold">
|
||||||
|
{{ format.formatToken(v) }}
|
||||||
|
</VListItemTitle>
|
||||||
|
<VListItemSubtitle class="text-xs">
|
||||||
|
≈${{ 0 }}
|
||||||
|
</VListItemSubtitle>
|
||||||
|
<template #append>
|
||||||
|
<VChip color="primary">{{ format.calculatePercent(v.amount, totalAmount) }}</VChip>
|
||||||
|
</template>
|
||||||
|
</VListItem>
|
||||||
|
<VListItem v-for="v in delegations">
|
||||||
|
<template #prepend>
|
||||||
|
<VAvatar
|
||||||
|
rounded
|
||||||
|
variant="tonal"
|
||||||
|
size="45"
|
||||||
|
color="info"
|
||||||
|
>
|
||||||
|
<VIcon icon="mdi-lock" />
|
||||||
|
</VAvatar>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<VListItemTitle class="text-sm font-weight-semibold">
|
||||||
|
{{ format.formatToken(v.balance) }}
|
||||||
|
</VListItemTitle>
|
||||||
|
<VListItemSubtitle class="text-xs">
|
||||||
|
≈${{ 0 }}
|
||||||
|
</VListItemSubtitle>
|
||||||
|
<template #append>
|
||||||
|
<VChip color="primary">{{ format.calculatePercent(v.balance.amount, totalAmount) }}</VChip>
|
||||||
|
</template>
|
||||||
|
</VListItem>
|
||||||
|
<VListItem v-for="v in rewards.total">
|
||||||
|
<template #prepend>
|
||||||
|
<VAvatar
|
||||||
|
rounded
|
||||||
|
variant="tonal"
|
||||||
|
size="45"
|
||||||
|
color="warning"
|
||||||
|
>
|
||||||
|
<VIcon icon="mdi-up" />
|
||||||
|
</VAvatar>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<VListItemTitle class="text-sm font-weight-semibold">
|
||||||
|
{{ format.formatToken(v) }}
|
||||||
|
</VListItemTitle>
|
||||||
|
<VListItemSubtitle class="text-xs">
|
||||||
|
≈${{ 0 }}
|
||||||
|
</VListItemSubtitle>
|
||||||
|
<template #append>
|
||||||
|
<VChip color="primary">{{ format.calculatePercent(v.amount, totalAmount) }}</VChip>
|
||||||
|
</template>
|
||||||
|
</VListItem>
|
||||||
|
</VList>
|
||||||
|
<VDivider class="my-2"></VDivider>
|
||||||
|
{{ totalAmount }}
|
||||||
|
</VCol>
|
||||||
|
</VRow>
|
||||||
|
</VCardItem>
|
||||||
|
</VCard>
|
||||||
|
|
||||||
|
<VCard class="my-5">
|
||||||
|
<VCardItem>
|
||||||
|
<VCardTitle>Delegations</VCardTitle>
|
||||||
|
<VTable>
|
||||||
|
<thead>
|
||||||
|
<tr><th>Validator</th><th>Delegation</th><th>Rewards</th><th>Action</th></tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr v-for="v in delegations">
|
||||||
|
<td>{{ format.validatorFromBech32(v.delegation.validator_address) }} </td>
|
||||||
|
<td>{{ format.formatToken(v.balance, true, "0,0.[00]") }} </td>
|
||||||
|
<td>{{ format.formatTokens(rewards?.rewards?.find(x => x.validator_address ===v.delegation.validator_address)?.reward) }} </td>
|
||||||
|
<td>
|
||||||
|
action
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</VTable>
|
||||||
|
</VCardItem>
|
||||||
|
</VCard>
|
||||||
|
<VCard class="my-5">
|
||||||
|
<VCardItem>
|
||||||
|
<VCardTitle>Transactions</VCardTitle>
|
||||||
|
<VTable>
|
||||||
|
<thead>
|
||||||
|
<tr><th>Height</th><th>Hash</th><th>Messages</th><th>Time</th></tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr v-for="v in txs">
|
||||||
|
<td>{{ v.height }} </td>
|
||||||
|
<td class="text-truncate" style="max-width: 200px;">{{ v.txhash }} </td>
|
||||||
|
<td>
|
||||||
|
{{ format.messages(v.tx.body.messages) }}
|
||||||
|
<VIcon v-if="v.code === 0" icon="mdi-check" color="success"></VIcon>
|
||||||
|
<VIcon v-else icon="mdi-multiply" color="error"></VIcon> </td>
|
||||||
|
<td>{{ format.toDay(v.timestamp, "from") }}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</VTable>
|
||||||
|
</VCardItem>
|
||||||
|
</VCard>
|
||||||
|
<VCard>
|
||||||
|
<VCardItem>
|
||||||
|
<VCardTitle>Account</VCardTitle>
|
||||||
|
<DynamicComponent :value="account"/>
|
||||||
|
</VCardItem>
|
||||||
|
</VCard>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
Account does not exists on chain
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.card-list {
|
||||||
|
--v-card-list-gap: 5px;
|
||||||
|
}
|
||||||
|
</style>
|
@ -225,7 +225,7 @@ onMounted(()=> {
|
|||||||
<VList class="pt-0">
|
<VList class="pt-0">
|
||||||
<VListItem>
|
<VListItem>
|
||||||
<VListItemTitle>Account</VListItemTitle>
|
<VListItemTitle>Account</VListItemTitle>
|
||||||
<VListItemSubtitle class="text-caption">{{ addresses.account }}</VListItemSubtitle>
|
<VListItemSubtitle class="text-caption"><RouterLink :to="`/${chain}/account/${addresses.account}`">{{ addresses.account }}</RouterLink></VListItemSubtitle>
|
||||||
</VListItem>
|
</VListItem>
|
||||||
<VListItem>
|
<VListItem>
|
||||||
<VListItemTitle>Operator Address</VListItemTitle>
|
<VListItemTitle>Operator Address</VListItemTitle>
|
||||||
|
@ -8,7 +8,7 @@ import updateLocale from 'dayjs/plugin/updateLocale'
|
|||||||
import utc from 'dayjs/plugin/utc'
|
import utc from 'dayjs/plugin/utc'
|
||||||
import localeData from 'dayjs/plugin/localeData'
|
import localeData from 'dayjs/plugin/localeData'
|
||||||
import { useStakingStore } from "./useStakingStore";
|
import { useStakingStore } from "./useStakingStore";
|
||||||
import { fromBase64, toHex } from "@cosmjs/encoding";
|
import { fromBase64, fromBech32, toHex } from "@cosmjs/encoding";
|
||||||
import { consensusPubkeyToHexAddress } from "@/libs";
|
import { consensusPubkeyToHexAddress } from "@/libs";
|
||||||
import { useBankStore } from "./useBankStore";
|
import { useBankStore } from "./useBankStore";
|
||||||
import type { DenomTrace } from "@/types";
|
import type { DenomTrace } from "@/types";
|
||||||
@ -75,7 +75,6 @@ export const useFormatter = defineStore('formatter', {
|
|||||||
let denom = token.denom
|
let denom = token.denom
|
||||||
|
|
||||||
if( denom && denom.startsWith("ibc/")) {
|
if( denom && denom.startsWith("ibc/")) {
|
||||||
console.log(denom)
|
|
||||||
let ibcDenom = this.ibcDenoms[denom.replace("ibc/", "")]
|
let ibcDenom = this.ibcDenoms[denom.replace("ibc/", "")]
|
||||||
if(ibcDenom) {
|
if(ibcDenom) {
|
||||||
denom = ibcDenom.base_denom
|
denom = ibcDenom.base_denom
|
||||||
@ -96,7 +95,7 @@ export const useFormatter = defineStore('formatter', {
|
|||||||
denom = unit.denom.toUpperCase()
|
denom = unit.denom.toUpperCase()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return `${numeral(amount).format(fmt)} ${withDenom ? denom: ''}`
|
return `${numeral(amount).format(fmt)} ${withDenom ? denom.substring(0, 10): ''}`
|
||||||
}
|
}
|
||||||
return '-'
|
return '-'
|
||||||
},
|
},
|
||||||
@ -109,20 +108,27 @@ export const useFormatter = defineStore('formatter', {
|
|||||||
const b = Number(pool.bonded_tokens)
|
const b = Number(pool.bonded_tokens)
|
||||||
const nb = Number(pool.not_bonded_tokens)
|
const nb = Number(pool.not_bonded_tokens)
|
||||||
const p = b/(b+nb)
|
const p = b/(b+nb)
|
||||||
console.log(b, nb, p, pool)
|
|
||||||
return numeral(p).format('0.[00]%')
|
return numeral(p).format('0.[00]%')
|
||||||
}
|
}
|
||||||
return '-'
|
return '-'
|
||||||
},
|
},
|
||||||
validator(address: string) {
|
validator(address: string) {
|
||||||
|
if(!address) return address
|
||||||
|
|
||||||
const txt = toHex(fromBase64(address)).toUpperCase()
|
const txt = toHex(fromBase64(address)).toUpperCase()
|
||||||
const validator = this.staking.validators.find(x => consensusPubkeyToHexAddress(x.consensus_pubkey) === txt)
|
const validator = this.staking.validators.find(x => consensusPubkeyToHexAddress(x.consensus_pubkey) === txt)
|
||||||
return validator?.description?.moniker
|
return validator?.description?.moniker
|
||||||
},
|
},
|
||||||
|
validatorFromBech32(address: string) {
|
||||||
|
if(!address) return address
|
||||||
|
const validator = this.staking.validators.find(x => x.operator_address === address)
|
||||||
|
return validator?.description?.moniker
|
||||||
|
},
|
||||||
calculatePercent(input?: string, total?: string|number ) {
|
calculatePercent(input?: string, total?: string|number ) {
|
||||||
if(!input || !total) return '0'
|
if(!input || !total) return '0'
|
||||||
const percent = Number(input)/Number(total)
|
const percent = Number(input)/Number(total)
|
||||||
return numeral(percent).format("0.[00]%")
|
console.log(input, total, percent);
|
||||||
|
return numeral(percent>0.0001?percent: 0).format("0.[00]%")
|
||||||
},
|
},
|
||||||
formatDecimalToPercent(decimal: string) {
|
formatDecimalToPercent(decimal: string) {
|
||||||
return numeral(decimal).format('0.[00]%')
|
return numeral(decimal).format('0.[00]%')
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import type { PaginatedResponse } from "./common"
|
import type { Coin, PaginatedResponse } from "./common"
|
||||||
|
|
||||||
export interface DistributionParams {
|
export interface DistributionParams {
|
||||||
params: {
|
params: {
|
||||||
@ -9,6 +9,14 @@ export interface DistributionParams {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface DelegatorRewards {
|
||||||
|
rewards: {
|
||||||
|
validator_address: string,
|
||||||
|
reward: Coin[],
|
||||||
|
}[],
|
||||||
|
total: Coin[],
|
||||||
|
}
|
||||||
|
|
||||||
export interface PaginatedSlashes extends PaginatedResponse {
|
export interface PaginatedSlashes extends PaginatedResponse {
|
||||||
slashes: any[]
|
slashes: any[]
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user