forked from cerc-io/cosmos-explorer
Merge branch 'master' of https://github.com/ping-pub/explorer
This commit is contained in:
@@ -37,7 +37,7 @@ function gotoPage(pageNum: number) {
|
||||
|
||||
</script>
|
||||
<template>
|
||||
<div class="my-5">
|
||||
<div class="my-5 text-center">
|
||||
<div v-if="total && limit" class="btn-group">
|
||||
<button v-for="{ page, color } in pages" :key="page"
|
||||
class="btn bg-gray-100 text-gray-500 hover:text-white border-none dark:bg-gray-800 dark:text-white" :class="{
|
||||
|
||||
@@ -62,6 +62,7 @@ const proposalInfo = ref();
|
||||
{{ item?.content?.title }}
|
||||
</RouterLink>
|
||||
<div
|
||||
v-if="item.content"
|
||||
class="bg-[#f6f2ff] text-[#9c6cff] dark:bg-gray-600 dark:text-gray-300 inline-block rounded-full px-2 py-[1px] text-xs mb-1"
|
||||
>
|
||||
{{ showType(item.content['@type']) }}
|
||||
@@ -157,6 +158,7 @@ const proposalInfo = ref();
|
||||
<div class="grid grid-cols-4 mt-2 mb-2">
|
||||
<div class="col-span-2">
|
||||
<div
|
||||
v-if="item.content"
|
||||
class="bg-[#f6f2ff] text-[#9c6cff] dark:bg-gray-600 dark:text-gray-300 inline-block rounded-full px-2 py-[1px] text-xs mb-1"
|
||||
>
|
||||
{{ showType(item.content['@type']) }}
|
||||
|
||||
+27
-4
@@ -6,11 +6,12 @@ import {
|
||||
type RequestRegistry,
|
||||
type AbstractRegistry,
|
||||
findApiProfileByChain,
|
||||
findApiProfileBySDKVersion,
|
||||
registryChainProfile,
|
||||
registryVersionProfile,
|
||||
withCustomRequest,
|
||||
} from './registry';
|
||||
import { PageRequest,type Coin } from '@/types';
|
||||
import { CUSTOM } from './custom_api/evmos'
|
||||
|
||||
export class BaseRestClient<R extends AbstractRegistry> {
|
||||
endpoint: string;
|
||||
@@ -28,15 +29,37 @@ export class BaseRestClient<R extends AbstractRegistry> {
|
||||
}
|
||||
}
|
||||
|
||||
// dynamic all custom request implementations
|
||||
function registeCustomRequest() {
|
||||
const extensions: Record<string, any> = import.meta.glob('./clients/*.ts', { eager: true });
|
||||
Object.values(extensions).forEach(m => {
|
||||
if(m.store === 'version') {
|
||||
registryVersionProfile(m.name, withCustomRequest(DEFAULT, m.requests))
|
||||
} else {
|
||||
registryChainProfile(m.name, withCustomRequest(DEFAULT, m.requests));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
registeCustomRequest()
|
||||
|
||||
export class CosmosRestClient extends BaseRestClient<RequestRegistry> {
|
||||
static newDefault(endpoint: string) {
|
||||
return new CosmosRestClient(endpoint, DEFAULT)
|
||||
}
|
||||
|
||||
static newStrategy(endpoint: string, chain: any) {
|
||||
registryChainProfile('evmos', withCustomRequest(DEFAULT, CUSTOM))
|
||||
const re = findApiProfileByChain(chain.chainName)
|
||||
return new CosmosRestClient(endpoint, re || DEFAULT)
|
||||
|
||||
let req
|
||||
if(chain) {
|
||||
// find by name first
|
||||
req = findApiProfileByChain(chain.chainName)
|
||||
// if not found. try sdk version
|
||||
if(!req && chain.versions?.cosmosSdk) {
|
||||
req = findApiProfileBySDKVersion(chain.versions?.cosmosSdk)
|
||||
}
|
||||
}
|
||||
return new CosmosRestClient(endpoint, req || DEFAULT)
|
||||
}
|
||||
|
||||
// Auth Module
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import type{ RequestRegistry } from '@/libs/registry'
|
||||
import { DEFAULT } from '@/libs'
|
||||
export const CUSTOM: Partial<RequestRegistry> = {
|
||||
|
||||
// which registry is store
|
||||
export const store = 'name' // name or version
|
||||
// Blockchain Name
|
||||
export const name = 'evmos'
|
||||
export const requests: Partial<RequestRegistry> = {
|
||||
mint_inflation: { url: '/evmos/inflation/v1/inflation_rate', adapter: (data: any) => ({inflation: (Number(data.inflation_rate || 0)/ 100 ).toFixed(2)}) },
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
import type { RequestRegistry } from '@/libs/registry'
|
||||
import { adapter } from '@/libs/registry'
|
||||
import type {
|
||||
GovParams,
|
||||
GovProposal,
|
||||
GovVote,
|
||||
PaginatedProposalDeposit,
|
||||
PaginatedProposalVotes,
|
||||
PaginatedProposals,
|
||||
Tally,
|
||||
} from '@/types/';
|
||||
|
||||
// which registry is store
|
||||
export const store = 'version' // name or version
|
||||
// Blockchain Name
|
||||
export const name = 'v0.46.7'
|
||||
|
||||
function proposalAdapter(p: any): GovProposal {
|
||||
if(p) {
|
||||
if(p.messages) p.content = p.messages[0].content
|
||||
p.proposal_id = p.id
|
||||
p.final_tally_result = {
|
||||
yes: p.final_tally_result?.yes_count,
|
||||
no: p.final_tally_result?.no_count,
|
||||
no_with_veto: p.final_tally_result?.no_with_veto_count,
|
||||
abstain: p.final_tally_result?.abstain_count,
|
||||
}
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
export const requests: Partial<RequestRegistry> = {
|
||||
gov_params_voting: { url: '/cosmos/gov/v1/params/voting', adapter },
|
||||
gov_params_tally: { url: '/cosmos/gov/v1/params/tallying', adapter },
|
||||
gov_params_deposit: { url: '/cosmos/gov/v1/params/deposit', adapter },
|
||||
gov_proposals: { url: '/cosmos/gov/v1/proposals', adapter: (source: any): PaginatedProposals => {
|
||||
const proposals = source.proposals.map((p:any) => proposalAdapter(p))
|
||||
return {
|
||||
proposals,
|
||||
pagination: source.pagination
|
||||
}
|
||||
}},
|
||||
gov_proposals_proposal_id: {
|
||||
url: '/cosmos/gov/v1/proposals/{proposal_id}',
|
||||
adapter: (source: any): {proposal: GovProposal} => {
|
||||
return {
|
||||
proposal: proposalAdapter(source.proposal)
|
||||
}
|
||||
},
|
||||
},
|
||||
gov_proposals_deposits: {
|
||||
url: '/cosmos/gov/v1/proposals/{proposal_id}/deposits',
|
||||
adapter,
|
||||
},
|
||||
gov_proposals_tally: {
|
||||
url: '/cosmos/gov/v1/proposals/{proposal_id}/tally',
|
||||
adapter,
|
||||
},
|
||||
gov_proposals_votes: {
|
||||
url: '/cosmos/gov/v1/proposals/{proposal_id}/votes',
|
||||
adapter,
|
||||
},
|
||||
gov_proposals_votes_voter: {
|
||||
url: '/cosmos/gov/v1/proposals/{proposal_id}/votes/{voter}',
|
||||
adapter,
|
||||
},
|
||||
}
|
||||
+8
-10
@@ -185,28 +185,26 @@ export function findApiProfileByChain(
|
||||
// if (!url) {
|
||||
// throw new Error(`Unsupported version or name: ${name}`);
|
||||
// }
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
export function findApiProfileBySDKVersion(
|
||||
version: string,
|
||||
): RequestRegistry {
|
||||
): RequestRegistry | undefined {
|
||||
let closestVersion: string | null = null;
|
||||
|
||||
for (const key in VERSION_REGISTRY) {
|
||||
if (semver.satisfies(key, version)) {
|
||||
for (const k in VERSION_REGISTRY) {
|
||||
const key = k.replace('v', "")
|
||||
// console.log(semver.gt(key, version), semver.gte(version, key), key, version)
|
||||
if (semver.lte(key, version)) {
|
||||
if (!closestVersion || semver.gt(key, closestVersion)) {
|
||||
closestVersion = key;
|
||||
closestVersion = k;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// console.log(`Closest version to ${version}: ${closestVersion}`, VERSION_REGISTRY);
|
||||
if (!closestVersion) {
|
||||
throw new Error(`Unsupported version: ${version}`);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
console.log(`Closest version to ${version}: ${closestVersion}`);
|
||||
|
||||
return VERSION_REGISTRY[closestVersion];
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
import {
|
||||
useBaseStore,
|
||||
useBlockchain,
|
||||
useDistributionStore,
|
||||
useFormatter,
|
||||
useMintStore,
|
||||
useStakingStore,
|
||||
@@ -120,7 +119,7 @@ const calculateRank = function (position: number) {
|
||||
|
||||
function isFeatured(endpoints: string[], who?: {website?: string, moniker: string }) {
|
||||
if(!endpoints || !who) return false
|
||||
return endpoints.findIndex(x => who.website && who.website?.substring(0, who.website?.lastIndexOf('.')).endsWith(x) || who?.moniker?.toLowerCase().search(x) > -1) > -1
|
||||
return endpoints.findIndex(x => who.website && who.website?.substring(0, who.website?.lastIndexOf('.')).endsWith(x) || who?.moniker?.toLowerCase().search(x.toLowerCase()) > -1) > -1
|
||||
}
|
||||
|
||||
const list = computed(() => {
|
||||
@@ -307,7 +306,7 @@ loadAvatars();
|
||||
<td>
|
||||
<div
|
||||
class="flex items-center overflow-hidden"
|
||||
style="max-width: 400px"
|
||||
style="max-width: 300px"
|
||||
>
|
||||
<div
|
||||
class="avatar mr-4 relative w-8 h-8 rounded-full overflow-hidden"
|
||||
@@ -331,7 +330,7 @@ loadAvatars();
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col">
|
||||
<h6 class="text-sm text-primary dark:invert">
|
||||
<span class="text-sm text-primary dark:invert whitespace-nowrap overflow-hidden">
|
||||
<RouterLink
|
||||
:to="{
|
||||
name: 'chain-staking-validator',
|
||||
@@ -340,11 +339,11 @@ loadAvatars();
|
||||
v.operator_address,
|
||||
},
|
||||
}"
|
||||
class="font-weight-medium user-list-name"
|
||||
class="font-weight-medium"
|
||||
>
|
||||
{{ v.description?.moniker }}
|
||||
</RouterLink>
|
||||
</h6>
|
||||
</span>
|
||||
<span class="text-xs">{{
|
||||
v.description?.website ||
|
||||
v.description?.identity ||
|
||||
@@ -357,7 +356,7 @@ loadAvatars();
|
||||
<!-- 👉 Voting Power -->
|
||||
<td class="text-right">
|
||||
<div class="flex flex-col">
|
||||
<h6 class="text-sm font-weight-medium">
|
||||
<h6 class="text-sm font-weight-medium whitespace-nowrap ">
|
||||
{{
|
||||
format.formatToken(
|
||||
{
|
||||
|
||||
@@ -179,7 +179,9 @@ function color(v: string) {
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<label for="add-validator" class="btn btn-primary mt-5">Add Validators</label>
|
||||
<div class="text-center">
|
||||
<label for="add-validator" class="btn btn-primary mt-5">Add Validators</label>
|
||||
</div>
|
||||
|
||||
<!-- Put this part before </body> tag -->
|
||||
<input type="checkbox" id="add-validator" class="modal-toggle" @change="initial" />
|
||||
@@ -212,7 +214,7 @@ function color(v: string) {
|
||||
</table>
|
||||
</div>
|
||||
<div class="modal-action">
|
||||
<label for="add-validator" class="btn" @click="add">add</label>
|
||||
<label class="btn btn-primary" @click="add">add</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -228,7 +228,7 @@ async function loadBalances(endpoint: string, address: string) {
|
||||
</script>
|
||||
<template>
|
||||
<div>
|
||||
<div class="overflow-x-auto w-full rounded-lg">
|
||||
<div class="overflow-x-auto w-full rounded-md">
|
||||
<div class="flex flex-wrap justify-between bg-base-100 p-5">
|
||||
<div class="min-w-0">
|
||||
<h2 class="text-2xl font-bold leading-7 sm:!truncate sm:!text-3xl sm:!tracking-tight">
|
||||
@@ -258,9 +258,9 @@ async function loadBalances(endpoint: string, address: string) {
|
||||
</div>
|
||||
|
||||
<div class="overflow-x-auto">
|
||||
<div v-for="{ key, subaccounts } in accounts" class="bg-base-100 rounded-xl my-5 py-5 px-2">
|
||||
<div v-for="{ key, subaccounts } in accounts" class="bg-base-100 rounded-md my-5 py-5">
|
||||
<div class="flex justify-self-center">
|
||||
<div class="mr-2 p-2">
|
||||
<div class="mx-2 p-2">
|
||||
<svg :fill="chainStore.current?.themeColor || '#666CFF'" height="28px" width="28px" version="1.1" id="Capa_1"
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 487.5 487.5"
|
||||
xml:space="preserve">
|
||||
@@ -340,7 +340,7 @@ async function loadBalances(endpoint: string, address: string) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class=" text-center bg-base-100 rounded-xl my-4 p-4">
|
||||
<div class=" text-center bg-base-100 rounded-md my-4 p-4">
|
||||
<a href="#address-modal"
|
||||
class="inline-flex items-center ml-3 rounded-md bg-white px-3 py-2 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50">
|
||||
<svg class="-ml-0.5 mr-1.5 h-5 w-5 text-gray-400" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||
|
||||
@@ -213,7 +213,7 @@ const currencySign = computed(() => {
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<div class="overflow-x-auto w-full rounded-lg">
|
||||
<div class="overflow-x-auto w-full rounded-md">
|
||||
<div class="flex flex-wrap justify-between bg-base-100 p-5">
|
||||
<div class="min-w-0">
|
||||
<h2 class="text-2xl font-bold leading-7 sm:!truncate sm:!text-3xl sm:!tracking-tight">
|
||||
|
||||
@@ -149,6 +149,9 @@ export function fromLocal(lc: LocalConfig): ChainConfig {
|
||||
{ denom: x.symbol.toLowerCase(), exponent: Number(x.exponent) },
|
||||
],
|
||||
}));
|
||||
conf.versions = {
|
||||
cosmosSdk: lc.sdk_version
|
||||
}
|
||||
conf.bech32Prefix = lc.addr_prefix;
|
||||
conf.chainName = lc.chain_name;
|
||||
conf.coinType = lc.coin_type;
|
||||
|
||||
@@ -350,7 +350,7 @@ export const useFormatter = defineStore('formatter', {
|
||||
}
|
||||
},
|
||||
multiLine(v: string) {
|
||||
return v ? v.replaceAll('\\n', '\n') : '';
|
||||
return v ? v.replace(/\\n|\\r/g, '\n') : '';
|
||||
},
|
||||
hexToString(hex: string) {
|
||||
if (hex) {
|
||||
|
||||
Reference in New Issue
Block a user