From b65c684fc5bc99e38aad70ce291175afb56e5821 Mon Sep 17 00:00:00 2001 From: liangping <18786721@qq.com> Date: Wed, 3 May 2023 13:54:27 +0800 Subject: [PATCH] add state-sync and cosmwasm --- src/libs/client.ts | 13 +- src/libs/registry.ts | 10 +- src/modules/[chain]/cosmwasm/WasmStore.ts | 76 ++++++++++ .../[chain]/cosmwasm/[code_id]/contracts.vue | 32 +++++ src/modules/[chain]/cosmwasm/index.vue | 43 ++++++ src/modules/[chain]/cosmwasm/types.ts | 53 +++++++ src/modules/[chain]/statesync/index.vue | 86 ++++++++++++ src/plugins/i18n/locales/en.json | 4 +- src/stores/useBlockchain.ts | 3 +- src/types/base.ts | 132 +++++++++--------- 10 files changed, 376 insertions(+), 76 deletions(-) create mode 100644 src/modules/[chain]/cosmwasm/WasmStore.ts create mode 100644 src/modules/[chain]/cosmwasm/[code_id]/contracts.vue create mode 100644 src/modules/[chain]/cosmwasm/index.vue create mode 100644 src/modules/[chain]/cosmwasm/types.ts create mode 100644 src/modules/[chain]/statesync/index.vue diff --git a/src/libs/client.ts b/src/libs/client.ts index a9e4ad24..6b50d901 100644 --- a/src/libs/client.ts +++ b/src/libs/client.ts @@ -1,13 +1,13 @@ import { fetchData } from '@/libs'; import { DEFAULT } from '@/libs' -import { adapter, type Request, type RequestRegistry } from './registry'; +import { adapter, withCustomAdapter, type Request, type RequestRegistry, type Registry, type AbstractRegistry } from './registry'; -export class CosmosRestClient { +export class BaseRestClient { endpoint: string; - registry: RequestRegistry; - constructor(endpoint: string, registry?: RequestRegistry) { + registry: R; + constructor(endpoint: string, registry: R) { this.endpoint = endpoint - this.registry = registry || DEFAULT + this.registry = registry } async request(request: Request, args: Record, query="") { let url = `${this.endpoint}${request.url}${query}` @@ -16,6 +16,9 @@ export class CosmosRestClient { }) return fetchData(url, adapter) } +} + +export class CosmosRestClient extends BaseRestClient { // Auth Module async getAuthAccounts() { return this.request(this.registry.auth_accounts, {}) diff --git a/src/libs/registry.ts b/src/libs/registry.ts index 3e7cdb7b..bb9b196d 100644 --- a/src/libs/registry.ts +++ b/src/libs/registry.ts @@ -13,8 +13,12 @@ export interface Request { adapter: (source: any) => T } +export interface AbstractRegistry { + [key: string]: Request +} + // use snake style, since the all return object use snake style. -export interface RequestRegistry { +export interface RequestRegistry extends AbstractRegistry { auth_params: Request auth_accounts: Request; auth_account_address: Request<{account: AuthAccount}>; @@ -102,8 +106,8 @@ export interface Registry { [key: string]: RequestRegistry; } -export function withCustomAdapter(target: T, source: Partial): T { - return Object.assign({}, target, source); +export function withCustomAdapter(target: T, source?: Partial): T { + return source ? Object.assign({}, target, source): target; } export function findConfigByName(name: string, registry: Registry): RequestRegistry { diff --git a/src/modules/[chain]/cosmwasm/WasmStore.ts b/src/modules/[chain]/cosmwasm/WasmStore.ts new file mode 100644 index 00000000..199a122b --- /dev/null +++ b/src/modules/[chain]/cosmwasm/WasmStore.ts @@ -0,0 +1,76 @@ +import { BaseRestClient } from "@/libs/client"; +import { adapter, type AbstractRegistry, type Request } from "@/libs/registry"; +import type { PaginabledAccounts } from "@/types"; +import { defineStore } from "pinia"; +import type { CodeInfo, PaginabledCodeInfos, PaginabledContractHistory, PaginabledContracts, PaginabledStates, WasmParam } from "./types"; +import { toBase64 } from "@cosmjs/encoding"; +import { useBlockchain } from "@/stores"; + +export interface WasmRequestRegistry extends AbstractRegistry { + cosmwasm_code: Request; + cosmwasm_code_id: Request; + cosmwasm_code_id_contracts: Request; + cosmwasm_param: Request; + cosmwasm_contract_address: Request; + cosmwasm_contract_address_history: Request; + cosmwasm_contract_address_raw_query_data: Request; + cosmwasm_contract_address_smart_query_data: Request; + cosmwasm_contract_address_state: Request; +} + +export const DEFAULT: WasmRequestRegistry = { + cosmwasm_code: { url: "/cosmwasm/wasm/v1/code", adapter }, + cosmwasm_code_id: { url: "/cosmwasm/wasm/v1/code/{code_id}", adapter }, + cosmwasm_code_id_contracts: { url: "/cosmwasm/wasm/v1/code/{code_id}/contracts", adapter }, + cosmwasm_param: { url: "/cosmwasm/wasm/v1/codes/params", adapter }, + cosmwasm_contract_address: { url: "/cosmwasm/wasm/v1/contract/{address}", adapter }, + cosmwasm_contract_address_history: { url: "/cosmwasm/wasm/v1/contract/{address}/history", adapter }, + cosmwasm_contract_address_raw_query_data: { url: "/cosmwasm/wasm/v1/contract/{address}/raw/{query_data}", adapter }, + cosmwasm_contract_address_smart_query_data: { url: "/cosmwasm/wasm/v1/contract/{address}/smart/{query_data}", adapter }, + cosmwasm_contract_address_state: { url: "/cosmwasm/wasm/v1/contract/{address}/state", adapter } +} + +class WasmRestClient extends BaseRestClient { + getWasmCodeList() { + return this.request(this.registry.cosmwasm_code, {}) + } + getWasmCodeById(code_id: string) { + return this.request(this.registry.cosmwasm_code, {code_id}) // `code_id` is a param in above url + } + getWasmCodeContracts(code_id: string) { + return this.request(this.registry.cosmwasm_code_id_contracts, {code_id}) + } + getWasmParams() { + return this.request(this.registry.cosmwasm_param, {}) + } + getWasmContracts(address: string) { + return this.request(this.registry.cosmwasm_contract_address, {address}) + } + getWasmContractHistory(address: string) { + return this.request(this.registry.cosmwasm_contract_address_history, {address}) + } + getWasmContractRawQuery(address: string, query: string) { + const query_data = toBase64(new TextEncoder().encode(query)) + return this.request(this.registry.cosmwasm_contract_address_raw_query_data, {address, query_data}) + } + getWasmContractSmartQuery(address: string, query: string) { + const query_data = toBase64(new TextEncoder().encode(query)) + return this.request(this.registry.cosmwasm_contract_address_smart_query_data, {address, query_data}) + } + getWasmContractStates(address: string) { + return this.request(this.registry.cosmwasm_contract_address_state, {address}) + } + +} + +export const useWasmStore = defineStore('module-wasm', { + state: () => { + return {} + }, + getters: { + wasmClient() { + const blockchain = useBlockchain() + return new WasmRestClient(blockchain.endpoint.address, DEFAULT) + } + } +}) \ No newline at end of file diff --git a/src/modules/[chain]/cosmwasm/[code_id]/contracts.vue b/src/modules/[chain]/cosmwasm/[code_id]/contracts.vue new file mode 100644 index 00000000..560f7dbd --- /dev/null +++ b/src/modules/[chain]/cosmwasm/[code_id]/contracts.vue @@ -0,0 +1,32 @@ + + diff --git a/src/modules/[chain]/cosmwasm/index.vue b/src/modules/[chain]/cosmwasm/index.vue new file mode 100644 index 00000000..a844e595 --- /dev/null +++ b/src/modules/[chain]/cosmwasm/index.vue @@ -0,0 +1,43 @@ + + + + + { + meta: { + i18n: 'cosmwasm' + } + } + \ No newline at end of file diff --git a/src/modules/[chain]/cosmwasm/types.ts b/src/modules/[chain]/cosmwasm/types.ts new file mode 100644 index 00000000..99fe1ba2 --- /dev/null +++ b/src/modules/[chain]/cosmwasm/types.ts @@ -0,0 +1,53 @@ +import type { PaginatedResponse } from "@/types" + +export interface CodeInfo { + code_id: string, + creator: string, + data_hash: string, + instantiate_permission: { + permission: string, + address: string, + addresses: string[] + } +} + +export interface WasmParam { + params: { + code_upload_access: { + permission: string, + address: string, + addresses: string[] + }, + instantiate_default_permission: string + } +} + +export interface HistoryEntry { + operation: string, + code_id: string, + updated: { + block_height: string, + tx_index: string + }, + msg: string +} + +export interface Models { + key: string, + value: string +} + +export interface PaginabledContractHistory extends PaginatedResponse { + entries: HistoryEntry[] +} + +export interface PaginabledStates extends PaginatedResponse { + models: Models[] +} + +export interface PaginabledCodeInfos extends PaginatedResponse { + code_infos: CodeInfo[] +} +export interface PaginabledContracts extends PaginatedResponse { + contracts: string[] +} \ No newline at end of file diff --git a/src/modules/[chain]/statesync/index.vue b/src/modules/[chain]/statesync/index.vue new file mode 100644 index 00000000..f5d79060 --- /dev/null +++ b/src/modules/[chain]/statesync/index.vue @@ -0,0 +1,86 @@ + + + + + { + meta: { + i18n: 'state-sync' + } + } + \ No newline at end of file diff --git a/src/plugins/i18n/locales/en.json b/src/plugins/i18n/locales/en.json index 6bc0715a..96280a36 100644 --- a/src/plugins/i18n/locales/en.json +++ b/src/plugins/i18n/locales/en.json @@ -5,7 +5,9 @@ "staking": "Staking", "governance": "Governance", "parameters": "Parameters", - "uptime": "Uptime" + "uptime": "Uptime", + "state-sync": "State Sync", + "cosmwasm": "Cosmwasm" }, "index": { "slogan": "Ping Dashboard is not just an explorer but also a wallet and more ... 🛠", diff --git a/src/stores/useBlockchain.ts b/src/stores/useBlockchain.ts index 67159285..b61a368f 100644 --- a/src/stores/useBlockchain.ts +++ b/src/stores/useBlockchain.ts @@ -5,6 +5,7 @@ import { useRouter } from "vue-router"; import { CosmosRestClient } from "@/libs/client"; import { useBankStore, useBaseStore, useGovStore, useMintStore, useStakingStore } from "."; import { useBlockModule } from "@/modules/[chain]/block/block"; +import { DEFAULT } from "@/libs"; export const useBlockchain = defineStore("blockchain", { state: () => { @@ -110,7 +111,7 @@ export const useBlockchain = defineStore("blockchain", { async setRestEndpoint(endpoint: Endpoint) { this.connErr = '' this.endpoint = endpoint - this.rpc = new CosmosRestClient(endpoint.address) + this.rpc = new CosmosRestClient(endpoint.address, DEFAULT) }, setCurrent(name: string) { this.chainName = name diff --git a/src/types/base.ts b/src/types/base.ts index a42533d1..bd3d2707 100644 --- a/src/types/base.ts +++ b/src/types/base.ts @@ -2,100 +2,100 @@ import type { Key } from "./common" import type { Tx } from "./tx" export interface NodeInfo { - "default_node_info": { - "protocol_version": { - "p2p": string, - "block": string, - "app": string + default_node_info: { + protocol_version: { + p2p: string, + block: string, + app: string }, - "default_node_id": string, - "listen_addr": string, - "network": string, - "version": string, - "channels": string, - "moniker": string, - "other": { - "tx_index": string, - "rpc_address": string + default_node_id: string, + listen_addr: string, + network: string, + version: string, + channels: string, + moniker: string, + other: { + tx_index: string, + rpc_address: string } }, - "application_version": { - "name": string, - "app_name": string, - "version": string, - "git_commit": string, - "build_tags": string, - "go_version": string, - "build_deps": [ + application_version: { + name: string, + app_name: string, + version: string, + git_commit: string, + build_tags: string, + go_version: string, + build_deps: [ { - "path": string, - "version": string, - "sum": string, + path: string, + version: string, + sum: string, }, ], - "cosmos_sdk_version": string, + cosmos_sdk_version: string, } } export interface BlockId { - "hash": string, - "part_set_header": { - "total": number, - "hash": string + hash: string, + part_set_header: { + total: number, + hash: string } } export interface Signature { - "block_id_flag": string, - "validator_address": string, - "timestamp": string, - "signature": string, + block_id_flag: string, + validator_address: string, + timestamp: string, + signature: string, } export interface Block { - "block_id": BlockId, - "block": { - "header": { - "version": { - "block": string, - "app": string + block_id: BlockId, + block: { + header: { + version: { + block: string, + app: string }, - "chain_id": string, - "height": string, - "time": string, - "last_block_id": BlockId, - "last_commit_hash": string, - "data_hash": string, - "validators_hash": string, - "next_validators_hash": string, - "consensus_hash": string, - "app_hash": string, - "last_results_hash": string, - "evidence_hash": string, - "proposer_address": string, + chain_id: string, + height: string, + time: string, + last_block_id: BlockId, + last_commit_hash: string, + data_hash: string, + validators_hash: string, + next_validators_hash: string, + consensus_hash: string, + app_hash: string, + last_results_hash: string, + evidence_hash: string, + proposer_address: string, }, - "data": { - "txs": any[] + data: { + txs: any[] }, - "evidence": { - "evidence": any[] + evidence: { + evidence: any[] }, - "last_commit": Commit + last_commit: Commit } } export interface Commit { - "height": string, - "round": number, - "block_id": BlockId, - "signatures": Signature[] + height: string, + round: number, + block_id: BlockId, + signatures: Signature[] } export interface TendermintValidator { - "address": string, - "pub_key": Key, - "voting_power": string, - "proposer_priority": string + address: string, + pub_key: Key, + voting_power: string, + proposer_priority: string } export interface PaginatedTendermintValidator {