From c37c4cbc8da202a5d5adac4dece15b520b6df213 Mon Sep 17 00:00:00 2001
From: liangping <18786721@qq.com>
Date: Wed, 10 May 2023 13:04:57 +0800
Subject: [PATCH 1/5] add asset panel
---
src/layouts/components/NavBarWallet.vue | 6 ++++--
src/modules/[chain]/index.vue | 18 +++++++++++++-----
2 files changed, 17 insertions(+), 7 deletions(-)
diff --git a/src/layouts/components/NavBarWallet.vue b/src/layouts/components/NavBarWallet.vue
index 55aeaf47..df8c1ff7 100644
--- a/src/layouts/components/NavBarWallet.vue
+++ b/src/layouts/components/NavBarWallet.vue
@@ -3,12 +3,14 @@ import { ref } from 'vue';
import { useBlockchain, useWalletStore } from '@/stores';
const walletStore = useWalletStore()
-
+walletStore.$subscribe((m, s) => {
+ console.log(m, s)
+})
{{ walletStore.currentAddress }}
-
+
diff --git a/src/modules/[chain]/index.vue b/src/modules/[chain]/index.vue
index 4e8d09f0..521dd631 100644
--- a/src/modules/[chain]/index.vue
+++ b/src/modules/[chain]/index.vue
@@ -14,6 +14,7 @@ import ProposalListItem from '@/components/ProposalListItem.vue';
const blockchain = useBlockchain();
const store = useIndexModule();
const walletStore = useWalletStore()
+const format = useFormatter()
const coinInfo = computed(() => {
return store.coinInfo;
@@ -21,9 +22,9 @@ const coinInfo = computed(() => {
onMounted(() => {
store.loadDashboard();
+ walletStore.loadMyAsset()
});
-const format = useFormatter();
const ticker = computed(() => store.coinInfo.tickers[store.tickerIndex]);
blockchain.$subscribe((m, s) => {
@@ -32,6 +33,7 @@ blockchain.$subscribe((m, s) => {
['chainName', 'endpoint'].includes(m.events.key)
) {
store.loadDashboard();
+ walletStore.loadMyAsset()
}
});
function shortName(name: string, id: string) {
@@ -226,10 +228,16 @@ const comLinks = [
More
diff --git a/src/stores/useDashboard.ts b/src/stores/useDashboard.ts
index 1347c49e..e77c32eb 100644
--- a/src/stores/useDashboard.ts
+++ b/src/stores/useDashboard.ts
@@ -234,6 +234,8 @@ export const useDashboard = defineStore('dashboard', {
favorite: fav as string[],
favoriteMap: favMap as Record,
chains: {} as Record,
+ prices: {},
+ coingecko: {} as Record,
};
},
getters: {
@@ -246,6 +248,28 @@ export const useDashboard = defineStore('dashboard', {
this.loadingFromLocal();
// this.loadingFromRegistry()
},
+ loadingPrices() {
+ const coinIds = [] as string[]
+ Object.keys(this.favoriteMap).forEach(k => {
+ if(this.chains[k]) this.chains[k].assets.forEach(a => {
+ if(a.coingecko_id !== undefined) {
+ coinIds.push(a.coingecko_id)
+ a.denom_units.forEach(u => {
+ this.coingecko[u.denom] = {
+ coinId: a.coingecko_id || '',
+ exponent: u.exponent,
+ symbol: a.symbol
+ }
+ })
+ }
+ })
+ })
+
+ const currencies = ['usd, cny'] // usd,cny,eur,jpy,krw,sgd,hkd
+ get(`https://api.coingecko.com/api/v3/simple/price?include_24hr_change=true&vs_currencies=${currencies.join(',')}&ids=${coinIds.join(",")}`).then(x => {
+ this.prices = x
+ })
+ },
async loadingFromRegistry() {
if (this.status === LoadingStatus.Empty) {
this.status = LoadingStatus.Loading;
@@ -274,12 +298,14 @@ export const useDashboard = defineStore('dashboard', {
for (let i = 0; i < this.favorite.length; i++) {
if (!blockchain.chainName && this.chains[this.favorite[i]]) {
blockchain.setCurrent(this.favorite[i]);
+ break
}
}
if (!blockchain.chainName) {
const [first] = Object.keys(this.chains);
blockchain.setCurrent(first);
}
+ this.loadingPrices()
}
},
setConfigSource(newSource: ConfigSource) {
diff --git a/src/stores/useFormatter.ts b/src/stores/useFormatter.ts
index 545e6312..2e8fa8b7 100644
--- a/src/stores/useFormatter.ts
+++ b/src/stores/useFormatter.ts
@@ -11,7 +11,8 @@ import { useStakingStore } from './useStakingStore';
import { fromBase64, fromBech32, fromHex, toHex } from '@cosmjs/encoding';
import { consensusPubkeyToHexAddress } from '@/libs';
import { useBankStore } from './useBankStore';
-import type { DenomTrace } from '@/types';
+import type { Coin, DenomTrace } from '@/types';
+import { useDashboard } from './useDashboard';
dayjs.extend(localeData);
dayjs.extend(duration);
@@ -52,6 +53,9 @@ export const useFormatter = defineStore('formatter', {
useBank() {
return useBankStore();
},
+ dashboard() {
+ return useDashboard()
+ }
},
actions: {
async fetchDenomTrace(denom: string) {
@@ -64,6 +68,33 @@ export const useFormatter = defineStore('formatter', {
}
return trace;
},
+ priceInfo(denom: string) {
+ const id = this.dashboard.coingecko[denom]?.coinId
+ const prices = this.dashboard.prices[id]
+ return prices
+ },
+ price(denom: string, currency = "usd") {
+ const info = this.priceInfo(denom);
+ console.log("info", info, denom)
+ return info? info[currency]||0 : 0
+ },
+ priceChanges(denom: string, currency="usd"): number {
+ const info = this.priceInfo(denom);
+ return info? info[`${currency}_24h_change`]||0 : 0
+ },
+ showChanges(v: number) {
+ return numeral(v).format("+0,0.[00]")
+ },
+ tokenValue(token: Coin) {
+ // find the symbol,
+ const symbol = this.dashboard.coingecko[token.denom]?.symbol || ""
+ // convert denomation to to symbol
+ const exponent = this.dashboard.coingecko[symbol.toLowerCase()]?.exponent || 0
+ // cacualte amount of symbol
+ const amount = Number(token.amount) / (10 ** exponent)
+ const value = amount * this.price(token.denom)
+ return numeral(value).format('0,0.[00]')
+ },
formatTokenAmount(token: { denom: string; amount: string }) {
return this.formatToken(token, false);
},
From d2c82499c0634338450a0443e4cf67465ad2de73 Mon Sep 17 00:00:00 2001
From: liangping <18786721@qq.com>
Date: Wed, 10 May 2023 18:39:39 +0800
Subject: [PATCH 4/5] add order on menu
---
src/modules/[chain]/block/index.vue | 3 ++-
src/modules/[chain]/gov/index.vue | 3 ++-
src/modules/[chain]/ibc/index.vue | 3 ++-
src/modules/[chain]/index.vue | 3 ++-
src/modules/[chain]/params/index.vue | 3 ++-
src/modules/[chain]/staking/index.vue | 3 ++-
src/modules/[chain]/uptime/index.vue | 3 ++-
src/stores/useBlockchain.ts | 3 ++-
8 files changed, 16 insertions(+), 8 deletions(-)
diff --git a/src/modules/[chain]/block/index.vue b/src/modules/[chain]/block/index.vue
index a3dc369b..78c0f946 100644
--- a/src/modules/[chain]/block/index.vue
+++ b/src/modules/[chain]/block/index.vue
@@ -97,7 +97,8 @@ const format = useFormatter();
{
meta: {
- i18n: 'blocks'
+ i18n: 'blocks',
+ order: 5
}
}
diff --git a/src/modules/[chain]/gov/index.vue b/src/modules/[chain]/gov/index.vue
index b10c3372..aea5d2ef 100644
--- a/src/modules/[chain]/gov/index.vue
+++ b/src/modules/[chain]/gov/index.vue
@@ -47,7 +47,8 @@ const changeTab = (val: '2' | '3' | '4') => {
{
meta: {
- i18n: 'governance'
+ i18n: 'governance',
+ order: 2
}
}
diff --git a/src/modules/[chain]/ibc/index.vue b/src/modules/[chain]/ibc/index.vue
index b403962f..aac5745c 100644
--- a/src/modules/[chain]/ibc/index.vue
+++ b/src/modules/[chain]/ibc/index.vue
@@ -70,7 +70,8 @@ function color(v: string) {
{
meta: {
- i18n: 'ibc'
+ i18n: 'ibc',
+ order: 8
}
}
diff --git a/src/modules/[chain]/index.vue b/src/modules/[chain]/index.vue
index f3afbd37..730f1ac0 100644
--- a/src/modules/[chain]/index.vue
+++ b/src/modules/[chain]/index.vue
@@ -267,7 +267,8 @@ const color= computed(() => {
{
meta: {
- i18n: 'dashboard'
+ i18n: 'dashboard',
+ order: 1,
}
}
diff --git a/src/modules/[chain]/params/index.vue b/src/modules/[chain]/params/index.vue
index 80276c84..699074ad 100644
--- a/src/modules/[chain]/params/index.vue
+++ b/src/modules/[chain]/params/index.vue
@@ -55,7 +55,8 @@ onMounted(() => {
{
meta: {
- i18n: 'parameters'
+ i18n: 'parameters',
+ order: 10
}
}
diff --git a/src/modules/[chain]/staking/index.vue b/src/modules/[chain]/staking/index.vue
index e782db81..a6938922 100644
--- a/src/modules/[chain]/staking/index.vue
+++ b/src/modules/[chain]/staking/index.vue
@@ -276,7 +276,8 @@ const rank = function (position: number) {
{
meta: {
- i18n: 'staking'
+ i18n: 'staking',
+ order: 3
}
}
diff --git a/src/modules/[chain]/uptime/index.vue b/src/modules/[chain]/uptime/index.vue
index ba164c0d..da9661f2 100644
--- a/src/modules/[chain]/uptime/index.vue
+++ b/src/modules/[chain]/uptime/index.vue
@@ -162,7 +162,8 @@ watchEffect(() => {
{
meta: {
- i18n: 'uptime'
+ i18n: 'uptime',
+ order: 8
}
}
diff --git a/src/stores/useBlockchain.ts b/src/stores/useBlockchain.ts
index b035d296..84f4bca0 100644
--- a/src/stores/useBlockchain.ts
+++ b/src/stores/useBlockchain.ts
@@ -68,8 +68,9 @@ export const useBlockchain = defineStore('blockchain', {
to: { path: x.path.replace(':chain', this.chainName) },
icon: { icon: 'mdi-chevron-right', size: '22' },
i18n: true,
+ order: Number(x.meta.order || 100)
}))
- .sort((a, b) => a.to.path.length - b.to.path.length),
+ .sort((a, b) => a.order - b.order),
},
];
}
From ee89e438c0319e6d68d2cddc868c6db85f83d343 Mon Sep 17 00:00:00 2001
From: liangping <18786721@qq.com>
Date: Wed, 10 May 2023 20:04:23 +0800
Subject: [PATCH 5/5] add 24h changes
---
src/libs/client.ts | 12 +++--
src/modules/[chain]/staking/index.vue | 72 ++++++++++++++++++---------
src/stores/useBaseStore.ts | 4 +-
src/stores/useFormatter.ts | 1 +
4 files changed, 59 insertions(+), 30 deletions(-)
diff --git a/src/libs/client.ts b/src/libs/client.ts
index 926176a2..b3f78029 100644
--- a/src/libs/client.ts
+++ b/src/libs/client.ts
@@ -193,13 +193,17 @@ export class CosmosRestClient extends BaseRestClient {
async getBaseNodeInfo() {
return this.request(this.registry.base_tendermint_node_info, {});
}
- async getBaseValidatorsetAt(height: string | number) {
+ async getBaseValidatorsetAt(height: string | number, offset: number) {
+ console.log("offset", offset)
+ const query = `?pagination.limit=100&pagination.offset=${offset}`
return this.request(this.registry.base_tendermint_validatorsets_height, {
height,
- });
+ }, query);
}
- async getBaseValidatorsetLatest() {
- return this.request(this.registry.base_tendermint_validatorsets_latest, {});
+ async getBaseValidatorsetLatest(offset: number) {
+ console.log(offset)
+ const query = `?pagination.limit=100&pagination.offset=${offset}`
+ return this.request(this.registry.base_tendermint_validatorsets_latest, {}, query);
}
// tx
async getTxsBySender(sender: string) {
diff --git a/src/modules/[chain]/staking/index.vue b/src/modules/[chain]/staking/index.vue
index a6938922..a3547e99 100644
--- a/src/modules/[chain]/staking/index.vue
+++ b/src/modules/[chain]/staking/index.vue
@@ -16,45 +16,69 @@ const tab = ref('active');
const unbondList = ref([] as Validator[]);
const base = useBaseStore();
onMounted(() => {
- fetchChange(0);
staking.fetchInacitveValdiators().then((x) => {
unbondList.value = x;
});
});
-function fetchChange(offset: number) {
- const base = useBaseStore();
- const diff = 86400000 / base.blocktime;
- // base.fetchAbciInfo().then(h => {
- // // console.log('block:', h)
- // base.fetchValidatorByHeight(h.lastBlockHeight, offset).then(x => {
- // x.validators.forEach(v => {
- // if(v.pubkey) latest.value[pubkeyToAddress(v.pubkey.algorithm, v.pubkey.data)] = Number(v.votingPower)
- // })
- // })
- // const height = Number(h.lastBlockHeight) - diff
- // base.fetchValidatorByHeight(height > 0 ? height : 1, offset).then(old => {
- // old.validators.forEach(v => {
- // if(v.pubkey) yesterday.value[pubkeyToAddress(v.pubkey.algorithm, v.pubkey.data)] = Number(v.votingPower)
- // })
- // // console.log(Object.keys(yesterday.value).map(x => x.toUpperCase()))
- // })
- // })
+async function fetchChange() {
+ console.log('fetch changes')
+ let page = 0
+
+ let height = Number(base.latest?.block?.header?.height || 0)
+ if (height > 14400) {
+ height -= 14400
+ } else {
+ height = 1
+ }
+ // voting power in 24h ago
+ while(page < staking.validators.length && height > 0) {
+ await base.fetchValidatorByHeight(height, page).then(x => {
+ x.validators.forEach(v => {
+ yesterday.value[v.pub_key.key] = Number(v.voting_power)
+ })
+ })
+ page += 100
+ }
+
+ page = 0
+ // voting power for now
+ while(page < staking.validators.length) {
+ await base.fetchLatestValidators(page).then(x => {
+ x.validators.forEach(v => {
+ latest.value[v.pub_key.key] = Number(v.voting_power)
+ })
+ })
+ page += 100
+ }
}
+fetchChange();
+
+const changes = computed(() => {
+ const changes = {} as Record
+ Object.keys(latest.value).forEach(k => {
+ const l = latest.value[k] || 0
+ const y = yesterday.value[k] || 0
+ changes[k] = l - y
+ })
+ return changes
+})
+
const change24 = (key: Key) => {
// console.log('hex key:', consensusPubkeyToHexAddress(key))
const txt = key.key;
- const n: number = latest.value[txt];
- const o: number = yesterday.value[txt];
- // console.log( txt, n, o)
- return n > 0 && o > 0 ? n - o : 0;
+ // const n: number = latest.value[txt];
+ // const o: number = yesterday.value[txt];
+ // // console.log( txt, n, o)
+ // return n > 0 && o > 0 ? n - o : 0;
+ return changes.value[txt]
};
const change24Text = (key?: Key) => {
if (!key) return '';
const v = change24(key);
- return v !== 0 ? format.numberAndSign(v) : '';
+ return v !== 0 ? format.showChanges(v) : '';
};
const change24Color = (key?: Key) => {
diff --git a/src/stores/useBaseStore.ts b/src/stores/useBaseStore.ts
index c66acb95..ee7cc1eb 100644
--- a/src/stores/useBaseStore.ts
+++ b/src/stores/useBaseStore.ts
@@ -56,10 +56,10 @@ export const useBaseStore = defineStore('baseStore', {
},
async fetchValidatorByHeight(height?: number, offset = 0) {
- return this.blockchain.rpc.getBaseValidatorsetAt(String(height));
+ return this.blockchain.rpc.getBaseValidatorsetAt(String(height), offset);
},
async fetchLatestValidators(offset = 0) {
- return this.blockchain.rpc.getBaseValidatorsetLatest();
+ return this.blockchain.rpc.getBaseValidatorsetLatest(offset);
},
async fetchBlock(height?: number) {
return this.blockchain.rpc.getBaseBlockAt(String(height));
diff --git a/src/stores/useFormatter.ts b/src/stores/useFormatter.ts
index 2e8fa8b7..065710ed 100644
--- a/src/stores/useFormatter.ts
+++ b/src/stores/useFormatter.ts
@@ -167,6 +167,7 @@ export const useFormatter = defineStore('formatter', {
);
return validator?.description?.moniker;
},
+ // find validator by operator address
validatorFromBech32(address: string) {
if (!address) return address;
const validator = this.staking.validators.find(