add ibc feature

This commit is contained in:
liangping 2023-05-05 07:37:45 +08:00
parent 8876a12aef
commit 58b79c9b03
8 changed files with 351 additions and 4627 deletions

View File

@ -47,19 +47,23 @@ export const DEFAULT: RequestRegistry = {
tx_txs_block: { url: "/cosmos/tx/v1beta1/txs/block/{height}", adapter },
tx_hash: { url: "/cosmos/tx/v1beta1/txs/{hash}", adapter },
mint_inflation: { url: "/cosmos/mint/v1beta1/inflation", adapter},
mint_params: { url: "/cosmos/mint/v1beta1/params", adapter},
mint_annual_provisions: { url: "/cosmos/mint/v1beta1/annual_provisions", adapter},
mint_inflation: { url: "/cosmos/mint/v1beta1/inflation", adapter },
mint_params: { url: "/cosmos/mint/v1beta1/params", adapter },
mint_annual_provisions: { url: "/cosmos/mint/v1beta1/annual_provisions", adapter },
// ibc
ibc_app_ica_controller_params: { url: "/ibc/apps/interchain_accounts/controller/v1/params", adapter },
ibc_app_ica_host_params: { url: "/ibc/apps/interchain_accounts/host/v1/params", adapter},
ibc_app_transfer_escrow_address: { url: "/ibc/apps/transfer/v1/channels/{channel_id}/ports/{port_id}/escrow_address", adapter},
ibc_app_transfer_denom_traces: { url: "/ibc/apps/transfer/v1/denom_traces", adapter},
ibc_app_transfer_denom_traces_hash: { url: "/ibc/apps/transfer/v1/denom_traces/{hash}", adapter},
ibc_core_channel_channels: { url: "/ibc/core/channel/v1/channels", adapter},
ibc_core_channel_channels_next_sequence: { url: "/ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/next_sequence", adapter},
ibc_core_channel_channels_acknowledgements: { url: "/ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/packet_acknowledgements", adapter}
ibc_app_ica_host_params: { url: "/ibc/apps/interchain_accounts/host/v1/params", adapter },
ibc_app_transfer_escrow_address: { url: "/ibc/apps/transfer/v1/channels/{channel_id}/ports/{port_id}/escrow_address", adapter },
ibc_app_transfer_denom_traces: { url: "/ibc/apps/transfer/v1/denom_traces", adapter },
ibc_app_transfer_denom_traces_hash: { url: "/ibc/apps/transfer/v1/denom_traces/{hash}", adapter },
ibc_core_channel_channels: { url: "/ibc/core/channel/v1/channels", adapter },
ibc_core_channel_channels_next_sequence: { url: "/ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/next_sequence", adapter },
ibc_core_channel_channels_acknowledgements: { url: "/ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/packet_acknowledgements", adapter },
ibc_core_channel_connections_channels: { url: "/ibc/core/channel/v1/connections/{connection_id}/channels", adapter },
ibc_core_connection_connections: { url: "/ibc/core/connection/v1/connections", adapter },
ibc_core_connection_connections_connection_id: { url: "/ibc/core/connection/v1/connections/{connection_id}", adapter },
ibc_core_connection_connections_connection_id_client_state: { url: "/ibc/core/connection/v1/connections/{connection_id}/client_state", adapter }
};
export const VERSION_REGISTRY: Registry = {

View File

@ -179,6 +179,27 @@ export class CosmosRestClient extends BaseRestClient<RequestRegistry> {
async getIBCAppTransferDenom(hash: string) {
return this.request(this.registry.ibc_app_transfer_denom_traces_hash, {hash})
}
async getIBCConnections() {
return this.request(this.registry.ibc_core_connection_connections, {})
}
async getIBCConnectionsById(connection_id: string) {
return this.request(this.registry.ibc_core_connection_connections_connection_id, {connection_id})
}
async getIBCConnectionsClientState(connection_id: string) {
return this.request(this.registry.ibc_core_connection_connections_connection_id_client_state, {connection_id})
}
async getIBCConnectionsChannels(connection_id: string) {
return this.request(this.registry.ibc_core_channel_connections_channels, {connection_id})
}
async getIBCChannels() {
return this.request(this.registry.ibc_core_channel_channels, {})
}
async getIBCChannelAcknowledgements(channel_id: string, port_id: string) {
return this.request(this.registry.ibc_core_channel_channels_acknowledgements, {channel_id, port_id})
}
async getIBCChannelNextSequence(channel_id: string, port_id: string) {
return this.request(this.registry.ibc_core_channel_channels_next_sequence, {channel_id, port_id})
}
}

View File

@ -1,11 +1,10 @@
import type { AuthAccount, Block, Coin, NodeInfo, PaginabledAccounts, PaginatedTendermintValidator,} from "@/types";
import type { AuthAccount, Block, ClientStateWithProof, Coin, ConnectionWithProof, DenomTrace, NodeInfo, PaginabledAccounts, PaginatedIBCChannels, PaginatedIBCConnections, PaginatedTendermintValidator,} from "@/types";
import type { BankParams, PaginatedBalances, PaginatedDenomMetadata, PaginatedSupply } from "@/types/bank";
import type { DistributionParams, PaginatedSlashes } from "@/types/distribution";
import type { GovParams, GovProposal, GovVote, PaginatedProposalDeposit, PaginatedProposalVotes, PaginatedProposals, Tally } from "@/types/gov";
import type { PaginatedSigningInfo } from "@/types/slashing";
import type { Delegation, PaginatedDelegations, PaginatedRedelegations, PaginatedUnbonding, PaginatedValdiators, StakingParam, StakingPool, Validator } from "@/types/staking";
import type { PaginatedTxs, Tx, TxResponse } from "@/types/tx";
import semver from "semver";
export interface Request<T> {
@ -86,15 +85,22 @@ export interface RequestRegistry extends AbstractRegistry {
ibc_app_transfer_escrow_address: Request<any>;
ibc_app_transfer_denom_traces: Request<any>;
ibc_app_transfer_denom_traces_hash: Request<{
"denom_trace": {
"path": "string",
"base_denom": "string"
denom_trace: DenomTrace
}>;
ibc_core_channel_channels: Request<PaginatedIBCChannels>;
ibc_core_channel_channels_next_sequence: Request<{
next_sequence_receive: string,
proof: string,
proof_height: {
revision_number: string,
revision_height: string
}
}>;
ibc_core_channel_channels: Request<any>;
ibc_core_channel_channels_next_sequence: Request<any>;
ibc_core_channel_channels_acknowledgements: Request<any>;
ibc_core_channel_connections_channels: Request<PaginatedIBCChannels>;
ibc_core_connection_connections: Request<PaginatedIBCConnections>;
ibc_core_connection_connections_connection_id: Request<ConnectionWithProof>;
ibc_core_connection_connections_connection_id_client_state: Request<ClientStateWithProof>;
}

View File

@ -0,0 +1,99 @@
<script lang="ts" setup>
import DynamicComponent from '@/components/dynamic/DynamicComponent.vue';
import { useBaseStore, useBlockchain, useFormatter } from '@/stores';
import type { ClientStateWithProof, Connection, ClientState, Channel } from '@/types';
import { onMounted } from 'vue';
import { ref } from 'vue';
const props = defineProps(['chain', 'connection_id'])
const chainStore = useBlockchain()
const baseStore = useBaseStore()
const conn = ref({} as Connection)
const clientState = ref({} as {client_id: string, client_state: ClientState})
const channels = ref([] as Channel[])
onMounted(() => {
if(props.connection_id) {
chainStore.rpc.getIBCConnectionsById(props.connection_id).then(x => {
conn.value = x.connection
})
chainStore.rpc.getIBCConnectionsClientState(props.connection_id).then(x => {
clientState.value = x.identified_client_state
})
chainStore.rpc.getIBCConnectionsChannels(props.connection_id).then(x => {
channels.value = x.channels
})
}
})
function loadChannel(channel: string, port: string) {
chainStore.rpc.getIBCChannelNextSequence(channel, port).then(x => {
console.log(x)
})
}
function color(v: string) {
if(v && v.indexOf("_OPEN") > -1) {
return "success"
}
return "warning"
}
</script>
<template>
<div>
<div class="bg-white py-24 sm:py-32">
<div class="mx-auto max-w-7xl px-6 lg:px-8">
<dl class="grid grid-cols-1 gap-x-8 gap-y-16 text-center lg:grid-cols-3">
<div class="mx-auto flex max-w-xs flex-col gap-y-4">
<dt class="text-base leading-7 text-gray-600">{{ conn.client_id }} {{props.connection_id}}</dt>
<dd class="order-first text-3xl font-semibold tracking-tight text-gray-900 sm:text-5xl">{{ baseStore.latest?.block?.header?.chain_id }}</dd>
</div>
<div class="mx-auto flex max-w-xs flex-col gap-y-4">
<dt class="text-base leading-7 text-gray-600">{{ conn.state }}</dt>
<dd class="order-first text-3xl font-semibold tracking-tight text-gray-900 sm:text-5xl"> &lt;&gt;<VProgressLinear class="w-100" color="success" /></dd>
</div>
<div class="mx-auto flex max-w-xs flex-col gap-y-4">
<dt class="text-base leading-7 text-gray-600">{{ conn.counterparty?.connection_id }} {{ clientState.client_id }}</dt>
<dd class="order-first text-3xl font-semibold tracking-tight text-gray-900 sm:text-5xl">{{clientState.client_state?.chain_id}}</dd>
</div>
</dl>
</div>
</div>
<VCard class="my-2">
<VCardTitle>IBC Client State</VCardTitle>
<VCardText>
<br>update after expiry: {{ clientState.client_state?.allow_update_after_expiry }}
<br>allow_update_after_misbehaviour: {{ clientState.client_state?.allow_update_after_misbehaviour }}
<br>trust_level: {{ clientState.client_state?.trust_level?.numerator }}/{{ clientState.client_state?.trust_level?.denominator }}
<br>trusting_period: {{ clientState.client_state?.trusting_period }}
<br>unbonding_period: {{ clientState.client_state?.unbonding_period }}
<br>frozen_height: {{ clientState.client_state?.frozen_height }}
<br>latest_height: {{ clientState.client_state?.latest_height }}
<br>type: {{ clientState.client_state?.['@type'] }}
<br>upgrade_path: {{ clientState.client_state?.upgrade_path }}
<br> {{ clientState.client_state?.max_clock_drift }}
</VCardText>
</VCard>
<VCard class="my-2">
<VCardTitle>Channels</VCardTitle>
<VTable>
<thead>
<tr><th>Channel Id</th><th>Port Id</th><th>Counterparty</th><th>Hops</th><th>Version</th><th>Ordering</th><th>State</th></tr>
</thead>
<tbody>
<tr v-for="v in channels">
<td><a href="#" @click="loadChannel(v.channel_id, v.port_id)">{{ v.channel_id }}</a></td>
<td>{{ v.port_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>
<td><VChip :color="color(v.state)">{{ v.state }}</VChip></td>
</tr>
</tbody>
</VTable>
</VCard>
</div>
</template>

View File

@ -0,0 +1,51 @@
<script lang="ts" setup>
import { useBlockchain, useFormatter } from '@/stores';
import type { Connection } from '@/types';
import { onMounted } from 'vue';
import { ref } from 'vue';
const props = defineProps(['chain'])
const chainStore = useBlockchain()
const list = ref([] as Connection[])
onMounted(() => {
chainStore.rpc.getIBCConnections().then(x => {
list.value = x.connections
})
})
function color(v: string) {
if(v && v.indexOf("_OPEN") > -1) {
return "success"
}
return "warning"
}
</script>
<template>
<div>
<VCard>
<VCardTitle>IBC Connections</VCardTitle>
<VTable>
<thead>
<tr><th>Connection Id</th><th>Connection</th><th>Delay Period</th><th>State</th></tr>
</thead>
<tbody>
<tr v-for="v in list">
<td><RouterLink :to="`/${chain}/ibc/${v.id}`">{{ v.id }}</RouterLink></td>
<td>{{ v.client_id }} {{ v.id }} <br> {{v.counterparty.client_id }} {{ v.counterparty.connection_id }} </td>
<td>{{ v.delay_period }}</td>
<td><VChip :color="color(v.state)">{{ v.state }}</VChip></td>
</tr>
</tbody>
</VTable>
</VCard>
</div>
</template>
<route>
{
meta: {
i18n: 'ibc'
}
}
</route>

View File

@ -7,7 +7,8 @@
"parameters": "Parameters",
"uptime": "Uptime",
"state-sync": "State Sync",
"cosmwasm": "Cosmwasm"
"cosmwasm": "Cosmwasm",
"ibc": "IBC"
},
"index": {
"slogan": "Ping Dashboard is not just an explorer but also a wallet and more ... 🛠",

View File

@ -1,4 +1,107 @@
export interface DenomTrace {
"path": "string",
"base_denom": "string"
import type { PaginatedResponse } from "."
export interface DenomTrace {
path: string,
base_denom: string
}
export interface Connection {
id: string,
client_id: string,
versions: {
identifier: string,
features: string[]
}[],
state: string,
counterparty: {
client_id: string,
connection_id: string,
prefix: {
key_prefix: string
}
},
delay_period: string
}
export interface Channel {
state: string,
ordering: string,
counterparty: {
port_id: string,
channel_id: string
},
connection_hops: string[],
version: string,
port_id: string,
channel_id: string
}
export interface ClientState {
"@type": string,
chain_id: string,
trust_level: {
numerator: string,
denominator: string
},
trusting_period: string,
unbonding_period: string,
max_clock_drift: string,
frozen_height: {
revision_number: string,
revision_height: string
},
latest_height: {
revision_number: string,
revision_height: string
},
proof_specs: {
leaf_spec: {
hash: string,
prehash_key: string,
prehash_value: string,
length: string,
prefix: string
},
inner_spec: {
child_order: number[],
child_size: number,
min_prefix_length: number,
max_prefix_length: number,
empty_child: string,
hash: string
},
max_depth: number,
min_depth: number
}[],
upgrade_path: string[],
allow_update_after_expiry: boolean,
allow_update_after_misbehaviour: boolean
}
export interface ClientStateWithProof {
identified_client_state: {
client_id: string,
client_state: ClientState
},
proof: string,
proof_height: {
revision_number: string,
revision_height: string
}
}
export interface ConnectionWithProof {
connection: Connection,
proof: string,
proof_height: {
revision_number: string,
revision_height: string
}
}
export interface PaginatedIBCChannels extends PaginatedResponse {
channels: Channel[]
}
export interface PaginatedIBCConnections extends PaginatedResponse {
connections: Connection[]
}

4649
yarn.lock

File diff suppressed because it is too large Load Diff