change to rpc endpoint
This commit is contained in:
parent
91aea18f61
commit
d02c0c646e
@ -3,7 +3,50 @@
|
|||||||
"api": [
|
"api": [
|
||||||
"https://api-cosmoshub-ia.cosmosia.notional.ventures"
|
"https://api-cosmoshub-ia.cosmosia.notional.ventures"
|
||||||
],
|
],
|
||||||
"rpc": ["https://rpc.cosmos.network:443", "https://cosmos-rpc.icycro.org", "https://rpc.cosmos.dragonstake.io"],
|
"rpc": [{
|
||||||
|
"address": "http://rpc-cosmoshub.freshstaking.com:26657/",
|
||||||
|
"provider": "FreshSTAKING"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "https://rpc.cosmos.bh.rocks/",
|
||||||
|
"provider": "BlockHunters 🎯"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "https://cosmoshub-rpc.lavenderfive.com/",
|
||||||
|
"provider": "Lavender.Five Nodes 🐝"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "https://cosmos-rpc.polkachu.com/",
|
||||||
|
"provider": "Polkachu"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "https://rpc.cosmos.dragonstake.io/",
|
||||||
|
"provider": "DragonStake"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "https://cosmos-rpc.rockrpc.net/",
|
||||||
|
"provider": "RockawayX Infra"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "https://rpc-cosmoshub.pupmos.network/",
|
||||||
|
"provider": "PUPMØS"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "https://cosmos-rpc.icycro.org/",
|
||||||
|
"provider": "IcyCRO 🧊"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "https://rpc.cosmos.interbloc.org/",
|
||||||
|
"provider": "Interbloc"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "https://rpc.cosmoshub.strange.love/",
|
||||||
|
"provider": "strangelove-ventures"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "https://rpc-cosmoshub.whispernode.com/",
|
||||||
|
"provider": "WhisperNode🤐"
|
||||||
|
}],
|
||||||
"sdk_version": "0.45.1",
|
"sdk_version": "0.45.1",
|
||||||
"coin_type": "118",
|
"coin_type": "118",
|
||||||
"min_tx_fee": "800",
|
"min_tx_fee": "800",
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
"name": "framework",
|
"name": "framework",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
|
"target": "",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"serve": "vite",
|
"serve": "vite",
|
||||||
"build": "run-p type-check build-only",
|
"build": "run-p type-check build-only",
|
||||||
@ -13,6 +14,8 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@casl/ability": "^6.3.3",
|
"@casl/ability": "^6.3.3",
|
||||||
"@casl/vue": "^2.2.1",
|
"@casl/vue": "^2.2.1",
|
||||||
|
"@cosmjs/crypto": "^0.29.5",
|
||||||
|
"@cosmjs/encoding": "^0.29.5",
|
||||||
"@floating-ui/dom": "^1.2.0",
|
"@floating-ui/dom": "^1.2.0",
|
||||||
"@iconify/vue": "^4.1.0",
|
"@iconify/vue": "^4.1.0",
|
||||||
"@intlify/unplugin-vue-i18n": "^0.8.2",
|
"@intlify/unplugin-vue-i18n": "^0.8.2",
|
||||||
|
@ -23,8 +23,8 @@ const series = computed(() => {
|
|||||||
<VTabs v-model="kind" align-tabs="end"><VTab value="price">Price</VTab><VTab value="volume">Volume</VTab></VTabs>
|
<VTabs v-model="kind" align-tabs="end"><VTab value="price">Price</VTab><VTab value="volume">Volume</VTab></VTabs>
|
||||||
<VueApexCharts
|
<VueApexCharts
|
||||||
type="area"
|
type="area"
|
||||||
|
height="261"
|
||||||
:options="chartConfig"
|
:options="chartConfig"
|
||||||
:series="series"
|
:series="series"
|
||||||
style="max-height: 280px;"
|
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
@ -18,9 +18,8 @@ export const getMarketPriceChartConfig = (themeColors: ThemeInstance['themes']['
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
chart: {
|
chart: {
|
||||||
redrawOnParentResize: false,
|
redrawOnParentResize: true,
|
||||||
width: '100%',
|
width: '100%',
|
||||||
height: '260px;',
|
|
||||||
parentHeightOffset: 0,
|
parentHeightOffset: 0,
|
||||||
toolbar: { show: false },
|
toolbar: { show: false },
|
||||||
},
|
},
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
import { useBlockchain, useBaseStore } from '@/stores';
|
import { useBlockchain, useBaseStore } from '@/stores';
|
||||||
const chainStore = useBlockchain()
|
const chainStore = useBlockchain()
|
||||||
const baseStore = useBaseStore()
|
const baseStore = useBaseStore()
|
||||||
|
chainStore.initial()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -33,14 +33,14 @@ const baseStore = useBaseStore()
|
|||||||
>
|
>
|
||||||
<VList>
|
<VList>
|
||||||
<!-- 👉 Rest -->
|
<!-- 👉 Rest -->
|
||||||
<VListSubheader v-if="chainStore.current.endpoints?.rest" title="Rest Endpoint" />
|
<VListSubheader v-if="chainStore.current?.endpoints?.rpc" title="Rest Endpoint" />
|
||||||
<VListItem v-for="i in chainStore.current.endpoints?.rest" link @click="chainStore.setRestEndpoint(i.address)">
|
<VListItem v-for="i in chainStore.current?.endpoints?.rpc" link @click="chainStore.setRestEndpoint(i)">
|
||||||
<VListItemTitle>{{ i.provider }} <VIcon v-if="chainStore.availableEndpoint && i.address === chainStore.availableEndpoint" icon="mdi-check" color="success" /></VListItemTitle>
|
<VListItemTitle>{{ i.provider }} <VIcon v-if="i.address === chainStore.endpoint?.address" icon="mdi-check" color="success" /></VListItemTitle>
|
||||||
<VListItemSubtitle>{{ i.address }}</VListItemSubtitle>
|
<VListItemSubtitle>{{ i.address }}</VListItemSubtitle>
|
||||||
</VListItem>
|
</VListItem>
|
||||||
|
|
||||||
<VListSubheader v-if="chainStore.current.endpoints?.grpc" title="gRPC Endpoint" />
|
<VListSubheader v-if="chainStore.current?.endpoints?.grpc" title="gRPC Endpoint" />
|
||||||
<VListItem v-for="i in chainStore.current.endpoints?.grpc" link>
|
<VListItem v-for="i in chainStore.current?.endpoints?.grpc" link>
|
||||||
<VListItemTitle>{{ i.provider }}</VListItemTitle>
|
<VListItemTitle>{{ i.provider }}</VListItemTitle>
|
||||||
<VListItemSubtitle>{{ i.address }}</VListItemSubtitle>
|
<VListItemSubtitle>{{ i.address }}</VListItemSubtitle>
|
||||||
</VListItem>
|
</VListItem>
|
||||||
@ -50,7 +50,7 @@ const baseStore = useBaseStore()
|
|||||||
</VAvatar>
|
</VAvatar>
|
||||||
</VBadge>
|
</VBadge>
|
||||||
</template>
|
</template>
|
||||||
<VListItemTitle>{{ baseStore.latest.block?.header?.chain_id || '' }}</VListItemTitle>
|
<VListItemTitle>{{ baseStore.latest.block?.header?.chain_id || chainStore.chainName || '' }}</VListItemTitle>
|
||||||
<VListItemSubtitle> {{ chainStore.availableEndpoint }}</VListItemSubtitle>
|
<VListItemSubtitle> {{ chainStore.connErr|| chainStore.endpoint.address }}</VListItemSubtitle>
|
||||||
</VListItem>
|
</VListItem>
|
||||||
</template>
|
</template>
|
||||||
|
@ -32,7 +32,7 @@ dashboard.initial()
|
|||||||
const blockchain = useBlockchain()
|
const blockchain = useBlockchain()
|
||||||
// blockchain.initial()
|
// blockchain.initial()
|
||||||
blockchain.$subscribe((m, s) => {
|
blockchain.$subscribe((m, s) => {
|
||||||
if(m.events.key === 'rest') {
|
if(!Array.isArray(m.events) && m.events.key === 'chainName') {
|
||||||
blockchain.initial()
|
blockchain.initial()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
36
packages/dashboard/src/libs/address.ts
Normal file
36
packages/dashboard/src/libs/address.ts
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import {fromBase64, fromBech32, toBech32, toHex} from '@cosmjs/encoding'
|
||||||
|
import { sha256 } from '@cosmjs/crypto'
|
||||||
|
|
||||||
|
export function decodeAddress(address: string) {
|
||||||
|
return fromBech32(address)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function valoperToPrefix(valoper: string) {
|
||||||
|
const prefixIndex = valoper.indexOf('valoper')
|
||||||
|
if (prefixIndex === -1) return null
|
||||||
|
return valoper.slice(0, prefixIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function operatorAddressToAccount(operAddress: string) {
|
||||||
|
const { prefix, data } = fromBech32(operAddress)
|
||||||
|
if (prefix === 'iva') { // handle special cases
|
||||||
|
return toBech32('iaa', data)
|
||||||
|
}
|
||||||
|
if (prefix === 'crocncl') { // handle special cases
|
||||||
|
return toBech32('cro', data)
|
||||||
|
}
|
||||||
|
return toBech32(prefix.replace('valoper', ''), data)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function pubKeyToValcons(pubkey: string, prefix: string) {
|
||||||
|
const addressData = sha256(fromBase64(pubkey.key)).slice(0, 20)
|
||||||
|
return toBech32(`${prefix}valcons`, addressData)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function toETHAddress(cosmosAddress: string) {
|
||||||
|
return `0x${toHex(fromBech32(cosmosAddress).data)}`
|
||||||
|
}
|
||||||
|
|
||||||
|
export function addressEnCode(prefix: string, pubkey: Uint8Array) {
|
||||||
|
return toBech32(prefix, pubkey)
|
||||||
|
}
|
114
packages/dashboard/src/libs/client.rpc.ts
Normal file
114
packages/dashboard/src/libs/client.rpc.ts
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
import { Tendermint34Client } from "@cosmjs/tendermint-rpc";
|
||||||
|
import { QueryClient, setupBankExtension, setupDistributionExtension, setupGovExtension, setupMintExtension, setupStakingExtension } from "@cosmjs/stargate";
|
||||||
|
import { cosmos } from '@ping-pub/codegen/src/index'
|
||||||
|
import type { BondStatus } from "@ping-pub/codegen/src/cosmos/staking/v1beta1/staking";
|
||||||
|
import long from "long";
|
||||||
|
import type { ProposalStatus } from "@ping-pub/codegen/src/cosmos/gov/v1/gov";
|
||||||
|
|
||||||
|
export declare type BondStatusString = keyof Pick<typeof BondStatus, "BOND_STATUS_BONDED" | "BOND_STATUS_UNBONDED" | "BOND_STATUS_UNBONDING"> | "";
|
||||||
|
|
||||||
|
export class RPCClient {
|
||||||
|
tmClient?: Tendermint34Client;
|
||||||
|
queryClient?: QueryClient;
|
||||||
|
endpoint: string;
|
||||||
|
constructor(endpoint: string) {
|
||||||
|
this.endpoint = endpoint
|
||||||
|
}
|
||||||
|
async getTMClient() {
|
||||||
|
if(this.tmClient) {
|
||||||
|
return this.tmClient
|
||||||
|
} else {
|
||||||
|
return await Tendermint34Client.connect(this.endpoint)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async getQueryClient() {
|
||||||
|
if(this.queryClient) {
|
||||||
|
return this.queryClient
|
||||||
|
} else {
|
||||||
|
return new QueryClient(await this.getTMClient())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async supplyOf(denom: string) {
|
||||||
|
return cosmos.bank.v1beta1.createRpcQueryExtension(await this.getQueryClient()).supplyOf({denom})
|
||||||
|
}
|
||||||
|
async balance(address: string, denom: string) {
|
||||||
|
return cosmos.bank.v1beta1.createRpcQueryExtension(await this.getQueryClient()).balance({address, denom})
|
||||||
|
}
|
||||||
|
async allBalance(address: string) {
|
||||||
|
return cosmos.bank.v1beta1.createRpcQueryExtension(await this.getQueryClient()).allBalances({address})
|
||||||
|
}
|
||||||
|
async block(height?: number) {
|
||||||
|
return (await this.getTMClient()).block(height)
|
||||||
|
}
|
||||||
|
async abciInfo() {
|
||||||
|
return (await this.getTMClient()).abciInfo()
|
||||||
|
}
|
||||||
|
async status() {
|
||||||
|
return (await this.getTMClient()).status()
|
||||||
|
}
|
||||||
|
async validatorsAtHeight(height?: number) {
|
||||||
|
return (await this.getTMClient()).validatorsAll(height)
|
||||||
|
}
|
||||||
|
|
||||||
|
async proposal(id: number) {
|
||||||
|
return cosmos.gov.v1beta1.createRpcQueryExtension(await this.getQueryClient()).proposal({proposalId: long.fromNumber(id)})
|
||||||
|
}
|
||||||
|
async tally(id: number) {
|
||||||
|
return cosmos.gov.v1beta1.createRpcQueryExtension(await this.getQueryClient()).tallyResult({proposalId: long.fromNumber(id)})
|
||||||
|
}
|
||||||
|
async proposals(proposalStatus: ProposalStatus, depositor: string, voter: string, ) {
|
||||||
|
return cosmos.gov.v1beta1.createRpcQueryExtension(await this.getQueryClient()).proposals({proposalStatus, depositor, voter, })
|
||||||
|
}
|
||||||
|
async govParam() {
|
||||||
|
const gov = cosmos.gov.v1beta1.createRpcQueryExtension(await this.getQueryClient())
|
||||||
|
const deposit = (await gov.params({paramsType: 'deposit'})).depositParams
|
||||||
|
const voting = (await gov.params({paramsType: 'voting'})).votingParams
|
||||||
|
const tally = (await gov.params({paramsType: 'tallying'})).tallyParams
|
||||||
|
return {
|
||||||
|
deposit, voting, tally
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async communityPool() {
|
||||||
|
return cosmos.distribution.v1beta1.createRpcQueryExtension(await this.getQueryClient()).communityPool()
|
||||||
|
}
|
||||||
|
async distributionParam() {
|
||||||
|
return cosmos.distribution.v1beta1.createRpcQueryExtension(await this.getQueryClient()).params()
|
||||||
|
}
|
||||||
|
async validatorCommission(validatorAddress: string) {
|
||||||
|
return cosmos.distribution.v1beta1.createRpcQueryExtension(await this.getQueryClient()).validatorCommission({validatorAddress})
|
||||||
|
}
|
||||||
|
async validatorOutstandingRewards(validatorAddress: string) {
|
||||||
|
return cosmos.distribution.v1beta1.createRpcQueryExtension(await this.getQueryClient()).validatorOutstandingRewards({validatorAddress})
|
||||||
|
}
|
||||||
|
async validatorSlashes(validatorAddress: string, start: number, end: number) {
|
||||||
|
const startingHeight = long.fromNumber(start)
|
||||||
|
const endingHeight = long.fromNumber(end)
|
||||||
|
return cosmos.distribution.v1beta1.createRpcQueryExtension(await this.getQueryClient()).validatorSlashes({validatorAddress, startingHeight, endingHeight})
|
||||||
|
}
|
||||||
|
async delegationRewards(delegatorAddress: string, validatorAddress: string) {
|
||||||
|
return cosmos.distribution.v1beta1.createRpcQueryExtension(await this.getQueryClient()).delegationRewards({delegatorAddress, validatorAddress})
|
||||||
|
}
|
||||||
|
async stakingPool() {
|
||||||
|
return cosmos.staking.v1beta1.createRpcQueryExtension(await this.getQueryClient()).pool()
|
||||||
|
}
|
||||||
|
async validator(validatorAddr: string) {
|
||||||
|
return cosmos.staking.v1beta1.createRpcQueryExtension(await this.getQueryClient()).validator({validatorAddr})
|
||||||
|
}
|
||||||
|
async validators(status: BondStatusString, key?: Uint8Array) {
|
||||||
|
return cosmos.staking.v1beta1.createRpcQueryExtension(await this.getQueryClient()).validators({status})
|
||||||
|
}
|
||||||
|
async stakingParams() {
|
||||||
|
return cosmos.staking.v1beta1.createRpcQueryExtension(await this.getQueryClient()).params()
|
||||||
|
}
|
||||||
|
async historicalInfo(height: number) {
|
||||||
|
return cosmos.staking.v1beta1.createRpcQueryExtension(await this.getQueryClient()).historicalInfo({height: long.fromNumber(height)})
|
||||||
|
}
|
||||||
|
async mintParams() {
|
||||||
|
return cosmos.mint.v1beta1.createRpcQueryExtension(await this.getQueryClient()).params()
|
||||||
|
}
|
||||||
|
async inflation() {
|
||||||
|
return cosmos.mint.v1beta1.createRpcQueryExtension(await this.getQueryClient()).inflation()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
4
packages/dashboard/src/libs/index.ts
Normal file
4
packages/dashboard/src/libs/index.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
export * from './address'
|
||||||
|
export * from './client'
|
||||||
|
export * from './http'
|
||||||
|
export * from './misc'
|
13
packages/dashboard/src/libs/misc.ts
Normal file
13
packages/dashboard/src/libs/misc.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import { PageRequest } from "@ping-pub/codegen/src/cosmos/base/query/v1beta1/pagination";
|
||||||
|
|
||||||
|
export function newPageRequest(param: {
|
||||||
|
key?: Uint8Array,
|
||||||
|
limit?: number,
|
||||||
|
offset?: number,
|
||||||
|
countTotal?: boolean,
|
||||||
|
reverse?: boolean
|
||||||
|
}) {
|
||||||
|
return PageRequest.fromPartial(
|
||||||
|
param
|
||||||
|
)
|
||||||
|
}
|
@ -17,7 +17,6 @@ loadFonts();
|
|||||||
|
|
||||||
// Create vue app
|
// Create vue app
|
||||||
const app = createApp(App);
|
const app = createApp(App);
|
||||||
|
|
||||||
// Use plugins
|
// Use plugins
|
||||||
app.use(i18n)
|
app.use(i18n)
|
||||||
app.use(vuetify);
|
app.use(vuetify);
|
||||||
|
@ -23,14 +23,11 @@ onMounted(() => {
|
|||||||
|
|
||||||
const format = useFormatter()
|
const format = useFormatter()
|
||||||
const ticker = computed(() => store.coinInfo.tickers[store.tickerIndex])
|
const ticker = computed(() => store.coinInfo.tickers[store.tickerIndex])
|
||||||
const desc = ref('')
|
|
||||||
const detailId = ref('')
|
|
||||||
|
|
||||||
store.$subscribe((m, s) => {
|
|
||||||
desc.value = s.coinInfo.description?.en || ''
|
|
||||||
})
|
|
||||||
blockchain.$subscribe((m, s) => {
|
blockchain.$subscribe((m, s) => {
|
||||||
if(m.events.key === 'rest') {
|
console.log('index:', m)
|
||||||
|
if(!Array.isArray(m.events) && ['chainName', 'endpoint'].includes(m.events.key)) {
|
||||||
|
console.log(m.events.key)
|
||||||
store.loadDashboard()
|
store.loadDashboard()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -44,7 +41,7 @@ function shortName(name: string, id: string) {
|
|||||||
<div>
|
<div>
|
||||||
<VCard v-if="coinInfo && coinInfo.name" class="mb-5">
|
<VCard v-if="coinInfo && coinInfo.name" class="mb-5">
|
||||||
<VRow>
|
<VRow>
|
||||||
<VCol md="4">
|
<VCol md="5">
|
||||||
<VCardItem>
|
<VCardItem>
|
||||||
<VCardTitle>
|
<VCardTitle>
|
||||||
{{ coinInfo.name }} (<span class="text-uppercase">{{ coinInfo.symbol }}</span>)
|
{{ coinInfo.name }} (<span class="text-uppercase">{{ coinInfo.symbol }}</span>)
|
||||||
@ -120,7 +117,7 @@ function shortName(name: string, id: string) {
|
|||||||
</VBtn>
|
</VBtn>
|
||||||
</VCardItem>
|
</VCardItem>
|
||||||
</VCol>
|
</VCol>
|
||||||
<VCol md="8">
|
<VCol md="7">
|
||||||
<VCardItem>
|
<VCardItem>
|
||||||
<PriceMarketChart />
|
<PriceMarketChart />
|
||||||
</VCardItem>
|
</VCardItem>
|
||||||
@ -129,7 +126,7 @@ function shortName(name: string, id: string) {
|
|||||||
<VDivider />
|
<VDivider />
|
||||||
<VCardText style="max-height: 250px; overflow:scroll;"><MdEditor :model-value="coinInfo.description?.en" previewOnly></MdEditor></VCardText>
|
<VCardText style="max-height: 250px; overflow:scroll;"><MdEditor :model-value="coinInfo.description?.en" previewOnly></MdEditor></VCardText>
|
||||||
<VCardItem>
|
<VCardItem>
|
||||||
<VChip v-for="tag in coinInfo.categories" size="x-small">{{ tag }}</VChip>
|
<VChip v-for="tag in coinInfo.categories" size="x-small" class="mr-2">{{ tag }}</VChip>
|
||||||
</VCardItem>
|
</VCardItem>
|
||||||
</VCard>
|
</VCard>
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ import { useBlockchain, useCoingecko, useBaseStore, useBankStore, useFormatter,
|
|||||||
import { useDistributionStore } from "@/stores/useDistributionStore";
|
import { useDistributionStore } from "@/stores/useDistributionStore";
|
||||||
import { useMintStore } from "@/stores/useMintStore";
|
import { useMintStore } from "@/stores/useMintStore";
|
||||||
import { useStakingStore } from "@/stores/useStakingStore";
|
import { useStakingStore } from "@/stores/useStakingStore";
|
||||||
import { ProposalStatus, type ProposalSDKType } from "@ping-pub/codegen/src/cosmos/gov/v1beta1/gov";
|
import { ProposalStatus, type ProposalSDKType, Proposal } from "@ping-pub/codegen/src/cosmos/gov/v1beta1/gov";
|
||||||
import numeral from "numeral";
|
import numeral from "numeral";
|
||||||
import { defineStore } from "pinia";
|
import { defineStore } from "pinia";
|
||||||
|
|
||||||
@ -65,12 +65,12 @@ export const useIndexModule = defineStore('module-index', {
|
|||||||
total_volumes: [] as number[],
|
total_volumes: [] as number[],
|
||||||
},
|
},
|
||||||
communityPool: [] as {amount: string, denom: string}[],
|
communityPool: [] as {amount: string, denom: string}[],
|
||||||
proposals: [] as ProposalSDKType[],
|
proposals: [] as Proposal[],
|
||||||
tally: {} as Record<number, {
|
tally: {} as Record<number, {
|
||||||
yes: string;
|
yes: string;
|
||||||
abstain: string;
|
abstain: string;
|
||||||
no: string;
|
no: string;
|
||||||
no_with_veto: string;
|
noWithVeto: string;
|
||||||
}>
|
}>
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -102,7 +102,6 @@ export const useIndexModule = defineStore('module-index', {
|
|||||||
|
|
||||||
priceChange(): string {
|
priceChange(): string {
|
||||||
const change = this.coinInfo.market_data?.price_change_percentage_24h || 0
|
const change = this.coinInfo.market_data?.price_change_percentage_24h || 0
|
||||||
console.log(change, 'change')
|
|
||||||
return numeral(change).format('+0.[00]')
|
return numeral(change).format('+0.[00]')
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -122,10 +121,6 @@ export const useIndexModule = defineStore('module-index', {
|
|||||||
return colorMap(change)
|
return colorMap(change)
|
||||||
},
|
},
|
||||||
|
|
||||||
mintStore() {
|
|
||||||
return useMintStore()
|
|
||||||
},
|
|
||||||
|
|
||||||
pool() {
|
pool() {
|
||||||
const staking = useStakingStore()
|
const staking = useStakingStore()
|
||||||
return staking.pool
|
return staking.pool
|
||||||
@ -135,7 +130,9 @@ export const useIndexModule = defineStore('module-index', {
|
|||||||
const base = useBaseStore()
|
const base = useBaseStore()
|
||||||
const bank = useBankStore()
|
const bank = useBankStore()
|
||||||
const staking = useStakingStore()
|
const staking = useStakingStore()
|
||||||
|
const mintStore = useMintStore()
|
||||||
const formatter = useFormatter()
|
const formatter = useFormatter()
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
title: 'Height',
|
title: 'Height',
|
||||||
@ -148,7 +145,7 @@ export const useIndexModule = defineStore('module-index', {
|
|||||||
title: 'Validators',
|
title: 'Validators',
|
||||||
color: 'error',
|
color: 'error',
|
||||||
icon: 'mdi-human-queue',
|
icon: 'mdi-human-queue',
|
||||||
stats: String(base.latest.block?.last_commit?.signatures.length || 0),
|
stats: String(base.latest.block?.lastCommit?.signatures.length || 0),
|
||||||
change: 0,
|
change: 0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -162,14 +159,14 @@ export const useIndexModule = defineStore('module-index', {
|
|||||||
title: 'Bonded Tokens',
|
title: 'Bonded Tokens',
|
||||||
color: 'warning',
|
color: 'warning',
|
||||||
icon: 'mdi-lock',
|
icon: 'mdi-lock',
|
||||||
stats: formatter.formatTokenAmount({amount: this.pool.bonded_tokens, denom: staking.params.bond_denom }),
|
stats: formatter.formatTokenAmount({amount: this.pool.bondedTokens, denom: staking.params.bondDenom }),
|
||||||
change: 0,
|
change: 0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Inflation',
|
title: 'Inflation',
|
||||||
color: 'success',
|
color: 'success',
|
||||||
icon: 'mdi-chart-multiple',
|
icon: 'mdi-chart-multiple',
|
||||||
stats: formatter.formatDecimalToPercent(this.mintStore.inflation),
|
stats: formatter.formatDecimalToPercent(mintStore.inflation),
|
||||||
change: 0,
|
change: 0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -184,25 +181,25 @@ export const useIndexModule = defineStore('module-index', {
|
|||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
async loadDashboard() {
|
async loadDashboard() {
|
||||||
|
console.log('initial dashboard')
|
||||||
this.$reset()
|
this.$reset()
|
||||||
this.initCoingecko()
|
this.initCoingecko()
|
||||||
this.mintStore.fetchInflation()
|
useMintStore().fetchInflation()
|
||||||
const dist = useDistributionStore()
|
useDistributionStore().fetchCommunityPool().then(x => {
|
||||||
dist.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)),
|
amount: String(parseInt(t.amount)),
|
||||||
denom: t.denom
|
denom: t.denom
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
const gov = useGovStore()
|
// const gov = useGovStore()
|
||||||
gov.fetchProposals(ProposalStatus.PROPOSAL_STATUS_VOTING_PERIOD).then(x => {
|
// gov.fetchProposals(ProposalStatus.PROPOSAL_STATUS_VOTING_PERIOD).then(x => {
|
||||||
this.proposals = x.proposals
|
// this.proposals = x.proposals
|
||||||
x.proposals.forEach(x1 => {
|
// x.proposals.forEach(x1 => {
|
||||||
gov.fetchTally(x1.proposal_id).then(t => {
|
// gov.fetchTally(Number(x1.proposalId)).then(t => {
|
||||||
if(t.tally) this.tally[Number(x1.proposal_id)] = t.tally
|
// if(t.tally) this.tally[Number(x1.proposalId)] = t.tally
|
||||||
})
|
// })
|
||||||
})
|
// })
|
||||||
})
|
// })
|
||||||
},
|
},
|
||||||
tickerColor(color: string) {
|
tickerColor(color: string) {
|
||||||
return colorMap(color)
|
return colorMap(color)
|
||||||
|
@ -0,0 +1,55 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { useStakingStore } from '@/stores';
|
||||||
|
import type { QueryValidatorResponseSDKType } from '@ping-pub/codegen/src/cosmos/staking/v1beta1/query';
|
||||||
|
import { onMounted } from 'vue';
|
||||||
|
import { useRoute } from 'vue-router';
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
const staking = useStakingStore()
|
||||||
|
const { validator } = route.params
|
||||||
|
const v = ref({} as QueryValidatorResponseSDKType)
|
||||||
|
const cache = JSON.parse(localStorage.getItem('avatars')||'{}')
|
||||||
|
const avatars = ref( cache || {} )
|
||||||
|
const identity = ref("")
|
||||||
|
|
||||||
|
onMounted(()=> {
|
||||||
|
if(validator) {
|
||||||
|
staking.fetchValidator(validator.toString()).then(res => {
|
||||||
|
v.value = res.validator
|
||||||
|
identity.value = res.validator?.description?.identity
|
||||||
|
if(identity.value && !avatars.value[identity.value]) {
|
||||||
|
console.log(identity.value, avatars)
|
||||||
|
staking.keybase(identity.value).then(d => {
|
||||||
|
if (Array.isArray(d.them) && d.them.length > 0) {
|
||||||
|
const uri = String(d.them[0]?.pictures?.primary?.url).replace("https://s3.amazonaws.com/keybase_processed_uploads/", "")
|
||||||
|
if(uri) {
|
||||||
|
avatars.value[identity.value] = uri
|
||||||
|
localStorage.setItem('avatars', JSON.stringify(avatars.value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<VCard class="card-box">
|
||||||
|
<VCardItem>
|
||||||
|
<VRow>
|
||||||
|
<VCol cols="12" md="6">
|
||||||
|
<VAvatar icon="mdi-help-circle-outline" :image="avatars[identity]" size="80" rounded variant="outlined" color="secondary"/>
|
||||||
|
<VList>
|
||||||
|
<VListItem>
|
||||||
|
<VListItemTitle>{{ v.description?.moniker }}</VListItemTitle>
|
||||||
|
<VListItemSubtitle> {{ v.description?.website || v.description?.identity || '-'}}</VListItemsubtitle>
|
||||||
|
</VListItem>
|
||||||
|
</VList>
|
||||||
|
</VCol>
|
||||||
|
<VCol cols="12" md="6">2</VCol>
|
||||||
|
</VRow>
|
||||||
|
</VCardItem>
|
||||||
|
</VCard>
|
||||||
|
</template>
|
226
packages/dashboard/src/modules/[chain]/staking/index.vue
Normal file
226
packages/dashboard/src/modules/[chain]/staking/index.vue
Normal file
@ -0,0 +1,226 @@
|
|||||||
|
<script lang=ts setup>
|
||||||
|
import { useBaseStore, useFormatter, useStakingStore } from '@/stores';
|
||||||
|
import type { ValidatorSDKType } from '@ping-pub/codegen/src/cosmos/staking/v1beta1/staking';
|
||||||
|
import { computed } from '@vue/reactivity';
|
||||||
|
import { onMounted, ref, type DebuggerEvent } from 'vue';
|
||||||
|
|
||||||
|
const staking = useStakingStore()
|
||||||
|
const format = useFormatter()
|
||||||
|
|
||||||
|
const cache = JSON.parse(localStorage.getItem('avatars')||'{}')
|
||||||
|
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([] as ValidatorSDKType[])
|
||||||
|
|
||||||
|
onMounted(()=> {
|
||||||
|
fetchChange(0)
|
||||||
|
staking.fetchInacitveValdiators().then(x => {
|
||||||
|
unbondList.value = x
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
function fetchChange(offset: number) {
|
||||||
|
const base = useBaseStore()
|
||||||
|
const diff = 86400000 / base.blocktime
|
||||||
|
base.fetchLatestValidators(offset).then(x => {
|
||||||
|
const height = Number(x.block_height) - diff
|
||||||
|
x.validators.forEach(v => {
|
||||||
|
latest.value[v.pub_key?.key] = Number(v.voting_power)
|
||||||
|
})
|
||||||
|
const len = Object.keys(latest.value).length
|
||||||
|
if(x.pagination && len < Number(x.pagination.total) ) {
|
||||||
|
fetchChange(len)
|
||||||
|
}
|
||||||
|
base.fetchValidatorByHeight(height > 0 ? height : 1, offset).then(old => {
|
||||||
|
old.validators.forEach(v => {
|
||||||
|
yesterday.value[v.pub_key?.key] = Number(v.voting_power)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const change24 = (key: string) => {
|
||||||
|
const n : number = latest.value[key];
|
||||||
|
const o : number = yesterday.value[key]
|
||||||
|
return n >0 && o > 0 ? n - o : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
const change24Text = (key?: string) => {
|
||||||
|
if(!key) return ''
|
||||||
|
const v = change24(key)
|
||||||
|
return v!==0 ? format.numberAndSign(v) : ''
|
||||||
|
}
|
||||||
|
|
||||||
|
const change24Color = (key?: string) => {
|
||||||
|
if(!key) return ''
|
||||||
|
const v = change24(key)
|
||||||
|
if(v > 0) return 'text-success'
|
||||||
|
if(v < 0) return 'text-error'
|
||||||
|
}
|
||||||
|
|
||||||
|
const update = (m: DebuggerEvent) => {
|
||||||
|
if(m.key === 'validators') {
|
||||||
|
loadAvatars()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const list = computed(() => {
|
||||||
|
return tab.value === 'active' ? staking.validators: unbondList.value
|
||||||
|
})
|
||||||
|
|
||||||
|
const loadAvatars = () => {
|
||||||
|
// fetch avatar from keybase
|
||||||
|
let promise = Promise.resolve()
|
||||||
|
staking.validators.forEach(item => {
|
||||||
|
promise = promise.then(() => new Promise(resolve => {
|
||||||
|
const identity = item.description?.identity
|
||||||
|
if(identity && !avatars.value[identity]){
|
||||||
|
staking.keybase(identity).then(d => {
|
||||||
|
if (Array.isArray(d.them) && d.them.length > 0) {
|
||||||
|
const uri = String(d.them[0]?.pictures?.primary?.url).replace("https://s3.amazonaws.com/keybase_processed_uploads/", "")
|
||||||
|
if(uri) {
|
||||||
|
avatars.value[identity] = uri
|
||||||
|
localStorage.setItem('avatars', JSON.stringify(avatars.value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resolve()
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
resolve()
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
staking.$subscribe((m, s)=> {
|
||||||
|
if (Array.isArray(m.events)) {
|
||||||
|
m.events.forEach(x => {
|
||||||
|
update(x)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
update(m.events)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const logo = (identity?: string) => {
|
||||||
|
if(!identity) return ''
|
||||||
|
const url = avatars.value[identity] || ''
|
||||||
|
return url.startsWith('http')? url: `https://s3.amazonaws.com/keybase_processed_uploads/${url}`
|
||||||
|
}
|
||||||
|
const rank = function(position: number) {
|
||||||
|
let sum = 0
|
||||||
|
for(let i = 0;i < position; i++) {
|
||||||
|
sum += Number(staking.validators[i]?.delegator_shares)
|
||||||
|
}
|
||||||
|
const percent = (sum / staking.totalPower)
|
||||||
|
|
||||||
|
switch (true) {
|
||||||
|
case tab.value ==='active' && percent < 0.33: return 'error'
|
||||||
|
case tab.value ==='active' && percent < 0.67: return 'warning'
|
||||||
|
default: return 'primary'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<VCard>
|
||||||
|
<VCardTitle class="d-flex justify-space-between">
|
||||||
|
<VBtnToggle v-model="tab" size="small" color="primary">
|
||||||
|
<VBtn value="active" variant="outlined" >Active</VBtn>
|
||||||
|
<VBtn value="inactive" variant="outlined">Inactive</VBtn>
|
||||||
|
</VBtnToggle>
|
||||||
|
<span class="mt-2">{{ list.length }}/{{ staking.params.max_validators }}</span>
|
||||||
|
</VCardTitle>
|
||||||
|
<VTable class="text-no-wrap table-header-bg rounded-0">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th
|
||||||
|
scope="col"
|
||||||
|
style="width: 3rem;"
|
||||||
|
>#</th>
|
||||||
|
<th scope="col">
|
||||||
|
VALIDATOR
|
||||||
|
</th>
|
||||||
|
<th scope="col" class="text-right">
|
||||||
|
VOTING POWER
|
||||||
|
</th>
|
||||||
|
<th scope="col" class="text-right">
|
||||||
|
24h CHANGES
|
||||||
|
</th>
|
||||||
|
<th scope="col" class="text-right">
|
||||||
|
COMMISSION
|
||||||
|
</th>
|
||||||
|
<th scope="col">
|
||||||
|
ACTIONS
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr
|
||||||
|
v-for="(v, i) in list"
|
||||||
|
:key="v.operator_address"
|
||||||
|
>
|
||||||
|
<!-- 👉 rank -->
|
||||||
|
<td>
|
||||||
|
<VChip label :color="rank(i)">
|
||||||
|
{{ i + 1 }}
|
||||||
|
</VChip>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<!-- 👉 Validator -->
|
||||||
|
<td>
|
||||||
|
<div class="d-flex align-center overflow-hidden" style="max-width: 400px;">
|
||||||
|
<VAvatar
|
||||||
|
variant="tonal"
|
||||||
|
class="me-3"
|
||||||
|
size="34"
|
||||||
|
icon="mdi-help-circle-outline"
|
||||||
|
:image="logo(v.description?.identity)"
|
||||||
|
/>
|
||||||
|
<div class="d-flex flex-column">
|
||||||
|
<h6 class="text-sm">
|
||||||
|
<RouterLink
|
||||||
|
:to="{name: 'chain-staking-validator', params: {validator: v.operator_address}}"
|
||||||
|
class="font-weight-medium user-list-name"
|
||||||
|
>
|
||||||
|
{{ v.description?.moniker }}
|
||||||
|
</RouterLink>
|
||||||
|
|
||||||
|
</h6>
|
||||||
|
<span class="text-xs">{{ v.description?.website || v.description?.identity || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<!-- 👉 Voting Power -->
|
||||||
|
<td class="text-right">
|
||||||
|
<div class="d-flex flex-column">
|
||||||
|
<h6 class="text-sm font-weight-medium">
|
||||||
|
{{ format.formatToken( {amount: parseInt(v.delegator_shares).toString(), denom: staking.params.bond_denom }, true, "0,0") }}
|
||||||
|
</h6>
|
||||||
|
<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.consensus_pubkey?.key)">
|
||||||
|
{{ change24Text(v.consensus_pubkey?.key) }} <VChip label v-if="v.jailed" color="error">Jailed</VChip>
|
||||||
|
</td>
|
||||||
|
<!-- 👉 commission -->
|
||||||
|
<td class="text-right">
|
||||||
|
{{ format.percent(v.commission?.commission_rates?.rate) }}
|
||||||
|
</td>
|
||||||
|
<!-- 👉 Action -->
|
||||||
|
<td>
|
||||||
|
{{ 2 }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</VTable>
|
||||||
|
<VDivider/>
|
||||||
|
<VCardActions class="py-2">
|
||||||
|
<VChip label color="error">Top 33%</VChip> <VChip label color="warning" class="mx-2">Top 67%</VChip>
|
||||||
|
</VCardActions>
|
||||||
|
</VCard>
|
||||||
|
</div>
|
||||||
|
</template>
|
@ -4,6 +4,9 @@ import ChainSummary from '@/components/ChainSummary.vue';
|
|||||||
import { computed, ref } from 'vue';
|
import { computed, ref } from 'vue';
|
||||||
import { useBlockchain } from '@/stores';
|
import { useBlockchain } from '@/stores';
|
||||||
|
|
||||||
|
import { Tendermint34Client } from "@cosmjs/tendermint-rpc";
|
||||||
|
import { QueryClient, setupBankExtension, setupDistributionExtension, setupGovExtension, setupMintExtension, setupStakingExtension } from "@cosmjs/stargate";
|
||||||
|
|
||||||
const dashboard = useDashboard()
|
const dashboard = useDashboard()
|
||||||
|
|
||||||
dashboard.$subscribe((mutation, state) => {
|
dashboard.$subscribe((mutation, state) => {
|
||||||
@ -18,6 +21,7 @@ const chains = computed(()=> {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
const chain = useBlockchain()
|
const chain = useBlockchain()
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div class="d-flex flex-column justify-center">
|
<div class="d-flex flex-column justify-center">
|
||||||
|
11
packages/dashboard/src/plugins/pinia/ClientProperties.ts
Normal file
11
packages/dashboard/src/plugins/pinia/ClientProperties.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import type { RPCClient } from '@/libs/client.rpc'
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
10
packages/dashboard/src/plugins/pinia/dashboardPlugin.ts
Normal file
10
packages/dashboard/src/plugins/pinia/dashboardPlugin.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import type { PiniaPluginContext } from "pinia"
|
||||||
|
|
||||||
|
export function DashboardPlugin(context: PiniaPluginContext) {
|
||||||
|
context.pinia // the pinia created with `createPinia()`
|
||||||
|
context.app // the current app created with `createApp()` (Vue 3 only)
|
||||||
|
context.store // the store the plugin is augmenting
|
||||||
|
context.options // the options object defining the store passed to `defineStore()`
|
||||||
|
// ...
|
||||||
|
context.store.$subscribe((m, s) => console.log(m, s))
|
||||||
|
}
|
@ -1 +1,4 @@
|
|||||||
// Write your overrides
|
// Write your overrides
|
||||||
|
.card-box {
|
||||||
|
border: 1px solid rgb(var(--v-theme-primary));
|
||||||
|
}
|
@ -1,65 +1,48 @@
|
|||||||
import { defineStore } from "pinia";
|
import { defineStore } from "pinia";
|
||||||
|
|
||||||
import { useBlockchain } from "./useBlockchain";
|
import { useBlockchain } from "./useBlockchain";
|
||||||
import { createBankClientForChain } from "@/libs/client";
|
import type { QueryTotalSupplyResponse, QueryTotalSupplyRequest } from "@ping-pub/codegen/src/cosmos/bank/v1beta1/query";
|
||||||
import { QuerySupplyOfRequest, type QueryTotalSupplyRequest, type QueryTotalSupplyResponseSDKType } from "@ping-pub/codegen/src/cosmos/bank/v1beta1/query";
|
import type { Coin } from "@ping-pub/codegen/src/cosmos/base/v1beta1/coin";
|
||||||
import type { CoinSDKType } from "@ping-pub/codegen/src/cosmos/base/v1beta1/coin";
|
|
||||||
import { useStakingStore } from "./useStakingStore";
|
import { useStakingStore } from "./useStakingStore";
|
||||||
|
import { createRpcQueryExtension } from '@ping-pub/codegen/src/cosmos/bank/v1beta1/query.rpc.Query'
|
||||||
|
import { Tendermint34Client } from "@cosmjs/tendermint-rpc";
|
||||||
|
import { QueryClient } from "@cosmjs/stargate";
|
||||||
|
|
||||||
export const useBankStore = defineStore('bankstore', {
|
export const useBankStore = defineStore('bankstore', {
|
||||||
state: () => {
|
state: () => {
|
||||||
return {
|
return {
|
||||||
supply: {} as CoinSDKType,
|
supply: {} as Coin,
|
||||||
balances: {} as Record<string, CoinSDKType[]>,
|
balances: {} as Record<string, Coin[]>,
|
||||||
totalSupply: {supply: []} as QueryTotalSupplyResponseSDKType,
|
totalSupply: {supply: []} as QueryTotalSupplyResponse,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getters: {
|
getters: {
|
||||||
blockchain() {
|
blockchain() {
|
||||||
return useBlockchain()
|
return useBlockchain()
|
||||||
},
|
},
|
||||||
client() {
|
|
||||||
const chain = useBlockchain()
|
|
||||||
return createBankClientForChain(chain.chainName, chain.restClient)
|
|
||||||
},
|
|
||||||
staking() {
|
staking() {
|
||||||
return useStakingStore()
|
return useStakingStore()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
initial() {
|
initial() {
|
||||||
this.supply = {} as CoinSDKType
|
this.$reset()
|
||||||
const denom = this.staking.params.bond_denom || this.blockchain.current.assets[0].base
|
this.supply = {} as Coin
|
||||||
this.fetchSupply(denom).then(res => {
|
const denom = this.staking.params.bondDenom || this.blockchain.current?.assets[0].base
|
||||||
|
if(denom) {
|
||||||
|
this.blockchain.rpc.supplyOf(denom).then(res => {
|
||||||
if(res.amount) this.supply = res.amount
|
if(res.amount) this.supply = res.amount
|
||||||
})
|
})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
// async fetchTotalSupply(param: QueryTotalSupplyRequest): Promise<QueryTotalSupplyResponse> {
|
||||||
// cacheBalance(address: string, balances: CoinSDKType[]) {
|
// const response = await this.blockchain.rpc.(param)
|
||||||
// if(this.balances[address]) {
|
// this.totalSupply.supply = [...this.totalSupply.supply, ...response.supply]
|
||||||
// this.balances[address] = [...this.balances[address], ... balances]
|
// this.totalSupply.pagination = response.pagination
|
||||||
// }else {
|
|
||||||
// this.balances[address] = balances
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// async fetchBalance(param: QueryBalanceRequest) : Promise<QueryBalanceResponseSDKType> {
|
|
||||||
// const response : QueryBalanceResponseSDKType = await this.lcdClient.balance(param)
|
|
||||||
// if (response.balance) this.cacheBalance(param.address, [response.balance])
|
|
||||||
// return response
|
// return response
|
||||||
// },
|
// },
|
||||||
// async fetchAllBalance(param: QueryAllBalancesRequest) : Promise<QueryAllBalancesResponseSDKType> {
|
|
||||||
// const response : QueryAllBalancesResponseSDKType = await this.lcdClient.allBalances(param)
|
|
||||||
// if (response.balances) this.cacheBalance(param.address, response.balances)
|
|
||||||
// return response
|
|
||||||
// },
|
|
||||||
async fetchTotalSupply(param: QueryTotalSupplyRequest): Promise<QueryTotalSupplyResponseSDKType> {
|
|
||||||
const response = await this.client.totalSupply(param)
|
|
||||||
this.totalSupply.supply = [...this.totalSupply.supply, ...response.supply]
|
|
||||||
this.totalSupply.pagination = response.pagination
|
|
||||||
return response
|
|
||||||
},
|
|
||||||
async fetchSupply(denom: string) {
|
async fetchSupply(denom: string) {
|
||||||
return this.client.supplyOf( { denom } )
|
return this.blockchain.rpc.supplyOf( denom )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -1,19 +1,35 @@
|
|||||||
import { defineStore } from "pinia";
|
import { defineStore } from "pinia";
|
||||||
import { createBaseClientForChain } from "@/libs/client";
|
import { createBaseClientForChain } from "@/libs/client";
|
||||||
import { useBlockchain } from "@/stores";
|
import { useBlockchain } from "@/stores";
|
||||||
import type { GetLatestBlockResponseSDKType } from "@ping-pub/codegen/src/cosmos/base/tendermint/v1beta1/query";
|
import dayjs from "dayjs";
|
||||||
|
import long from "long";
|
||||||
|
import { PageRequest } from "@ping-pub/codegen/src/cosmos/base/query/v1beta1/pagination";
|
||||||
|
import { newPageRequest } from "@/libs";
|
||||||
|
|
||||||
|
import { createRpcQueryExtension } from '@ping-pub/codegen/src/cosmos/base/tendermint/v1beta1/query.rpc.Service'
|
||||||
|
import { Tendermint34Client, type BlockResponse } from "@cosmjs/tendermint-rpc";
|
||||||
|
import { QueryClient, createProtobufRpcClient, setupBankExtension, Setup } from "@cosmjs/stargate";
|
||||||
|
|
||||||
export const useBaseStore = defineStore('baseStore', {
|
export const useBaseStore = defineStore('baseStore', {
|
||||||
state: () => {
|
state: () => {
|
||||||
return {
|
return {
|
||||||
latest: {} as GetLatestBlockResponseSDKType,
|
earlest: {} as BlockResponse,
|
||||||
recents: [] as GetLatestBlockResponseSDKType[]
|
latest: {} as BlockResponse,
|
||||||
|
recents: [] as BlockResponse[]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getters: {
|
getters: {
|
||||||
client() {
|
blocktime(): number {
|
||||||
const chain = useBlockchain()
|
if(this.earlest && this.latest) {
|
||||||
return createBaseClientForChain(chain.chainName, chain.restClient)
|
if(this.latest.block?.header?.height !== this.earlest.block?.header?.height) {
|
||||||
|
const diff = dayjs(this.latest.block?.header?.time).diff(this.earlest.block?.header?.time)
|
||||||
|
return diff
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 6000
|
||||||
|
},
|
||||||
|
blockchain() {
|
||||||
|
return useBlockchain()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
@ -24,18 +40,30 @@ export const useBaseStore = defineStore('baseStore', {
|
|||||||
this.recents = []
|
this.recents = []
|
||||||
},
|
},
|
||||||
async fetchLatest() {
|
async fetchLatest() {
|
||||||
this.latest = await this.client.getLatestBlock()
|
this.latest = await this.blockchain.rpc.block()
|
||||||
|
if(!this.earlest || this.earlest.block?.header?.chainId != this.latest.block?.header?.chainId) {
|
||||||
|
//reset earlest and recents
|
||||||
|
this.earlest = this.latest
|
||||||
|
this.recents = []
|
||||||
|
}
|
||||||
if(this.recents.length>= 50) {
|
if(this.recents.length>= 50) {
|
||||||
this.recents.pop()
|
this.recents.pop()
|
||||||
}
|
}
|
||||||
this.recents.push(this.latest)
|
this.recents.push(this.latest)
|
||||||
return this.latest
|
return this.latest
|
||||||
},
|
},
|
||||||
async fetchSync() {
|
|
||||||
return this.client.getSyncing()
|
async fetchValidatorByHeight(height?: number, offset = 0) {
|
||||||
|
return this.blockchain.rpc.validatorsAtHeight(height)
|
||||||
},
|
},
|
||||||
async fetchNodeInfo() {
|
async fetchLatestValidators(offset = 0) {
|
||||||
return this.client.getNodeInfo()
|
return this.blockchain.rpc.validatorsAtHeight()
|
||||||
}
|
},
|
||||||
|
async fetchBlock(height: number) {
|
||||||
|
return this.blockchain.rpc.block(height)
|
||||||
|
},
|
||||||
|
// async fetchNodeInfo() {
|
||||||
|
// return this.blockchain.rpc.no()
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
})
|
})
|
@ -1,5 +1,5 @@
|
|||||||
import { defineStore } from "pinia";
|
import { defineStore } from "pinia";
|
||||||
import { useDashboard, type ChainConfig } from "./useDashboard";
|
import { useDashboard, type ChainConfig, type Endpoint, EndpointType } from "./useDashboard";
|
||||||
import { LCDClient } from '@osmonauts/lcd'
|
import { LCDClient } from '@osmonauts/lcd'
|
||||||
import type { VerticalNavItems } from '@/@layouts/types'
|
import type { VerticalNavItems } from '@/@layouts/types'
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
@ -7,36 +7,30 @@ import { useStakingStore } from "./useStakingStore";
|
|||||||
import { useBankStore } from "./useBankStore";
|
import { useBankStore } from "./useBankStore";
|
||||||
import { useBaseStore } from "./useBaseStore";
|
import { useBaseStore } from "./useBaseStore";
|
||||||
import { useGovStore } from "./useGovStore";
|
import { useGovStore } from "./useGovStore";
|
||||||
|
import { RPCClient } from '../libs/client.rpc'
|
||||||
|
import { ref } from "vue";
|
||||||
|
|
||||||
export const useBlockchain = defineStore("blockchain", {
|
export const useBlockchain = defineStore("blockchain", {
|
||||||
state: () => {
|
state: () => {
|
||||||
return {
|
return {
|
||||||
status: {} as Record<string, string>,
|
status: {} as Record<string, string>,
|
||||||
rest: '',
|
rest: '',
|
||||||
chainName: ""
|
chainName: "",
|
||||||
|
endpoint: {} as {
|
||||||
|
type?: EndpointType,
|
||||||
|
address: string
|
||||||
|
provider: string
|
||||||
|
},
|
||||||
|
connErr: ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getters: {
|
getters: {
|
||||||
current() : ChainConfig {
|
current() : ChainConfig | undefined {
|
||||||
return this.dashboard.chains[this.chainName]
|
return this.dashboard.chains[this.chainName]
|
||||||
},
|
},
|
||||||
logo(): string {
|
logo(): string {
|
||||||
return this.current?.logo || ''
|
return this.current?.logo || ''
|
||||||
},
|
},
|
||||||
availableEndpoint() : string {
|
|
||||||
const all = this.current?.endpoints?.rest
|
|
||||||
if(all) {
|
|
||||||
if(this.rest || all.findIndex(x => x.address === this.rest) < 0) {
|
|
||||||
const rn = Math.random()
|
|
||||||
const endpoint = all[Math.floor(rn * all.length)]
|
|
||||||
this.rest = endpoint?.address || ''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this.rest
|
|
||||||
},
|
|
||||||
restClient() : LCDClient {
|
|
||||||
return new LCDClient({restEndpoint: this.rest})
|
|
||||||
},
|
|
||||||
dashboard() {
|
dashboard() {
|
||||||
return useDashboard()
|
return useDashboard()
|
||||||
},
|
},
|
||||||
@ -46,6 +40,7 @@ export const useBlockchain = defineStore("blockchain", {
|
|||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const routes = router?.getRoutes()||[]
|
const routes = router?.getRoutes()||[]
|
||||||
|
console.log(routes)
|
||||||
if(this.current && routes) {
|
if(this.current && routes) {
|
||||||
currNavItem = [{
|
currNavItem = [{
|
||||||
title: this.current?.prettyName || this.chainName || '',
|
title: this.current?.prettyName || this.chainName || '',
|
||||||
@ -99,16 +94,35 @@ export const useBlockchain = defineStore("blockchain", {
|
|||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
async initial() {
|
async initial() {
|
||||||
|
console.log('begin Setup')
|
||||||
|
await this.randomSetupEndpoint()
|
||||||
|
console.log('rpc setup')
|
||||||
await useStakingStore().init()
|
await useStakingStore().init()
|
||||||
await useBankStore().initial()
|
useBankStore().initial()
|
||||||
useBaseStore().initial()
|
useBaseStore().initial()
|
||||||
useGovStore().initial()
|
useGovStore().initial()
|
||||||
|
|
||||||
},
|
},
|
||||||
setRestEndpoint(endpoint: string) {
|
|
||||||
this.rest = endpoint
|
async randomSetupEndpoint() {
|
||||||
|
const all = this.current?.endpoints?.rpc
|
||||||
|
if(all) {
|
||||||
|
const rn = Math.random()
|
||||||
|
const endpoint = all[Math.floor(rn * all.length)]
|
||||||
|
await this.setRestEndpoint(endpoint)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async setRestEndpoint(endpoint: Endpoint) {
|
||||||
|
this.connErr = ''
|
||||||
|
this.endpoint = endpoint
|
||||||
|
this.rpc = new RPCClient(endpoint.address)
|
||||||
|
console.log(this.rpc.endpoint)
|
||||||
},
|
},
|
||||||
setCurrent(name: string) {
|
setCurrent(name: string) {
|
||||||
this.chainName = name
|
this.chainName = name
|
||||||
}
|
console.log('set current', name)
|
||||||
|
},
|
||||||
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -209,10 +209,6 @@ export const useDashboard = defineStore('dashboard', {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
getters: {
|
getters: {
|
||||||
current() : string {
|
|
||||||
const blockchain = useBlockchain()
|
|
||||||
return blockchain.chainName || this.favorite[0] || ''
|
|
||||||
},
|
|
||||||
length() : number {
|
length() : number {
|
||||||
return Object.keys(this.chains).length
|
return Object.keys(this.chains).length
|
||||||
}
|
}
|
||||||
@ -234,14 +230,29 @@ export const useDashboard = defineStore('dashboard', {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
async loadingFromLocal() {
|
async loadingFromLocal() {
|
||||||
const source = this.networkType === NetworkType.Mainnet
|
const source: Record<string, LocalConfig> = this.networkType === NetworkType.Mainnet
|
||||||
? import.meta.glob('../../chains/mainnet/*.json', {eager: true})
|
? import.meta.glob('../../chains/mainnet/*.json', {eager: true})
|
||||||
: import.meta.glob('../../chains/testnet/*.json', {eager: true})
|
: import.meta.glob('../../chains/testnet/*.json', {eager: true})
|
||||||
Object.values(source).forEach((x: LocalConfig) => {
|
Object.values<LocalConfig>(source).forEach((x: LocalConfig) => {
|
||||||
this.chains[x.chain_name] = fromLocal(x)
|
this.chains[x.chain_name] = fromLocal(x)
|
||||||
})
|
})
|
||||||
|
this.setupDefault()
|
||||||
this.status = LoadingStatus.Loaded
|
this.status = LoadingStatus.Loaded
|
||||||
},
|
},
|
||||||
|
setupDefault() {
|
||||||
|
if(this.length > 0) {
|
||||||
|
const blockchain = useBlockchain()
|
||||||
|
for(let i=0; i < this.favorite.length; i++) {
|
||||||
|
if(!blockchain.chainName && this.chains[this.favorite[i]]) {
|
||||||
|
blockchain.setCurrent(this.favorite[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!blockchain.chainName) {
|
||||||
|
const [first] = Object.keys(this.chains)
|
||||||
|
blockchain.setCurrent(first)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
setConfigSource(newSource: ConfigSource) {
|
setConfigSource(newSource: ConfigSource) {
|
||||||
this.source = newSource
|
this.source = newSource
|
||||||
this.initial()
|
this.initial()
|
||||||
|
@ -2,20 +2,23 @@ import { defineStore } from "pinia";
|
|||||||
import { useBlockchain } from "./useBlockchain";
|
import { useBlockchain } from "./useBlockchain";
|
||||||
import { createDistributionClientForChain } from "@/libs/client";
|
import { createDistributionClientForChain } from "@/libs/client";
|
||||||
|
|
||||||
|
import { createRpcQueryExtension } from '@ping-pub/codegen/src/cosmos/distribution/v1beta1/query.rpc.Query'
|
||||||
|
import { Tendermint34Client } from "@cosmjs/tendermint-rpc";
|
||||||
|
import { QueryClient } from "@cosmjs/stargate";
|
||||||
|
|
||||||
export const useDistributionStore = defineStore('distributionStore', {
|
export const useDistributionStore = defineStore('distributionStore', {
|
||||||
state: () => {
|
state: () => {
|
||||||
return {
|
return {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getters: {
|
getters: {
|
||||||
client() {
|
blockchain() {
|
||||||
const chain = useBlockchain()
|
return useBlockchain()
|
||||||
return createDistributionClientForChain(chain.chainName, chain.restClient)
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
fetchCommunityPool() {
|
async fetchCommunityPool() {
|
||||||
return this.client.communityPool()
|
return this.blockchain.rpc.communityPool()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
@ -47,9 +47,12 @@ export const useFormatter = defineStore('formatter', {
|
|||||||
formatTokenAmount(token: {denom: string, amount: string;}) {
|
formatTokenAmount(token: {denom: string, amount: string;}) {
|
||||||
return this.formatToken(token, false)
|
return this.formatToken(token, false)
|
||||||
},
|
},
|
||||||
formatToken(token: { denom: string, amount: string;}, withDenom = true) : string {
|
formatToken2(token: { denom: string, amount: string;}, withDenom = true) {
|
||||||
|
return this.formatToken(token, true, '0,0.[00]')
|
||||||
|
},
|
||||||
|
formatToken(token: { denom: string, amount: string;}, withDenom = true, fmt='0.0a') : string {
|
||||||
if(token && token.amount) {
|
if(token && token.amount) {
|
||||||
let amount = Long.fromValue(token.amount)
|
let amount = Number(token.amount)
|
||||||
let denom = token.denom
|
let denom = token.denom
|
||||||
const conf = this.blockchain.current?.assets?.find(x => x.base === token.denom || x.base.denom === token.denom)
|
const conf = this.blockchain.current?.assets?.find(x => x.base === token.denom || x.base.denom === token.denom)
|
||||||
if(conf) {
|
if(conf) {
|
||||||
@ -61,11 +64,11 @@ export const useFormatter = defineStore('formatter', {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
if(unit && unit.exponent > 0) {
|
if(unit && unit.exponent > 0) {
|
||||||
amount = Long.fromValue(token.amount).divide(Math.pow(10, unit?.exponent))
|
amount = amount / Math.pow(10, unit?.exponent)
|
||||||
denom = unit.denom.toUpperCase()
|
denom = unit.denom.toUpperCase()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return `${numeral(amount).format('0.0a')} ${withDenom ? denom: ''}`
|
return `${numeral(amount).format(fmt)} ${withDenom ? denom: ''}`
|
||||||
}
|
}
|
||||||
return '-'
|
return '-'
|
||||||
},
|
},
|
||||||
@ -82,7 +85,7 @@ export const useFormatter = defineStore('formatter', {
|
|||||||
}
|
}
|
||||||
return '-'
|
return '-'
|
||||||
},
|
},
|
||||||
calculatePercent(input?: string, total?: string ) {
|
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]%")
|
return numeral(percent).format("0.[00]%")
|
||||||
@ -90,8 +93,11 @@ export const useFormatter = defineStore('formatter', {
|
|||||||
formatDecimalToPercent(decimal: string) {
|
formatDecimalToPercent(decimal: string) {
|
||||||
return numeral(decimal).format('0.[00]%')
|
return numeral(decimal).format('0.[00]%')
|
||||||
},
|
},
|
||||||
formatDateTo(date: string) {
|
percent(decimal?: string) {
|
||||||
return dayjs(date).to
|
return decimal ? numeral(decimal).format('0.[00]%') : '-'
|
||||||
|
},
|
||||||
|
numberAndSign(input: number, fmt="+0,0") {
|
||||||
|
return numeral(input).format(fmt)
|
||||||
},
|
},
|
||||||
toDay(time?: string, format = 'long') {
|
toDay(time?: string, format = 'long') {
|
||||||
if(!time) return ''
|
if(!time) return ''
|
||||||
|
@ -1,52 +1,47 @@
|
|||||||
import { defineStore } from "pinia";
|
import { defineStore } from "pinia";
|
||||||
import { useBlockchain } from "./useBlockchain";
|
import { useBlockchain } from "./useBlockchain";
|
||||||
import { createGovRestClientForChain } from "@/libs/client";
|
import { createGovRestClientForChain } from "@/libs/client";
|
||||||
import type { ProposalStatus } from "@ping-pub/codegen/src/cosmos/gov/v1/gov";
|
import type { DepositParams, ProposalStatus } from "@ping-pub/codegen/src/cosmos/gov/v1/gov";
|
||||||
import type { PageRequest } from "@ping-pub/codegen/src/helpers";
|
import type { PageRequest } from "@ping-pub/codegen/src/helpers";
|
||||||
import type { DepositParams, DepositParamsSDKType, TallyParams, TallyParamsSDKType, VotingParams, VotingParamsSDKType } from "@ping-pub/codegen/src/cosmos/gov/v1beta1/gov";
|
import { createRpcQueryExtension } from '@ping-pub/codegen/src/cosmos/gov/v1beta1/query.rpc.Query'
|
||||||
|
import { Tendermint34Client } from "@cosmjs/tendermint-rpc";
|
||||||
|
import { QueryClient } from "@cosmjs/stargate";
|
||||||
|
|
||||||
export const useGovStore = defineStore('govStore', {
|
export const useGovStore = defineStore('govStore', {
|
||||||
state: () => {
|
state: () => {
|
||||||
return {
|
return {
|
||||||
params: {
|
params: {
|
||||||
deposit: {} as DepositParamsSDKType,
|
deposit: {} as DepositParams,
|
||||||
voting: {} as VotingParamsSDKType,
|
voting: {} as VotingParams,
|
||||||
tally: {} as TallyParamsSDKType,
|
tally: {} as TallyParams,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getters: {
|
getters: {
|
||||||
client() {
|
blockchain() {
|
||||||
const chain = useBlockchain()
|
return useBlockchain()
|
||||||
return createGovRestClientForChain(chain.chainName, chain.restClient)
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
initial() {
|
initial() {
|
||||||
this.fetchParams()
|
this.fetchParams()
|
||||||
},
|
},
|
||||||
fetchProposals( proposalStatus: ProposalStatus, pagination?: PageRequest ) {
|
async fetchProposals( proposalStatus: ProposalStatus, pagination?: PageRequest ) {
|
||||||
const param = {
|
const param = {
|
||||||
proposalStatus,
|
proposalStatus,
|
||||||
voter: '',
|
voter: '',
|
||||||
depositor: '',
|
depositor: '',
|
||||||
pagination,
|
pagination,
|
||||||
}
|
}
|
||||||
return this.client.proposals(param)
|
return this.blockchain.rpc.proposals(proposalStatus, '', '')
|
||||||
},
|
},
|
||||||
fetchParams() {
|
async fetchParams() {
|
||||||
this.client.params({paramsType: 'deposit'}).then(x => {
|
// this.blockchain.rpc.govParam().then(x => {
|
||||||
if(x.deposit_params) this.params.deposit = x.deposit_params
|
// this.params.deposit = x.deposit
|
||||||
})
|
// })
|
||||||
this.client.params({paramsType: 'voting'}).then(x => {
|
|
||||||
if(x.voting_params) this.params.voting = x.voting_params
|
|
||||||
})
|
|
||||||
this.client.params({paramsType: 'tallying'}).then(x => {
|
|
||||||
if(x.tally_params) this.params.tally = x.tally_params
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
fetchTally(proposalId: Long) {
|
async fetchTally(proposalId: number) {
|
||||||
return this.client.tallyResult({proposalId})
|
return this.blockchain.rpc.tally(proposalId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -2,6 +2,10 @@ import { defineStore } from "pinia";
|
|||||||
import { useBlockchain } from "./useBlockchain";
|
import { useBlockchain } from "./useBlockchain";
|
||||||
import { createMintClientForChain } from "@/libs/client";
|
import { createMintClientForChain } from "@/libs/client";
|
||||||
|
|
||||||
|
import { createRpcQueryExtension } from '@ping-pub/codegen/src/cosmos/mint/v1beta1/query.rpc.Query'
|
||||||
|
import { Tendermint34Client } from "@cosmjs/tendermint-rpc";
|
||||||
|
import { QueryClient, setupMintExtension } from "@cosmjs/stargate";
|
||||||
|
|
||||||
export const useMintStore = defineStore('mintStore', {
|
export const useMintStore = defineStore('mintStore', {
|
||||||
state: () => {
|
state: () => {
|
||||||
return {
|
return {
|
||||||
@ -9,16 +13,16 @@ export const useMintStore = defineStore('mintStore', {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
getters: {
|
getters: {
|
||||||
client() {
|
blockchain() {
|
||||||
const chain = useBlockchain()
|
return useBlockchain()
|
||||||
return createMintClientForChain(chain.chainName, chain.restClient)
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
fetchInflation() {
|
async fetchInflation() {
|
||||||
this.client.inflation({}).then(x => {
|
this.blockchain.rpc.inflation().then(x => {
|
||||||
this.inflation = String(x.inflation)
|
this.inflation = String(x)
|
||||||
console.log(this.inflation)
|
}).catch(err => {
|
||||||
|
this.inflation = ""
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,36 +1,64 @@
|
|||||||
import { defineStore } from "pinia";
|
import { defineStore } from "pinia";
|
||||||
import { useBlockchain } from "./useBlockchain";
|
import { useBlockchain } from "./useBlockchain";
|
||||||
import { createStakingRestClientForChain } from "@/libs/client";
|
import type { Params, Pool, Validator} from "@ping-pub/codegen/src/cosmos/staking/v1beta1/staking";
|
||||||
import type { ParamsSDKType, PoolSDKType } from "@ping-pub/codegen/src/cosmos/staking/v1beta1/staking";
|
|
||||||
|
import { get } from "@/libs/http";
|
||||||
|
|
||||||
|
import type { BondStatusString } from "@/libs/client.rpc";
|
||||||
|
|
||||||
export const useStakingStore = defineStore('stakingStore', {
|
export const useStakingStore = defineStore('stakingStore', {
|
||||||
state: () => {
|
state: () => {
|
||||||
return {
|
return {
|
||||||
params: {} as ParamsSDKType,
|
validators: [] as Validator[],
|
||||||
pool: {} as PoolSDKType,
|
params: {} ,
|
||||||
|
pool: {} as Pool | undefined,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getters: {
|
getters: {
|
||||||
client() {
|
totalPower(): number {
|
||||||
const chain = useBlockchain()
|
const sum = (s:number, e: Validator) => { return s + parseInt(e.delegatorShares) }
|
||||||
return createStakingRestClientForChain(chain.chainName, chain.restClient)
|
return this.validators ? this.validators.reduce(sum, 0): 0
|
||||||
|
},
|
||||||
|
blockchain() {
|
||||||
|
return useBlockchain()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
async init() {
|
async init() {
|
||||||
|
this.$reset()
|
||||||
this.fetchPool()
|
this.fetchPool()
|
||||||
|
this.fetchAcitveValdiators()
|
||||||
return await this.fetchParams()
|
return await this.fetchParams()
|
||||||
},
|
},
|
||||||
|
async keybase(identity: string) {
|
||||||
|
return get(`https://keybase.io/_/api/1.0/user/lookup.json?key_suffix=${identity}&fields=pictures`)
|
||||||
|
},
|
||||||
async fetchParams() {
|
async fetchParams() {
|
||||||
const response = await this.client.params({})
|
const response = await this.blockchain.rpc.stakingParams()
|
||||||
if(response.params) this.params = response.params
|
if(response.params) this.params = response.params
|
||||||
return this.params
|
return this.params
|
||||||
},
|
},
|
||||||
async fetchPool() {
|
async fetchPool() {
|
||||||
const response = await this.client.pool({})
|
const response = await this.blockchain.rpc.stakingPool()
|
||||||
if(response.pool) {
|
|
||||||
this.pool = response.pool
|
this.pool = response.pool
|
||||||
|
},
|
||||||
|
async fetchAcitveValdiators() {
|
||||||
|
return this.fetchValidators('BOND_STATUS_BONDED')
|
||||||
|
},
|
||||||
|
async fetchInacitveValdiators() {
|
||||||
|
return this.fetchValidators('BOND_STATUS_UNBONDED')
|
||||||
|
},
|
||||||
|
async fetchValidator(validatorAddr: string) {
|
||||||
|
return this.blockchain.rpc.validator(validatorAddr)
|
||||||
|
},
|
||||||
|
async fetchValidators(status: BondStatusString) {
|
||||||
|
return this.blockchain.rpc.validators(status, undefined).then(res => {
|
||||||
|
const vals = res.validators.sort((a, b) => (Number(b.delegatorShares) - Number(a.delegatorShares)))
|
||||||
|
if(status==='BOND_STATUS_BONDED') {
|
||||||
|
this.validators = vals
|
||||||
}
|
}
|
||||||
|
return vals
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
@ -2,6 +2,10 @@
|
|||||||
"extends": "@vue/tsconfig/tsconfig.web.json",
|
"extends": "@vue/tsconfig/tsconfig.web.json",
|
||||||
"include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
|
"include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
|
"lib": [
|
||||||
|
"es2017",
|
||||||
|
"dom"
|
||||||
|
],
|
||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
"paths": {
|
"paths": {
|
||||||
"@/*": ["./src/*"]
|
"@/*": ["./src/*"]
|
||||||
|
Loading…
Reference in New Issue
Block a user