diff --git a/.env.example b/.env.example index 3e4e5051..4921ff88 100644 --- a/.env.example +++ b/.env.example @@ -1,4 +1,22 @@ # rename to .env.local or .env. -VITE_REFRESH_INTERVAL=2000 -VITE_FETCH_ALL_BLOCKS=true -VITE_RECENT_BLOCK_LIMIT=100 + +# Refresh interval for the app to query api for new blocks +VITE_REFRESH_INTERVAL=6000 + +# Enable fetching all blocks (this can increase api calls to public nodes resulting in rate limiting) +VITE_FETCH_ALL_BLOCKS=false + +# Limit for recent blocks and associated transactions displayed in the UI +VITE_RECENT_BLOCK_LIMIT=50 + +# URL for CoinGecko API or custom proxy +VITE_COINGECKO_URL=https://api.coingecko.com + +# GITHUB_API_URL default +VITE_GITHUB_API_URL=https://api.github.com/repos/cosmos/chain-registry/contents + +# PINGPUB_API_URL default +VITE_PINGPUB_API_URL=https://registry.ping.pub + +# IBC use PINGPUB_API_URL by Default (false) or GITHUB_API_URL (true) +VITE_IBC_USE_GITHUB_API=false diff --git a/.prettierrc.json b/.prettierrc.json index ef7e9a53..35ff4599 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -1,12 +1,12 @@ { - "tabWidth": 2, - "singleQuote": true, - "semi": true, - "endOfLine": "auto", - "bracketSpacing": true, - "trailingComma": "es5", "arrowParens": "always", + "bracketSpacing": true, + "endOfLine": "auto", + "printWidth": 80, + "semi": true, "singleAttributePerLine": false, - "printWidth": 120, + "singleQuote": true, + "tabWidth": 2, + "trailingComma": "es5", "useTabs": false } diff --git a/chains/mainnet/xion.json b/chains/mainnet/xion.json index 5e82d72d..49dafec0 100644 --- a/chains/mainnet/xion.json +++ b/chains/mainnet/xion.json @@ -1,5 +1,6 @@ { "chain_name": "xion", + "chain_id": "xion-mainnet-1", "registry_name": "xion", "coingecko": "xion", "network_type": "mainnet", @@ -32,7 +33,7 @@ } ], "snapshot_provider": "", - "sdk_version": "0.50.13", + "sdk_version": "0.53.3", "coin_type": "118", "min_tx_fee": "100", "addr_prefix": "xion", diff --git a/env.d.ts b/env.d.ts index 33f49a00..68dc2b97 100644 --- a/env.d.ts +++ b/env.d.ts @@ -1,3 +1,16 @@ /// declare module '@personaxyz/ad-sdk'; +interface ImportMetaEnv { + readonly VITE_REFRESH_INTERVAL?: number, + readonly VITE_FETCH_ALL_BLOCKS?: boolean, + readonly VITE_RECENT_BLOCK_LIMIT?: number, + readonly VITE_COINGECKO_URL?: string, + readonly VITE_GITHUB_API_URL?: string, + readonly VITE_PINGPUB_API_URL?: string, + readonly VITE_IBC_USE_GITHUB_API?: string, +} + +interface ImportMeta { + readonly env: ImportMetaEnv; +} diff --git a/package.json b/package.json index ef0ebd10..6faca93c 100644 --- a/package.json +++ b/package.json @@ -13,19 +13,20 @@ "type-check": "vue-tsc --noEmit" }, "dependencies": { - "@chain-registry/types": "^0.50.162", + "@chain-registry/client": "^1.53.184", + "@chain-registry/types": "^0.50.184", "@chenfengyuan/vue-countdown": "2", "@cosmjs/amino": "^0.32.3", "@cosmjs/crypto": "^0.32.3", "@cosmjs/encoding": "^0.32.3", "@cosmjs/stargate": "^0.32.3", + "@cosmjs/cosmwasm-stargate": "^0.30.0", "@iconify/vue": "^4.1.0", "@intlify/unplugin-vue-i18n": "^0.8.2", "@leapwallet/cosmos-snap-provider": "^0.1.20", "@leapwallet/name-matcha": "^2.0.0", "@osmonauts/lcd": "^0.8.0", "@personaxyz/ad-sdk": "0.0.25", - "@ping-pub/chain-registry-client": "^0.0.25", "@vitejs/plugin-vue-jsx": "^3.0.0", "@vueuse/core": "^9.12.0", "@vueuse/integrations": "^10.1.2", @@ -33,11 +34,14 @@ "apexcharts": "^3.37.1", "autoprefixer": "^10.4.14", "axios": "^1.3.2", + "bech32": "^1.1.4", "buffer": "^6.0.3", "build": "^0.1.4", "cross-fetch": "^3.1.5", "daisyui": "^3.1.0", "dayjs": "^1.11.7", + "idna-uts46-hx": "^5.0.7", + "js-sha3": "^0.8.0", "lazy-load-vue3": "^1.3.0", "long": "^5.2.1", "md-editor-v3": "^2.8.1", @@ -67,7 +71,7 @@ "@vue/tsconfig": "^0.1.3", "husky": "^9.1.7", "npm-run-all": "^4.1.5", - "prettier": "^2.7.1", + "prettier": "^3.0.0", "pretty-quick": "^4.2.2", "sass": "^1.58.0", "shiki": "^1.0.0-beta.0", diff --git a/src/modules/[chain]/ibc/connStore.ts b/src/modules/[chain]/ibc/connStore.ts index 9d6eeaad..f529ed35 100644 --- a/src/modules/[chain]/ibc/connStore.ts +++ b/src/modules/[chain]/ibc/connStore.ts @@ -1,37 +1,43 @@ import { defineStore } from 'pinia'; import { useBlockchain } from '@/stores'; -import ChainRegistryClient from '@ping-pub/chain-registry-client'; -import type { IBCPath, IBCInfo } from '@ping-pub/chain-registry-client/dist/types'; -import type { Channel } from '@/types'; +import { ChainRegistryClient } from '@chain-registry/client'; +import type { IBCData } from '@chain-registry/types/ibc_data.schema'; import router from '@/router'; +import fetch from 'cross-fetch'; + +const IBC_USE_GITHUB_API = import.meta.env.VITE_IBC_USE_GITHUB_API === 'true'; +const PINGPUB_API_URL = import.meta.env.VITE_PINGPUB_API_URL || 'https://registry.ping.pub'; +const GITHUB_API_URL = + import.meta.env.VITE_GITHUB_API_URL || 'https://api.github.com/repos/cosmos/chain-registry/contents'; +const IBC_API_URL = IBC_USE_GITHUB_API ? GITHUB_API_URL : PINGPUB_API_URL; export const useIBCModule = defineStore('module-ibc', { state: () => { return { - paths: [] as IBCPath[], + info: [] as IBCData[], connectionId: '' as string, - registryConf: {} as IBCInfo, + registryConf: {} as IBCData, }; }, getters: { chain() { return useBlockchain(); }, - commonIBCs(): any { - return this.paths.filter( - (x: IBCPath) => x.path.search(this.chain.current?.prettyName || this.chain.chainName) > -1 + chainName(): string { + return this.chain.chainName; + }, + isFirstChain(): boolean { + return ( + this.registryConf.chain_1.chain_name === this.chain.current?.prettyName || + this.registryConf.chain_1.chain_name === this.chain.chainName ); }, sourceField(): string { - return this.registryConf?.chain_1?.chain_name === this.chain.current?.prettyName || this.chain.chainName - ? 'chain_1' - : 'chain_2'; + return this.isFirstChain ? 'chain_1' : 'chain_2'; }, destField(): string { - return this.registryConf?.chain_1?.chain_name === this.chain.current?.prettyName || this.chain.chainName - ? 'chain_2' - : 'chain_1'; + return this.isFirstChain ? 'chain_2' : 'chain_1'; }, registryChannels(): any { return this.registryConf.channels; @@ -39,22 +45,54 @@ export const useIBCModule = defineStore('module-ibc', { }, actions: { load() { - const client = new ChainRegistryClient(); - client.fetchIBCPaths().then((res) => { - this.paths = res; + const prefix = this.chain.current?.networkType?.includes('testnet') ? 'testnets/' : ''; + const client = new ChainRegistryClient({ + chainNames: [this.chainName], + baseUrl: IBC_USE_GITHUB_API ? undefined : new URL(`${prefix}`, PINGPUB_API_URL + '/').toString(), + }); + this.fetchIBCUrls().then((res) => { + res.forEach((element: any) => { + if (element.download_url) { + client.urls.push(element.download_url); + } + }); + client.fetchUrls().then(() => { + const info = client.getChainIbcData(this.chainName); + this.info = info.sort((a, b) => { + // Sort by remote chain name (not equal to this.chainName) + const getRemote = (x: any) => + x?.chain_1?.chain_name === this.chain.current?.prettyName || + x?.chain_1?.chain_name === this.chain.chainName + ? x.chain_2.chain_name + : x.chain_1.chain_name; + return getRemote(a).localeCompare(getRemote(b)); + }); + }); }); }, - fetchConnection(path: string) { - const client = new ChainRegistryClient(); - client.fetchIBCPathInfo(path).then((res) => { - const isFirstChain = - res.chain_1.chain_name === this.chain.current?.prettyName || res.chain_1.chain_name === this.chain.chainName; + async fetchIBCUrls(): Promise { + const prefix = this.chain.current?.networkType?.includes('testnet') ? 'testnets/' : ''; + const ibcEndpoint = new URL(`${prefix}_IBC`, IBC_API_URL + '/').toString(); + console.log('Fetching IBC URLs from:', IBC_API_URL); + let entries = await fetch(ibcEndpoint) + .then((res) => res.json()) + .then((data: any) => (Array.isArray(data) ? data.filter((x: any) => x.name.match(this.chainName)) : [])); - const connId = isFirstChain ? res.chain_1.connection_id : res.chain_2.connection_id; - - this.registryConf = res; - this.showConnection(connId); - }); + // If using PINGPUB_API_URL, add thedownload URLs + if (IBC_API_URL == PINGPUB_API_URL) { + return entries.map((entry: any) => { + entry.download_url = new URL(`${prefix}_IBC/${entry.name}`, PINGPUB_API_URL + '/').toString(); + return entry; + }); + } + return entries; + }, + fetchConnection(index: number) { + this.registryConf = this.info[index]; + const connId = this.isFirstChain + ? this.registryConf.chain_1.connection_id + : this.registryConf.chain_2.connection_id; + this.showConnection(connId); }, showConnection(connId?: string | number) { if (!connId) { diff --git a/src/modules/[chain]/ibc/connection.vue b/src/modules/[chain]/ibc/connection.vue index ff1bfb81..ae3d8845 100644 --- a/src/modules/[chain]/ibc/connection.vue +++ b/src/modules/[chain]/ibc/connection.vue @@ -1,13 +1,9 @@