add balance cache

This commit is contained in:
liangping 2023-02-17 09:34:49 +08:00
parent 65b2cc6451
commit e60d7b5cf5
7 changed files with 114 additions and 46 deletions

View File

@ -12,9 +12,6 @@ const props = defineProps({
const dashboardStore = useDashboard() const dashboardStore = useDashboard()
const conf = computed(()=> dashboardStore.chains[props.name] || {}) const conf = computed(()=> dashboardStore.chains[props.name] || {})
const logoPath = computed(() => {
return getLogo(conf.value.logo_URIs)
})
</script> </script>
<template> <template>
<VCard outlined class="p-1"> <VCard outlined class="p-1">
@ -22,16 +19,16 @@ const logoPath = computed(() => {
<VListItem :to="`/${name}`"> <VListItem :to="`/${name}`">
<template #prepend> <template #prepend>
<VAvatar rounded size="45" variant="tonal" class="me-3"> <VAvatar rounded size="45" variant="tonal" class="me-3">
<VImg :src="logoPath" height="22"/> <VImg :src="conf.logo" height="22"/>
</VAvatar> </VAvatar>
</template> </template>
<VListItemTitle class="font-weight-semibold text-sm mb-1"> <VListItemTitle class="font-weight-semibold text-sm mb-1">
{{ conf?.pretty_name || props.name }} {{ conf?.prettyName || props.name }}
</VListItemTitle> </VListItemTitle>
<VListItemSubtitle class="text-xs"> <VListItemSubtitle class="text-xs">
{{conf?.chain_id || ''}} {{conf?.chainId || ''}}
</VListItemSubtitle> </VListItemSubtitle>
<template #append> <template #append>

View File

@ -32,14 +32,14 @@ const chainStore = useBlockchain()
> >
<VList> <VList>
<!-- 👉 Rest --> <!-- 👉 Rest -->
<VListSubheader v-if="chainStore.current.apis?.rest" title="Rest Endpoint" /> <VListSubheader v-if="chainStore.current.endpoints?.rest" title="Rest Endpoint" />
<VListItem v-for="i in chainStore.current.apis?.rest" link @click="chainStore.setRestEndpoint(i.address)"> <VListItem v-for="i in chainStore.current.endpoints?.rest" link @click="chainStore.setRestEndpoint(i.address)">
<VListItemTitle>{{ i.provider }} <VIcon v-if="chainStore.availableEndpoint && i.address === chainStore.availableEndpoint" icon="mdi-check" color="success" /></VListItemTitle> <VListItemTitle>{{ i.provider }} <VIcon v-if="chainStore.availableEndpoint && i.address === chainStore.availableEndpoint" icon="mdi-check" color="success" /></VListItemTitle>
<VListItemSubtitle>{{ i.address }}</VListItemSubtitle> <VListItemSubtitle>{{ i.address }}</VListItemSubtitle>
</VListItem> </VListItem>
<VListSubheader v-if="chainStore.current.apis?.grpc" title="gRPC Endpoint" /> <VListSubheader v-if="chainStore.current.endpoints?.grpc" title="gRPC Endpoint" />
<VListItem v-for="i in chainStore.current.apis?.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>
@ -49,7 +49,7 @@ const chainStore = useBlockchain()
</VAvatar> </VAvatar>
</VBadge> </VBadge>
</template> </template>
<VListItemTitle>{{ chainStore.current?.chain_id || '' }}</VListItemTitle> <VListItemTitle>{{ chainStore.current?.chainId || '' }}</VListItemTitle>
<VListItemSubtitle> {{ chainStore.availableEndpoint }}</VListItemSubtitle> <VListItemSubtitle> {{ chainStore.availableEndpoint }}</VListItemSubtitle>
</VListItem> </VListItem>
</template> </template>

View File

@ -1,8 +1,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { useDashboard, LoadingStatus } from '@/stores/useDashboard'; import { useDashboard, LoadingStatus, type ChainConfig } from '@/stores/useDashboard';
import ChainSummary from '@/components/ChainSummary.vue'; import ChainSummary from '@/components/ChainSummary.vue';
import { computed, ref } from 'vue'; import { computed, ref } from 'vue';
import type { Chain } from '@ping-pub/chain-registry-client/dist/types';
const dashboard = useDashboard() const dashboard = useDashboard()
@ -12,7 +11,7 @@ dashboard.$subscribe((mutation, state) => {
const keywords = ref('') const keywords = ref('')
const chains = computed(()=> { const chains = computed(()=> {
if(keywords.value) { if(keywords.value) {
return Object.values(dashboard.chains).filter( (x: Chain)=>x.chain_name.indexOf(keywords.value) > -1) return Object.values(dashboard.chains).filter( (x: ChainConfig)=>x.chainName.indexOf(keywords.value) > -1)
}else{ }else{
return Object.values(dashboard.chains) return Object.values(dashboard.chains)
} }
@ -43,7 +42,7 @@ const chains = computed(()=> {
<VRow class="my-auto"> <VRow class="my-auto">
<VCol v-for="k in chains" md="3"> <VCol v-for="k in chains" md="3">
<VLazy min-height="40" min-width="200" transition="fade-transition"> <VLazy min-height="40" min-width="200" transition="fade-transition">
<ChainSummary :name="k.chain_name" /> <ChainSummary :name="k.chainName" />
</VLazy> </VLazy>
</VCol> </VCol>
</VRow> </VRow>

View File

@ -9,12 +9,14 @@ import type { QueryTotalSupplyRequest, QueryTotalSupplyResponseSDKType } from "o
export const useBank = defineStore("usebank", () => { export const useBank = defineStore("usebank", () => {
const totalSupply = ref({} as QueryTotalSupplyResponseSDKType); const totalSupply = ref({} as QueryTotalSupplyResponseSDKType);
const blockchain = useBlockchain()
const client = computed(() => {
const client: ComputedRef<LCDQueryClient> = computed(() => new LCDQueryClient(blockchain.restClient)) const blockchain = useBlockchain()
return new LCDQueryClient(new LCDClient({restEndpoint: blockchain.availableEndpoint}))
})
async function fetchTotalSupply({}) { async function fetchTotalSupply({}) {
console.log(client)
totalSupply.value = await client.value.totalSupply({}) totalSupply.value = await client.value.totalSupply({})
return totalSupply.value; return totalSupply.value;
} }

View File

@ -1,33 +1,55 @@
import { ref, computed } from "vue"; import { ref, computed } from "vue";
import { defineStore } from "pinia"; import { defineStore } from "pinia";
import { osmosis } from 'osmojs'; import { osmosis } from 'osmojs';
import { LCDClient } from '@osmonauts/lcd'
// import { LCDClient } from 'osmojs/node_modules/@osmonauts/lcd/types/rest'
//import { LCDQueryClient } from 'osmojs/src/codegen/cosmos/bank/v1beta1/query.lcd'
import { LCDQueryClient } from 'osmojs/main/codegen/cosmos/bank/v1beta1/query.lcd.js' import { LCDQueryClient } from 'osmojs/main/codegen/cosmos/bank/v1beta1/query.lcd.js'
import type { QueryTotalSupplyRequest, QueryTotalSupplyResponseSDKType } from "osmojs/types/codegen/cosmos/bank/v1beta1/query"; import type { QuerySupplyOfRequest, QueryTotalSupplyRequest, QueryBalanceRequest,QueryAllBalancesRequest, QueryAllBalancesResponseSDKType, QueryBalanceResponseSDKType, QueryTotalSupplyResponseSDKType } from "osmojs/types/codegen/cosmos/bank/v1beta1/query";
import { useBlockchain } from "./useBlockchain"; import { useBlockchain } from "./useBlockchain";
import type { CoinSDKType } from "osmojs/types/codegen/cosmos/base/v1beta1/coin";
export const useBankStore = defineStore('pinia.bank.store', { export const useBankStore = defineStore('bankstore', {
state: () => { state: () => {
return { return {
totalSupply: {} as QueryTotalSupplyResponseSDKType, balances: {} as Record<string, CoinSDKType[]>,
totalSupply: {supply: []} as QueryTotalSupplyResponseSDKType,
} }
}, },
getters: { getters: {
lcdClient() { lcdClient() : LCDQueryClient {
const requestClient = new LCDClient({restEndpoint: useBlockchain().availableEndpoint}) const requestClient = useBlockchain().restClient
console.log(requestClient, 'rest client')
return new LCDQueryClient( { requestClient }) return new LCDQueryClient( { requestClient })
}, },
}, },
actions: { actions: {
cacheBalance(address: string, balances: CoinSDKType[]) {
if(this.balances[address]) {
this.balances[address] = [...this.balances[address], ... balances]
}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
},
async fetchAllBalance(param: QueryAllBalancesRequest) : Promise<QueryAllBalancesResponseSDKType> {
const response : QueryAllBalancesResponseSDKType = await this.lcdClient.balance(param)
if (response.balances) this.cacheBalance(param.address, response.balances)
return response
},
async fetchTotalSupply(param: QueryTotalSupplyRequest): Promise<QueryTotalSupplyResponseSDKType> { async fetchTotalSupply(param: QueryTotalSupplyRequest): Promise<QueryTotalSupplyResponseSDKType> {
this.totalSupply = await this.lcdClient.totalSupply(param) const response = await this.lcdClient.totalSupply(param)
return this.totalSupply this.totalSupply.supply = [...this.totalSupply.supply, ...response.supply]
this.totalSupply.pagination = response.pagination
return response
},
async fetchSupply(param: QuerySupplyOfRequest) {
const c: LCDQueryClient = new LCDQueryClient( { requestClient: {} })
return '';
} }
} }
}) })

View File

@ -15,10 +15,10 @@ export const useBlockchain = defineStore("blockchain", () => {
return dbstore.getCurrentChain() return dbstore.getCurrentChain()
}); });
const logo = computed(() => { const logo = computed(() => {
return getLogo(current.value?.logo_URIs) return current.value?.logo
}) })
const name = computed(() => { const name = computed(() => {
return current.value.chain_name return current.value.chainName
}) })
const primaryColor = computed(() => { const primaryColor = computed(() => {
@ -31,7 +31,7 @@ export const useBlockchain = defineStore("blockchain", () => {
return color return color
}) })
const availableEndpoint = computed(() => { const availableEndpoint = computed(() => {
const all = current.value?.apis?.rest const all = current.value?.endpoints?.rest
if(all) { if(all) {
if(!rest.value || all.findIndex(x => x.address === rest.value) < 0) { if(!rest.value || all.findIndex(x => x.address === rest.value) < 0) {
const rn = Math.random() const rn = Math.random()
@ -44,8 +44,7 @@ export const useBlockchain = defineStore("blockchain", () => {
}) })
const restClient = computed(()=> { const restClient = computed(()=> {
console.log(availableEndpoint, 'endpoint') return new LCDClient({restEndpoint: availableEndpoint.value})
return new LCDClient({restEndpoint: availableEndpoint})
}) })
function setRestEndpoint(endpoint: string) { function setRestEndpoint(endpoint: string) {

View File

@ -6,12 +6,26 @@ import type { VerticalNavItems } from '@/@layouts/types'
import ChainRegistryClient from '@ping-pub/chain-registry-client' import ChainRegistryClient from '@ping-pub/chain-registry-client'
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
export enum EndpointType {
rpc,
rest,
grpc,
// webgrpc
}
export interface Endpoint {
type?: EndpointType,
address: string,
provider: string
}
// Chain config structure of cosmos.directory
export interface DirectoryChain { export interface DirectoryChain {
assets: Asset[], assets: Asset[],
bech32_prefix: string, bech32_prefix: string,
best_apis: { best_apis: {
rest: {address: string, provider: string}[] rest: Endpoint[]
rpc: {address: string, provider: string}[] rpc: Endpoint[]
}, },
chain_id: string, chain_id: string,
chain_name: string, chain_name: string,
@ -33,18 +47,54 @@ export interface DirectoryChain {
name: string, name: string,
network_type: string, network_type: string,
symbol: string, symbol: string,
versions: { versions?: {
application_version: string, application_version: string,
cosmos_sdk_version: string, cosmos_sdk_version: string,
tendermint_version: string, tendermint_version: string,
} }
} }
export interface ChainConfig {
chainName: string,
prettyName: string,
bech32Prefix: string,
chainId: string,
assets: Asset[],
endpoints: {
rest?: Endpoint[]
rpc?: Endpoint[]
grpc?: Endpoint[]
},
logo: string,
versions: {
application?: string,
cosmosSdk?: string,
tendermint?: string,
},
}
export function fromDirectory(source: DirectoryChain): ChainConfig {
const conf = {} as ChainConfig
conf.assets = source.assets,
conf.bech32Prefix = source.bech32_prefix,
conf.chainId = source.chain_id,
conf.chainName = source.chain_name,
conf.prettyName = source.pretty_name,
conf.versions = {
application: source.versions?.application_version || '',
cosmosSdk: source.versions?.cosmos_sdk_version || '',
tendermint: source.versions?.tendermint_version || '',
},
conf.logo = pathConvert(source.image)
conf.endpoints = source.best_apis
return conf
}
function pathConvert(path: string | undefined) { function pathConvert(path: string | undefined) {
if(path) { if(path) {
path = path.replace('https://raw.githubusercontent.com/cosmos/chain-registry/master', 'https://registry.ping.pub') path = path.replace('https://raw.githubusercontent.com/cosmos/chain-registry/master', 'https://registry.ping.pub')
} }
return path return path || ''
} }
export function getLogo(conf: { export function getLogo(conf: {
@ -99,7 +149,7 @@ export const useDashboard = defineStore("dashboard", () => {
const source = ref(ConfigSource.MainnetCosmosDirectory) const source = ref(ConfigSource.MainnetCosmosDirectory)
const favorite = ref(JSON.parse(localStorage.getItem('favorite') || '["cosmoshub", "osmosis"]') as string[]) const favorite = ref(JSON.parse(localStorage.getItem('favorite') || '["cosmoshub", "osmosis"]') as string[])
const current = ref(favorite.value[0]) const current = ref(favorite.value[0])
const chains = ref({} as Record<string, Chain>); const chains = ref({} as Record<string, ChainConfig>);
const findChainByName = computed((name) => chains.value[name]); const findChainByName = computed((name) => chains.value[name]);
@ -110,11 +160,10 @@ export const useDashboard = defineStore("dashboard", () => {
const router = useRouter() const router = useRouter()
const routes = router?.getRoutes()||[] const routes = router?.getRoutes()||[]
console.log(routes)
if(currChain && routes) { if(currChain && routes) {
currNavItem = [{ currNavItem = [{
title: currChain.pretty_name || currChain.chain_name || current.value, title: currChain.prettyName || currChain.chainName || current.value,
icon: {image: getLogo(currChain.logo_URIs), size: '22'}, icon: {image: currChain.logo, size: '22'},
i18n: false, i18n: false,
children: routes children: routes
.filter(x=>x.name && x.name.toString().startsWith('chain')) .filter(x=>x.name && x.name.toString().startsWith('chain'))
@ -133,9 +182,9 @@ export const useDashboard = defineStore("dashboard", () => {
const ch = chains.value[name] const ch = chains.value[name]
if(ch) { if(ch) {
favNavItems.push({ favNavItems.push({
title: ch.pretty_name || ch.chain_name || name, title: ch.prettyName || ch.chainName || name,
to: { path: `/${ch.chain_name || name}`}, to: { path: `/${ch.chainName || name}`},
icon: {image: getLogo(ch.logo_URIs), size: '22'} icon: {image: ch.logo, size: '22'}
} ) } )
} }
}) })
@ -178,7 +227,7 @@ export const useDashboard = defineStore("dashboard", () => {
status.value = LoadingStatus.Loading status.value = LoadingStatus.Loading
get(source.value).then((res)=> { get(source.value).then((res)=> {
res.chains.forEach(( x: DirectoryChain ) => { res.chains.forEach(( x: DirectoryChain ) => {
chains.value[x.chain_name] = createChainFromDirectory(x) chains.value[x.chain_name] = fromDirectory(x)
}); });
status.value = LoadingStatus.Loaded status.value = LoadingStatus.Loaded
}) })