add accounts
This commit is contained in:
parent
fc8aab6ce0
commit
5f7339c04b
22
src/components/charts/DonutChart.vue
Normal file
22
src/components/charts/DonutChart.vue
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import VueApexCharts from 'vue3-apexcharts'
|
||||||
|
import { useTheme } from 'vuetify'
|
||||||
|
import { getDonutChartConfig } from './apexChartConfig'
|
||||||
|
|
||||||
|
const props = defineProps(["series", "labels"])
|
||||||
|
|
||||||
|
const vuetifyTheme = useTheme()
|
||||||
|
|
||||||
|
const expenseRationChartConfig = computed(() => getDonutChartConfig(vuetifyTheme.current.value, props.labels))
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<VueApexCharts
|
||||||
|
type="donut"
|
||||||
|
height="410"
|
||||||
|
:options="expenseRationChartConfig"
|
||||||
|
:series="series"
|
||||||
|
/>
|
||||||
|
</template>
|
@ -1,7 +1,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import VueApexCharts from 'vue3-apexcharts'
|
import VueApexCharts from 'vue3-apexcharts'
|
||||||
import { useTheme } from 'vuetify'
|
import { useTheme } from 'vuetify'
|
||||||
import { getAreaChartSplineConfig, getMarketPriceChartConfig } from './apexCharConfig'
|
import { getAreaChartSplineConfig, getMarketPriceChartConfig } from './apexChartConfig'
|
||||||
import { useIndexModule } from '@/modules/[chain]/indexStore';
|
import { useIndexModule } from '@/modules/[chain]/indexStore';
|
||||||
import { computed, ref } from '@vue/reactivity';
|
import { computed, ref } from '@vue/reactivity';
|
||||||
|
|
||||||
|
@ -383,7 +383,7 @@ export const getRadialBarChartConfig = (themeColors: ThemeInstance['themes']['va
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getDonutChartConfig = (themeColors: ThemeInstance['themes']['value']['colors']) => {
|
export const getDonutChartConfig = (themeColors: ThemeInstance['themes']['value']['colors'], labels: string[]) => {
|
||||||
const donutColors = {
|
const donutColors = {
|
||||||
series1: '#fdd835',
|
series1: '#fdd835',
|
||||||
series2: '#00d4bd',
|
series2: '#00d4bd',
|
||||||
@ -396,7 +396,7 @@ export const getDonutChartConfig = (themeColors: ThemeInstance['themes']['value'
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
stroke: { width: 0 },
|
stroke: { width: 0 },
|
||||||
labels: ['Operational', 'Networking', 'Hiring', 'R&D'],
|
labels,
|
||||||
colors: [donutColors.series1, donutColors.series5, donutColors.series3, donutColors.series2],
|
colors: [donutColors.series1, donutColors.series5, donutColors.series3, donutColors.series2],
|
||||||
dataLabels: {
|
dataLabels: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
@ -425,10 +425,10 @@ export const getDonutChartConfig = (themeColors: ThemeInstance['themes']['value'
|
|||||||
formatter: (val: string) => `${parseInt(val, 10)}`,
|
formatter: (val: string) => `${parseInt(val, 10)}`,
|
||||||
},
|
},
|
||||||
total: {
|
total: {
|
||||||
show: true,
|
show: false,
|
||||||
fontSize: '1.5rem',
|
fontSize: '1.5rem',
|
||||||
label: 'Operational',
|
// label: 'Operational',
|
||||||
formatter: () => '31%',
|
// formatter: () => '31%',
|
||||||
color: themePrimaryTextColor,
|
color: themePrimaryTextColor,
|
||||||
},
|
},
|
||||||
},
|
},
|
@ -64,7 +64,7 @@ export interface RequestRegistry {
|
|||||||
staking_validators_address: Request<{validator: Validator}>;
|
staking_validators_address: Request<{validator: Validator}>;
|
||||||
staking_validators_delegations: Request<PaginatedDelegations>;
|
staking_validators_delegations: Request<PaginatedDelegations>;
|
||||||
staking_validators_delegations_delegator: Request<{delegation_response: Delegation}>;
|
staking_validators_delegations_delegator: Request<{delegation_response: Delegation}>;
|
||||||
staking_validators_delegations_unbonding_delegations: Request<any>;
|
staking_validators_delegations_unbonding_delegations: Request<PaginatedUnbonding>;
|
||||||
|
|
||||||
base_tendermint_abci_query: Request<any>;
|
base_tendermint_abci_query: Request<any>;
|
||||||
base_tendermint_block_latest: Request<Block>;
|
base_tendermint_block_latest: Request<Block>;
|
||||||
|
@ -1,32 +1,52 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useBlockchain, useFormatter } from '@/stores';
|
import { useBlockchain, useFormatter, useStakingStore } from '@/stores';
|
||||||
import DynamicComponent from '@/components/dynamic/DynamicComponent.vue';
|
import DynamicComponent from '@/components/dynamic/DynamicComponent.vue';
|
||||||
|
import DonutChart from '@/components/charts/DonutChart.vue'
|
||||||
import { computed, ref } from '@vue/reactivity';
|
import { computed, ref } from '@vue/reactivity';
|
||||||
import 'vue-json-pretty/lib/styles.css';
|
import 'vue-json-pretty/lib/styles.css';
|
||||||
import type { AuthAccount, Delegation, TxResponse, DelegatorRewards } from '@/types';
|
import type { AuthAccount, Delegation, TxResponse, DelegatorRewards, UnbondingResponses } from '@/types';
|
||||||
import type { Coin } from '@cosmjs/amino';
|
import type { Coin } from '@cosmjs/amino';
|
||||||
|
|
||||||
const props = defineProps(['address', 'chain'])
|
const props = defineProps(['address', 'chain'])
|
||||||
|
|
||||||
const blockchain = useBlockchain()
|
const blockchain = useBlockchain()
|
||||||
|
const stakingStore = useStakingStore()
|
||||||
const format = useFormatter()
|
const format = useFormatter()
|
||||||
const account = ref({} as AuthAccount)
|
const account = ref({} as AuthAccount)
|
||||||
const txs = ref({} as TxResponse[])
|
const txs = ref({} as TxResponse[])
|
||||||
const delegations = ref([] as Delegation[])
|
const delegations = ref([] as Delegation[])
|
||||||
const rewards = ref({} as DelegatorRewards)
|
const rewards = ref({} as DelegatorRewards)
|
||||||
const balances = ref([] as Coin[])
|
const balances = ref([] as Coin[])
|
||||||
const totalAmount = computed(()=> {
|
const unbonding = ref([] as UnbondingResponses[])
|
||||||
let total = 0;
|
const unbondingTotal = ref(0)
|
||||||
|
const chart = {}
|
||||||
|
|
||||||
|
const totalAmountByCategory = computed(()=> {
|
||||||
|
let sumDel = 0;
|
||||||
delegations.value?.forEach(x => {
|
delegations.value?.forEach(x => {
|
||||||
total += Number(x.balance.amount)
|
sumDel += Number(x.balance.amount)
|
||||||
})
|
})
|
||||||
|
let sumRew = 0
|
||||||
rewards.value?.total?.forEach(x => {
|
rewards.value?.total?.forEach(x => {
|
||||||
total += Number(x.amount)
|
sumRew += Number(x.amount)
|
||||||
})
|
})
|
||||||
|
let sumBal = 0
|
||||||
balances.value?.forEach(x => {
|
balances.value?.forEach(x => {
|
||||||
total += Number(x.amount)
|
sumBal += Number(x.amount)
|
||||||
})
|
})
|
||||||
return total
|
let sumUn = 0
|
||||||
|
unbonding.value?.forEach(x => {
|
||||||
|
x.entries?.forEach(y => {
|
||||||
|
sumUn += Number(y.balance)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
return [sumBal, sumDel, sumRew, sumUn]
|
||||||
|
})
|
||||||
|
|
||||||
|
const labels = ['Balance', 'Delegation', 'Reward', 'Unbonding']
|
||||||
|
|
||||||
|
const totalAmount= computed(()=> {
|
||||||
|
return totalAmountByCategory.value.reduce((p, c)=> c + p, 0)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@ -46,6 +66,14 @@ function loadAccount(address: string) {
|
|||||||
blockchain.rpc.getBankBalances(address).then(x => {
|
blockchain.rpc.getBankBalances(address).then(x => {
|
||||||
balances.value = x.balances
|
balances.value = x.balances
|
||||||
})
|
})
|
||||||
|
blockchain.rpc.getStakingDelegatorUnbonding(address).then(x => {
|
||||||
|
unbonding.value = x.unbonding_responses
|
||||||
|
x.unbonding_responses?.forEach(y => {
|
||||||
|
y.entries.forEach(z => {
|
||||||
|
unbondingTotal.value += Number(z.balance)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
loadAccount(props.address)
|
loadAccount(props.address)
|
||||||
</script>
|
</script>
|
||||||
@ -80,7 +108,7 @@ loadAccount(props.address)
|
|||||||
<VCardItem>
|
<VCardItem>
|
||||||
<VRow>
|
<VRow>
|
||||||
<VCol cols="12" md="4">
|
<VCol cols="12" md="4">
|
||||||
xx
|
<DonutChart :series="totalAmountByCategory" :labels="labels"/>
|
||||||
</VCol>
|
</VCol>
|
||||||
<VCol cols="12" md="8">
|
<VCol cols="12" md="8">
|
||||||
<VList class="card-list">
|
<VList class="card-list">
|
||||||
@ -89,10 +117,10 @@ loadAccount(props.address)
|
|||||||
<VAvatar
|
<VAvatar
|
||||||
rounded
|
rounded
|
||||||
variant="tonal"
|
variant="tonal"
|
||||||
size="45"
|
size="35"
|
||||||
color="success"
|
color="info"
|
||||||
>
|
>
|
||||||
<VIcon icon="mdi-card" />
|
<VIcon icon="mdi-account-cash" size="20"/>
|
||||||
</VAvatar>
|
</VAvatar>
|
||||||
</template>
|
</template>
|
||||||
<VListItemTitle class="text-sm font-weight-semibold">
|
<VListItemTitle class="text-sm font-weight-semibold">
|
||||||
@ -110,10 +138,10 @@ loadAccount(props.address)
|
|||||||
<VAvatar
|
<VAvatar
|
||||||
rounded
|
rounded
|
||||||
variant="tonal"
|
variant="tonal"
|
||||||
size="45"
|
size="35"
|
||||||
color="info"
|
color="warning"
|
||||||
>
|
>
|
||||||
<VIcon icon="mdi-lock" />
|
<VIcon icon="mdi-user-clock" size="20" />
|
||||||
</VAvatar>
|
</VAvatar>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -132,10 +160,10 @@ loadAccount(props.address)
|
|||||||
<VAvatar
|
<VAvatar
|
||||||
rounded
|
rounded
|
||||||
variant="tonal"
|
variant="tonal"
|
||||||
size="45"
|
size="35"
|
||||||
color="warning"
|
color="success"
|
||||||
>
|
>
|
||||||
<VIcon icon="mdi-up" />
|
<VIcon icon="mdi-account-arrow-up" size="20" />
|
||||||
</VAvatar>
|
</VAvatar>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -149,6 +177,29 @@ loadAccount(props.address)
|
|||||||
<VChip color="primary">{{ format.calculatePercent(v.amount, totalAmount) }}</VChip>
|
<VChip color="primary">{{ format.calculatePercent(v.amount, totalAmount) }}</VChip>
|
||||||
</template>
|
</template>
|
||||||
</VListItem>
|
</VListItem>
|
||||||
|
|
||||||
|
<VListItem>
|
||||||
|
<template #prepend>
|
||||||
|
<VAvatar
|
||||||
|
rounded
|
||||||
|
variant="tonal"
|
||||||
|
size="35"
|
||||||
|
color="error"
|
||||||
|
>
|
||||||
|
<VIcon icon="mdi-account-arrow-right" size="20" />
|
||||||
|
</VAvatar>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<VListItemTitle class="text-sm font-weight-semibold">
|
||||||
|
{{ format.formatToken({amount: String(unbondingTotal), denom: stakingStore.params.bond_denom}) }}
|
||||||
|
</VListItemTitle>
|
||||||
|
<VListItemSubtitle class="text-xs">
|
||||||
|
≈${{ 0 }}
|
||||||
|
</VListItemSubtitle>
|
||||||
|
<template #append>
|
||||||
|
<VChip color="primary">{{ format.calculatePercent(unbondingTotal, totalAmount) }}</VChip>
|
||||||
|
</template>
|
||||||
|
</VListItem>
|
||||||
</VList>
|
</VList>
|
||||||
<VDivider class="my-2"></VDivider>
|
<VDivider class="my-2"></VDivider>
|
||||||
{{ totalAmount }}
|
{{ totalAmount }}
|
||||||
@ -177,6 +228,29 @@ loadAccount(props.address)
|
|||||||
</VTable>
|
</VTable>
|
||||||
</VCardItem>
|
</VCardItem>
|
||||||
</VCard>
|
</VCard>
|
||||||
|
<VCard class="my-5" v-if="unbonding && unbonding.length > 0">
|
||||||
|
<VCardItem>
|
||||||
|
<VCardTitle>Unbonding Delegations</VCardTitle>
|
||||||
|
<VTable>
|
||||||
|
<thead>
|
||||||
|
<tr><th>Creation Height</th><th>Initial Balance</th><th>Balance</th><th>Completion Time</th></tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<div v-for="v in unbonding">
|
||||||
|
<tr>
|
||||||
|
<td>{{ format.validatorFromBech32(v.validator_address) }} </td>
|
||||||
|
</tr>
|
||||||
|
<tr v-for="entry in v.entries">
|
||||||
|
<td>{{ entry.creation_height }}</td>
|
||||||
|
<td>{{ format.formatToken({ amount: entry.initial_balance, denom: stakingStore.params.bond_denom }, true, "0,0.[00]") }}</td>
|
||||||
|
<td>{{ format.formatToken({ amount: entry.balance, denom: stakingStore.params.bond_denom }, true, "0,0.[00]") }}</td>
|
||||||
|
<td>{{ format.toDay(entry.completion_time, "to") }} </td>
|
||||||
|
</tr>
|
||||||
|
</div>
|
||||||
|
</tbody>
|
||||||
|
</VTable>
|
||||||
|
</VCardItem>
|
||||||
|
</VCard>
|
||||||
<VCard class="my-5">
|
<VCard class="my-5">
|
||||||
<VCardItem>
|
<VCardItem>
|
||||||
<VCardTitle>Transactions</VCardTitle>
|
<VCardTitle>Transactions</VCardTitle>
|
||||||
|
@ -124,7 +124,7 @@ export const useFormatter = defineStore('formatter', {
|
|||||||
const validator = this.staking.validators.find(x => x.operator_address === address)
|
const validator = this.staking.validators.find(x => x.operator_address === address)
|
||||||
return validator?.description?.moniker
|
return validator?.description?.moniker
|
||||||
},
|
},
|
||||||
calculatePercent(input?: string, total?: string|number ) {
|
calculatePercent(input?: string|number, 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)
|
||||||
console.log(input, total, percent);
|
console.log(input, total, percent);
|
||||||
|
@ -29,6 +29,17 @@ export interface CommissionRate {
|
|||||||
"update_time": string
|
"update_time": string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface UnbondingResponses {
|
||||||
|
delegator_address: string,
|
||||||
|
validator_address: string,
|
||||||
|
entries: {
|
||||||
|
creation_height: string,
|
||||||
|
completion_time: string,
|
||||||
|
initial_balance: string,
|
||||||
|
balance: string
|
||||||
|
}[]
|
||||||
|
}
|
||||||
|
|
||||||
export interface Delegation {
|
export interface Delegation {
|
||||||
delegation: {
|
delegation: {
|
||||||
delegator_address: string,
|
delegator_address: string,
|
||||||
@ -70,7 +81,7 @@ export interface PaginatedRedelegations extends PaginatedResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface PaginatedUnbonding extends PaginatedResponse {
|
export interface PaginatedUnbonding extends PaginatedResponse {
|
||||||
unbonding_responses: any[]
|
unbonding_responses: UnbondingResponses[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PaginatedValdiators extends PaginatedResponse {
|
export interface PaginatedValdiators extends PaginatedResponse {
|
||||||
|
Loading…
Reference in New Issue
Block a user