diff --git a/src/layouts/components/ChainProfile.vue b/src/layouts/components/ChainProfile.vue index b1049d80..b9d4628d 100644 --- a/src/layouts/components/ChainProfile.vue +++ b/src/layouts/components/ChainProfile.vue @@ -83,13 +83,15 @@ chainStore.$subscribe((m, s) => {
-
+
#{{ baseStore.latest?.block?.header?.height || chainStore.chainName || '' }}
+
+ diff --git a/src/libs/client.ts b/src/libs/client.ts index 391af7b3..d6ffe9f8 100644 --- a/src/libs/client.ts +++ b/src/libs/client.ts @@ -26,8 +26,8 @@ export class BaseRestClient { } export class CosmosRestClient extends BaseRestClient { - constructor(endpoint: string) { - super(endpoint, DEFAULT) + static newDefault(endpoint: string) { + return new CosmosRestClient(endpoint, DEFAULT) } // Auth Module async getAuthAccounts() { diff --git a/src/modules/[chain]/indexStore.ts b/src/modules/[chain]/indexStore.ts index 83277b17..771976df 100644 --- a/src/modules/[chain]/indexStore.ts +++ b/src/modules/[chain]/indexStore.ts @@ -72,7 +72,6 @@ export const useIndexModule = defineStore('module-index', { total_volumes: [] as number[], }, communityPool: [] as { amount: string; denom: string }[], - proposals: {} as PaginatedProposals, tally: {} as Record, }; }, @@ -130,6 +129,11 @@ export const useIndexModule = defineStore('module-index', { return staking.pool; }, + proposals() { + const gov = useGovStore() + return gov.proposals['2'] + }, + stats() { const base = useBaseStore(); const bank = useBankStore(); @@ -205,10 +209,10 @@ export const useIndexModule = defineStore('module-index', { denom: t.denom, })); }); - const gov = useGovStore(); - gov.fetchProposals('2').then((x) => { - this.proposals = x; - }); + // const gov = useGovStore(); + // gov.fetchProposals('2').then((x) => { + // this.proposals = x; + // }); }, tickerColor(color: string) { return colorMap(color); diff --git a/src/modules/wallet/accounts.vue b/src/modules/wallet/accounts.vue index 47f1a442..e1248547 100644 --- a/src/modules/wallet/accounts.vue +++ b/src/modules/wallet/accounts.vue @@ -1,15 +1,278 @@ +
+
+
+
+

Accounts

+
+
+ + Manage all your assets in one page +
+
+
+
+ + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
AccountDelegationBalance
+ + + +
+
+
+ +
+
+
+
{{ acc.chainName }}
+ +
+
+
+
+
+ {{ format.formatToken(acc.delegation, true, '0,0.[0000]', 'all') }} +
${{ + format.tokenValue(acc.delegation) }}
+
+
+
+ + {{ format.formatToken(b, true, '0,0.[0000]', 'all') }} +
${{ format.tokenValue(b) }} ({{ + format.showChanges(format.priceChanges(b.denom)) }}%)
+
+
+
+ +
+
+ +
+
+
+ + +
diff --git a/src/modules/wallet/portfolio.vue b/src/modules/wallet/portfolio.vue new file mode 100644 index 00000000..cb7a60f4 --- /dev/null +++ b/src/modules/wallet/portfolio.vue @@ -0,0 +1,87 @@ + + diff --git a/src/modules/wallet/portfollio.vue b/src/modules/wallet/portfollio.vue deleted file mode 100644 index 47f1a442..00000000 --- a/src/modules/wallet/portfollio.vue +++ /dev/null @@ -1,15 +0,0 @@ - - diff --git a/src/modules/wallet/utils.ts b/src/modules/wallet/utils.ts new file mode 100644 index 00000000..bdc90688 --- /dev/null +++ b/src/modules/wallet/utils.ts @@ -0,0 +1,49 @@ +import { useDashboard } from "@/stores" +import type { Coin } from "@/types" +import { fromBech32, toBech32 } from "@cosmjs/encoding" + +export interface AccountEntry { + chainName: string, + logo: string, + address: string, + coinType: string, + endpoint?: string, + delegation?: Coin, + balances?: Coin[], +} + +export function scanLocalKeys() { + const connected = [] as {cosmosAddress: string, hdPath: string}[] + for (let i = 0; i < localStorage.length; i++) { + const key = localStorage.key(i) + if (key?.startsWith("m/44")) { + const wallet = JSON.parse(localStorage.getItem(key) || "") + if (wallet) { + connected.push(wallet) + } + } + } + return connected + } + + +export function scanCompatibleAccounts() { + const dashboard = useDashboard() + const available = [] as AccountEntry[] + scanLocalKeys().forEach(wallet => { + dashboard.favorite.forEach(chainName => { + const chain = dashboard.chains[chainName] + if (chain && wallet.hdPath.indexOf(chain.coinType) === 6) { + const { data } = fromBech32(wallet.cosmosAddress) + available.push({ + chainName: chain.chainName, + logo: chain.logo, + address: toBech32(chain.bech32Prefix, data), + coinType: chain.coinType, + endpoint: chain.endpoints.rest?.at(0)?.address + }) + } + }) + }) + return available + } \ No newline at end of file diff --git a/src/stores/useBlockchain.ts b/src/stores/useBlockchain.ts index 84f4bca0..9e11c3c8 100644 --- a/src/stores/useBlockchain.ts +++ b/src/stores/useBlockchain.ts @@ -44,8 +44,8 @@ export const useBlockchain = defineStore('blockchain', { // if(cointype === "60") { // return `m/44'/${cointype}` // } - // return `m/44'/${cointype}/0'/0/0` - return "connected-wallet" + return `m/44'/${cointype}/0'/0/0` + //return "connected-wallet" }, dashboard() { return useDashboard(); diff --git a/src/stores/useFormatter.ts b/src/stores/useFormatter.ts index b3978c05..42c1d2c7 100644 --- a/src/stores/useFormatter.ts +++ b/src/stores/useFormatter.ts @@ -73,7 +73,18 @@ export const useFormatter = defineStore('formatter', { const prices = this.dashboard.prices[id]; return prices; }, - price(denom: string, currency = 'usd') { + priceColor(denom: string, currency = "usd") { + const change = this.priceChanges(denom, currency) + switch (true) { + case change > 0: + return "text-success" + case change < 0: + return "text-error" + default: + return "" + } + }, + price(denom: string, currency = "usd") { const info = this.priceInfo(denom); return info ? info[currency] || 0 : 0; }, @@ -82,18 +93,22 @@ export const useFormatter = defineStore('formatter', { return info ? info[`${currency}_24h_change`] || 0 : 0; }, showChanges(v: number) { - return numeral(v).format('+0,0.[00]'); + return v!==0 ? numeral(v).format("+0,0.[00]"): "" }, - tokenValue(token: Coin) { - // find the symbol, - const symbol = this.dashboard.coingecko[token.denom]?.symbol || ''; + tokenValue(token?: Coin) { + return token ? numeral(this.formatTokenAmount(token)).format('0,0.[00]') : "" + }, + tokenValueNumber(token?: Coin) { + if(!token) return 0 + // 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]'); + const amount = Number(token.amount) / (10 ** exponent) + const value = amount * this.price(token.denom) + return value }, formatTokenAmount(token: { denom: string; amount: string }) { return this.formatToken(token, false); @@ -101,10 +116,21 @@ export const useFormatter = defineStore('formatter', { formatToken2(token: { denom: string; amount: string }, withDenom = true) { return this.formatToken(token, true, '0,0.[00]'); }, + findGlobalAssetConfig(denom: string) { + const chains = Object.values(this.dashboard.chains) + for ( let i =0; i < chains.length; i++ ) { + const conf = chains[i].assets.find(a => a.base === denom) + if(conf) { + return conf + } + } + return null + }, formatToken( - token: { denom: string; amount: string }, + token?: { denom: string; amount: string }, withDenom = true, - fmt = '0.0a' + fmt = '0.0a', + mode = 'local' ): string { if (token && token.amount && token?.denom) { let amount = Number(token.amount); @@ -117,9 +143,10 @@ export const useFormatter = defineStore('formatter', { } } - const conf = this.blockchain.current?.assets?.find( + const conf = mode === 'local'? this.blockchain.current?.assets?.find( (x) => x.base === token.denom || x.base.denom === token.denom - ); + ): this.findGlobalAssetConfig(token.denom) + if (conf) { let unit = { exponent: 6, denom: '' }; // find the max exponent for display diff --git a/src/stores/useGovStore.ts b/src/stores/useGovStore.ts index 13e42169..9bb628da 100644 --- a/src/stores/useGovStore.ts +++ b/src/stores/useGovStore.ts @@ -23,7 +23,9 @@ export const useGovStore = defineStore('govStore', { }, actions: { initial() { + this.$reset() this.fetchParams(); + this.fetchProposals("2"); }, async fetchProposals(status: string, pagination?: PageRequest) { if (!this.loading[status]) {