forked from cerc-io/cosmos-explorer
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 471fa450b8 |
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ping.pub",
|
"name": "ping.pub",
|
||||||
"version": "3.0.1-zenith-0.1.2",
|
"version": "3.0.1-zenith-0.2.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"target": "",
|
"target": "",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@ -46,7 +46,12 @@ const chain = useBlockchain();
|
|||||||
<tr v-for="item in txs">
|
<tr v-for="item in txs">
|
||||||
<td>{{ item.injected }}</td>
|
<td>{{ item.injected }}</td>
|
||||||
<td>
|
<td>
|
||||||
<span v-if="item.injected === 'Injected'">{{ item.hash }}</span>
|
<RouterLink
|
||||||
|
v-if="item.injected === 'Injected'"
|
||||||
|
:to="`/${chain.chainName}/tx/${item.hash}?type=injected`"
|
||||||
|
class="text-primary dark:invert">
|
||||||
|
{{ item.hash }}
|
||||||
|
</RouterLink>
|
||||||
<RouterLink v-else :to="`/${chain.chainName}/tx/${item.hash}`" class="text-primary dark:invert">{{
|
<RouterLink v-else :to="`/${chain.chainName}/tx/${item.hash}`" class="text-primary dark:invert">{{
|
||||||
item.hash
|
item.hash
|
||||||
}}</RouterLink>
|
}}</RouterLink>
|
||||||
|
|||||||
@ -1,27 +1,78 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import { onMounted } from 'vue';
|
||||||
|
import { useRoute } from 'vue-router';
|
||||||
|
import { JsonViewer } from 'vue3-json-viewer';
|
||||||
import { useBaseStore, useBlockchain, useFormatter } from '@/stores';
|
import { useBaseStore, useBlockchain, useFormatter } from '@/stores';
|
||||||
import DynamicComponent from '@/components/dynamic/DynamicComponent.vue';
|
import DynamicComponent from '@/components/dynamic/DynamicComponent.vue';
|
||||||
import { computed, ref } from '@vue/reactivity';
|
import { computed, ref } from '@vue/reactivity';
|
||||||
import type { Tx, TxResponse } from '@/types';
|
import type { Tx, TxResponse } from '@/types';
|
||||||
|
|
||||||
import { JsonViewer } from 'vue3-json-viewer';
|
|
||||||
// if you used v1.0.5 or latster ,you should add import "vue3-json-viewer/dist/index.css"
|
// if you used v1.0.5 or latster ,you should add import "vue3-json-viewer/dist/index.css"
|
||||||
import 'vue3-json-viewer/dist/index.css';
|
import 'vue3-json-viewer/dist/index.css';
|
||||||
|
|
||||||
const props = defineProps(['hash', 'chain']);
|
const props = defineProps(['hash', 'chain']);
|
||||||
|
const route = useRoute();
|
||||||
|
|
||||||
const blockchain = useBlockchain();
|
const blockchain = useBlockchain();
|
||||||
const baseStore = useBaseStore();
|
const baseStore = useBaseStore();
|
||||||
|
const chainStore = useBlockchain();
|
||||||
const format = useFormatter();
|
const format = useFormatter();
|
||||||
|
const rpcList = ref(chainStore.current?.endpoints?.rpc || [{ address: '', provider: '' }]);
|
||||||
|
let rpc = ref('');
|
||||||
const tx = ref(
|
const tx = ref(
|
||||||
{} as {
|
{} as {
|
||||||
tx: Tx;
|
tx: Tx;
|
||||||
tx_response: TxResponse;
|
tx_response: TxResponse;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
if (props.hash) {
|
const voteExtension = ref(null as any);
|
||||||
|
const bundleTx = ref(null as any);
|
||||||
|
|
||||||
|
const isInjected = computed(() => route.query.type === 'injected');
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
rpc.value = rpcList.value[0].address;
|
||||||
|
|
||||||
|
if (props.hash) {
|
||||||
|
if (isInjected.value) {
|
||||||
|
getTxFromRPC(props.hash).then((data) => {
|
||||||
|
if (data.result) {
|
||||||
|
const txBytes = new Uint8Array(atob(data.result.tx).split('').map((c: string) => c.charCodeAt(0)));
|
||||||
|
const decoded = new TextDecoder().decode(txBytes);
|
||||||
|
|
||||||
|
// Check if it's a bundle tx
|
||||||
|
if (decoded.startsWith('INCLUDE_BUNDLE_TX:')) {
|
||||||
|
const bundleJson = decoded.replace('INCLUDE_BUNDLE_TX:', '');
|
||||||
|
bundleTx.value = {
|
||||||
|
...data.result,
|
||||||
|
decoded: JSON.parse(bundleJson)
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
// It's a vote extension
|
||||||
|
voteExtension.value = {
|
||||||
|
...data.result,
|
||||||
|
decoded: JSON.parse(decoded)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
blockchain.rpc.getTx(props.hash).then((x) => (tx.value = x));
|
blockchain.rpc.getTx(props.hash).then((x) => (tx.value = x));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
async function getTxFromRPC(hash: string) {
|
||||||
|
const response = await fetch(rpc.value + `/tx?hash=0x${hash}`);
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`HTTP error: ${response.status}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
const messages = computed(() => {
|
const messages = computed(() => {
|
||||||
return (
|
return (
|
||||||
tx.value.tx?.body?.messages.map((x) => {
|
tx.value.tx?.body?.messages.map((x) => {
|
||||||
@ -33,6 +84,22 @@ const messages = computed(() => {
|
|||||||
}) || []
|
}) || []
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const jsonData = computed(() => {
|
||||||
|
if (tx.value.tx_response) {
|
||||||
|
return tx.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (voteExtension.value) {
|
||||||
|
return voteExtension.value.decoded
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bundleTx.value) {
|
||||||
|
return bundleTx.value.decoded
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
@ -44,6 +111,50 @@ const messages = computed(() => {
|
|||||||
<a class="tab text-gray-400 uppercase tab-active">Transaction</a>
|
<a class="tab text-gray-400 uppercase tab-active">Transaction</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div v-if="bundleTx" class="bg-base-100 px-4 pt-3 pb-4 rounded shadow mb-4">
|
||||||
|
<h2 class="card-title truncate mb-2">Bundle Transaction</h2>
|
||||||
|
<div class="overflow-hidden">
|
||||||
|
<table class="table text-sm">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>Tx Hash</td>
|
||||||
|
<td class="overflow-hidden">{{ bundleTx.hash }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Height</td>
|
||||||
|
<td>
|
||||||
|
<RouterLink :to="`/${props.chain}/block/${bundleTx.height}`" class="text-primary dark:invert"
|
||||||
|
>{{ bundleTx.height }}
|
||||||
|
</RouterLink>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="voteExtension" class="bg-base-100 px-4 pt-3 pb-4 rounded shadow mb-4">
|
||||||
|
<h2 class="card-title truncate mb-2">Vote Extension</h2>
|
||||||
|
<div class="overflow-hidden">
|
||||||
|
<table class="table text-sm">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>Tx Hash</td>
|
||||||
|
<td class="overflow-hidden">{{ voteExtension.hash }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Height</td>
|
||||||
|
<td>
|
||||||
|
<RouterLink :to="`/${props.chain}/block/${voteExtension.height}`" class="text-primary dark:invert"
|
||||||
|
>{{ voteExtension.height }}
|
||||||
|
</RouterLink>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div v-if="tx.tx_response" class="bg-base-100 px-4 pt-3 pb-4 rounded shadow mb-4">
|
<div v-if="tx.tx_response" class="bg-base-100 px-4 pt-3 pb-4 rounded shadow mb-4">
|
||||||
<h2 class="card-title truncate mb-2">{{ $t('tx.title') }}</h2>
|
<h2 class="card-title truncate mb-2">{{ $t('tx.title') }}</h2>
|
||||||
<div class="overflow-hidden">
|
<div class="overflow-hidden">
|
||||||
@ -116,16 +227,16 @@ const messages = computed(() => {
|
|||||||
<div v-if="messages.length === 0">{{ $t('tx.no_messages') }}</div>
|
<div v-if="messages.length === 0">{{ $t('tx.no_messages') }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="tx.tx_response" class="bg-base-100 px-4 pt-3 pb-4 rounded shadow">
|
<div v-if="jsonData" class="bg-base-100 px-4 pt-3 pb-4 rounded shadow">
|
||||||
<h2 class="card-title truncate mb-2">JSON</h2>
|
<h2 class="card-title truncate mb-2">JSON</h2>
|
||||||
<JsonViewer
|
<JsonViewer
|
||||||
:value="tx"
|
:value="jsonData"
|
||||||
:theme="baseStore.theme"
|
:theme="baseStore.theme"
|
||||||
style="background: transparent"
|
style="background: transparent"
|
||||||
copyable
|
copyable
|
||||||
boxed
|
boxed
|
||||||
sort
|
sort
|
||||||
expand-depth="5"
|
:expand-depth="5"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user