From 0960ad65964768562f4de2370d69d9a73b7ada92 Mon Sep 17 00:00:00 2001 From: liangping <18786721@qq.com> Date: Sun, 1 Sep 2024 15:04:33 +0800 Subject: [PATCH] refactor version compatible support --- .../{clients => api/customization}/evmos.ts | 4 +- .../{clients => api/customization}/nolus.ts | 4 +- .../{clients => api/customization}/osmosis.ts | 4 +- .../{clients => api/customization}/v0.46.0.ts | 4 +- src/libs/api/customization/v0.50.0.ts | 69 +++++++++++++++++++ src/libs/{api.ts => api/index.ts} | 0 src/libs/{ => api}/registry.ts | 5 +- src/libs/client.ts | 37 ++++++---- src/modules/[chain]/cosmwasm/WasmClient.ts | 2 +- src/modules/[chain]/gov/[proposal_id].vue | 11 ++- 10 files changed, 113 insertions(+), 27 deletions(-) rename src/libs/{clients => api/customization}/evmos.ts (95%) rename src/libs/{clients => api/customization}/nolus.ts (95%) rename src/libs/{clients => api/customization}/osmosis.ts (95%) rename src/libs/{clients => api/customization}/v0.46.0.ts (94%) create mode 100644 src/libs/api/customization/v0.50.0.ts rename src/libs/{api.ts => api/index.ts} (100%) rename src/libs/{ => api}/registry.ts (98%) diff --git a/src/libs/clients/evmos.ts b/src/libs/api/customization/evmos.ts similarity index 95% rename from src/libs/clients/evmos.ts rename to src/libs/api/customization/evmos.ts index 9adb405d..09f8c527 100644 --- a/src/libs/clients/evmos.ts +++ b/src/libs/api/customization/evmos.ts @@ -1,5 +1,5 @@ -import type{ RequestRegistry } from '@/libs/registry' -import { adapter } from '@/libs/registry' +import type{ RequestRegistry } from '../registry' +import { adapter } from '../registry' import type { GovProposal, PaginatedProposals } from '@/types' // which registry is store export const store = 'name' // name or version diff --git a/src/libs/clients/nolus.ts b/src/libs/api/customization/nolus.ts similarity index 95% rename from src/libs/clients/nolus.ts rename to src/libs/api/customization/nolus.ts index 03416d5f..3418d220 100644 --- a/src/libs/clients/nolus.ts +++ b/src/libs/api/customization/nolus.ts @@ -1,8 +1,8 @@ -import type { RequestRegistry } from '@/libs/registry' +import type { RequestRegistry } from '@/libs/api/registry' import type { GovProposal, PaginatedProposals } from '@/types' import { CosmosRestClient } from '@/libs/client'; import { useBlockchain } from '@/stores'; -import { adapter } from '@/libs/registry' +import { adapter } from '@/libs/api/registry' // Blockchain Name export const name = 'nolus'; diff --git a/src/libs/clients/osmosis.ts b/src/libs/api/customization/osmosis.ts similarity index 95% rename from src/libs/clients/osmosis.ts rename to src/libs/api/customization/osmosis.ts index 6dc384b3..60c7e56a 100644 --- a/src/libs/clients/osmosis.ts +++ b/src/libs/api/customization/osmosis.ts @@ -1,6 +1,6 @@ -import type{ RequestRegistry } from '@/libs/registry' +import type{ RequestRegistry } from '@/libs/api/registry' // import dayjs from 'dayjs' -import { adapter } from '@/libs/registry' +import { adapter } from '@/libs/api/registry' import type { GovProposal, PaginatedProposals } from '@/types' // which registry is store diff --git a/src/libs/clients/v0.46.0.ts b/src/libs/api/customization/v0.46.0.ts similarity index 94% rename from src/libs/clients/v0.46.0.ts rename to src/libs/api/customization/v0.46.0.ts index 6c3d814e..e6b4c15b 100644 --- a/src/libs/clients/v0.46.0.ts +++ b/src/libs/api/customization/v0.46.0.ts @@ -1,5 +1,5 @@ -import type { RequestRegistry } from '@/libs/registry' -import { adapter } from '@/libs/registry' +import type { RequestRegistry } from '@/libs/api/registry' +import { adapter } from '@/libs/api/registry' import type { GovParams, GovProposal, diff --git a/src/libs/api/customization/v0.50.0.ts b/src/libs/api/customization/v0.50.0.ts new file mode 100644 index 00000000..578c759d --- /dev/null +++ b/src/libs/api/customization/v0.50.0.ts @@ -0,0 +1,69 @@ +import type { RequestRegistry } from '@/libs/api/registry' +import { adapter } from '@/libs/api/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.50.0' + +function proposalAdapter(p: any): GovProposal { + if(p) { + if(p.messages && p.messages.length >= 1) p.content = p.messages[0].content || p.messages[0] + 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 = { + + bank_supply_by_denom: { url: '/cosmos/bank/v1beta1/supply/by_denom?denom={denom}', adapter }, + 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: async (source: any): Promise => { + 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: async (source: any): Promise<{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, + }, +} diff --git a/src/libs/api.ts b/src/libs/api/index.ts similarity index 100% rename from src/libs/api.ts rename to src/libs/api/index.ts diff --git a/src/libs/registry.ts b/src/libs/api/registry.ts similarity index 98% rename from src/libs/registry.ts rename to src/libs/api/registry.ts index f65edfcf..56fba5d0 100644 --- a/src/libs/registry.ts +++ b/src/libs/api/registry.ts @@ -195,11 +195,10 @@ export function findApiProfileBySDKVersion( version: string, ): RequestRegistry | undefined { let closestVersion: string | null = null; - + const chain_version = version.match(/(\d+\.\d+\.?\d*)/g) || [""]; 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 (semver.lte(key, chain_version[0])) { if (!closestVersion || semver.gt(key, closestVersion)) { closestVersion = k; } diff --git a/src/libs/client.ts b/src/libs/client.ts index 1238495e..3a7213ad 100644 --- a/src/libs/client.ts +++ b/src/libs/client.ts @@ -10,15 +10,18 @@ import { registryChainProfile, registryVersionProfile, withCustomRequest, -} from './registry'; +} from './api/registry'; import { PageRequest,type Coin } from '@/types'; +import semver from 'semver' export class BaseRestClient { + version: string; endpoint: string; registry: R; - constructor(endpoint: string, registry: R) { + constructor(endpoint: string, registry: R, version?: string) { this.endpoint = endpoint; this.registry = registry; + this.version = version || 'v0.40' } async request(request: Request, args: Record, query = '', adapter?: (source: any) => Promise ) { let url = `${request.url.startsWith("http")?'':this.endpoint}${request.url}${query}`; @@ -31,7 +34,7 @@ export class BaseRestClient { // dynamic all custom request implementations function registeCustomRequest() { - const extensions: Record = import.meta.glob('./clients/*.ts', { eager: true }); + const extensions: Record = import.meta.glob('./api/customization/*.ts', { eager: true }); Object.values(extensions).forEach(m => { if(m.store === 'version') { registryVersionProfile(m.name, withCustomRequest(DEFAULT, m.requests)) @@ -49,17 +52,18 @@ export class CosmosRestClient extends BaseRestClient { } static newStrategy(endpoint: string, chain: any) { - - let req + // sdk version of current chain + const ver = localStorage.getItem(`sdk_version_${chain.chainName}`) || chain.versions?.cosmosSdk + let profile if(chain) { // find by name first - req = findApiProfileByChain(chain.chainName) + profile = findApiProfileByChain(chain.chainName) // if not found. try sdk version - if(!req && chain.versions?.cosmosSdk) { - req = findApiProfileBySDKVersion(localStorage.getItem(`sdk_version_${chain.chainName}`) || chain.versions?.cosmosSdk) + if(!profile && chain.versions?.cosmosSdk) { + profile = findApiProfileBySDKVersion(ver) } } - return new CosmosRestClient(endpoint, req || DEFAULT) + return new CosmosRestClient(endpoint, profile || DEFAULT, ver) } // Auth Module @@ -274,7 +278,11 @@ export class CosmosRestClient extends BaseRestClient { // tx async getTxsBySender(sender: string, page?: PageRequest) { if(!page) page = new PageRequest() - const query = `?order_by=2&events=message.sender='${sender}'&pagination.limit=${page.limit}&pagination.offset=${page.offset||0}`; + + let query = `?events=message.sender='${sender}'&pagination.limit=${page.limit}&pagination.offset=${page.offset||0}`; + if (semver.gte(this.version.replaceAll('v', ''), '0.50.0')) { + query = `?query=message.sender='${sender}'&pagination.limit=${page.limit}&pagination.offset=${page.offset||0}`; + } return this.request(this.registry.tx_txs, {}, query); } // query ibc sending msgs @@ -282,8 +290,13 @@ export class CosmosRestClient extends BaseRestClient { // query ibc receiving msgs // ?&pagination.reverse=true&events=recv_packet.packet_dst_channel='${channel}'&events=recv_packet.packet_dst_port='${port}' async getTxs(query: string, params: any, page?: PageRequest) { - if(!page) page = new PageRequest() - return this.request(this.registry.tx_txs, params, `${query}&${page.toQueryString()}`); + if(!page) page = new PageRequest() + if (semver.gte(this.version.replaceAll('v', ''), '0.50.0')) { + let query_edit = query.replaceAll('events=', 'query=') + return this.request(this.registry.tx_txs, params, `${query_edit}&${page.toQueryString()}`); + } else { + return this.request(this.registry.tx_txs, params, `${query}&${page.toQueryString()}`); + } } async getTxsAt(height: string | number) { return this.request(this.registry.tx_txs_block, { height }); diff --git a/src/modules/[chain]/cosmwasm/WasmClient.ts b/src/modules/[chain]/cosmwasm/WasmClient.ts index 75597557..0feb102c 100644 --- a/src/modules/[chain]/cosmwasm/WasmClient.ts +++ b/src/modules/[chain]/cosmwasm/WasmClient.ts @@ -1,5 +1,5 @@ import { BaseRestClient } from '@/libs/client'; -import { adapter, type AbstractRegistry, type Request } from '@/libs/registry'; +import { adapter, type AbstractRegistry, type Request } from '@/libs/api/registry'; import { defineStore } from 'pinia'; import type { CodeInfo, diff --git a/src/modules/[chain]/gov/[proposal_id].vue b/src/modules/[chain]/gov/[proposal_id].vue index 083b6e3a..4cf268d2 100644 --- a/src/modules/[chain]/gov/[proposal_id].vue +++ b/src/modules/[chain]/gov/[proposal_id].vue @@ -32,7 +32,7 @@ const stakingStore = useStakingStore(); const chainStore = useBlockchain(); store.fetchProposal(props.proposal_id).then((res) => { - const proposalDetail = reactive(res.proposal); + let proposalDetail = reactive(res.proposal); // when status under the voting, final_tally_result are no data, should request fetchTally if (res.proposal?.status === 'PROPOSAL_STATUS_VOTING_PERIOD') { store.fetchTally(props.proposal_id).then((tallRes) => { @@ -55,7 +55,7 @@ store.fetchProposal(props.proposal_id).then((res) => { }) } - const msgType = proposalDetail.content['@type'] || ''; + const msgType = proposalDetail.content?.['@type'] || ''; if(msgType.endsWith('MsgUpdateParams')) { if(msgType.indexOf('staking') > -1) { chainStore.rpc.getStakingParams().then((res) => { @@ -214,7 +214,12 @@ function pageload(p: number) { } function metaItem(metadata: string|undefined): { title: string; summary: string } { - return metadata ? JSON.parse(metadata) : {} + if (!metadata) { + return { title: '', summary: '' } + } else if (metadata.startsWith('{') && metadata.endsWith('}')) { + return JSON.parse(metadata) + } + return { title: metadata, summary: '' } }