Skip to content

Commit 9c0d810

Browse files
authored
Merge pull request #650 from burnt-labs/feat/registry-ibc
Feat/registry ibc
2 parents 6d85f2f + f72dccd commit 9c0d810

File tree

12 files changed

+261
-746
lines changed

12 files changed

+261
-746
lines changed

.env.example

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,22 @@
11
# rename to .env.local or .env.<your_environment>
2-
VITE_REFRESH_INTERVAL=2000
3-
VITE_FETCH_ALL_BLOCKS=true
4-
VITE_RECENT_BLOCK_LIMIT=100
2+
3+
# Refresh interval for the app to query api for new blocks
4+
VITE_REFRESH_INTERVAL=6000
5+
6+
# Enable fetching all blocks (this can increase api calls to public nodes resulting in rate limiting)
7+
VITE_FETCH_ALL_BLOCKS=false
8+
9+
# Limit for recent blocks and associated transactions displayed in the UI
10+
VITE_RECENT_BLOCK_LIMIT=50
11+
12+
# URL for CoinGecko API or custom proxy
13+
VITE_COINGECKO_URL=https://api.coingecko.com
14+
15+
# GITHUB_API_URL default
16+
VITE_GITHUB_API_URL=https://api.github.com/repos/cosmos/chain-registry/contents
17+
18+
# PINGPUB_API_URL default
19+
VITE_PINGPUB_API_URL=https://registry.ping.pub
20+
21+
# IBC use PINGPUB_API_URL by Default (false) or GITHUB_API_URL (true)
22+
VITE_IBC_USE_GITHUB_API=false

.prettierrc.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
{
2-
"tabWidth": 2,
3-
"singleQuote": true,
4-
"semi": true,
5-
"endOfLine": "auto",
6-
"bracketSpacing": true,
7-
"trailingComma": "es5",
82
"arrowParens": "always",
3+
"bracketSpacing": true,
4+
"endOfLine": "auto",
5+
"printWidth": 80,
6+
"semi": true,
97
"singleAttributePerLine": false,
10-
"printWidth": 120,
8+
"singleQuote": true,
9+
"tabWidth": 2,
10+
"trailingComma": "es5",
1111
"useTabs": false
1212
}

chains/mainnet/xion.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"chain_name": "xion",
3+
"chain_id": "xion-mainnet-1",
34
"registry_name": "xion",
45
"coingecko": "xion",
56
"network_type": "mainnet",
@@ -32,7 +33,7 @@
3233
}
3334
],
3435
"snapshot_provider": "",
35-
"sdk_version": "0.50.13",
36+
"sdk_version": "0.53.3",
3637
"coin_type": "118",
3738
"min_tx_fee": "100",
3839
"addr_prefix": "xion",

env.d.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
11
/// <reference types="vite/client" />
22

33
declare module '@personaxyz/ad-sdk';
4+
interface ImportMetaEnv {
5+
readonly VITE_REFRESH_INTERVAL?: number,
6+
readonly VITE_FETCH_ALL_BLOCKS?: boolean,
7+
readonly VITE_RECENT_BLOCK_LIMIT?: number,
8+
readonly VITE_COINGECKO_URL?: string,
9+
readonly VITE_GITHUB_API_URL?: string,
10+
readonly VITE_PINGPUB_API_URL?: string,
11+
readonly VITE_IBC_USE_GITHUB_API?: string,
12+
}
13+
14+
interface ImportMeta {
15+
readonly env: ImportMetaEnv;
16+
}

package.json

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,31 +13,35 @@
1313
"type-check": "vue-tsc --noEmit"
1414
},
1515
"dependencies": {
16-
"@chain-registry/types": "^0.50.162",
16+
"@chain-registry/client": "^1.53.184",
17+
"@chain-registry/types": "^0.50.184",
1718
"@chenfengyuan/vue-countdown": "2",
1819
"@cosmjs/amino": "^0.32.3",
1920
"@cosmjs/crypto": "^0.32.3",
2021
"@cosmjs/encoding": "^0.32.3",
2122
"@cosmjs/stargate": "^0.32.3",
23+
"@cosmjs/cosmwasm-stargate": "^0.30.0",
2224
"@iconify/vue": "^4.1.0",
2325
"@intlify/unplugin-vue-i18n": "^0.8.2",
2426
"@leapwallet/cosmos-snap-provider": "^0.1.20",
2527
"@leapwallet/name-matcha": "^2.0.0",
2628
"@osmonauts/lcd": "^0.8.0",
2729
"@personaxyz/ad-sdk": "0.0.25",
28-
"@ping-pub/chain-registry-client": "^0.0.25",
2930
"@vitejs/plugin-vue-jsx": "^3.0.0",
3031
"@vueuse/core": "^9.12.0",
3132
"@vueuse/integrations": "^10.1.2",
3233
"@vueuse/math": "^9.12.0",
3334
"apexcharts": "^3.37.1",
3435
"autoprefixer": "^10.4.14",
3536
"axios": "^1.3.2",
37+
"bech32": "^1.1.4",
3638
"buffer": "^6.0.3",
3739
"build": "^0.1.4",
3840
"cross-fetch": "^3.1.5",
3941
"daisyui": "^3.1.0",
4042
"dayjs": "^1.11.7",
43+
"idna-uts46-hx": "^5.0.7",
44+
"js-sha3": "^0.8.0",
4145
"lazy-load-vue3": "^1.3.0",
4246
"long": "^5.2.1",
4347
"md-editor-v3": "^2.8.1",
@@ -67,7 +71,7 @@
6771
"@vue/tsconfig": "^0.1.3",
6872
"husky": "^9.1.7",
6973
"npm-run-all": "^4.1.5",
70-
"prettier": "^2.7.1",
74+
"prettier": "^3.0.0",
7175
"pretty-quick": "^4.2.2",
7276
"sass": "^1.58.0",
7377
"shiki": "^1.0.0-beta.0",

src/modules/[chain]/ibc/connStore.ts

Lines changed: 65 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,98 @@
11
import { defineStore } from 'pinia';
22

33
import { useBlockchain } from '@/stores';
4-
import ChainRegistryClient from '@ping-pub/chain-registry-client';
5-
import type { IBCPath, IBCInfo } from '@ping-pub/chain-registry-client/dist/types';
6-
import type { Channel } from '@/types';
4+
import { ChainRegistryClient } from '@chain-registry/client';
5+
import type { IBCData } from '@chain-registry/types/ibc_data.schema';
76
import router from '@/router';
7+
import fetch from 'cross-fetch';
8+
9+
const IBC_USE_GITHUB_API = import.meta.env.VITE_IBC_USE_GITHUB_API === 'true';
10+
const PINGPUB_API_URL = import.meta.env.VITE_PINGPUB_API_URL || 'https://registry.ping.pub';
11+
const GITHUB_API_URL =
12+
import.meta.env.VITE_GITHUB_API_URL || 'https://api.github.com/repos/cosmos/chain-registry/contents';
13+
const IBC_API_URL = IBC_USE_GITHUB_API ? GITHUB_API_URL : PINGPUB_API_URL;
814

915
export const useIBCModule = defineStore('module-ibc', {
1016
state: () => {
1117
return {
12-
paths: [] as IBCPath[],
18+
info: [] as IBCData[],
1319
connectionId: '' as string,
14-
registryConf: {} as IBCInfo,
20+
registryConf: {} as IBCData,
1521
};
1622
},
1723
getters: {
1824
chain() {
1925
return useBlockchain();
2026
},
21-
commonIBCs(): any {
22-
return this.paths.filter(
23-
(x: IBCPath) => x.path.search(this.chain.current?.prettyName || this.chain.chainName) > -1
27+
chainName(): string {
28+
return this.chain.chainName;
29+
},
30+
isFirstChain(): boolean {
31+
return (
32+
this.registryConf.chain_1.chain_name === this.chain.current?.prettyName ||
33+
this.registryConf.chain_1.chain_name === this.chain.chainName
2434
);
2535
},
2636
sourceField(): string {
27-
return this.registryConf?.chain_1?.chain_name === this.chain.current?.prettyName || this.chain.chainName
28-
? 'chain_1'
29-
: 'chain_2';
37+
return this.isFirstChain ? 'chain_1' : 'chain_2';
3038
},
3139
destField(): string {
32-
return this.registryConf?.chain_1?.chain_name === this.chain.current?.prettyName || this.chain.chainName
33-
? 'chain_2'
34-
: 'chain_1';
40+
return this.isFirstChain ? 'chain_2' : 'chain_1';
3541
},
3642
registryChannels(): any {
3743
return this.registryConf.channels;
3844
},
3945
},
4046
actions: {
4147
load() {
42-
const client = new ChainRegistryClient();
43-
client.fetchIBCPaths().then((res) => {
44-
this.paths = res;
48+
const prefix = this.chain.current?.networkType?.includes('testnet') ? 'testnets/' : '';
49+
const client = new ChainRegistryClient({
50+
chainNames: [this.chainName],
51+
baseUrl: IBC_USE_GITHUB_API ? undefined : new URL(`${prefix}`, PINGPUB_API_URL + '/').toString(),
52+
});
53+
this.fetchIBCUrls().then((res) => {
54+
res.forEach((element: any) => {
55+
if (element.download_url) {
56+
client.urls.push(element.download_url);
57+
}
58+
});
59+
client.fetchUrls().then(() => {
60+
const info = client.getChainIbcData(this.chainName);
61+
this.info = info.sort((a, b) => {
62+
// Sort by remote chain name (not equal to this.chainName)
63+
const getRemote = (x: any) =>
64+
x?.chain_1?.chain_name === this.chain.current?.prettyName ||
65+
x?.chain_1?.chain_name === this.chain.chainName
66+
? x.chain_2.chain_name
67+
: x.chain_1.chain_name;
68+
return getRemote(a).localeCompare(getRemote(b));
69+
});
70+
});
4571
});
4672
},
47-
fetchConnection(path: string) {
48-
const client = new ChainRegistryClient();
49-
client.fetchIBCPathInfo(path).then((res) => {
50-
const isFirstChain =
51-
res.chain_1.chain_name === this.chain.current?.prettyName || res.chain_1.chain_name === this.chain.chainName;
52-
53-
const connId = isFirstChain ? res.chain_1.connection_id : res.chain_2.connection_id;
73+
async fetchIBCUrls(): Promise<any[]> {
74+
const prefix = this.chain.current?.networkType?.includes('testnet') ? 'testnets/' : '';
75+
const ibcEndpoint = new URL(`${prefix}_IBC`, IBC_API_URL + '/').toString();
76+
console.log('Fetching IBC URLs from:', IBC_API_URL);
77+
let entries = await fetch(ibcEndpoint)
78+
.then((res) => res.json())
79+
.then((data: any) => (Array.isArray(data) ? data.filter((x: any) => x.name.match(this.chainName)) : []));
5480

55-
this.registryConf = res;
56-
this.showConnection(connId);
57-
});
81+
// If using PINGPUB_API_URL, add thedownload URLs
82+
if (IBC_API_URL == PINGPUB_API_URL) {
83+
return entries.map((entry: any) => {
84+
entry.download_url = new URL(`${prefix}_IBC/${entry.name}`, PINGPUB_API_URL + '/').toString();
85+
return entry;
86+
});
87+
}
88+
return entries;
89+
},
90+
fetchConnection(index: number) {
91+
this.registryConf = this.info[index];
92+
const connId = this.isFirstChain
93+
? this.registryConf.chain_1.connection_id
94+
: this.registryConf.chain_2.connection_id;
95+
this.showConnection(connId);
5896
},
5997
showConnection(connId?: string | number) {
6098
if (!connId) {

src/modules/[chain]/ibc/connection.vue

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
11
<script lang="ts" setup>
2-
import PaginationBar from '@/components/PaginationBar.vue';
3-
import { useBlockchain, useFormatter } from '@/stores';
2+
import { useBlockchain } from '@/stores';
43
import { PageRequest, type Connection, type Pagination } from '@/types';
5-
import { computed, onMounted } from 'vue';
4+
import { onMounted } from 'vue';
65
import { ref } from 'vue';
76
8-
import ChainRegistryClient from '@ping-pub/chain-registry-client';
9-
import type { IBCPath } from '@ping-pub/chain-registry-client/dist/types';
10-
import router from '@/router';
117
import { useIBCModule } from './connStore';
128
139
const props = defineProps(['chain']);
@@ -29,7 +25,7 @@ function pageload(p: number) {
2925
list.value = x.connections;
3026
pageResponse.value = x.pagination;
3127
if (x.pagination.total && Number(x.pagination.total) > 0) {
32-
ibcStore.showConnection(0);
28+
ibcStore.showConnection(list.value[0].id);
3329
}
3430
});
3531
}
@@ -40,26 +36,44 @@ function pageload(p: number) {
4036
<div class="flex flex-wrap gap-4 items-center">
4137
<h2 class="card-title py-4">{{ $t('ibc.title') }}</h2>
4238
<div class="tabs tabs-boxed">
43-
<a class="tab" :class="{ 'tab-active': tab === 'registry' }" @click="tab = 'registry'">{{
44-
$t('ibc.registry')
45-
}}</a>
46-
<a class="tab" :class="{ 'tab-active': tab === 'favorite' }" @click="tab = 'favorite'">{{
47-
$t('module.favorite')
48-
}}</a>
39+
<a
40+
class="tab"
41+
:class="{ 'tab-active': tab === 'registry' }"
42+
@click="tab = 'registry'"
43+
>{{ $t('ibc.registry') }}</a
44+
>
45+
<a
46+
class="tab"
47+
:class="{ 'tab-active': tab === 'favorite' }"
48+
@click="tab = 'favorite'"
49+
>{{ $t('module.favorite') }}</a
50+
>
4951
</div>
5052
</div>
5153
<div>
5254
<div v-show="tab === 'registry'" class="flex flex-wrap gap-1 p-4">
5355
<span
54-
v-for="s in ibcStore.commonIBCs"
56+
v-for="(s, i) in ibcStore.info"
5557
class="btn btn-xs btn-link mr-1"
56-
@click="ibcStore.fetchConnection(s.path)"
57-
>{{ s.from }} &#x21cc; {{ s.to }}</span
58+
@click="ibcStore.fetchConnection(i)"
59+
>{{
60+
s.chain_1.chain_name === ibcStore.chainName
61+
? s.chain_2.chain_name
62+
: s.chain_1.chain_name
63+
}}
64+
&#x21cc;
65+
{{
66+
s.chain_1.chain_name === ibcStore.chainName
67+
? s.chain_1.chain_name
68+
: s.chain_2.chain_name
69+
}}</span
5870
>
5971
</div>
6072
<div v-show="tab === 'favorite'" class="flex flex-wrap gap-1 p-4">
6173
<div class="join border border-primary">
62-
<button class="join-item px-2">{{ $t('ibc.connection_id') }}:</button>
74+
<button class="join-item px-2">
75+
{{ $t('ibc.connection_id') }}:
76+
</button>
6377
<input
6478
v-model="ibcStore.connectionId"
6579
type="number"
@@ -68,7 +82,10 @@ function pageload(p: number) {
6882
:max="pageResponse.total || 0"
6983
:placeholder="`0~${pageResponse.total}`"
7084
/>
71-
<button class="join-item btn btn-primary" @click="ibcStore.showConnection()">
85+
<button
86+
class="join-item btn btn-primary"
87+
@click="ibcStore.showConnection()"
88+
>
7289
{{ $t('ibc.btn_apply') }}
7390
</button>
7491
</div>

0 commit comments

Comments
 (0)