diff --git a/src/libs/address.ts b/src/libs/address.ts index b9fafc8f..5f10bbb4 100644 --- a/src/libs/address.ts +++ b/src/libs/address.ts @@ -6,8 +6,11 @@ import { toBech32, toHex, } from '@cosmjs/encoding'; +import { PubKey as Ed25519PubKey } from 'cosmjs-types/cosmos/crypto/ed25519/keys'; +import { PubKey as Secp256k1PubKey } from 'cosmjs-types/cosmos/crypto/secp256k1/keys'; import { Ripemd160, sha256 } from '@cosmjs/crypto'; import type { Any } from 'cosmjs-types/google/protobuf/any'; +import type { Key } from '@/types'; export function decodeAddress(address: string) { return fromBech32(address); @@ -15,10 +18,9 @@ export function decodeAddress(address: string) { export function valoperToPrefix(valoper?: string) { if (!valoper) return ''; - // const prefixIndex = valoper.indexOf('valoper'); - // if (prefixIndex === -1) return null; - // return valoper.slice(0, prefixIndex); - return fromBech32(valoper).prefix; + const { prefix } = fromBech32(valoper); + if (!prefix) return ''; + return prefix.replace('valoper', ''); } export function operatorAddressToAccount(operAddress?: string) { @@ -35,28 +37,55 @@ export function operatorAddressToAccount(operAddress?: string) { return toBech32(prefix.replace('valoper', ''), data); } -export function consensusPubkeyToHexAddress(consensusPubkey?: Any) { - if (!consensusPubkey) return ''; - let raw = ''; +export const decodeKey = (value: Any): Key => { + const key: Key = { + '@type': value.typeUrl, + key: '', + }; + try { + switch (value.typeUrl) { + case '/cosmos.crypto.ed25519.PubKey': + key.key = toBase64(Ed25519PubKey.decode(value.value).key); + break; + default: + key.key = toBase64(Secp256k1PubKey.decode(value.value).key); + break; + } + } catch { + // already decoded + key.key = toBase64(value.value); + } + return key; +}; + +export function consensusPubkeyToKey(consensusPubkey?: Any) { + if (!consensusPubkey) return; if (consensusPubkey.typeUrl === '/cosmos.crypto.ed25519.PubKey') { - const pubkey = consensusPubkey.value; - if (pubkey) return toHex(sha256(pubkey)).slice(0, 40).toUpperCase(); + return Ed25519PubKey.decode(consensusPubkey.value).key; + } + if (consensusPubkey.typeUrl === '/cosmos.crypto.secp256k1.PubKey') { + return Secp256k1PubKey.decode(consensusPubkey.value).key; + } +} + +export function consensusPubkeyToHexAddress(consensusPubkey?: Any) { + const pubkey = consensusPubkeyToKey(consensusPubkey); + if (!pubkey) return ''; + if (consensusPubkey?.typeUrl === '/cosmos.crypto.ed25519.PubKey') { + return toHex(sha256(pubkey)).slice(0, 40).toUpperCase(); } - if (consensusPubkey.typeUrl === '/cosmos.crypto.secp256k1.PubKey') { - const pubkey = consensusPubkey.value; - if (pubkey) return toHex(new Ripemd160().update(sha256(pubkey)).digest()); + if (consensusPubkey?.typeUrl === '/cosmos.crypto.secp256k1.PubKey') { + return toHex(new Ripemd160().update(sha256(pubkey)).digest()); } - return raw; + return ''; } export function pubKeyToValcons(consensusPubkey: Any, prefix: string) { - if (consensusPubkey && consensusPubkey.value) { - const pubkey = consensusPubkey.value; - if (pubkey) { - const addressData = sha256(pubkey).slice(0, 20); - return toBech32(`${prefix}valcons`, addressData); - } + const pubkey = consensusPubkeyToKey(consensusPubkey); + if (pubkey) { + const addressData = sha256(pubkey).slice(0, 20); + return toBech32(`${prefix}valcons`, addressData); } return ''; } diff --git a/src/libs/client.ts b/src/libs/client.ts index 33428a9b..2e39c185 100644 --- a/src/libs/client.ts +++ b/src/libs/client.ts @@ -103,6 +103,7 @@ import { type AbstractRegistry, type RequestRegistry, } from './registry'; +import { decodeProto } from '@/components/dynamic'; export const DEFAULT_SDK_VERSION = '0.45.16'; export const LCD_FALLBACK_CHAINS = ['OraiBtcMainnet']; @@ -963,11 +964,14 @@ export class CosmosRestClient extends BaseRestClient { if (decodeRaw) { res.txs.forEach((tx, i) => { + const txRaw = decodeTxRaw(tx.tx); + + // txRaw.body.messages = txRaw.body.messages.map(decodeProto); // @ts-ignore - tx.txRaw = decodeTxRaw(tx.tx); + tx.txRaw = txRaw; }); } - console.log('getTxs', res); + // console.log('getTxs', res); // @ts-ignore return res; } @@ -1008,8 +1012,9 @@ export class CosmosRestClient extends BaseRestClient { type: e.type, attributes: e.attributes.map((a) => { const attribute: EventAttribute = { - key: toBase64(a.key), - value: toBase64(a.value), + key: typeof a.key === 'string' ? a.key : toBase64(a.key), + value: + typeof a.value === 'string' ? a.value : toBase64(a.value), index: false, }; return attribute; @@ -1036,9 +1041,13 @@ export class CosmosRestClient extends BaseRestClient { } async getMintInflation() { // return this.request(this.registry.mint_inflation, {}); - const res = await this.queryClient.mint.inflation(); - console.log(res); - return res; + try { + const res = await this.queryClient.mint.inflation(); + console.log('getMintInflation', res); + return res; + } catch (ex) { + console.log('getMintInflation', ex); + } } async getMintAnnualProvisions() { // return this.request(this.registry.mint_annual_provisions, {}); diff --git a/src/modules/[chain]/staking/[validator].vue b/src/modules/[chain]/staking/[validator].vue index 5c8fd4c3..f6c9c69c 100644 --- a/src/modules/[chain]/staking/[validator].vue +++ b/src/modules/[chain]/staking/[validator].vue @@ -7,6 +7,7 @@ import { operatorAddressToAccount, pubKeyToValcons, valoperToPrefix, + decodeKey, } from '@/libs'; import type { ExtraTxResponse, ExtraTxSearchResponse } from '@/libs/client'; import { stringToUint8Array } from '@/libs/utils'; @@ -18,7 +19,7 @@ import { useTxDialog, } from '@/stores'; import { PageRequest, type Coin } from '@/types'; -import { fromAscii, toBase64, toHex } from '@cosmjs/encoding'; +import { fromAscii, fromBech32, toBase64, toHex } from '@cosmjs/encoding'; import type { Event } from '@cosmjs/tendermint-rpc'; import { Icon } from '@iconify/vue'; import type { QueryValidatorDelegationsResponse } from 'cosmjs-types/cosmos/staking/v1beta1/query'; @@ -81,8 +82,14 @@ blockchain.rpc.getTxsBySender(addresses.value.account).then((x) => { txs.value = x; }); +const consensusPubkey = computed(() => { + return v.value.consensusPubkey + ? decodeKey(v.value.consensusPubkey) + : undefined; +}); + const apr = computed(() => { - const rate = v.value?.commission?.commissionRates || 0; + const rate = Number(v.value?.commission?.commissionRates.rate || 0) / 1e18; const inflation = useMintStore().inflation; if (Number(inflation)) { return format.percent((1 - Number(rate)) * Number(inflation)); @@ -235,7 +242,6 @@ const selectedEventType = ref(EventType.Delegate); function loadPowerEvents(p: number, type: EventType) { selectedEventType.value = type; page.setPage(p); - page.setPageSize(5); blockchain.rpc .getTxs( [ @@ -408,7 +414,7 @@ function mapDelegators(messages: any[]) { bondStatusToJSON(v.status) .toLowerCase() .replace(/^bond_status/, '') - .replaceAll(/_(.)/g, (m, g) => ' ' + g.toUpperCase()) + .replaceAll(/_(.)/g, ' $1') .trim() }} @@ -595,7 +601,7 @@ function mapDelegators(messages: any[]) { variant="outlined" class="mr-1 mb-1 badge text-xs" > - {{ format.formatToken2(i) }} + {{ format.formatToken2(i, 1e18) }}
{{ $t('staking.outstanding') }} {{ $t('account.rewards') }} @@ -605,7 +611,7 @@ function mapDelegators(messages: any[]) { :key="`reward-${k}`" class="mr-1 mb-1 badge text-xs" > - {{ format.formatToken2(i) }} + {{ format.formatToken2(i, 1e18) }}
@@ -689,10 +695,10 @@ function mapDelegators(messages: any[]) { icon="mdi:content-copy" class="ml-2 cursor-pointer" v-show="v.consensusPubkey" - @click="copyWebsite(JSON.stringify(v.consensusPubkey) || '')" + @click="copyWebsite(JSON.stringify(consensusPubkey) || '')" />
-
{{ v.consensusPubkey }}
+
{{ consensusPubkey }}
diff --git a/src/modules/[chain]/staking/index.vue b/src/modules/[chain]/staking/index.vue index 0e2afefc..af60a2c2 100644 --- a/src/modules/[chain]/staking/index.vue +++ b/src/modules/[chain]/staking/index.vue @@ -15,10 +15,8 @@ import { formatSeconds } from '@/libs/utils'; import type { Validator } from 'cosmjs-types/cosmos/staking/v1beta1/staking'; import type { Params } from 'cosmjs-types/cosmos/slashing/v1beta1/slashing'; import { fromAscii, toBase64 } from '@cosmjs/encoding'; -import { decodeProto } from '@/components/dynamic'; import type { Any } from 'cosmjs-types/google/protobuf/any'; -import { PubKey as Ed25519PubKey } from 'cosmjs-types/cosmos/crypto/ed25519/keys'; -import { PubKey as Secp256k1PubKey } from 'cosmjs-types/cosmos/crypto/secp256k1/keys'; +import { decodeKey } from '@/libs'; const staking = useStakingStore(); const base = useBaseStore(); @@ -98,27 +96,6 @@ const change24 = (key: Key) => { return changes.value[txt]; }; -const decodeKey = (value: Any): Key => { - const key: Key = { - '@type': value.typeUrl, - key: '', - }; - try { - switch (value.typeUrl) { - case '/cosmos.crypto.ed25519.PubKey': - key.key = toBase64(Ed25519PubKey.decode(value.value).key); - break; - default: - key.key = toBase64(Secp256k1PubKey.decode(value.value).key); - break; - } - } catch { - // already decoded - key.key = toBase64(value.value); - } - return key; -}; - const change24Text = (value?: Any) => { if (!value) return ''; const key = decodeKey(value); diff --git a/src/stores/useFormatter.ts b/src/stores/useFormatter.ts index 91bc32e8..a00ca06c 100644 --- a/src/stores/useFormatter.ts +++ b/src/stores/useFormatter.ts @@ -149,8 +149,8 @@ export const useFormatter = defineStore('formatter', { formatTokenAmount(token: { denom: string; amount: string }) { return this.formatToken(token, false); }, - formatToken2(token: { denom: string; amount: string }, withDenom = true) { - return this.formatToken(token, true, '0,0.[00]'); + formatToken2(token: { denom: string; amount: string }, decimal?: number) { + return this.formatToken(token, true, '0,0.[00]', undefined, decimal); }, findGlobalAssetConfig(denom: string) { @@ -237,10 +237,17 @@ export const useFormatter = defineStore('formatter', { token?: { denom: string; amount: string }, withDenom = true, fmt = '0,0.[0]', - mode = 'local' + mode = 'local', + decimal?: number ): string { if (token && token.amount && token?.denom) { let amount = Number(token.amount); + + if (decimal) { + // could be DecCoin + amount /= decimal; + } + let denom = token.denom; let conf =