Merge pull request #646 from burnt-labs/chore/addtypes

separate types from useDashBoard
This commit is contained in:
ping 2025-07-29 08:07:29 +08:00 committed by GitHub
commit 1bfc76cd3b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 994 additions and 210 deletions

View File

@ -13,6 +13,7 @@
"type-check": "vue-tsc --noEmit"
},
"dependencies": {
"@chain-registry/types": "^0.50.162",
"@chenfengyuan/vue-countdown": "2",
"@cosmjs/amino": "^0.32.3",
"@cosmjs/crypto": "^0.32.3",

View File

@ -1,5 +1,6 @@
<script setup lang="ts">
import { useBlockchain, useBaseStore, type Endpoint } from '@/stores';
import { useBlockchain, useBaseStore } from '@/stores';
import type { Endpoint } from '@/types/chaindata';
import { useRouter } from 'vue-router';
const chainStore = useBlockchain();
const baseStore = useBaseStore();

View File

@ -9,7 +9,8 @@ import NavbarSearch from '@/layouts/components/NavbarSearch.vue';
import ChainProfile from '@/layouts/components/ChainProfile.vue';
import Sponsors from '@/layouts/components/Sponsors.vue';
import { NetworkType, useDashboard } from '@/stores/useDashboard';
import { useDashboard } from '@/stores/useDashboard';
import { NetworkType } from '@/types/chaindata';
import { useBaseStore, useBlockchain } from '@/stores';
import NavBarI18n from './NavBarI18n.vue';

View File

@ -144,7 +144,7 @@ const list = computed(() => {
if (endpoint) {
endpoint.push('ping');
return staking.validators
.filter((x) => isFeatured(endpoint, x.description))
.filter((x) => isFeatured(endpoint.filter(Boolean) as string[], x.description))
.map((x, i) => ({ v: x, rank: 'primary', logo: logo(x.description.identity) }));
}
return [];

View File

@ -8,7 +8,7 @@ import {
type DenomMetadata,
} from '@/types';
import { onMounted } from 'vue';
import type { Asset } from '@ping-pub/chain-registry-client/dist/types';
import type { Asset } from '@/types/chaindata';
import PaginationBar from '@/components/PaginationBar.vue';
const props = defineProps(['chain']);
@ -45,7 +45,7 @@ async function mergeDenomMetadata(denom: string, denomsMetadatas: DenomMetadata[
if (asset && denomMetadata) {
asset = { ...denomMetadata, ...asset };
asset.display = denomMetadata.display;
asset.logo = asset.logo_URIs?.svg || asset.logo_URIs?.png || asset.logo_URIs?.jpeg || undefined;
asset.logo = asset.logo_URIs?.svg || asset.logo_URIs?.png || undefined;
} else if (denomMetadata) {
return denomMetadata as SupplyAsset;
}
@ -65,7 +65,7 @@ function pageload(p: number) {
amount: format.tokenAmountNumber({ amount: coin.amount, denom: denom }).toString(),
base: asset.base || coin.denom,
info: asset.display || coin.denom,
logo: asset?.logo_URIs?.svg || asset?.logo_URIs?.png || asset?.logo_URIs?.jpeg || '/logo.svg',
logo: asset?.logo_URIs?.svg || asset?.logo_URIs?.png || '/logo.svg',
};
})
);

View File

@ -1,6 +1,7 @@
<script setup lang="ts">
import { ref } from 'vue';
import { useDashboard, type ChainConfig, useBlockchain } from '@/stores';
import { useDashboard, useBlockchain } from '@/stores';
import type { ChainConfig, DenomUnit } from '@/types/chaindata';
import { CosmosRestClient } from '@/libs/client';
import { onMounted } from 'vue';
import AdBanner from '@/components/ad/AdBanner.vue';
@ -29,7 +30,7 @@ async function initParamsForKeplr() {
high: 0.03,
};
const coinDecimals =
chain.assets[0].denom_units.find((x) => x.denom === chain.assets[0].symbol.toLowerCase())?.exponent || 6;
chain.assets[0].denom_units.find((x: DenomUnit) => x.denom === chain.assets[0].symbol.toLowerCase())?.exponent || 6;
conf.value = JSON.stringify(
{
chainId: chainid,

View File

@ -3,10 +3,10 @@ import { computed, ref } from 'vue';
import { suggestChain } from '@leapwallet/cosmos-snap-provider';
import {
useDashboard,
type ChainConfig,
useBlockchain,
NetworkType,
} from '@/stores';
import type { ChainConfig } from '@/types/chaindata';
import { NetworkType } from '@/types/chaindata';
import { CosmosRestClient } from '@/libs/client';
import { onMounted } from 'vue';
import AdBanner from '@/components/ad/AdBanner.vue';

View File

@ -1,6 +1,7 @@
<script setup lang="ts">
import { ref } from 'vue';
import { useDashboard, type ChainConfig, useBlockchain } from '@/stores';
import { useDashboard, useBlockchain } from '@/stores';
import type { ChainConfig } from '@/types/chaindata';
import { CosmosRestClient } from '@/libs/client';
import { onMounted } from 'vue';
import AdBanner from '@/components/ad/AdBanner.vue';

View File

@ -1,6 +1,7 @@
<script lang="ts" setup>
import { Icon } from '@iconify/vue';
import { useDashboard, LoadingStatus, type ChainConfig } from '@/stores/useDashboard';
import { useDashboard, LoadingStatus } from '@/stores';
import type { ChainConfig } from '@/types/chaindata';
import ChainSummary from '@/components/ChainSummary.vue';
import AdBanner from '@/components/ad/AdBanner.vue';

View File

@ -1,5 +1,6 @@
import { defineStore } from 'pinia';
import { useDashboard, type ChainConfig, type Endpoint, EndpointType } from './useDashboard';
import type { ChainConfig, Endpoint } from '@/types/chaindata';
import { useDashboard} from './useDashboard';
import type { NavGroup, NavLink, NavSectionTitle, VerticalNavItems } from '@/layouts/types';
import { useRouter } from 'vue-router';
import { CosmosRestClient } from '@/libs/client';
@ -22,11 +23,7 @@ export const useBlockchain = defineStore('blockchain', {
status: {} as Record<string, string>,
rest: '',
chainName: '',
endpoint: {} as {
type?: EndpointType;
address: string;
provider: string;
},
endpoint: {} as Endpoint,
connErr: '',
};
},

View File

@ -1,137 +1,10 @@
import { defineStore } from 'pinia';
import { get } from '../libs/http';
import type { Chain, Asset } from '@ping-pub/chain-registry-client/dist/types';
import type { ChainConfig, DirectoryChainConfig, Endpoint, LocalChainConfig } from '@/types/chaindata';
import { ConfigSource, NetworkType } from '@/types/chaindata';
import { useBlockchain } from './useBlockchain';
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 {
assets: Asset[];
bech32_prefix: string;
best_apis: {
rest: Endpoint[];
rpc: Endpoint[];
};
chain_id: string;
chain_name: string;
pretty_name: string;
coingecko_id: string;
cosmwasm_enabled: boolean;
decimals: number;
denom: string;
display: string;
explorers:
| {
name?: string | undefined;
kind?: string | undefined;
url?: string | undefined;
tx_page?: string | undefined;
account_page?: string | undefined;
}[]
| undefined;
height: number;
image: string;
name: string;
network_type: string;
symbol: string;
versions?: {
application_version: string;
cosmos_sdk_version: string;
tendermint_version: string;
};
}
export interface ChainConfig {
chainName: string;
prettyName: string;
bech32Prefix: string;
bech32ConsensusPrefix: string;
chainId: string;
coinType: string;
assets: Asset[];
themeColor?: string;
features?: string[];
endpoints: {
rest?: Endpoint[];
rpc?: Endpoint[];
grpc?: Endpoint[];
};
logo: string;
versions: {
application?: string;
cosmosSdk?: string;
tendermint?: string;
};
exponent: string;
excludes?: string;
providerChain: {
api: Endpoint[];
};
// keplr config
keplrFeatures?: string[];
keplrPriceStep?: {
low: number;
average: number;
high: number;
};
faucet?: {
amount: string;
ip_limit: number;
address_limit: number;
fees: string;
};
}
export interface LocalConfig {
addr_prefix: string;
consensus_prefix?: string;
alias: string;
api: string[] | Endpoint[];
grpc: Endpoint[];
provider_chain: {
api: string[] | Endpoint[];
};
assets: {
base: string;
coingecko_id: string;
exponent: string;
logo: string;
symbol: string;
}[];
chain_name: string;
coin_type: string;
logo: string;
theme_color?: string;
min_tx_fee: string;
rpc: string[] | Endpoint[];
sdk_version: string;
registry_name?: string;
features?: string[];
keplr_price_step?: {
low: number;
average: number;
high: number;
};
keplr_features: string[];
faucet?: {
amount: string;
ip_limit: number;
address_limit: number;
fees: string;
};
}
function apiConverter(api: any[]) {
if (!api) return [];
@ -149,7 +22,7 @@ function apiConverter(api: any[]) {
});
}
export function fromLocal(lc: LocalConfig): ChainConfig {
export function convertFromLocal(lc: LocalChainConfig): ChainConfig {
const conf = {} as ChainConfig;
if (lc.assets && Array.isArray(lc.assets)) {
conf.assets = lc.assets.map((x) => ({
@ -164,6 +37,7 @@ export function fromLocal(lc: LocalConfig): ChainConfig {
{ denom: x.base, exponent: 0 },
{ denom: x.symbol.toLowerCase(), exponent: Number(x.exponent) },
],
type_asset: 'sdk.coin'
}));
}
conf.versions = {
@ -194,7 +68,7 @@ export function fromLocal(lc: LocalConfig): ChainConfig {
return conf;
}
export function fromDirectory(source: DirectoryChain): ChainConfig {
export function convertFromDirectory(source: DirectoryChainConfig): ChainConfig {
const conf = {} as ChainConfig;
(conf.assets = source.assets),
(conf.bech32Prefix = source.bech32_prefix),
@ -234,43 +108,36 @@ export function getLogo(
return undefined;
}
function createChainFromDirectory(source: DirectoryChain): Chain {
const conf: Chain = {} as Chain;
conf.apis = source.best_apis;
conf.bech32_prefix = source.bech32_prefix;
conf.chain_id = source.chain_id;
conf.chain_name = source.chain_name;
conf.explorers = source.explorers;
conf.pretty_name = source.pretty_name;
if (source.versions) {
conf.codebase = {
recommended_version: source.versions.application_version,
cosmos_sdk_version: source.versions.cosmos_sdk_version,
tendermint_version: source.versions.tendermint_version,
};
}
if (source.image) {
conf.logo_URIs = {
svg: source.image,
};
}
return conf;
}
// Unused function, kept for reference
// function createChainFromDirectory(source: DirectoryChain): ChainConfig {
// const conf = {} as ChainConfig;
// conf.apis = source.best_apis;
// conf.bech32_prefix = source.bech32_prefix;
// conf.chain_id = source.chain_id;
// conf.chain_name = source.chain_name;
// conf.explorers = source.explorers;
// conf.pretty_name = source.pretty_name;
// if (source.versions) {
// conf.codebase = {
// recommended_version: source.versions.application_version,
// cosmos_sdk_version: source.versions.cosmos_sdk_version,
// tendermint_version: source.versions.tendermint_version,
// };
// }
// if (source.image) {
// conf.logo_URIs = {
// svg: source.image,
// };
// }
// return conf;
// }
export enum LoadingStatus {
Empty,
Loading,
Loaded,
}
export enum NetworkType {
Mainnet,
Testnet,
}
export enum ConfigSource {
MainnetCosmosDirectory = 'https://chains.cosmos.directory',
TestnetCosmosDirectory = 'https://chains.testcosmos.directory',
Local = 'local',
}
export const useDashboard = defineStore('dashboard', {
state: () => {
@ -292,8 +159,8 @@ export const useDashboard = defineStore('dashboard', {
},
actions: {
async initial() {
await this.loadingFromLocal();
// await this.loadingFromRegistry()
//await this.loadingFromLocal();
await this.loadingFromRegistry()
},
loadingPrices() {
const coinIds = [] as string[];
@ -328,8 +195,8 @@ export const useDashboard = defineStore('dashboard', {
if (this.status === LoadingStatus.Empty) {
this.status = LoadingStatus.Loading;
get(this.source).then((res) => {
res.chains.forEach((x: DirectoryChain) => {
this.chains[x.chain_name] = fromDirectory(x);
res.chains.forEach((x: DirectoryChainConfig) => {
this.chains[x.chain_name] = convertFromDirectory(x);
});
this.status = LoadingStatus.Loaded;
});
@ -339,24 +206,24 @@ export const useDashboard = defineStore('dashboard', {
if (window.location.hostname.search('testnet') > -1) {
this.networkType = NetworkType.Testnet;
}
const source: Record<string, LocalConfig> =
const source: Record<string, LocalChainConfig> =
this.networkType === NetworkType.Mainnet
? import.meta.glob('../../chains/mainnet/*.json', { eager: true })
: import.meta.glob('../../chains/testnet/*.json', { eager: true });
Object.values<LocalConfig>(source).forEach((x: LocalConfig) => {
this.chains[x.chain_name] = fromLocal(x);
Object.values<LocalChainConfig>(source).forEach((x: LocalChainConfig) => {
this.chains[x.chain_name] = convertFromLocal(x);
});
this.setupDefault();
this.status = LoadingStatus.Loaded;
},
async loadLocalConfig(network: NetworkType) {
const config: Record<string, ChainConfig> = {};
const source: Record<string, LocalConfig> =
const source: Record<string, LocalChainConfig> =
network === NetworkType.Mainnet
? import.meta.glob('../../chains/mainnet/*.json', { eager: true })
: import.meta.glob('../../chains/testnet/*.json', { eager: true });
Object.values<LocalConfig>(source).forEach((x: LocalConfig) => {
config[x.chain_name] = fromLocal(x);
Object.values<LocalChainConfig>(source).forEach((x: LocalChainConfig) => {
config[x.chain_name] = convertFromLocal(x);
});
return config;
},

View File

@ -13,7 +13,7 @@ import { consensusPubkeyToHexAddress, get } from '@/libs';
import { useBankStore } from './useBankStore';
import type { Coin, DenomTrace } from '@/types';
import { useDashboard } from './useDashboard';
import type { Asset } from '@ping-pub/chain-registry-client/dist/types';
import type { Asset } from '@/types/chaindata';
dayjs.extend(localeData);
dayjs.extend(duration);

142
src/types/chaindata.ts Normal file
View File

@ -0,0 +1,142 @@
import type { Asset as RegistryAsset, DenomUnit as RegistryDenomUnit } from '@chain-registry/types';
import type { Chain as RegistryChain, Endpoint as RegistryEndPoint } from '@chain-registry/types/chain.schema';
export enum NetworkType {
Mainnet,
Testnet,
}
export enum ConfigSource {
MainnetCosmosDirectory = 'https://chains.cosmos.directory',
TestnetCosmosDirectory = 'https://chains.testcosmos.directory',
Local = 'local',
}
export enum EndpointType {
rpc,
rest,
grpc,
// webgrpc
}
export interface Chain extends RegistryChain {}
export interface Asset extends RegistryAsset {}
export interface Endpoint extends RegistryEndPoint {}
export interface DenomUnit extends RegistryDenomUnit {}
export interface LocalChainConfig {
addr_prefix: string;
consensus_prefix?: string;
alias: string;
api: string[] | Endpoint[];
grpc: Endpoint[];
provider_chain: {
api: string[] | Endpoint[];
};
assets: {
base: string;
coingecko_id: string;
exponent: string;
logo: string;
symbol: string;
}[];
chain_name: string;
coin_type: string;
logo: string;
theme_color?: string;
min_tx_fee: string;
rpc: string[] | Endpoint[];
sdk_version: string;
registry_name?: string;
features?: string[];
keplr_price_step?: {
low: number;
average: number;
high: number;
};
keplr_features: string[];
faucet?: {
amount: string;
ip_limit: number;
address_limit: number;
fees: string;
};
}
// Chain config structure of cosmos.directory
export interface DirectoryChainConfig {
assets: Asset[];
bech32_prefix: string;
best_apis: {
rest: Endpoint[];
rpc: Endpoint[];
};
chain_id: string;
chain_name: string;
pretty_name: string;
coingecko_id: string;
cosmwasm_enabled: boolean;
decimals: number;
denom: string;
display: string;
explorers:
| {
name?: string | undefined;
kind?: string | undefined;
url?: string | undefined;
tx_page?: string | undefined;
account_page?: string | undefined;
}[]
| undefined;
height: number;
image: string;
name: string;
network_type: string;
symbol: string;
versions?: {
application_version: string;
cosmos_sdk_version: string;
tendermint_version: string;
};
}
export interface ChainConfig {
chainName: string;
prettyName: string;
bech32Prefix: string;
bech32ConsensusPrefix: string;
chainId: string;
coinType: string;
assets: Asset[];
themeColor?: string;
features?: string[];
endpoints: {
rest?: Endpoint[];
rpc?: Endpoint[];
grpc?: Endpoint[];
};
logo: string;
versions: {
application?: string;
cosmosSdk?: string;
tendermint?: string;
};
exponent: string;
excludes?: string;
providerChain: {
api: Endpoint[];
};
// keplr config
keplrFeatures?: string[];
keplrPriceStep?: {
low: number;
average: number;
high: number;
};
faucet?: {
amount: string;
ip_limit: number;
address_limit: number;
fees: string;
};
}

810
yarn.lock

File diff suppressed because it is too large Load Diff