Refactor RPC endpoint in REST client

This commit is contained in:
Nabarun 2025-12-03 17:22:11 +05:30
parent 9fc9ca715d
commit cb0265f842
2 changed files with 63 additions and 69 deletions

View File

@ -17,11 +17,9 @@ 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, rpcEndpoint?: string) {
constructor(endpoint: string, registry: R, version?: string) {
this.endpoint = endpoint;
this.rpcEndpoint = rpcEndpoint || '';
this.registry = registry;
this.version = version || 'v0.40';
}
@ -72,8 +70,7 @@ export class CosmosRestClient extends BaseRestClient<RequestRegistry> {
profile = findApiProfileBySDKVersion(ver);
}
}
const rpcEndpoint = chain?.endpoints?.rpc?.[0]?.address;
return new CosmosRestClient(endpoint, profile || DEFAULT, ver, rpcEndpoint);
return new CosmosRestClient(endpoint, profile || DEFAULT, ver);
}
// Auth Module
@ -315,12 +312,6 @@ 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() {

View File

@ -1,11 +1,12 @@
<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 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';
@ -14,7 +15,10 @@ const route = useRoute();
const blockchain = useBlockchain();
const baseStore = useBaseStore();
const chainStore = useBlockchain();
const format = useFormatter();
const rpcList = ref(chainStore.current?.endpoints?.rpc || [{ address: '', provider: '' }]);
let rpc = ref('');
const tx = ref(
{} as {
tx: Tx;
@ -23,31 +27,50 @@ const tx = ref(
);
const voteExtension = ref(null as any);
const bundleTx = ref(null as any);
const isVoteExtension = computed(() => route.query.type === 'injected');
if (props.hash) {
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);
const isInjected = computed(() => route.query.type === 'injected');
// 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;
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));
});
} else {
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(() => {
@ -62,14 +85,20 @@ 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;
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>
<template>
@ -198,36 +227,10 @@ const voteExtDecoded = 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">
<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>
<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
:value="tx"
:value="jsonData"
:theme="baseStore.theme"
style="background: transparent"
copyable