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",
|
||||
"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"],
|
||||
"snapshot_provider": "",
|
||||
"sdk_version": "0.46.1",
|
||||
|
@ -10,10 +10,11 @@ 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_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 },
|
||||
distribution_delegator_rewards: { url: "/cosmos/distribution/v1beta1/delegators/{delegator_addr}/rewards", adapter },
|
||||
slashing_params: { url: "/cosmos/slashing/v1beta1/params", adapter },
|
||||
slashing_signing_info: { url: "/cosmos/slashing/v1beta1/signing_infos", 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, {})
|
||||
}
|
||||
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) {
|
||||
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_outstanding_rewards: Request<{rewards?: {rewards?: Coin[]}}>;
|
||||
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_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">
|
||||
<VListItem>
|
||||
<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>
|
||||
<VListItemTitle>Operator Address</VListItemTitle>
|
||||
|
@ -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 { fromBase64, toHex } from "@cosmjs/encoding";
|
||||
import { fromBase64, fromBech32, toHex } from "@cosmjs/encoding";
|
||||
import { consensusPubkeyToHexAddress } from "@/libs";
|
||||
import { useBankStore } from "./useBankStore";
|
||||
import type { DenomTrace } from "@/types";
|
||||
@ -75,7 +75,6 @@ export const useFormatter = defineStore('formatter', {
|
||||
let denom = token.denom
|
||||
|
||||
if( denom && denom.startsWith("ibc/")) {
|
||||
console.log(denom)
|
||||
let ibcDenom = this.ibcDenoms[denom.replace("ibc/", "")]
|
||||
if(ibcDenom) {
|
||||
denom = ibcDenom.base_denom
|
||||
@ -96,7 +95,7 @@ export const useFormatter = defineStore('formatter', {
|
||||
denom = unit.denom.toUpperCase()
|
||||
}
|
||||
}
|
||||
return `${numeral(amount).format(fmt)} ${withDenom ? denom: ''}`
|
||||
return `${numeral(amount).format(fmt)} ${withDenom ? denom.substring(0, 10): ''}`
|
||||
}
|
||||
return '-'
|
||||
},
|
||||
@ -109,20 +108,27 @@ export const useFormatter = defineStore('formatter', {
|
||||
const b = Number(pool.bonded_tokens)
|
||||
const nb = Number(pool.not_bonded_tokens)
|
||||
const p = b/(b+nb)
|
||||
console.log(b, nb, p, pool)
|
||||
return numeral(p).format('0.[00]%')
|
||||
}
|
||||
return '-'
|
||||
},
|
||||
validator(address: string) {
|
||||
if(!address) return address
|
||||
|
||||
const txt = toHex(fromBase64(address)).toUpperCase()
|
||||
const validator = this.staking.validators.find(x => consensusPubkeyToHexAddress(x.consensus_pubkey) === txt)
|
||||
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 ) {
|
||||
if(!input || !total) return '0'
|
||||
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) {
|
||||
return numeral(decimal).format('0.[00]%')
|
||||
|
@ -1,4 +1,4 @@
|
||||
import type { PaginatedResponse } from "./common"
|
||||
import type { Coin, PaginatedResponse } from "./common"
|
||||
|
||||
export interface DistributionParams {
|
||||
params: {
|
||||
@ -9,6 +9,14 @@ export interface DistributionParams {
|
||||
}
|
||||
}
|
||||
|
||||
export interface DelegatorRewards {
|
||||
rewards: {
|
||||
validator_address: string,
|
||||
reward: Coin[],
|
||||
}[],
|
||||
total: Coin[],
|
||||
}
|
||||
|
||||
export interface PaginatedSlashes extends PaginatedResponse {
|
||||
slashes: any[]
|
||||
}
|
Loading…
Reference in New Issue
Block a user