forked from LaconicNetwork/cosmos-explorer
View vote extension and includebundle transaction
This commit is contained in:
parent
f28cba9e82
commit
59e7a3dbcd
@ -46,7 +46,12 @@ const chain = useBlockchain();
|
||||
<tr v-for="item in txs">
|
||||
<td>{{ item.injected }}</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">{{
|
||||
item.hash
|
||||
}}</RouterLink>
|
||||
|
||||
@ -17,9 +17,11 @@ import semver from 'semver';
|
||||
export class BaseRestClient<R extends AbstractRegistry> {
|
||||
version: string;
|
||||
endpoint: string;
|
||||
rpcEndpoint: string;
|
||||
registry: R;
|
||||
constructor(endpoint: string, registry: R, version?: string) {
|
||||
constructor(endpoint: string, registry: R, version?: string, rpcEndpoint?: string) {
|
||||
this.endpoint = endpoint;
|
||||
this.rpcEndpoint = rpcEndpoint || '';
|
||||
this.registry = registry;
|
||||
this.version = version || 'v0.40';
|
||||
}
|
||||
@ -70,7 +72,8 @@ export class CosmosRestClient extends BaseRestClient<RequestRegistry> {
|
||||
profile = findApiProfileBySDKVersion(ver);
|
||||
}
|
||||
}
|
||||
return new CosmosRestClient(endpoint, profile || DEFAULT, ver);
|
||||
const rpcEndpoint = chain?.endpoints?.rpc?.[0]?.address;
|
||||
return new CosmosRestClient(endpoint, profile || DEFAULT, ver, rpcEndpoint);
|
||||
}
|
||||
|
||||
// Auth Module
|
||||
@ -312,6 +315,12 @@ export class CosmosRestClient extends BaseRestClient<RequestRegistry> {
|
||||
async getTx(hash: string) {
|
||||
return this.request(this.registry.tx_hash, { hash });
|
||||
}
|
||||
async getTxFromRPC(hash: string) {
|
||||
return this.request(
|
||||
{ url: `${this.rpcEndpoint}/tx?hash=0x{hash}`, adapter: async (source: any) => source },
|
||||
{ hash }
|
||||
);
|
||||
}
|
||||
|
||||
// mint
|
||||
async getMintParam() {
|
||||
|
||||
@ -3,12 +3,14 @@ import { useBaseStore, useBlockchain, useFormatter } from '@/stores';
|
||||
import DynamicComponent from '@/components/dynamic/DynamicComponent.vue';
|
||||
import { computed, ref } from '@vue/reactivity';
|
||||
import type { Tx, TxResponse } from '@/types';
|
||||
import { useRoute } from 'vue-router';
|
||||
|
||||
import { JsonViewer } from 'vue3-json-viewer';
|
||||
// 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';
|
||||
|
||||
const props = defineProps(['hash', 'chain']);
|
||||
const route = useRoute();
|
||||
|
||||
const blockchain = useBlockchain();
|
||||
const baseStore = useBaseStore();
|
||||
@ -19,9 +21,35 @@ const tx = ref(
|
||||
tx_response: TxResponse;
|
||||
}
|
||||
);
|
||||
const voteExtension = ref(null as any);
|
||||
const bundleTx = ref(null as any);
|
||||
const isVoteExtension = computed(() => route.query.type === 'injected');
|
||||
|
||||
if (props.hash) {
|
||||
blockchain.rpc.getTx(props.hash).then((x) => (tx.value = x));
|
||||
if (isVoteExtension.value) {
|
||||
blockchain.rpc.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;
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
blockchain.rpc.getTx(props.hash).then((x) => (tx.value = x));
|
||||
}
|
||||
}
|
||||
|
||||
const messages = computed(() => {
|
||||
return (
|
||||
tx.value.tx?.body?.messages.map((x) => {
|
||||
@ -33,6 +61,16 @@ const messages = computed(() => {
|
||||
}) || []
|
||||
);
|
||||
});
|
||||
|
||||
const voteExtDecoded = computed(() => {
|
||||
if (!voteExtension.value?.tx) return null;
|
||||
try {
|
||||
const txBytes = new Uint8Array(atob(voteExtension.value.tx).split('').map((c: string) => c.charCodeAt(0)));
|
||||
return JSON.parse(new TextDecoder().decode(txBytes));
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<div>
|
||||
@ -44,6 +82,74 @@ const messages = computed(() => {
|
||||
<a class="tab text-gray-400 uppercase tab-active">Transaction</a>
|
||||
</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>
|
||||
<tr v-if="bundleTx.decoded?.type">
|
||||
<td>Type</td>
|
||||
<td>{{ bundleTx.decoded.type }}</td>
|
||||
</tr>
|
||||
<tr v-if="bundleTx.decoded?.star_id">
|
||||
<td>Star ID</td>
|
||||
<td>{{ bundleTx.decoded.star_id }}</td>
|
||||
</tr>
|
||||
<tr v-if="bundleTx.decoded?.bundle_id">
|
||||
<td>Bundle ID</td>
|
||||
<td>{{ bundleTx.decoded.bundle_id }}</td>
|
||||
</tr>
|
||||
<tr v-if="bundleTx.decoded?.transaction_count">
|
||||
<td>Transaction Count</td>
|
||||
<td>{{ bundleTx.decoded.transaction_count }}</td>
|
||||
</tr>
|
||||
<tr v-if="bundleTx.decoded?.timestamp">
|
||||
<td>Timestamp</td>
|
||||
<td>
|
||||
{{ format.toLocaleDate(bundleTx.decoded.timestamp) }} ({{
|
||||
format.toDay(bundleTx.decoded.timestamp, 'from')
|
||||
}})
|
||||
</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">
|
||||
<h2 class="card-title truncate mb-2">{{ $t('tx.title') }}</h2>
|
||||
<div class="overflow-hidden">
|
||||
@ -116,6 +222,32 @@ const messages = computed(() => {
|
||||
<div v-if="messages.length === 0">{{ $t('tx.no_messages') }}</div>
|
||||
</div>
|
||||
|
||||
<div v-if="bundleTx" class="bg-base-100 px-4 pt-3 pb-4 rounded shadow">
|
||||
<h2 class="card-title truncate mb-2">JSON</h2>
|
||||
<JsonViewer
|
||||
:value="bundleTx.decoded"
|
||||
:theme="baseStore.theme"
|
||||
style="background: transparent"
|
||||
copyable
|
||||
boxed
|
||||
sort
|
||||
:expand-depth="5"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div v-if="voteExtension" class="bg-base-100 px-4 pt-3 pb-4 rounded shadow">
|
||||
<h2 class="card-title truncate mb-2">JSON</h2>
|
||||
<JsonViewer
|
||||
:value="voteExtDecoded"
|
||||
:theme="baseStore.theme"
|
||||
style="background: transparent"
|
||||
copyable
|
||||
boxed
|
||||
sort
|
||||
:expand-depth="5"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div v-if="tx.tx_response" class="bg-base-100 px-4 pt-3 pb-4 rounded shadow">
|
||||
<h2 class="card-title truncate mb-2">JSON</h2>
|
||||
<JsonViewer
|
||||
@ -125,7 +257,7 @@ const messages = computed(() => {
|
||||
copyable
|
||||
boxed
|
||||
sort
|
||||
expand-depth="5"
|
||||
:expand-depth="5"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user