forked from LaconicNetwork/cosmos-explorer
Merge pull request #650 from burnt-labs/feat/registry-ibc
Feat/registry ibc
This commit is contained in:
commit
9c0d810854
24
.env.example
24
.env.example
@ -1,4 +1,22 @@
|
||||
# rename to .env.local or .env.<your_environment>
|
||||
VITE_REFRESH_INTERVAL=2000
|
||||
VITE_FETCH_ALL_BLOCKS=true
|
||||
VITE_RECENT_BLOCK_LIMIT=100
|
||||
|
||||
# Refresh interval for the app to query api for new blocks
|
||||
VITE_REFRESH_INTERVAL=6000
|
||||
|
||||
# Enable fetching all blocks (this can increase api calls to public nodes resulting in rate limiting)
|
||||
VITE_FETCH_ALL_BLOCKS=false
|
||||
|
||||
# Limit for recent blocks and associated transactions displayed in the UI
|
||||
VITE_RECENT_BLOCK_LIMIT=50
|
||||
|
||||
# URL for CoinGecko API or custom proxy
|
||||
VITE_COINGECKO_URL=https://api.coingecko.com
|
||||
|
||||
# GITHUB_API_URL default
|
||||
VITE_GITHUB_API_URL=https://api.github.com/repos/cosmos/chain-registry/contents
|
||||
|
||||
# PINGPUB_API_URL default
|
||||
VITE_PINGPUB_API_URL=https://registry.ping.pub
|
||||
|
||||
# IBC use PINGPUB_API_URL by Default (false) or GITHUB_API_URL (true)
|
||||
VITE_IBC_USE_GITHUB_API=false
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
{
|
||||
"tabWidth": 2,
|
||||
"singleQuote": true,
|
||||
"semi": true,
|
||||
"endOfLine": "auto",
|
||||
"bracketSpacing": true,
|
||||
"trailingComma": "es5",
|
||||
"arrowParens": "always",
|
||||
"bracketSpacing": true,
|
||||
"endOfLine": "auto",
|
||||
"printWidth": 80,
|
||||
"semi": true,
|
||||
"singleAttributePerLine": false,
|
||||
"printWidth": 120,
|
||||
"singleQuote": true,
|
||||
"tabWidth": 2,
|
||||
"trailingComma": "es5",
|
||||
"useTabs": false
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
{
|
||||
"chain_name": "xion",
|
||||
"chain_id": "xion-mainnet-1",
|
||||
"registry_name": "xion",
|
||||
"coingecko": "xion",
|
||||
"network_type": "mainnet",
|
||||
@ -32,7 +33,7 @@
|
||||
}
|
||||
],
|
||||
"snapshot_provider": "",
|
||||
"sdk_version": "0.50.13",
|
||||
"sdk_version": "0.53.3",
|
||||
"coin_type": "118",
|
||||
"min_tx_fee": "100",
|
||||
"addr_prefix": "xion",
|
||||
|
||||
13
env.d.ts
vendored
13
env.d.ts
vendored
@ -1,3 +1,16 @@
|
||||
/// <reference types="vite/client" />
|
||||
|
||||
declare module '@personaxyz/ad-sdk';
|
||||
interface ImportMetaEnv {
|
||||
readonly VITE_REFRESH_INTERVAL?: number,
|
||||
readonly VITE_FETCH_ALL_BLOCKS?: boolean,
|
||||
readonly VITE_RECENT_BLOCK_LIMIT?: number,
|
||||
readonly VITE_COINGECKO_URL?: string,
|
||||
readonly VITE_GITHUB_API_URL?: string,
|
||||
readonly VITE_PINGPUB_API_URL?: string,
|
||||
readonly VITE_IBC_USE_GITHUB_API?: string,
|
||||
}
|
||||
|
||||
interface ImportMeta {
|
||||
readonly env: ImportMetaEnv;
|
||||
}
|
||||
|
||||
10
package.json
10
package.json
@ -13,19 +13,20 @@
|
||||
"type-check": "vue-tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@chain-registry/types": "^0.50.162",
|
||||
"@chain-registry/client": "^1.53.184",
|
||||
"@chain-registry/types": "^0.50.184",
|
||||
"@chenfengyuan/vue-countdown": "2",
|
||||
"@cosmjs/amino": "^0.32.3",
|
||||
"@cosmjs/crypto": "^0.32.3",
|
||||
"@cosmjs/encoding": "^0.32.3",
|
||||
"@cosmjs/stargate": "^0.32.3",
|
||||
"@cosmjs/cosmwasm-stargate": "^0.30.0",
|
||||
"@iconify/vue": "^4.1.0",
|
||||
"@intlify/unplugin-vue-i18n": "^0.8.2",
|
||||
"@leapwallet/cosmos-snap-provider": "^0.1.20",
|
||||
"@leapwallet/name-matcha": "^2.0.0",
|
||||
"@osmonauts/lcd": "^0.8.0",
|
||||
"@personaxyz/ad-sdk": "0.0.25",
|
||||
"@ping-pub/chain-registry-client": "^0.0.25",
|
||||
"@vitejs/plugin-vue-jsx": "^3.0.0",
|
||||
"@vueuse/core": "^9.12.0",
|
||||
"@vueuse/integrations": "^10.1.2",
|
||||
@ -33,11 +34,14 @@
|
||||
"apexcharts": "^3.37.1",
|
||||
"autoprefixer": "^10.4.14",
|
||||
"axios": "^1.3.2",
|
||||
"bech32": "^1.1.4",
|
||||
"buffer": "^6.0.3",
|
||||
"build": "^0.1.4",
|
||||
"cross-fetch": "^3.1.5",
|
||||
"daisyui": "^3.1.0",
|
||||
"dayjs": "^1.11.7",
|
||||
"idna-uts46-hx": "^5.0.7",
|
||||
"js-sha3": "^0.8.0",
|
||||
"lazy-load-vue3": "^1.3.0",
|
||||
"long": "^5.2.1",
|
||||
"md-editor-v3": "^2.8.1",
|
||||
@ -67,7 +71,7 @@
|
||||
"@vue/tsconfig": "^0.1.3",
|
||||
"husky": "^9.1.7",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prettier": "^2.7.1",
|
||||
"prettier": "^3.0.0",
|
||||
"pretty-quick": "^4.2.2",
|
||||
"sass": "^1.58.0",
|
||||
"shiki": "^1.0.0-beta.0",
|
||||
|
||||
@ -1,37 +1,43 @@
|
||||
import { defineStore } from 'pinia';
|
||||
|
||||
import { useBlockchain } from '@/stores';
|
||||
import ChainRegistryClient from '@ping-pub/chain-registry-client';
|
||||
import type { IBCPath, IBCInfo } from '@ping-pub/chain-registry-client/dist/types';
|
||||
import type { Channel } from '@/types';
|
||||
import { ChainRegistryClient } from '@chain-registry/client';
|
||||
import type { IBCData } from '@chain-registry/types/ibc_data.schema';
|
||||
import router from '@/router';
|
||||
import fetch from 'cross-fetch';
|
||||
|
||||
const IBC_USE_GITHUB_API = import.meta.env.VITE_IBC_USE_GITHUB_API === 'true';
|
||||
const PINGPUB_API_URL = import.meta.env.VITE_PINGPUB_API_URL || 'https://registry.ping.pub';
|
||||
const GITHUB_API_URL =
|
||||
import.meta.env.VITE_GITHUB_API_URL || 'https://api.github.com/repos/cosmos/chain-registry/contents';
|
||||
const IBC_API_URL = IBC_USE_GITHUB_API ? GITHUB_API_URL : PINGPUB_API_URL;
|
||||
|
||||
export const useIBCModule = defineStore('module-ibc', {
|
||||
state: () => {
|
||||
return {
|
||||
paths: [] as IBCPath[],
|
||||
info: [] as IBCData[],
|
||||
connectionId: '' as string,
|
||||
registryConf: {} as IBCInfo,
|
||||
registryConf: {} as IBCData,
|
||||
};
|
||||
},
|
||||
getters: {
|
||||
chain() {
|
||||
return useBlockchain();
|
||||
},
|
||||
commonIBCs(): any {
|
||||
return this.paths.filter(
|
||||
(x: IBCPath) => x.path.search(this.chain.current?.prettyName || this.chain.chainName) > -1
|
||||
chainName(): string {
|
||||
return this.chain.chainName;
|
||||
},
|
||||
isFirstChain(): boolean {
|
||||
return (
|
||||
this.registryConf.chain_1.chain_name === this.chain.current?.prettyName ||
|
||||
this.registryConf.chain_1.chain_name === this.chain.chainName
|
||||
);
|
||||
},
|
||||
sourceField(): string {
|
||||
return this.registryConf?.chain_1?.chain_name === this.chain.current?.prettyName || this.chain.chainName
|
||||
? 'chain_1'
|
||||
: 'chain_2';
|
||||
return this.isFirstChain ? 'chain_1' : 'chain_2';
|
||||
},
|
||||
destField(): string {
|
||||
return this.registryConf?.chain_1?.chain_name === this.chain.current?.prettyName || this.chain.chainName
|
||||
? 'chain_2'
|
||||
: 'chain_1';
|
||||
return this.isFirstChain ? 'chain_2' : 'chain_1';
|
||||
},
|
||||
registryChannels(): any {
|
||||
return this.registryConf.channels;
|
||||
@ -39,22 +45,54 @@ export const useIBCModule = defineStore('module-ibc', {
|
||||
},
|
||||
actions: {
|
||||
load() {
|
||||
const client = new ChainRegistryClient();
|
||||
client.fetchIBCPaths().then((res) => {
|
||||
this.paths = res;
|
||||
const prefix = this.chain.current?.networkType?.includes('testnet') ? 'testnets/' : '';
|
||||
const client = new ChainRegistryClient({
|
||||
chainNames: [this.chainName],
|
||||
baseUrl: IBC_USE_GITHUB_API ? undefined : new URL(`${prefix}`, PINGPUB_API_URL + '/').toString(),
|
||||
});
|
||||
this.fetchIBCUrls().then((res) => {
|
||||
res.forEach((element: any) => {
|
||||
if (element.download_url) {
|
||||
client.urls.push(element.download_url);
|
||||
}
|
||||
});
|
||||
client.fetchUrls().then(() => {
|
||||
const info = client.getChainIbcData(this.chainName);
|
||||
this.info = info.sort((a, b) => {
|
||||
// Sort by remote chain name (not equal to this.chainName)
|
||||
const getRemote = (x: any) =>
|
||||
x?.chain_1?.chain_name === this.chain.current?.prettyName ||
|
||||
x?.chain_1?.chain_name === this.chain.chainName
|
||||
? x.chain_2.chain_name
|
||||
: x.chain_1.chain_name;
|
||||
return getRemote(a).localeCompare(getRemote(b));
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
fetchConnection(path: string) {
|
||||
const client = new ChainRegistryClient();
|
||||
client.fetchIBCPathInfo(path).then((res) => {
|
||||
const isFirstChain =
|
||||
res.chain_1.chain_name === this.chain.current?.prettyName || res.chain_1.chain_name === this.chain.chainName;
|
||||
async fetchIBCUrls(): Promise<any[]> {
|
||||
const prefix = this.chain.current?.networkType?.includes('testnet') ? 'testnets/' : '';
|
||||
const ibcEndpoint = new URL(`${prefix}_IBC`, IBC_API_URL + '/').toString();
|
||||
console.log('Fetching IBC URLs from:', IBC_API_URL);
|
||||
let entries = await fetch(ibcEndpoint)
|
||||
.then((res) => res.json())
|
||||
.then((data: any) => (Array.isArray(data) ? data.filter((x: any) => x.name.match(this.chainName)) : []));
|
||||
|
||||
const connId = isFirstChain ? res.chain_1.connection_id : res.chain_2.connection_id;
|
||||
|
||||
this.registryConf = res;
|
||||
this.showConnection(connId);
|
||||
});
|
||||
// If using PINGPUB_API_URL, add thedownload URLs
|
||||
if (IBC_API_URL == PINGPUB_API_URL) {
|
||||
return entries.map((entry: any) => {
|
||||
entry.download_url = new URL(`${prefix}_IBC/${entry.name}`, PINGPUB_API_URL + '/').toString();
|
||||
return entry;
|
||||
});
|
||||
}
|
||||
return entries;
|
||||
},
|
||||
fetchConnection(index: number) {
|
||||
this.registryConf = this.info[index];
|
||||
const connId = this.isFirstChain
|
||||
? this.registryConf.chain_1.connection_id
|
||||
: this.registryConf.chain_2.connection_id;
|
||||
this.showConnection(connId);
|
||||
},
|
||||
showConnection(connId?: string | number) {
|
||||
if (!connId) {
|
||||
|
||||
@ -1,13 +1,9 @@
|
||||
<script lang="ts" setup>
|
||||
import PaginationBar from '@/components/PaginationBar.vue';
|
||||
import { useBlockchain, useFormatter } from '@/stores';
|
||||
import { useBlockchain } from '@/stores';
|
||||
import { PageRequest, type Connection, type Pagination } from '@/types';
|
||||
import { computed, onMounted } from 'vue';
|
||||
import { onMounted } from 'vue';
|
||||
import { ref } from 'vue';
|
||||
|
||||
import ChainRegistryClient from '@ping-pub/chain-registry-client';
|
||||
import type { IBCPath } from '@ping-pub/chain-registry-client/dist/types';
|
||||
import router from '@/router';
|
||||
import { useIBCModule } from './connStore';
|
||||
|
||||
const props = defineProps(['chain']);
|
||||
@ -29,7 +25,7 @@ function pageload(p: number) {
|
||||
list.value = x.connections;
|
||||
pageResponse.value = x.pagination;
|
||||
if (x.pagination.total && Number(x.pagination.total) > 0) {
|
||||
ibcStore.showConnection(0);
|
||||
ibcStore.showConnection(list.value[0].id);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -40,26 +36,44 @@ function pageload(p: number) {
|
||||
<div class="flex flex-wrap gap-4 items-center">
|
||||
<h2 class="card-title py-4">{{ $t('ibc.title') }}</h2>
|
||||
<div class="tabs tabs-boxed">
|
||||
<a class="tab" :class="{ 'tab-active': tab === 'registry' }" @click="tab = 'registry'">{{
|
||||
$t('ibc.registry')
|
||||
}}</a>
|
||||
<a class="tab" :class="{ 'tab-active': tab === 'favorite' }" @click="tab = 'favorite'">{{
|
||||
$t('module.favorite')
|
||||
}}</a>
|
||||
<a
|
||||
class="tab"
|
||||
:class="{ 'tab-active': tab === 'registry' }"
|
||||
@click="tab = 'registry'"
|
||||
>{{ $t('ibc.registry') }}</a
|
||||
>
|
||||
<a
|
||||
class="tab"
|
||||
:class="{ 'tab-active': tab === 'favorite' }"
|
||||
@click="tab = 'favorite'"
|
||||
>{{ $t('module.favorite') }}</a
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div v-show="tab === 'registry'" class="flex flex-wrap gap-1 p-4">
|
||||
<span
|
||||
v-for="s in ibcStore.commonIBCs"
|
||||
v-for="(s, i) in ibcStore.info"
|
||||
class="btn btn-xs btn-link mr-1"
|
||||
@click="ibcStore.fetchConnection(s.path)"
|
||||
>{{ s.from }} ⇌ {{ s.to }}</span
|
||||
@click="ibcStore.fetchConnection(i)"
|
||||
>{{
|
||||
s.chain_1.chain_name === ibcStore.chainName
|
||||
? s.chain_2.chain_name
|
||||
: s.chain_1.chain_name
|
||||
}}
|
||||
⇌
|
||||
{{
|
||||
s.chain_1.chain_name === ibcStore.chainName
|
||||
? s.chain_1.chain_name
|
||||
: s.chain_2.chain_name
|
||||
}}</span
|
||||
>
|
||||
</div>
|
||||
<div v-show="tab === 'favorite'" class="flex flex-wrap gap-1 p-4">
|
||||
<div class="join border border-primary">
|
||||
<button class="join-item px-2">{{ $t('ibc.connection_id') }}:</button>
|
||||
<button class="join-item px-2">
|
||||
{{ $t('ibc.connection_id') }}:
|
||||
</button>
|
||||
<input
|
||||
v-model="ibcStore.connectionId"
|
||||
type="number"
|
||||
@ -68,7 +82,10 @@ function pageload(p: number) {
|
||||
:max="pageResponse.total || 0"
|
||||
:placeholder="`0~${pageResponse.total}`"
|
||||
/>
|
||||
<button class="join-item btn btn-primary" @click="ibcStore.showConnection()">
|
||||
<button
|
||||
class="join-item btn btn-primary"
|
||||
@click="ibcStore.showConnection()"
|
||||
>
|
||||
{{ $t('ibc.btn_apply') }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@ -120,7 +120,9 @@ function color(v: string) {
|
||||
>
|
||||
{{ baseStore.latest?.block?.header?.chain_id }}
|
||||
</div>
|
||||
<div class="text-sm text-gray-500 dark:text-gray-400">{{ conn.client_id }} {{ props.connection_id }}</div>
|
||||
<div class="text-sm text-gray-500 dark:text-gray-400">
|
||||
{{ conn.client_id }} {{ props.connection_id }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mx-auto flex items-center">
|
||||
@ -147,7 +149,10 @@ function color(v: string) {
|
||||
|
||||
<div class="bg-base-100 px-4 pt-3 pb-4 rounded mb-4 shadow">
|
||||
<h2 class="card-title mb-4 overflow-hidden">
|
||||
{{ $t('ibc.title_2') }}<span class="ml-2 text-sm">{{ clientState.client_state?.['@type'] }}</span>
|
||||
{{ $t('ibc.title_2')
|
||||
}}<span class="ml-2 text-sm">{{
|
||||
clientState.client_state?.['@type']
|
||||
}}</span>
|
||||
</h2>
|
||||
<div class="overflow-x-auto grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<table class="table table-sm capitalize">
|
||||
@ -204,7 +209,9 @@ function color(v: string) {
|
||||
<td colspan="2">
|
||||
<div class="flex justify-between">
|
||||
<span>{{ $t('ibc.allow_update_after_expiry') }}:</span>
|
||||
<span>{{ clientState.client_state?.allow_update_after_expiry }}</span>
|
||||
<span>{{
|
||||
clientState.client_state?.allow_update_after_expiry
|
||||
}}</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@ -212,7 +219,9 @@ function color(v: string) {
|
||||
<td colspan="2">
|
||||
<div class="flex justify-between">
|
||||
<span>{{ $t('ibc.allow_update_after_misbehaviour') }}: </span>
|
||||
<span>{{ clientState.client_state?.allow_update_after_misbehaviour }}</span>
|
||||
<span>{{
|
||||
clientState.client_state?.allow_update_after_misbehaviour
|
||||
}}</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@ -245,32 +254,6 @@ function color(v: string) {
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="v in ibcStore.registryChannels">
|
||||
<td>
|
||||
<div class="flex gap-1">
|
||||
<button
|
||||
class="btn btn-xs"
|
||||
@click="fetchSendingTxs(v[ibcStore.sourceField].channel_id, v[ibcStore.sourceField].port_id)"
|
||||
:disabled="loading"
|
||||
>
|
||||
<span v-if="loading" class="loading loading-spinner loading-sm"></span>
|
||||
{{ $t('ibc.btn_out') }}
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-xs"
|
||||
@click="fetchRecevingTxs(v[ibcStore.sourceField].channel_id, v[ibcStore.sourceField].port_id)"
|
||||
:disabled="loading"
|
||||
>
|
||||
<span v-if="loading" class="loading loading-spinner loading-sm"></span>
|
||||
{{ $t('ibc.btn_in') }}
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<a href="#">{{ v[ibcStore.sourceField].channel_id }}</a>
|
||||
</td>
|
||||
<td>{{ v[ibcStore.sourceField].port_id }}</td>
|
||||
</tr>
|
||||
<tr v-for="v in channels">
|
||||
<td>
|
||||
<div class="flex gap-1">
|
||||
@ -299,7 +282,9 @@ function color(v: string) {
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<a href="#" @click="loadChannel(v.channel_id, v.port_id)">{{ v.channel_id }}</a>
|
||||
<a href="#" @click="loadChannel(v.channel_id, v.port_id)">{{
|
||||
v.channel_id
|
||||
}}</a>
|
||||
</td>
|
||||
<td>{{ v.port_id }}</td>
|
||||
<td>
|
||||
@ -314,7 +299,9 @@ function color(v: string) {
|
||||
{{ v.state }}
|
||||
</div>
|
||||
</td>
|
||||
<td>{{ v.counterparty?.port_id }}/{{ v.counterparty?.channel_id }}</td>
|
||||
<td>
|
||||
{{ v.counterparty?.port_id }}/{{ v.counterparty?.channel_id }}
|
||||
</td>
|
||||
<td>{{ v.connection_hops.join(', ') }}</td>
|
||||
<td>{{ v.version }}</td>
|
||||
<td>{{ v.ordering }}</td>
|
||||
@ -324,7 +311,9 @@ function color(v: string) {
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="channel_id">
|
||||
<h3 class="card-title capitalize">Transactions ({{ channel_id }} {{ port_id }} {{ direction }})</h3>
|
||||
<h3 class="card-title capitalize">
|
||||
Transactions ({{ channel_id }} {{ port_id }} {{ direction }})
|
||||
</h3>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
|
||||
@ -45,6 +45,7 @@ export function convertFromLocal(lc: LocalChainConfig): ChainConfig {
|
||||
conf.bech32Prefix = lc.addr_prefix;
|
||||
conf.bech32ConsensusPrefix = lc.consensus_prefix ?? lc.addr_prefix + 'valcons';
|
||||
conf.chainName = lc.chain_name;
|
||||
conf.networkType = lc.network_type;
|
||||
conf.coinType = lc.coin_type;
|
||||
conf.prettyName = lc.registry_name || lc.chain_name;
|
||||
conf.endpoints = {
|
||||
@ -74,6 +75,7 @@ export function convertFromDirectory(source: DirectoryChainConfig): ChainConfig
|
||||
(conf.chainId = source.chain_id),
|
||||
(conf.chainName = source.chain_name),
|
||||
(conf.prettyName = source.pretty_name),
|
||||
(conf.networkType = source.network_type),
|
||||
(conf.versions = {
|
||||
application: source.versions?.application_version || '',
|
||||
cosmosSdk: source.versions?.cosmos_sdk_version || '',
|
||||
@ -209,6 +211,9 @@ export const useDashboard = defineStore('dashboard', {
|
||||
: import.meta.glob('../../chains/testnet/*.json', { eager: true });
|
||||
Object.values<LocalChainConfig>(source).forEach((x: LocalChainConfig) => {
|
||||
this.chains[x.chain_name] = convertFromLocal(x);
|
||||
if (!this.chains[x.chain_name].networkType) {
|
||||
this.chains[x.chain_name].networkType = this.networkType.toString().toLowerCase();
|
||||
}
|
||||
});
|
||||
this.setupDefault();
|
||||
this.status = LoadingStatus.Loaded;
|
||||
@ -221,6 +226,9 @@ export const useDashboard = defineStore('dashboard', {
|
||||
: import.meta.glob('../../chains/testnet/*.json', { eager: true });
|
||||
Object.values<LocalChainConfig>(source).forEach((x: LocalChainConfig) => {
|
||||
config[x.chain_name] = convertFromLocal(x);
|
||||
if (!config[x.chain_name].networkType) {
|
||||
config[x.chain_name].networkType = network.toString().toLowerCase();
|
||||
}
|
||||
});
|
||||
return config;
|
||||
},
|
||||
|
||||
@ -41,6 +41,7 @@ export interface LocalChainConfig {
|
||||
symbol: string;
|
||||
}[];
|
||||
chain_name: string;
|
||||
network_type?: string;
|
||||
coin_type: string;
|
||||
logo: string;
|
||||
theme_color?: string;
|
||||
@ -103,6 +104,7 @@ export interface DirectoryChainConfig {
|
||||
export interface ChainConfig {
|
||||
chainName: string;
|
||||
prettyName: string;
|
||||
networkType?: string;
|
||||
bech32Prefix: string;
|
||||
bech32ConsensusPrefix: string;
|
||||
chainId: string;
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
import type { PaginatedResponse } from '.';
|
||||
import type { IBCInfo as RegistryIBCInfo } from "@chain-registry/types"
|
||||
|
||||
export interface IBCInfo extends RegistryIBCInfo { }
|
||||
|
||||
export interface DenomTrace {
|
||||
path: string;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user